From 1e5ee985cad0d842b748727678b73045970c5f29 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sat, 8 Nov 2025 23:15:25 +0100 Subject: [PATCH 001/194] (core) add as_bytes_mut variant --- modules/stormkit/core/typesafe/byte.mpp | 167 +++++++++++---------- modules/stormkit/core/utils/filesystem.mpp | 51 +++---- modules/stormkit/gpu/resource/buffer.mpp | 54 +++---- src/image/png.mpp | 89 ++++------- src/image/qoi.mpp | 58 +++---- 5 files changed, 181 insertions(+), 238 deletions(-) diff --git a/modules/stormkit/core/typesafe/byte.mpp b/modules/stormkit/core/typesafe/byte.mpp index 7523b1545..adb7e3026 100644 --- a/modules/stormkit/core/typesafe/byte.mpp +++ b/modules/stormkit/core/typesafe/byte.mpp @@ -21,7 +21,17 @@ import :utils.tags; namespace stdr = std::ranges; +template +consteval auto get_byte_extent_value_of() { + if constexpr (EXTENT == std::dynamic_extent) return EXTENT; + else if constexpr (stormkit::meta::Is, void>) + return EXTENT; + else + return EXTENT * sizeof(T); +} + export namespace stormkit { inline namespace core { + using std::byte; using Byte = std::byte; using ByteView = std::span; template @@ -39,33 +49,38 @@ export namespace stormkit { inline namespace core { [[nodiscard]] constexpr auto byte_swap(const T& value) noexcept -> T; - template - [[nodiscard]] - constexpr auto as_bytes(T& container) noexcept -> std::span>; + // std::span + using std::as_bytes; - template + template [[nodiscard]] - constexpr auto as_bytes(T ptr, usize size = 1) noexcept - -> std::span, Byte>>; + constexpr auto as_bytes(const T* const ptr, usize size = 1) noexcept -> std::span; template [[nodiscard]] - constexpr auto as_bytes(T& value) noexcept -> std::span>; + constexpr auto as_bytes(const T& value) noexcept -> std::span; + + // std::span + template + [[nodiscard]] + constexpr auto as_bytes_mut(std::span container) noexcept + -> std::span()>; + + template + [[nodiscard]] + constexpr auto as_bytes_mut(T* const ptr, usize size = 1) noexcept -> std::span; template [[nodiscard]] - constexpr auto as_bytes(T& value, Force) noexcept -> std::span>; + constexpr auto as_bytes_mut(T& value) noexcept -> std::span; - template - requires(stdr::range and meta::IsOneOf) + template [[nodiscard]] - constexpr auto bytes_as(Bytes& bytes) noexcept -> T; + constexpr auto bytes_as(std::span bytes) noexcept -> const T&; - template - requires(meta::IsOneOf) + template [[nodiscard]] - constexpr auto bytes_as(Bytes& bytes) noexcept - -> meta::ForwardConst; + constexpr auto bytes_mut_as(std::span bytes) noexcept -> T&; template [[nodiscard]] @@ -73,7 +88,7 @@ export namespace stormkit { inline namespace core { namespace literals { [[nodiscard]] - constexpr auto operator""_b(unsigned long long value) noexcept -> Byte; + constexpr auto operator""_b(unsigned long long value) noexcept -> byte; [[nodiscard]] constexpr auto operator""_kb(unsigned long long x) noexcept -> u64; @@ -105,15 +120,14 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline constexpr auto zero_bytes(T& value) noexcept -> void { - auto bytes = as_bytes(value); - - std::memset(&bytes[0], 0, stdr::size(bytes)); + constexpr auto zero_bytes(T& value) noexcept -> void { + auto bytes = as_bytes_mut(value); + stdr::fill(bytes, byte { 0 }); } template STORMKIT_FORCE_INLINE - inline constexpr auto zeroed() noexcept -> T { + constexpr auto zeroed() noexcept -> T { auto data = T {}; zero_bytes(data); return data; @@ -122,149 +136,136 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - STORMKIT_CONST STORMKIT_FORCE_INLINE - inline constexpr auto byte_swap(const T& value) noexcept -> T { - auto repr = std::bit_cast>(value); + constexpr auto byte_swap(const T& value) noexcept -> T { + if constexpr (meta::IsIntegral) return std::byteswap(value); + else { + auto repr = std::bit_cast>(value); - stdr::reverse(repr); + stdr::reverse(repr); - return std::bit_cast(repr); + return std::bit_cast(repr); + } } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - STORMKIT_PURE - inline constexpr auto as_bytes(T& container) noexcept - -> std::span> { - return as_bytes(stdr::data(container), stdr::size(container)); + constexpr auto as_bytes(const T* const ptr, usize size) noexcept -> std::span { + return std::as_bytes(std::span { ptr, size }); } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - STORMKIT_PURE - inline constexpr auto as_bytes(T ptr, usize size) noexcept - -> std::span, Byte>> { - auto raw_ptr = std::to_address(ptr); - - using PtrType = decltype(raw_ptr); - using ElementType = meta::ElementType; - using ByteType = meta::ForwardConst; - - constexpr auto byte_count = []() { - if constexpr (meta::Is) return 1; - else - return sizeof(ElementType); - }(); - - return std::span { std::bit_cast(raw_ptr), size * byte_count }; + constexpr auto as_bytes(const T& value) noexcept -> std::span { + return std::as_bytes(std::span { &value, 1 }); } ///////////////////////////////////// ///////////////////////////////////// - template + template + constexpr auto as_bytes_mut(std::span container) noexcept + -> std::span()> { + return std::as_writable_bytes(container); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - STORMKIT_PURE - inline constexpr auto as_bytes(T& value) noexcept -> std::span> { - return as_bytes(&value, 1); + constexpr auto as_bytes_mut(T* const ptr, usize size) noexcept -> std::span { + return std::as_writable_bytes(std::span { ptr, size }); } ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE - STORMKIT_PURE - inline constexpr auto as_bytes(T& value, Force) noexcept - -> std::span> { - return as_bytes(&value, 1); + constexpr auto as_bytes_mut(T& value) noexcept -> std::span { + return std::as_writable_bytes(std::span { &value, 1 }); } ///////////////////////////////////// ///////////////////////////////////// - template - requires(meta::IsOneOf) + template STORMKIT_FORCE_INLINE - STORMKIT_PURE - inline constexpr auto bytes_as(Bytes& bytes) noexcept - -> meta::ForwardConst { - return *std::bit_cast< - meta::ForwardConst*>(stdr::data(bytes)); + constexpr auto bytes_mut_as(std::span bytes) noexcept -> const T& { + if constexpr (EXTENT != std::dynamic_extent) EXPECTS(EXTENT == sizeof(T)); + EXPECTS(stdr::size(bytes) == sizeof(T)); + return *std::bit_cast(stdr::data(bytes)); } ///////////////////////////////////// ///////////////////////////////////// - template - requires(stdr::range and meta::IsOneOf) + template STORMKIT_FORCE_INLINE - STORMKIT_PURE - inline constexpr auto bytes_as(Bytes& bytes) noexcept -> T { - using ElementType = typename T::element_type; - return T { std::bit_cast(stdr::data(bytes)), - stdr::size(bytes) * sizeof(ElementType) }; + constexpr auto bytes_mut_as(std::span bytes) noexcept -> T& { + if constexpr (EXTENT != std::dynamic_extent) EXPECTS(EXTENT == sizeof(T)); + EXPECTS(stdr::size(bytes) == sizeof(T)); + return *std::bit_cast(stdr::data(bytes)); } ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE STORMKIT_PURE - inline constexpr auto into_bytes(const T (&bytes)[N]) noexcept -> ByteArray { - EXPECTS(static_cast(static_cast(bytes[0])) == bytes[0]); + constexpr auto into_bytes(const T (&bytes)[N]) noexcept -> ByteArray { + EXPECTS(static_cast(static_cast(bytes[0])) == bytes[0]); auto out = ByteArray {}; - auto i = 0uz; - for (auto&& byte : bytes) out[i++] = static_cast(byte); + auto i = 0_usize; + for (auto&& byte : bytes) out[i++] = static_cast(byte); return out; } namespace literals { ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE STORMKIT_INTRINSIC - inline constexpr auto operator""_b(unsigned long long value) noexcept -> Byte { - return static_cast(value); + STORMKIT_FORCE_INLINE STORMKIT_CONST STORMKIT_INTRINSIC + inline constexpr auto operator""_b(unsigned long long value) noexcept -> byte { + return static_cast(value); } ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE + STORMKIT_FORCE_INLINE STORMKIT_CONST inline constexpr auto operator""_kb(unsigned long long x) noexcept -> u64 { return x * 1000ULL; } ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE + STORMKIT_FORCE_INLINE STORMKIT_CONST inline constexpr auto operator""_mb(unsigned long long x) noexcept -> u64 { return x * 1000_kb; } ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE + STORMKIT_FORCE_INLINE STORMKIT_CONST inline constexpr auto operator""_gb(unsigned long long x) noexcept -> u64 { return x * 1000_mb; } ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE + STORMKIT_FORCE_INLINE STORMKIT_CONST inline constexpr auto operator""_kib(unsigned long long x) noexcept -> u64 { return x * 1024; } ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE + STORMKIT_FORCE_INLINE STORMKIT_CONST inline constexpr auto operator""_mib(unsigned long long x) noexcept -> u64 { return x * 1024_kib; } ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE + STORMKIT_FORCE_INLINE STORMKIT_CONST inline constexpr auto operator""_gib(unsigned long long x) noexcept -> u64 { return x * 1024_mib; } diff --git a/modules/stormkit/core/utils/filesystem.mpp b/modules/stormkit/core/utils/filesystem.mpp index a213fd5b4..0456dd258 100644 --- a/modules/stormkit/core/utils/filesystem.mpp +++ b/modules/stormkit/core/utils/filesystem.mpp @@ -69,9 +69,8 @@ export { struct PrivateFuncTag {}; public: - static auto open(const stdfs::path& path, Access access) noexcept - -> Expected; - auto close() noexcept; + static auto open(const stdfs::path& path, Access access) noexcept -> Expected; + auto close() noexcept; ~Descriptor() noexcept; @@ -114,19 +113,15 @@ export { using TextFile = Descriptor; template - auto read_text_to(const stdfs::path& path, - std::span> output) noexcept -> Expected; + auto read_text_to(const stdfs::path& path, std::span> output) noexcept -> Expected; template - auto read_text(const stdfs::path& path) noexcept - -> Expected>>; + auto read_text(const stdfs::path& path) noexcept -> Expected>>; auto read_to(const stdfs::path& path, std::span output) noexcept -> Expected; auto read(const stdfs::path& path) noexcept -> Expected>; template - auto write_text(const stdfs::path& path, - std::span> data) noexcept - -> Expected; + auto write_text(const stdfs::path& path, std::span> data) noexcept -> Expected; auto write(const stdfs::path& path, std::span data) noexcept -> Expected; }}} // namespace stormkit::core::io @@ -143,8 +138,7 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// //////////////////////////////////////// template - inline auto Descriptor::open(const stdfs::path& path, Access access) noexcept - -> Expected> { + inline auto Descriptor::open(const stdfs::path& path, Access access) noexcept -> Expected> { const auto p = path.string(); const auto posix_access = [&access]() noexcept { if (access == Access::READ) return O_RDONLY; @@ -183,8 +177,7 @@ namespace stormkit { inline namespace core { namespace io { const auto // err = _sopen_s(&ret, stdr::data(p), posix_access | text_mode, _SH_DENYNO, // win32_access); - err - = _sopen_s(&ret, stdr::data(p), posix_access | text_mode, _SH_SECURE, win32_access); + err = _sopen_s(&ret, stdr::data(p), posix_access | text_mode, _SH_SECURE, win32_access); if (err != 0) return std::unexpected { SystemError::from_errno() }; #else const auto ret = ::open(stdr::data(p), posix_access); @@ -267,7 +260,8 @@ namespace stormkit { inline namespace core { namespace io { inline auto Descriptor::read_to(std::span out) noexcept -> Expected requires(mode == Mode::UTF8 or mode == Mode::AINSI) { - return read_to(as_bytes(out)); + static_assert(stdr::contiguous_range>); + return read_to(as_bytes_mut(out)); } //////////////////////////////////////// @@ -277,7 +271,7 @@ namespace stormkit { inline namespace core { namespace io { inline auto Descriptor::read_to(std::span out) noexcept -> Expected requires(mode == Mode::WIDE) { - return read_to(as_bytes(out)); + return read_to(as_bytes_mut(out)); } //////////////////////////////////////// @@ -392,27 +386,24 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto read_text_to(const stdfs::path& path, - std::span> out) noexcept - -> Expected { - return TextFile::open(path, Access::READ) - .and_then([&out](auto&& file) mutable noexcept { - EXPECTS(file.size() >= stdr::size(out)); - return file.read_to(out); - }); + inline auto read_text_to(const stdfs::path& path, std::span> out) noexcept -> Expected { + return TextFile::open(path, Access::READ).and_then([&out](auto&& file) mutable noexcept { + EXPECTS(file.size() >= stdr::size(out)); + return file.read_to(out); + }); } //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto read_text(const stdfs::path& path) noexcept - -> Expected>> { + inline auto read_text(const stdfs::path& path) noexcept -> Expected>> { auto out = std::vector> {}; return TextFile::open(path, Access::READ) .and_then([&out](auto&& file) mutable noexcept { out.resize(file.size()); - return file.read_to(out); + static_assert(core::meta::Is, decltype(out)>); + return file.read_to(std::span> { out }); }) .transform(monadic::discard()) .transform(monadic::consume(out)); @@ -446,8 +437,7 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto write_text(const stdfs::path& path, - std::span> data) noexcept + inline auto write_text(const stdfs::path& path, std::span> data) noexcept -> Expected { return TextFile::open(path, Access::WRITE).and_then(bind_back(&File::write, data)); } @@ -455,8 +445,7 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto write(const stdfs::path& path, std::span data) noexcept - -> Expected { + inline auto write(const stdfs::path& path, std::span data) noexcept -> Expected { return File::open(path, Access::WRITE).and_then(std::bind_back(&File::write, data)); } }}} // namespace stormkit::core::io diff --git a/modules/stormkit/gpu/resource/buffer.mpp b/modules/stormkit/gpu/resource/buffer.mpp index dea610bc0..47352871c 100644 --- a/modules/stormkit/gpu/resource/buffer.mpp +++ b/modules/stormkit/gpu/resource/buffer.mpp @@ -26,8 +26,7 @@ export namespace stormkit::gpu { struct CreateInfo { BufferUsageFlag usages; usize size; - MemoryPropertyFlag property = MemoryPropertyFlag::HOST_VISIBLE - | MemoryPropertyFlag::HOST_COHERENT; + MemoryPropertyFlag property = MemoryPropertyFlag::HOST_VISIBLE | MemoryPropertyFlag::HOST_COHERENT; }; static constexpr auto DEBUG_TYPE = DebugObjectType::BUFFER; @@ -40,12 +39,10 @@ export namespace stormkit::gpu { Buffer(Buffer&&) noexcept; auto operator=(Buffer&&) noexcept -> Buffer&; - static auto create(const Device& device, - const CreateInfo& info, - bool persistently_mapped = false) noexcept -> Expected; - static auto allocate(const Device& device, - const CreateInfo& info, - bool persistently_mapped = false) noexcept -> Expected>; + static auto create(const Device& device, const CreateInfo& info, bool persistently_mapped = false) noexcept + -> Expected; + static auto allocate(const Device& device, const CreateInfo& info, bool persistently_mapped = false) noexcept + -> Expected>; [[nodiscard]] auto usages() const noexcept -> BufferUsageFlag; @@ -65,8 +62,7 @@ export namespace stormkit::gpu { auto data(this Self& self) noexcept -> core::meta::ForwardConst*; template [[nodiscard]] - auto data(this Self& self, usize size) noexcept - -> core::meta::If, ByteView, MutableByteView>; + auto data(this Self& self, usize size) noexcept -> core::meta::If, ByteView, MutableByteView>; template [[nodiscard]] @@ -86,10 +82,7 @@ export namespace stormkit::gpu { [[nodiscard]] auto native_handle() const noexcept -> VkBuffer; - Buffer(const Device& device, - const CreateInfo& info, - bool persistently_mapping, - PrivateFuncTag) noexcept; + Buffer(const Device& device, const CreateInfo& info, bool persistently_mapping, PrivateFuncTag) noexcept; private: static auto find_memory_type(u32, @@ -133,16 +126,15 @@ export namespace stormkit::gpu { namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - inline Buffer::Buffer(const Device& device, - const CreateInfo& info, - bool persistently_mapped, - PrivateFuncTag) noexcept - : m_usages { info.usages }, m_size { info.size }, m_memory_property { info.property }, - m_is_persistently_mapped { persistently_mapped }, m_vk_device { device.native_handle() }, + inline Buffer::Buffer(const Device& device, const CreateInfo& info, bool persistently_mapped, PrivateFuncTag) noexcept + : m_usages { info.usages }, + m_size { info.size }, + m_memory_property { info.property }, + m_is_persistently_mapped { persistently_mapped }, + m_vk_device { device.native_handle() }, m_vk_device_table { as_ref(device.device_table()) }, m_vma_allocator { device.allocator() }, - m_vk_handle { [vk_device_table = *m_vk_device_table, - vk_device = m_vk_device](auto handle) noexcept { + m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { vk_device_table.vkDestroyBuffer(vk_device, handle, nullptr); } } { } @@ -171,9 +163,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Buffer::create(const Device& device, - const CreateInfo& info, - bool persistently_mapped) noexcept -> Expected { + inline auto Buffer::create(const Device& device, const CreateInfo& info, bool persistently_mapped) noexcept + -> Expected { auto buffer = Buffer { device, info, persistently_mapped, PrivateFuncTag {} }; return buffer.do_init(info.property).transform(core::monadic::consume(buffer)); } @@ -181,11 +172,9 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Buffer::allocate(const Device& device, - const CreateInfo& info, - bool persistently_mapped) noexcept -> Expected> { - auto - buffer = std::make_unique(device, info, persistently_mapped, PrivateFuncTag {}); + inline auto Buffer::allocate(const Device& device, const CreateInfo& info, bool persistently_mapped) noexcept + -> Expected> { + auto buffer = std::make_unique(device, info, persistently_mapped, PrivateFuncTag {}); return buffer->do_init(info.property).transform(core::monadic::consume(buffer)); } @@ -226,7 +215,7 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto Buffer::map(ioffset offset, usize size) noexcept -> Expected { EXPECTS(m_vma_allocation and m_vk_handle); - return map(offset).transform([&size](auto&& ptr) noexcept { return as_bytes(ptr, size); }); + return map(offset).transform([&size](auto&& ptr) noexcept { return as_bytes_mut(ptr, size); }); } ///////////////////////////////////// @@ -305,8 +294,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Buffer::upload(std::span data, ioffset offset) noexcept - -> Expected { + inline auto Buffer::upload(std::span data, ioffset offset) noexcept -> Expected { EXPECTS(stdr::size(data) <= m_size); if (m_is_persistently_mapped) { diff --git a/src/image/png.mpp b/src/image/png.mpp index 8af185424..0f85e89ea 100644 --- a/src/image/png.mpp +++ b/src/image/png.mpp @@ -18,18 +18,18 @@ import stormkit.image; export namespace stormkit::image::details { [[nodiscard]] - auto load_png(std::span data) noexcept - -> std::expected; + auto load_png(std::span data) noexcept -> std::expected; [[nodiscard]] auto save_png(const image::Image& image, const std::filesystem::path& filepath) noexcept -> std::expected; [[nodiscard]] - auto save_png(const image::Image& image) noexcept - -> std::expected, image::Image::Error>; + auto save_png(const image::Image& image) noexcept -> std::expected, image::Image::Error>; } // namespace stormkit::image::details +namespace stdr = std::ranges; + namespace stormkit::image::details { template using Unexpected = std::unexpected; @@ -50,12 +50,12 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// static auto read_func(png_struct* ps, png_byte* d, png_size_t length) noexcept -> void { - auto& param = *reinterpret_cast(png_get_io_ptr(ps)); + auto& param = *std::bit_cast(png_get_io_ptr(ps)); - auto _d = as_bytes(d, length); + auto _d = as_bytes_mut(d, length); auto data = param.data.subspan(param.readed, length); - std::ranges::copy(data, std::ranges::begin(_d)); + stdr::copy(data, stdr::begin(_d)); param.readed += length; } @@ -63,43 +63,39 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// static auto write_func(png_struct* ps, png_byte* d, png_size_t length) -> void { - auto& param = *reinterpret_cast(png_get_io_ptr(ps)); + auto& param = *std::bit_cast(png_get_io_ptr(ps)); auto _d = as_bytes(d, length); param.data.reserve(std::size(param.data) + length); - std::ranges::copy(_d, std::back_inserter(param.data)); + stdr::copy(_d, std::back_inserter(param.data)); } } // namespace png ///////////////////////////////////// ///////////////////////////////////// - auto load_png(std::span data) noexcept - -> std::expected { + auto load_png(std::span data) noexcept -> std::expected { auto image_memory = std::vector {}; auto format = Format {}; auto extent = math::Extent3 {}; auto read_param = png::ReadParam { 8u, data }; - auto sig = reinterpret_cast(std::data(data)); + auto sig = std::bit_cast(std::data(data)); if (!png_check_sig(sig, 8u)) - return std::unexpected(Error { - .reason = Reason::FAILED_TO_PARSE, - .str_error = "[libpng] Failed to validate PNG signature" }); + return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, + .str_error = "[libpng] Failed to validate PNG signature" }); auto png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); if (!png_ptr) - return std::unexpected(Error { - .reason = Reason::FAILED_TO_PARSE, - .str_error = "[libpng] Failed to init (png_create_read_struct)" }); + return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, + .str_error = "[libpng] Failed to init (png_create_read_struct)" }); auto info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, nullptr, nullptr); - return std::unexpected(Error { - .reason = Reason::FAILED_TO_PARSE, - .str_error = "[libpng] Failed to init (png_create_info_struct)" }); + return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, + .str_error = "[libpng] Failed to init (png_create_info_struct)" }); } png_set_read_fn(png_ptr, &read_param, png::read_func); @@ -109,15 +105,7 @@ namespace stormkit::image::details { auto bit_depth = 0; auto color_type = 0; - png_get_IHDR(png_ptr, - info_ptr, - &extent.width, - &extent.height, - &bit_depth, - &color_type, - nullptr, - nullptr, - nullptr); + png_get_IHDR(png_ptr, info_ptr, &extent.width, &extent.height, &bit_depth, &color_type, nullptr, nullptr, nullptr); if (color_type == PNG_COLOR_TYPE_GRAY) png_set_expand_gray_1_2_4_to_8(png_ptr); else if (color_type == PNG_COLOR_TYPE_PALETTE) { @@ -127,15 +115,7 @@ namespace stormkit::image::details { if (bit_depth < 8) png_set_packing(png_ptr); if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); - png_get_IHDR(png_ptr, - info_ptr, - &extent.width, - &extent.height, - &bit_depth, - &color_type, - nullptr, - nullptr, - nullptr); + png_get_IHDR(png_ptr, info_ptr, &extent.width, &extent.height, &bit_depth, &color_type, nullptr, nullptr, nullptr); switch (color_type) { case PNG_COLOR_TYPE_GRAY: { @@ -188,7 +168,7 @@ namespace stormkit::image::details { for (auto i : range(extent.height)) row_pointers[i] = &buff_pos[row_bytes * i]; - png_read_image(png_ptr, reinterpret_cast(std::data(row_pointers))); + png_read_image(png_ptr, std::bit_cast(std::data(row_pointers))); png_read_end(png_ptr, info_ptr); png_destroy_info_struct(png_ptr, &info_ptr); @@ -210,40 +190,35 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto save_png(const image::Image&, const std::filesystem::path&) noexcept - -> std::expected { + auto save_png(const image::Image&, const std::filesystem::path&) noexcept -> std::expected { assert(false, "Not implemented yet !"); return {}; } ///////////////////////////////////// ///////////////////////////////////// - auto save_png(const image::Image& image) noexcept - -> std::expected, image::Image::Error> { + auto save_png(const image::Image& image) noexcept -> std::expected, image::Image::Error> { auto output = std::vector {}; auto write_param = png::WriteParam { output }; auto png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); if (!png_ptr) - return std::unexpected(Error { - .reason = Reason::FAILED_TO_PARSE, - .str_error = "[libpng] Failed to init (png_create_write_struct)" }); + return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, + .str_error = "[libpng] Failed to init (png_create_write_struct)" }); auto info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, nullptr); - return std::unexpected(Error { - .reason = Reason::FAILED_TO_PARSE, - .str_error = "[libpng] Failed to init (png_create_info_struct)" }); + return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, + .str_error = "[libpng] Failed to init (png_create_info_struct)" }); } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_info_struct(png_ptr, &info_ptr); png_destroy_write_struct(&png_ptr, nullptr); - return std::unexpected(Error { - .reason = Reason::FAILED_TO_PARSE, - .str_error = "[libpng] Unkown error during png creation" }); + return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, + .str_error = "[libpng] Unkown error during png creation" }); } png_set_write_fn(png_ptr, &write_param, png::write_func, nullptr); @@ -263,12 +238,10 @@ namespace stormkit::image::details { auto rows = std::vector { data.extent.height, nullptr }; for (auto i : range(data.extent.height)) - rows[i] = const_cast(&data.data[i - * data.extent.width - * data.channel_count - * data.bytes_per_channel]); // TODO Fix this shit + rows[i] = const_cast< + Byte*>(&data.data[i * data.extent.width * data.channel_count * data.bytes_per_channel]); // TODO Fix this shit - png_set_rows(png_ptr, info_ptr, reinterpret_cast(std::data(rows))); + png_set_rows(png_ptr, info_ptr, std::bit_cast(std::data(rows))); png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, nullptr); png_write_end(png_ptr, info_ptr); diff --git a/src/image/qoi.mpp b/src/image/qoi.mpp index e6036affa..ae315b265 100644 --- a/src/image/qoi.mpp +++ b/src/image/qoi.mpp @@ -17,20 +17,20 @@ import stormkit.image; export namespace stormkit::image::details { [[nodiscard]] - auto load_qoi(std::span data) noexcept - -> std::expected; + auto load_qoi(std::span data) noexcept -> std::expected; [[nodiscard]] auto save_qoi(const image::Image& image, const std::filesystem::path& filepath) noexcept -> std::expected; [[nodiscard]] - auto save_qoi(const image::Image& image) noexcept - -> std::expected, image::Image::Error>; + auto save_qoi(const image::Image& image) noexcept -> std::expected, image::Image::Error>; } // namespace stormkit::image::details using namespace std::literals; +namespace stdr = std::ranges; + namespace stormkit::image::details { template using Unexpected = std::unexpected; @@ -48,11 +48,9 @@ namespace stormkit::image::details { namespace { constexpr auto SIZE_OF_HEADER = 14; - constexpr auto CHANNELS_TO_FORMAT = frozen:: - make_unordered_map>({ - { 3, std::array { image::Image::Format::SRGB8, image::Image::Format::RGB8_UNORM } }, - { 4, - std::array { image::Image::Format::SRGBA8, image::Image::Format::RGBA8_UNORM } } + constexpr auto CHANNELS_TO_FORMAT = frozen::make_unordered_map>({ + { 3, std::array { image::Image::Format::SRGB8, image::Image::Format::RGB8_UNORM } }, + { 4, std::array { image::Image::Format::SRGBA8, image::Image::Format::RGBA8_UNORM } } }); constexpr auto END_OF_FILE = into_bytes({ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }); @@ -83,26 +81,23 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// constexpr auto indexHash(const Pixel& pixel) noexcept { - return (pixel.rgba.r * 3u + pixel.rgba.g * 5u + pixel.rgba.b * 7u + pixel.rgba.a * 11u) - % PIXEL_CACHE_SIZE; + return (pixel.rgba.r * 3u + pixel.rgba.g * 5u + pixel.rgba.b * 7u + pixel.rgba.a * 11u) % PIXEL_CACHE_SIZE; } ///////////////////////////////////// ///////////////////////////////////// - auto load_qoi(std::span data) noexcept - -> std::expected { - const auto raw_header = std::span { std::data(data), SIZE_OF_HEADER }; - const auto* header = std::bit_cast(std::data(raw_header)); + auto load_qoi(std::span data) noexcept -> std::expected { + const auto raw_header = data.subspan(SIZE_OF_HEADER); + const auto* header = std::bit_cast(stdr::data(raw_header)); - const auto extent = math::Extent3 { .width = byte_swap(header->width), - .height = byte_swap(header->height) }; + const auto extent = math::Extent3 { .width = byte_swap(header->width), .height = byte_swap(header->height) }; const auto channels = header->channels; const auto format = CHANNELS_TO_FORMAT.at(header->channels)[header->colorspace]; auto pixel_cache = std::array {}; - const auto chunks = std::span { std::bit_cast(std::data(data)) + SIZE_OF_HEADER, - std::size(data) - SIZE_OF_HEADER }; + const auto chunks = std::span { std::bit_cast(stdr::data(data)) + SIZE_OF_HEADER, + stdr::size(data) - SIZE_OF_HEADER }; const auto output_size = extent.width * extent.height * channels; @@ -114,18 +109,17 @@ namespace stormkit::image::details { auto run = 0; const auto diff = 4 - channels; - auto it = std::ranges::begin(chunks); + auto it = stdr::begin(chunks); - const auto chunks_size = output_size - std::size(END_OF_FILE); + const auto chunks_size = output_size - stdr::size(END_OF_FILE); for (auto _ : range(output_size, channels)) { const auto tag = *it; - const auto position = as(std::distance(std::ranges::begin(chunks), it)); + const auto position = as(std::distance(stdr::begin(chunks), it)); if (run > 0) --run; - else if (std::memcmp(&*it, std::data(END_OF_FILE), std::size(END_OF_FILE)) == 0) - [[unlikely]] { - it = std::ranges::cend(chunks); + else if (std::memcmp(&*it, std::data(END_OF_FILE), stdr::size(END_OF_FILE)) == 0) [[unlikely]] { + it = stdr::cend(chunks); } else if (position < chunks_size) { ++it; if (static_cast(tag) == QOI_OPERATION::RGB) { @@ -177,10 +171,10 @@ namespace stormkit::image::details { cached = previous_pixel; } - std::ranges::transform(std::begin(previous_pixel.data), - std::end(previous_pixel.data) - diff, - std::back_inserter(output), - monadic::as()); + stdr::transform(stdr::begin(previous_pixel.data), + stdr::end(previous_pixel.data) - diff, + std::back_inserter(output), + monadic::as()); } auto image_data = image::Image::ImageData { @@ -200,8 +194,7 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto save_qoi(const image::Image&, const std::filesystem::path&) noexcept - -> std::expected { + auto save_qoi(const image::Image&, const std::filesystem::path&) noexcept -> std::expected { assert(false, "Not implemented yet !"); return {}; } @@ -209,8 +202,7 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// [[nodiscard]] - auto save_qoi(const image::Image&) noexcept - -> std::expected, image::Image::Error> { + auto save_qoi(const image::Image&) noexcept -> std::expected, image::Image::Error> { assert(false, "Not implemented yet !"); return {}; } From f16d3034600a19ded4a80e64c3bf6d6553a126c7 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 23 Jan 2026 22:10:38 +0100 Subject: [PATCH 002/194] (luau) minimal test implementation --- examples/wsi/luau/luau/events.luau | 13 ++ examples/wsi/luau/src/main.cpp | 107 ++++++++++++++ examples/wsi/luau/xmake.lua | 35 +++++ include/stormkit/core/config.hpp.in | 1 + include/stormkit/luau/lua.hpp | 14 ++ xmake.lua | 218 ++++++++++++++-------------- xmake/dependencies.xmake.lua | 122 +++++++++++----- xmake/options.xmake.lua | 1 + xmake/targets.xmake.lua | 8 +- 9 files changed, 376 insertions(+), 143 deletions(-) create mode 100644 examples/wsi/luau/luau/events.luau create mode 100644 examples/wsi/luau/src/main.cpp create mode 100644 examples/wsi/luau/xmake.lua create mode 100644 include/stormkit/luau/lua.hpp diff --git a/examples/wsi/luau/luau/events.luau b/examples/wsi/luau/luau/events.luau new file mode 100644 index 000000000..795ee2ce4 --- /dev/null +++ b/examples/wsi/luau/luau/events.luau @@ -0,0 +1,13 @@ +print(wsi.EventType) + +local window = wsi.open_window("test", 800, 600, wsi.WindowFlag.RESIZEABLE) + +print("wm: " .. window:wm()) + +-- window:on(wsi.EventType.CLOSED, function() +-- print("Close event!") +-- end) + +-- window:event_loop(function() +-- window.clear() +-- end) diff --git a/examples/wsi/luau/src/main.cpp b/examples/wsi/luau/src/main.cpp new file mode 100644 index 000000000..9c1dee595 --- /dev/null +++ b/examples/wsi/luau/src/main.cpp @@ -0,0 +1,107 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +import std; + +import stormkit.core; +import stormkit.main; +import stormkit.log; +import stormkit.wsi; +import stormkit.luau; + +#include + +#include + +LOGGER("Luau-Events"); + +#ifndef LUAU_DIR + #define LUAU_DIR "../luau" +#endif + +using namespace stormkit; + +auto open_window(std::string name, u32 width, u32 height, wsi::WindowFlag flags) noexcept { + return wsi::Window::open(std::move(name), { width, height }, flags); +} + +auto closed() { + return wsi::EventType::CLOSED; +} + +//////////////////////////////////////// +//////////////////////////////////////// +auto main(std::span args) -> int { + wsi::parse_args(args); + auto logger = log::Logger::create_logger_instance(); + + auto engine = luau::Engine::create(LUAU_DIR "/events.luau"); + + engine.global_namespace() + .beginNamespace("wsi") + .beginNamespace("WindowFlag") + .addProperty( + "DEFAULT", + +[] static noexcept { return wsi::WindowFlag::DEFAULT; }) + .addProperty( + "BORDERLESS", + +[] static noexcept { return wsi::WindowFlag::BORDERLESS; }) + .addProperty( + "RESIZEABLE", + +[] static noexcept { return wsi::WindowFlag::RESIZEABLE; }) + .addProperty( + "EXTERNAL_CONTEXT", + +[] static noexcept { return wsi::WindowFlag::EXTERNAL_CONTEXT; }) + .endNamespace() + .beginNamespace("EventType") + .addProperty( + "NONE", + +[] static noexcept { return wsi::EventType::NONE; }) + .addProperty( + "CLOSED", + +[] static noexcept { return wsi::EventType::CLOSED; }) + .addProperty( + "MONITOR_CHANGED", + +[] static noexcept { return wsi::EventType::MONITOR_CHANGED; }) + .addProperty( + "RESIZED", + +[] static noexcept { return wsi::EventType::RESIZED; }) + .addProperty( + "RESTORED", + +[] static noexcept { return wsi::EventType::RESTORED; }) + .addProperty( + "MINIMIZED", + +[] static noexcept { return wsi::EventType::MINIMIZED; }) + .addProperty( + "KEY_DOWN", + +[] static noexcept { return wsi::EventType::KEY_DOWN; }) + .addProperty( + "KEY_UP", + +[] static noexcept { return wsi::EventType::KEY_UP; }) + .addProperty( + "MOUSE_BUTTON_DOWN", + +[] static noexcept { return wsi::EventType::MOUSE_BUTTON_DOWN; }) + .addProperty( + "MOUSE_BUTTON_UP", + +[] static noexcept { return wsi::EventType::MOUSE_BUTTON_UP; }) + .addProperty( + "MOUSE_MOVED", + +[] static noexcept { return wsi::EventType::MOUSE_MOVED; }) + .addProperty( + "ACTIVATE", + +[] static noexcept { return wsi::EventType::ACTIVATE; }) + .addProperty( + "DEACTIVATE", + +[] static noexcept { return wsi::EventType::DEACTIVATE; }) + .endNamespace() + .beginClass("window") + .addFunction("wm", &wsi::Window::wm) + .endClass() + .addFunction("open_window", open_window) + .endNamespace(); + + engine.lua_main().transform_error(monadic::assert("lua runtime error!\n-------------------------------\n")); + + return 0; +} diff --git a/examples/wsi/luau/xmake.lua b/examples/wsi/luau/xmake.lua new file mode 100644 index 000000000..2f0c2b5dc --- /dev/null +++ b/examples/wsi/luau/xmake.lua @@ -0,0 +1,35 @@ +if get_config("luau") then + namespace("luau", function() + target("events", function() + set_kind("binary") + set_languages("cxxlatest", "clatest") + + add_rules("stormkit.flags") + add_rules("platform.windows.subsystem.console") + + add_deps("stormkit::core", "stormkit::main", "stormkit::log", "stormkit::wsi", "stormkit::luau") + + add_packages("luau") + + if is_mode("debug") then + add_defines("STORMKIT_BUILD_DEBUG") + add_defines("STORMKIT_ASSERT=1") + set_suffixname("-d") + else + add_defines("STORMKIT_ASSERT=0") + end + + add_files("src/main.cpp") + if is_plat("windows") then add_files("win32/*.manifest") end + + if get_config("devmode") then + add_defines('LUAU_DIR="$(builddir)/luau"') + set_rundir("$(projectdir)") + end + + after_build(function(target) os.cp("examples/wsi/luau/luau", "$(builddir)") end) + + set_group("examples/stormkit-wsi/luau") + end) + end) +end diff --git a/include/stormkit/core/config.hpp.in b/include/stormkit/core/config.hpp.in index 2689f0ed1..b5fa6e918 100644 --- a/include/stormkit/core/config.hpp.in +++ b/include/stormkit/core/config.hpp.in @@ -14,6 +14,7 @@ ${define STORMKIT_LIB_ENTITIES_ENABLED} ${define STORMKIT_LIB_IMAGE_ENABLED} ${define STORMKIT_LIB_WSI_ENABLED} ${define STORMKIT_LIB_GPU_ENABLED} +${define STORMKIT_LIB_LUAU_ENABLED} #ifndef NO_CONSTANTS _STORMKIT_EXPORT namespace stormkit { inline namespace core { diff --git a/include/stormkit/luau/lua.hpp b/include/stormkit/luau/lua.hpp new file mode 100644 index 000000000..a8f3b2aee --- /dev/null +++ b/include/stormkit/luau/lua.hpp @@ -0,0 +1,14 @@ +#ifndef STORMKIT_LUA_HPP +#define STORMKIT_LUA_HPP + +extern "C" { +#include + +#include +#include +} + +#include +#undef assert + +#endif diff --git a/xmake.lua b/xmake.lua index 904013519..900a807b3 100644 --- a/xmake.lua +++ b/xmake.lua @@ -6,6 +6,8 @@ local allowed_modes = { "profile", } +-- add_repositories("nazara-repo https://github.com/arthapz/xmake-repo-nazara") +add_repositories("nazara-repo https://github.com/NazaraEngine/xmake-repo") add_repositories("tapzcrew-repo https://github.com/Tapzcrew/xmake-repo main") set_xmakever("3.0.0") @@ -70,136 +72,138 @@ end ---------------------------- targets ---------------------------- namespace("stormkit", function() - for _, name in ipairs({ "log", "entities", "image", "wsi", "gpu" }) do + for _, name in ipairs({ "log", "entities", "image", "wsi", "gpu", "luau" }) do if get_config(name) then set_configvar("STORMKIT_LIB_" .. string.upper(name) .. "_ENABLED", "true") end end for name, module in pairs(modules) do - local modulename = module.modulename - - if name == "core" or name == "main" or name == "test" or get_config(name) then - target(name, function() - set_group("libraries") - - if module.custom then module.custom() end - - if name == "main" or name == "test" then - set_kind("static") - else - set_kind("$(kind)") - end - - set_languages("cxxlatest", "clatest") - - add_rules("stormkit.flags") - add_defines("STORMKIT_BUILD") - if is_mode("debug") then - add_defines("STORMKIT_BUILD_DEBUG") - set_suffixname("-d") - end - - if is_kind("static") then add_defines("STORMKIT_STATIC", { public = true }) end - - local src_path = path.join("src", modulename) - local module_path = path.join("modules", "stormkit", modulename) - local include_path = path.join("include", "(stormkit", modulename) - - for _, file in ipairs(os.files(path.join(src_path, "**.mpp"))) do - add_files(file) - end - for _, file in ipairs(os.files(path.join(src_path, "**.cpp"))) do - add_files(file) - end - for _, file in ipairs(os.files(path.join(src_path, "**.mm"))) do - add_files(file, { mxxflags = "-std=c++23" }) - end - for _, file in ipairs(os.files(path.join(src_path, "**.m"))) do - add_files(file) - end - for _, file in ipairs(os.files(path.join(src_path, "**.inl"))) do - add_files(file) - end - - if os.exists(module_path .. ".mpp") then add_files(module_path .. ".mpp", { public = true }) end - - if os.files(module_path) then - for _, file in ipairs(os.files(path.join(module_path, "**.mpp"))) do - add_files(file, { public = true }) + if module then + local modulename = module.modulename + + if name == "core" or name == "main" or name == "test" or get_config(name) then + target(name, function() + set_group("libraries") + + if module.custom then module.custom() end + + if name == "main" or name == "test" then + set_kind("static") + else + set_kind("$(kind)") end - for _, file in ipairs(os.files(path.join(module_path, "**.inl"))) do - add_headerfiles(file) + + set_languages("cxxlatest", "clatest") + + add_rules("stormkit.flags") + add_defines("STORMKIT_BUILD") + if is_mode("debug") then + add_defines("STORMKIT_BUILD_DEBUG") + set_suffixname("-d") end - end - - local _include_path = include_path:gsub("%(", "") - if os.exists(_include_path) then - add_headerfiles(path.join(include_path, "**.inl)")) - add_headerfiles(path.join(include_path, "**.hpp)")) - end - - if is_plat("windows") or is_plat("mingw") then - for _, plat in ipairs({ "posix", "linux", "darwin", "macos", "ios", "bsd", "android" }) do - remove_files(path.join(src_path, plat, "**")) - remove_headerfiles(path.join(src_path, plat, "**")) + + if is_kind("static") then add_defines("STORMKIT_STATIC", { public = true }) end + + local src_path = path.join("src", modulename) + local module_path = path.join("modules", "stormkit", modulename) + local include_path = path.join("include", "(stormkit", modulename) + + for _, file in ipairs(os.files(path.join(src_path, "**.mpp"))) do + add_files(file) end - elseif is_plat("macosx") then - for _, plat in ipairs({ "linux", "win32", "ios", "bsd", "android" }) do - remove_files(path.join(src_path, plat, "**")) - remove_headerfiles(path.join(src_path, plat, "**")) + for _, file in ipairs(os.files(path.join(src_path, "**.cpp"))) do + add_files(file) end - elseif is_plat("ios") then - for _, plat in ipairs({ "linux", "macos", "win32", "bsd", "android" }) do - remove_files(path.join(src_path, plat, "**")) - remove_headerfiles(path.join(src_path, plat, "**")) + for _, file in ipairs(os.files(path.join(src_path, "**.mm"))) do + add_files(file, { mxxflags = "-std=c++23" }) end - elseif is_plat("android") then - for _, plat in ipairs({ "linux", "darwin", "macos", "ios", "bsd", "win32" }) do - remove_files(path.join(src_path, plat, "**")) - remove_headerfiles(path.join(src_path, plat, "**")) + for _, file in ipairs(os.files(path.join(src_path, "**.m"))) do + add_files(file) end - elseif is_plat("linux") then - for _, plat in ipairs({ "win32", "darwin", "macos", "ios", "bsd", "android" }) do - remove_files(path.join(src_path, plat, "**")) - remove_headerfiles(path.join(src_path, plat, "**")) + for _, file in ipairs(os.files(path.join(src_path, "**.inl"))) do + add_files(file) end - end - add_includedirs("$(projectdir)/include", { public = true }) + if os.exists(module_path .. ".mpp") then add_files(module_path .. ".mpp", { public = true }) end - if module.defines then add_defines(module.defines) end + if os.files(module_path) then + for _, file in ipairs(os.files(path.join(module_path, "**.mpp"))) do + add_files(file, { public = true }) + end + for _, file in ipairs(os.files(path.join(module_path, "**.inl"))) do + add_headerfiles(file) + end + end - if module.public_defines then add_defines(module.public_defines, { public = true }) end + local _include_path = include_path:gsub("%(", "") + if os.exists(_include_path) then + add_headerfiles(path.join(include_path, "**.inl)")) + add_headerfiles(path.join(include_path, "**.hpp)")) + end + + if is_plat("windows") or is_plat("mingw") then + for _, plat in ipairs({ "posix", "linux", "darwin", "macos", "ios", "bsd", "android" }) do + remove_files(path.join(src_path, plat, "**")) + remove_headerfiles(path.join(src_path, plat, "**")) + end + elseif is_plat("macosx") then + for _, plat in ipairs({ "linux", "win32", "ios", "bsd", "android" }) do + remove_files(path.join(src_path, plat, "**")) + remove_headerfiles(path.join(src_path, plat, "**")) + end + elseif is_plat("ios") then + for _, plat in ipairs({ "linux", "macos", "win32", "bsd", "android" }) do + remove_files(path.join(src_path, plat, "**")) + remove_headerfiles(path.join(src_path, plat, "**")) + end + elseif is_plat("android") then + for _, plat in ipairs({ "linux", "darwin", "macos", "ios", "bsd", "win32" }) do + remove_files(path.join(src_path, plat, "**")) + remove_headerfiles(path.join(src_path, plat, "**")) + end + elseif is_plat("linux") then + for _, plat in ipairs({ "win32", "darwin", "macos", "ios", "bsd", "android" }) do + remove_files(path.join(src_path, plat, "**")) + remove_headerfiles(path.join(src_path, plat, "**")) + end + end - if module.cxxflags then - add_cxxflags(module.cxxflags) - add_mxxflags(module.cxxflags) - end + add_includedirs("$(projectdir)/include", { public = true }) - if module.deps then add_deps(module.deps) end + if module.defines then add_defines(module.defines) end - if module.public_deps then add_deps(module.public_deps, { public = true }) end + if module.public_defines then add_defines(module.public_defines, { public = true }) end - if module.packages then - local packages = {} - for _, package in ipairs(module.packages) do - table.insert(packages, package:split(" ")[1]) + if module.cxxflags then + add_cxxflags(module.cxxflags) + add_mxxflags(module.cxxflags) end - add_packages(packages, { public = is_kind("static") }) - end + if module.deps then add_deps(module.deps) end + + if module.public_deps then add_deps(module.public_deps, { public = true }) end - if module.public_packages then - local packages = {} - for _, package in ipairs(module.public_packages) do - table.insert(packages, package:split(" ")[1]) + if module.packages then + local packages = {} + for _, package in ipairs(module.packages) do + table.insert(packages, package:split(" ")[1]) + end + + add_packages(packages, { public = is_kind("static") }) + end + + if module.public_packages then + local packages = {} + for _, package in ipairs(module.public_packages) do + table.insert(packages, package:split(" ")[1]) + end + add_packages(packages, { public = true }) end - add_packages(packages, { public = true }) - end - if module.frameworks then add_frameworks(module.frameworks, { public = is_kind("static") }) end + if module.frameworks then add_frameworks(module.frameworks, { public = is_kind("static") }) end - add_options("sanitizers") - end) + add_options("sanitizers") + end) + end end end @@ -213,7 +217,7 @@ namespace("stormkit", function() add_files("modules/stormkit.mpp") add_deps("core", "main") - for _, name in ipairs({ "log", "entities", "image", "wsi", "gpu" }) do + for _, name in ipairs({ "log", "entities", "image", "wsi", "gpu", "luau" }) do if get_config(name) then add_deps(name) set_configvar("STORMKIT_LIB_" .. string.upper(name) .. "_ENABLED", "true") diff --git a/xmake/dependencies.xmake.lua b/xmake/dependencies.xmake.lua index 3d21f5338..a96823188 100644 --- a/xmake/dependencies.xmake.lua +++ b/xmake/dependencies.xmake.lua @@ -1,19 +1,25 @@ local global_package_configs = { configs = { shared = get_config("shared_deps"), - ["x11"] = is_plat("linux"), - wayland = is_plat("linux"), - modules = true, - std_import = true, - cpp = "latest", + runtimes = get_config("toolchain") == "llvm" and get_config("runtimes") or nil, }, } if get_config("on_ci") then global_package_configs.system = false end -add_requireconfs("nzsl.fmt", { version = "master", override = true, system = false }) if not is_plat("windows") then add_requires("libdwarf") end +local cxx_isystem = "--cxx-isystem" +local cxx_runtime = nil +if get_config("toolchain") == "llvm" then + if get_config("sdk") then + cxx_isystem = cxx_isystem .. path.join(get_config("sdk"), "include", "c++", "v1") + elseif is_plat("linux") or is_plat("darwin") then + cxx_isystem = cxx_isystem .. "/usr/include/c++/v1" + end + if get_config("runtimes") and get_config("runtimes"):startswith("c++") then cxx_runtime = "-stdlib=libc++" end +end + local package_configs = { ["libjpeg-turbo"] = { windows = { @@ -24,6 +30,22 @@ local package_configs = { }, }, }, + luau = { + global = { + system = false, + version = "master", + configs = { + extern_c = true, + cxflags = { cxx_runtime }, + }, + }, + }, + luabridge3 = { + global = { + system = false, + version = "master", + }, + }, libktx = { llvm = { configs = { @@ -31,44 +53,74 @@ local package_configs = { }, }, }, - frozen = { + libxkbcommon = { global = { system = false, + configs = { + wayland = true, + x11 = true, + }, }, }, - ["vulkan-header"] = { + unordered_dense = { global = { - version = "v1.4.309", system = false, + configs = { + modules = true, + std_import = true, + }, }, }, - ["vulkan-memory-allocator"] = { + tl_function_ref = { global = { - version = "v3.3.0", system = false, - }, - }, - nzsl = { - linux = { configs = { - toolchains = "gcc", - runtimes = "stdc++_shared", + modules = true, + std_import = true, }, }, - windows = { + }, + frozen = { + global = { + system = false, configs = { - toolchains = "msvc", - runtimes = "MD", + modules = true, + std_import = true, + cpp = "latest", }, }, + }, + ["vulkan-header"] = { global = { + version = "v1.4.335", + system = false, override = true, configs = { - fs_watcher = false, - link = {}, + modules = false, }, }, }, + ["vulkan-memory-allocator"] = { + global = { + version = "v3.3.0", + system = false, + }, + }, + -- nzsl = { + -- windows = { + -- configs = { + -- toolchains = "msvc", + -- runtimes = "MD", + -- }, + -- }, + -- global = { + -- override = true, + -- configs = { + -- kind = "binary", + -- fs_watcher = false, + -- }, + -- }, + -- }, } function add_requires_with_conf(package) @@ -103,17 +155,17 @@ function add_requires_with_conf_transitive(package) get_config("toolchain") == "gcc" and configs.gcc or {} ) ) - add_requireconfs( - package .. ".**", - table.join( - global_package_configs, - configs.global or {}, - is_plat("windows") and configs.windows or {}, - is_plat("linux") and configs.linux or {}, - is_plat("macosx") and configs.macos or {}, - get_config("toolchain") == "llvm" and configs.llvm or {}, - get_config("toolchain") == "msvc" and configs.msvc or {}, - get_config("toolchain") == "gcc" and configs.gcc or {} - ) - ) + -- add_requireconfs( + -- package .. ".**", + -- table.join( + -- global_package_configs, + -- configs.global or {}, + -- is_plat("windows") and configs.windows or {}, + -- is_plat("linux") and configs.linux or {}, + -- is_plat("macosx") and configs.macos or {}, + -- get_config("toolchain") == "llvm" and configs.llvm or {}, + -- get_config("toolchain") == "msvc" and configs.msvc or {}, + -- get_config("toolchain") == "gcc" and configs.gcc or {} + -- ) + -- ) end diff --git a/xmake/options.xmake.lua b/xmake/options.xmake.lua index bea2a18ba..6ce81fe0f 100644 --- a/xmake/options.xmake.lua +++ b/xmake/options.xmake.lua @@ -51,6 +51,7 @@ option("entities", { default = true, category = "root menu/modules" }) option("image", { default = true, category = "root menu/modules", deps = { "log" } }) option("wsi", { default = true, category = "root menu/modules", deps = { "log" } }) option("gpu", { default = true, category = "root menu/modules", deps = { "log", "image", "wsi" } }) +option("luau", { default = false, category = "root menu/modules" }) option("compile_commands", { default = false, category = "root menu/support" }) option("vsxmake", { default = false, category = "root menu/support" }) diff --git a/xmake/targets.xmake.lua b/xmake/targets.xmake.lua index 671456bb6..4c61d9aa7 100644 --- a/xmake/targets.xmake.lua +++ b/xmake/targets.xmake.lua @@ -57,6 +57,12 @@ modules = { end, frameworks = is_plat("macosx") and { "CoreFoundation" } or nil, }, + luau = get_config("luau") and { + modulename = "luau", + public_deps = { "core" }, + public_packages = { "luau", "luabridge3" }, + public_defines = { 'LUA_API=extern __attribute__((visibility("default")))' }, + } or nil, wsi = { modulename = "wsi", public_deps = { "core" }, @@ -71,7 +77,7 @@ modules = { "wayland", "wayland-protocols", "libxkbcommon", - } or nil, + } or {}, -- frameworks = is_plat("macosx") and { "CoreFoundation", "Foundation", "AppKit", "Metal", "IOKit", "QuartzCore" } -- or nil, custom = function() From e1c40efafa6994c323e8be00170833753f28d046 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 23 Jan 2026 22:10:53 +0100 Subject: [PATCH 003/194] (all) format --- examples/gpu/common/app.mpp | 15 +- examples/gpu/imgui/src/main.cpp | 149 +- examples/gpu/textured_cube/src/main.cpp | 240 +- examples/gpu/textured_cube/xmake.lua | 11 +- examples/gpu/triangle/src/main.cpp | 83 +- examples/gpu/triangle/xmake.lua | 23 +- examples/wsi/events/src/main.cpp | 123 +- examples/wsi/framebuffer/src/main.cpp | 66 +- modules/stormkit.mpp | 3 + modules/stormkit/core/console/style.mpp | 16 +- modules/stormkit/core/containers.mpp | 6 +- .../stormkit/core/containers/multi_buffer.mpp | 58 +- .../stormkit/core/containers/raii_capsule.mpp | 51 +- .../stormkit/core/containers/ringbuffer.mpp | 10 +- .../stormkit/core/containers/shmbuffer.mpp | 20 +- modules/stormkit/core/containers/tree.mpp | 66 +- modules/stormkit/core/containers/utils.mpp | 42 +- modules/stormkit/core/coroutines.mpp | 116 +- modules/stormkit/core/errors.mpp | 28 +- .../core/functional/error_handling.mpp | 61 +- modules/stormkit/core/functional/monadic.mpp | 122 +- modules/stormkit/core/functional/utils.mpp | 42 +- modules/stormkit/core/hash/base.mpp | 2 +- modules/stormkit/core/hash/string.mpp | 23 +- modules/stormkit/core/math/combinatoric.mpp | 5 +- modules/stormkit/core/math/extent.mpp | 62 +- modules/stormkit/core/math/geometry.mpp | 32 +- modules/stormkit/core/math/linear-matrix.mpp | 80 +- modules/stormkit/core/math/linear-vector.mpp | 63 +- modules/stormkit/core/math/linear.mpp | 170 +- modules/stormkit/core/meta/algorithms.mpp | 15 +- modules/stormkit/core/meta/concepts.mpp | 87 +- modules/stormkit/core/meta/type_query.mpp | 14 +- modules/stormkit/core/parallelism/locked.mpp | 94 +- .../stormkit/core/parallelism/threadpool.mpp | 12 +- modules/stormkit/core/string/encodings.mpp | 51 +- modules/stormkit/core/string/format.mpp | 34 +- modules/stormkit/core/string/operations.mpp | 71 +- .../stormkit/core/typesafe/checked_value.mpp | 124 +- modules/stormkit/core/typesafe/flags.mpp | 51 +- modules/stormkit/core/typesafe/float.mpp | 4 +- modules/stormkit/core/typesafe/ref.mpp | 71 +- modules/stormkit/core/typesafe/safecasts.mpp | 60 +- .../stormkit/core/typesafe/strong_type.mpp | 125 +- modules/stormkit/core/utils/algorithms.mpp | 48 +- modules/stormkit/core/utils/allocation.mpp | 27 +- modules/stormkit/core/utils/color.mpp | 65 +- modules/stormkit/core/utils/contract.mpp | 93 +- modules/stormkit/core/utils/deferinit.mpp | 40 +- .../stormkit/core/utils/dynamic_loader.mpp | 36 +- modules/stormkit/core/utils/filesystem.mpp | 3 +- modules/stormkit/core/utils/handle.mpp | 9 +- modules/stormkit/core/utils/numeric_range.mpp | 49 +- .../stormkit/core/utils/signal_handler.mpp | 3 +- modules/stormkit/core/utils/singleton.mpp | 4 +- modules/stormkit/core/utils/stacktrace.mpp | 3 +- modules/stormkit/entities.mpp | 43 +- modules/stormkit/gpu.mpp | 2 +- modules/stormkit/gpu/core/device.mpp | 58 +- modules/stormkit/gpu/core/instance.mpp | 77 +- modules/stormkit/gpu/core/structs.mpp | 8 +- modules/stormkit/gpu/core/sync.mpp | 48 +- modules/stormkit/gpu/core/vulkan/enums.mpp | 1962 ++++++----------- modules/stormkit/gpu/core/vulkan/structs.mpp | 10 +- modules/stormkit/gpu/core/vulkan/utils.mpp | 66 +- .../stormkit/gpu/execution/command_buffer.mpp | 321 +-- .../stormkit/gpu/execution/descriptors.mpp | 307 ++- modules/stormkit/gpu/execution/pipeline.mpp | 103 +- .../gpu/execution/raster_pipeline.mpp | 4 +- .../stormkit/gpu/execution/render_pass.mpp | 116 +- modules/stormkit/gpu/execution/swapchain.mpp | 41 +- modules/stormkit/gpu/resource/buffer.mpp | 3 +- modules/stormkit/gpu/resource/image.mpp | 113 +- modules/stormkit/gpu/resource/shader.mpp | 103 +- modules/stormkit/image.mpp | 65 +- modules/stormkit/log.mpp | 15 +- modules/stormkit/luau.mpp | 151 ++ modules/stormkit/test.mpp | 27 +- modules/stormkit/wsi/monitor.mpp | 19 +- modules/stormkit/wsi/window.mpp | 33 +- src/core/contract.mpp | 10 +- src/gpu/execution/pipeline_cache.cpp | 6 +- src/image/hdr.mpp | 15 +- src/image/jpg.mpp | 49 +- src/image/ktx.mpp | 15 +- src/image/ppm.mpp | 19 +- src/image/tga.mpp | 15 +- src/wsi/common/window_base.mpp | 18 +- src/wsi/linux/common/xkb.mpp | 15 +- src/wsi/linux/wayland/context.mpp | 36 +- src/wsi/linux/wayland/monitor.mpp | 4 +- src/wsi/linux/wayland/wayland.mpp | 179 +- src/wsi/linux/wayland/window.mpp | 21 +- src/wsi/linux/window.mpp | 50 +- src/wsi/linux/x11/context.mpp | 6 +- src/wsi/linux/x11/monitor.mpp | 23 +- src/wsi/linux/x11/utils.mpp | 6 +- src/wsi/linux/x11/window.mpp | 39 +- src/wsi/linux/x11/xcb.mpp | 39 +- tests/core/containers/tree.cpp | 15 +- tests/core/typesafe/safecasts.integer.cpp | 60 +- 101 files changed, 2744 insertions(+), 4572 deletions(-) create mode 100644 modules/stormkit/luau.mpp diff --git a/examples/gpu/common/app.mpp b/examples/gpu/common/app.mpp index caec4ac2a..da562a8c7 100644 --- a/examples/gpu/common/app.mpp +++ b/examples/gpu/common/app.mpp @@ -49,19 +49,15 @@ export namespace base { auto init_window(std::string_view example_name) noexcept -> void { m_window = wsi::Window::open(std::format("Stormkit GPU {} example", example_name), { 800_u32, 600_u32 }, - wsi::WindowFlag::DEFAULT - | wsi::WindowFlag::EXTERNAL_CONTEXT); - m_window->on([this](u8 /*id*/, - wsi::Key key, - char /*c*/) mutable noexcept { + wsi::WindowFlag::DEFAULT | wsi::WindowFlag::EXTERNAL_CONTEXT); + m_window->on([this](u8 /*id*/, wsi::Key key, char /*c*/) mutable noexcept { if (key == wsi::Key::ESCAPE) m_window->close(); }); } auto init_gpu(std::string_view example_name) noexcept -> void { // initialize gpu backend (vulkan or webgpu depending the platform) - *gpu::initialize_backend() - .transform_error(monadic::assert("Failed to initialize gpu backend")); + *gpu::initialize_backend().transform_error(monadic::assert("Failed to initialize gpu backend")); // create gpu instance and attach surface to window m_instance = gpu::Instance::create(std::string { example_name }) @@ -69,8 +65,7 @@ export namespace base { .value(); m_surface = gpu::Surface::create_from_window(m_instance, m_window) - .transform_error(monadic:: - assert("Failed to initialize window gpu surface")) + .transform_error(monadic::assert("Failed to initialize window gpu surface")) .value(); // pick the best physical device const auto& physical_devices = m_instance->physical_devices(); @@ -100,7 +95,7 @@ export namespace base { // create swapchain const auto window_extent = m_window->extent(); - m_swapchain = gpu::SwapChain::create(m_device, m_surface, window_extent) + m_swapchain = gpu::SwapChain::create(m_device, m_surface, window_extent) .transform_error(monadic::assert("Failed to create swapchain")) .value(); diff --git a/examples/gpu/imgui/src/main.cpp b/examples/gpu/imgui/src/main.cpp index ba751c442..e53a8b10e 100644 --- a/examples/gpu/imgui/src/main.cpp +++ b/examples/gpu/imgui/src/main.cpp @@ -49,22 +49,19 @@ class Application: public base::Application { auto init_resources() -> void { // initialilze descriptor pool static constexpr auto POOL_SIZES = std::array { - gpu::DescriptorPool::Size { .type = gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, - .descriptor_count = BUFFERING_COUNT } + gpu::DescriptorPool::Size { .type = gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, .descriptor_count = BUFFERING_COUNT } }; m_descriptor_pool = gpu::DescriptorPool::create(m_device, POOL_SIZES, BUFFERING_COUNT) .transform_error(monadic::assert("Failed to create descriptor pool")) .value(); // initialize render pass - m_render_pass - = gpu::RenderPass:: - create(m_device, - { .attachments = { { .format = m_swapchain->pixel_format() } }, - .subpasses = { { .bind_point = gpu::PipelineBindPoint::GRAPHICS, - .color_attachment_refs = { { .attachment_id = 0u } } } } }) - .transform_error(monadic::assert("Failed to create render pass")) - .value(); + m_render_pass = gpu::RenderPass::create(m_device, + { .attachments = { { .format = m_swapchain->pixel_format() } }, + .subpasses = { { .bind_point = gpu::PipelineBindPoint::GRAPHICS, + .color_attachment_refs = { { .attachment_id = 0u } } } } }) + .transform_error(monadic::assert("Failed to create render pass")) + .value(); const auto window_extent = m_window->extent(); @@ -74,9 +71,8 @@ class Application: public base::Application { for (auto _ : range(BUFFERING_COUNT)) { out.push_back({ .in_flight = gpu::Fence::create_signaled(m_device) - .transform_error(monadic:: - assert("Failed to create swapchain image " - "in flight fence")) + .transform_error(monadic::assert("Failed to create swapchain image " + "in flight fence")) .value(), .image_available = gpu::Semaphore::create(m_device) .transform_error(monadic::assert("Failed to create " @@ -93,24 +89,20 @@ class Application: public base::Application { // transition swapchain image to present image const auto& images = m_swapchain->images(); - const auto image_count = stdr::size(images); - auto transition_cmbs - = m_command_pool->create_command_buffers(image_count) - .transform_error(monadic::assert("Failed to create transition command buffers")) - .value(); + const auto image_count = stdr::size(images); + auto transition_cmbs = m_command_pool->create_command_buffers(image_count) + .transform_error(monadic::assert("Failed to create transition command buffers")) + .value(); m_image_resources.reserve(stdr::size(images)); auto image_index = 0u; for (const auto& swap_image : images) { auto view = gpu::ImageView::create(m_device, swap_image) - .transform_error(core::monadic:: - assert("Failed to create swapchain image view")) + .transform_error(core::monadic::assert("Failed to create swapchain image view")) .value(); - auto framebuffer = m_render_pass - ->create_frame_buffer(m_device, window_extent, to_refs(view)) - .transform_error(core::monadic::assert( - std::format("Failed to create framebuffer for image {}", - image_index))) + auto framebuffer = m_render_pass->create_frame_buffer(m_device, window_extent, to_refs(view)) + .transform_error(core::monadic::assert(std::format("Failed to create framebuffer for image {}", + image_index))) .value(); m_image_resources.push_back({ @@ -125,13 +117,10 @@ class Application: public base::Application { auto& transition_cmb = transition_cmbs[image_index]; *transition_cmb.begin(true) - .transform_error(monadic:: - assert("Failed to begin texture transition command buffer")) + .transform_error(monadic::assert("Failed to begin texture transition command buffer")) .value() ->begin_debug_region(std::format("transition image {}", image_index)) - .transition_image_layout(swap_image, - gpu::ImageLayout::UNDEFINED, - gpu::ImageLayout::PRESENT_SRC) + .transition_image_layout(swap_image, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::PRESENT_SRC) .end_debug_region() .end() .transform_error(monadic::assert("Failed to begin texture transition command " @@ -168,15 +157,17 @@ class Application: public base::Application { .QueueFamily = 0, .Queue = m_raster_queue->native_handle(), .DescriptorPool = m_descriptor_pool->native_handle(), - .RenderPass = m_render_pass->native_handle(), .MinImageCount = BUFFERING_COUNT, .ImageCount = BUFFERING_COUNT, - .MSAASamples = VK_SAMPLE_COUNT_1_BIT, .PipelineCache = nullptr, - .Subpass = 0, .DescriptorPoolSize = 0, - .UseDynamicRendering = false, + .PipelineInfoMain = { + .RenderPass = m_render_pass->native_handle(), + .Subpass = 0, + .MSAASamples = VK_SAMPLE_COUNT_1_BIT, .PipelineRenderingCreateInfo = {}, + }, + .UseDynamicRendering = false, .Allocator = nullptr, .CheckVkResultFn = [](auto result) static noexcept { @@ -188,42 +179,38 @@ class Application: public base::Application { ImGui_ImplVulkan_Init(&init_info); m_window - ->on(wsi::KeyDownEventFunc { [this, - &io](u8 /*id*/, wsi::Key key, char c) mutable noexcept { + ->on(wsi::KeyDownEventFunc { [this, &io](u8 /*id*/, wsi::Key key, char c) mutable noexcept { if (key == wsi::Key::ESCAPE) m_window->close(); io.AddInputCharactersUTF8(&c); } }, - wsi::MouseMovedEventFunc { - [&io](u8 /*id*/, const math::vec2i& position) mutable noexcept { - const auto _position = position.to(); - - io.AddMouseSourceEvent(ImGuiMouseSource_Mouse); - io.AddMousePosEvent(_position.x, _position.y); - } }, - wsi::MouseButtonDownEventFunc { - [&io](u8 /*id*/, wsi::MouseButton button, const math::vec2i&) mutable noexcept { - auto mouse_button = -1; - if (button == wsi::MouseButton::LEFT) mouse_button = 0; - if (button == wsi::MouseButton::RIGHT) mouse_button = 1; - if (button == wsi::MouseButton::MIDDLE) mouse_button = 2; - if (button == wsi::MouseButton::BUTTON_1) mouse_button = 3; - if (button == wsi::MouseButton::BUTTON_2) mouse_button = 4; - if (mouse_button == -1) return; - io.AddMouseSourceEvent(ImGuiMouseSource_Mouse); - io.AddMouseButtonEvent(mouse_button, true); - } }, - wsi::MouseButtonUpEventFunc { - [&io](u8 /*id*/, wsi::MouseButton button, const math::vec2i&) mutable noexcept { - auto mouse_button = -1; - if (button == wsi::MouseButton::LEFT) mouse_button = 0; - if (button == wsi::MouseButton::RIGHT) mouse_button = 1; - if (button == wsi::MouseButton::MIDDLE) mouse_button = 2; - if (button == wsi::MouseButton::BUTTON_1) mouse_button = 3; - if (button == wsi::MouseButton::BUTTON_2) mouse_button = 4; - if (mouse_button == -1) return; - io.AddMouseSourceEvent(ImGuiMouseSource_Mouse); - io.AddMouseButtonEvent(mouse_button, false); - } }); + wsi::MouseMovedEventFunc { [&io](u8 /*id*/, const math::vec2i& position) mutable noexcept { + const auto _position = position.to(); + + io.AddMouseSourceEvent(ImGuiMouseSource_Mouse); + io.AddMousePosEvent(_position.x, _position.y); + } }, + wsi::MouseButtonDownEventFunc { [&io](u8 /*id*/, wsi::MouseButton button, const math::vec2i&) mutable noexcept { + auto mouse_button = -1; + if (button == wsi::MouseButton::LEFT) mouse_button = 0; + if (button == wsi::MouseButton::RIGHT) mouse_button = 1; + if (button == wsi::MouseButton::MIDDLE) mouse_button = 2; + if (button == wsi::MouseButton::BUTTON_1) mouse_button = 3; + if (button == wsi::MouseButton::BUTTON_2) mouse_button = 4; + if (mouse_button == -1) return; + io.AddMouseSourceEvent(ImGuiMouseSource_Mouse); + io.AddMouseButtonEvent(mouse_button, true); + } }, + wsi::MouseButtonUpEventFunc { [&io](u8 /*id*/, wsi::MouseButton button, const math::vec2i&) mutable noexcept { + auto mouse_button = -1; + if (button == wsi::MouseButton::LEFT) mouse_button = 0; + if (button == wsi::MouseButton::RIGHT) mouse_button = 1; + if (button == wsi::MouseButton::MIDDLE) mouse_button = 2; + if (button == wsi::MouseButton::BUTTON_1) mouse_button = 3; + if (button == wsi::MouseButton::BUTTON_2) mouse_button = 4; + if (mouse_button == -1) return; + io.AddMouseSourceEvent(ImGuiMouseSource_Mouse); + io.AddMouseButtonEvent(mouse_button, false); + } }); } auto run_example() { @@ -240,30 +227,24 @@ class Application: public base::Application { const auto& wait = submission_resource.image_available; auto& in_flight = submission_resource.in_flight; - const auto acquire_next_image = bind_front(&gpu::SwapChain::acquire_next_image, - &*m_swapchain, - 100ms, - std::cref(wait)); + const auto acquire_next_image = bind_front(&gpu::SwapChain::acquire_next_image, &*m_swapchain, 100ms, std::cref(wait)); const auto extract_index = [](auto&& _result) static noexcept { auto&& [result, _image_index] = _result; return _image_index; }; - const auto image_index - = in_flight.wait() - .transform([&in_flight](auto&&) mutable noexcept { in_flight.reset(); }) - .and_then(acquire_next_image) - .transform(extract_index) - .transform_error(monadic::assert("Failed to acquire next swapchain image")) - .value(); + const auto image_index = in_flight.wait() + .transform([&in_flight](auto&&) mutable noexcept { in_flight.reset(); }) + .and_then(acquire_next_image) + .transform(extract_index) + .transform_error(monadic::assert("Failed to acquire next swapchain image")) + .value(); const auto& swapchain_image_resource = m_image_resources[image_index]; const auto& framebuffer = swapchain_image_resource.framebuffer; const auto& signal = swapchain_image_resource.render_finished; - static constexpr auto PIPELINE_FLAGS = std::array { - gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT - }; + static constexpr auto PIPELINE_FLAGS = std::array { gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT }; // render in it auto& render_cmb = submission_resource.render_cmb; @@ -283,11 +264,7 @@ class Application: public base::Application { .end() .transform_error(monadic::assert("Failed to end render command buffer")) .value() - ->submit(m_raster_queue, - as_refs(wait), - PIPELINE_FLAGS, - as_refs(signal), - as_ref(in_flight)) + ->submit(m_raster_queue, as_refs(wait), PIPELINE_FLAGS, as_refs(signal), as_ref(in_flight)) .transform_error(monadic::assert("Failed to submit render command buffer")); // present it diff --git a/examples/gpu/textured_cube/src/main.cpp b/examples/gpu/textured_cube/src/main.cpp index 7b2566504..7aa6c4573 100644 --- a/examples/gpu/textured_cube/src/main.cpp +++ b/examples/gpu/textured_cube/src/main.cpp @@ -53,17 +53,10 @@ struct Vertex { math::vec3f position; math::vec2f uv; - static constexpr auto attribute_descriptions() noexcept - -> std::array { + static constexpr auto attribute_descriptions() noexcept -> std::array { return { - gpu::VertexInputAttributeDescription { - 0, 0, - gpu::PixelFormat::RGB32F, - offsetof(Vertex, position) }, - gpu::VertexInputAttributeDescription { - 1, 0, - gpu::PixelFormat::RG32F, - offsetof(Vertex, uv) }, + gpu::VertexInputAttributeDescription { 0, 0, gpu::PixelFormat::RGB32F, offsetof(Vertex, position) }, + gpu::VertexInputAttributeDescription { 1, 0, gpu::PixelFormat::RG32F, offsetof(Vertex, uv) }, }; } @@ -138,54 +131,44 @@ class Application: public base::Application { .type = gpu::DescriptorType::UNIFORM_BUFFER, .descriptor_count = BUFFERING_COUNT, }, - gpu::DescriptorPool::Size { .type = gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, - .descriptor_count = BUFFERING_COUNT } + gpu::DescriptorPool::Size { .type = gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, .descriptor_count = BUFFERING_COUNT } }; m_descriptor_pool = gpu::DescriptorPool::create(m_device, POOL_SIZES, BUFFERING_COUNT * 2) .transform_error(monadic::assert("Failed to create descriptor pool")) .value(); // load shaders - m_vertex_shader = gpu::Shader::load_from_file(m_device, - SHADER_DIR "/textured_cube.spv", - gpu::ShaderStageFlag::VERTEX) + m_vertex_shader = gpu::Shader::load_from_file(m_device, SHADER_DIR "/textured_cube.spv", gpu::ShaderStageFlag::VERTEX) .transform_error(monadic::assert("Failed to load vertex shader")) .value(); - m_fragment_shader = gpu::Shader::load_from_file(m_device, - SHADER_DIR "/textured_cube.spv", - gpu::ShaderStageFlag::FRAGMENT) + m_fragment_shader = gpu::Shader::load_from_file(m_device, SHADER_DIR "/textured_cube.spv", gpu::ShaderStageFlag::FRAGMENT) .transform_error(monadic::assert("Failed to load fragment shader")) .value(); - m_descriptor_set_layout - = gpu::DescriptorSetLayout:: - create(m_device, - into_dyn_array(ViewerData::layout_binding(), - gpu::DescriptorSetLayoutBinding { - 1, - gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, - gpu::ShaderStageFlag::FRAGMENT, - 1 })) - .transform_error(monadic::assert("Failed to create descriptor set layout")) - .value(); - m_pipeline_layout = gpu::PipelineLayout::create( - m_device, - { .descriptor_set_layouts = to_refs(m_descriptor_set_layout) }) + m_descriptor_set_layout = gpu::DescriptorSetLayout::create(m_device, + into_dyn_array(ViewerData::layout_binding(), + gpu::DescriptorSetLayoutBinding { + 1, + gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, + gpu::ShaderStageFlag::FRAGMENT, + 1 })) + .transform_error(monadic::assert("Failed to create descriptor set layout")) + .value(); + m_pipeline_layout = gpu::PipelineLayout::create(m_device, { .descriptor_set_layouts = to_refs(m_descriptor_set_layout) }) .transform_error(monadic::assert("Failed to create pipeline layout")) .value(); // initialize render pass const auto depth_format = [this] { const auto formats_properties = m_physical_device->formats_properties(); - const auto candidates = std::array { gpu::PixelFormat::DEPTH32F, + const auto candidates = std::array { gpu::PixelFormat::DEPTH32F, gpu::PixelFormat::DEPTH32F_STENCIL8U, gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U }; for (const auto format : candidates) { - const auto properties = stdr::find_if(formats_properties, - [format](const auto& pair) { - return pair.first == format; - }); + const auto properties = stdr::find_if(formats_properties, [format](const auto& pair) { + return pair.first == format; + }); ENSURES(properties != stdr::cend(formats_properties)); if (check_flag_bit(properties->second.optimal_tiling_features, gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT)) { @@ -264,31 +247,26 @@ class Application: public base::Application { image.load_from_file(TEXTURE_DIR "/cube.png").transform_error(monadic::assert()).value(); m_texture = gpu::Image::create(m_device, - { .extent = image.extent(), - .format = gpu::PixelFormat::RGBA8_UNORM, - .usages = gpu::ImageUsageFlag::SAMPLED - | gpu::ImageUsageFlag::TRANSFER_DST, + { .extent = image.extent(), + .format = gpu::PixelFormat::RGBA8_UNORM, + .usages = gpu::ImageUsageFlag::SAMPLED | gpu::ImageUsageFlag::TRANSFER_DST, .property = gpu::MemoryPropertyFlag::DEVICE_LOCAL }) .transform_error(monadic::assert("Failed to allocate texture")) .value(); { - auto staging_buffer - = gpu::Buffer::create(m_device, - { .usages = gpu::BufferUsageFlag::TRANSFER_SRC, - .size = image.size() }) - .transform_error(monadic::assert("Failed to allocate gpu texture staging buffer")) - .value(); + auto staging_buffer = gpu::Buffer::create(m_device, + { .usages = gpu::BufferUsageFlag::TRANSFER_SRC, .size = image.size() }) + .transform_error(monadic::assert("Failed to allocate gpu texture staging buffer")) + .value(); staging_buffer.upload(image.data()) .transform_error(monadic::assert("Failed to upload texture data to staging buffer")) .value(); - auto - cpy_fence = gpu::Fence::create(m_device) - .transform_error(monadic:: - assert("Failed to create copy texture buffer fence")) - .value(); + auto cpy_fence = gpu::Fence::create(m_device) + .transform_error(monadic::assert("Failed to create copy texture buffer fence")) + .value(); const auto copy = { gpu::BufferImageCopy { @@ -300,18 +278,15 @@ class Application: public base::Application { .extent = image.extent() } }; auto copy_cmb = m_command_pool->create_command_buffer() - .transform_error(monadic:: - assert("Failed to allocate copy texture buffer " - "commandbuffer")) + .transform_error(monadic::assert("Failed to allocate copy texture buffer " + "commandbuffer")) .value(); copy_cmb.begin() .transform_error(monadic::assert("Failed to begin texture upload command buffer")) .value() ->begin_debug_region("Upload texture data") - .transition_image_layout(m_texture, - gpu::ImageLayout::UNDEFINED, - gpu::ImageLayout::TRANSFER_DST_OPTIMAL) + .transition_image_layout(m_texture, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::TRANSFER_DST_OPTIMAL) .copy_buffer_to_image(staging_buffer, m_texture, as_view(copy)) .transition_image_layout(m_texture, gpu::ImageLayout::TRANSFER_DST_OPTIMAL, @@ -331,9 +306,7 @@ class Application: public base::Application { .transform_error(monadic::assert("Failed to create texture view")) .value(); - m_sampler = gpu::Sampler::create(m_device, {}) - .transform_error(monadic::assert("Failed to create sampler")) - .value(); + m_sampler = gpu::Sampler::create(m_device, {}).transform_error(monadic::assert("Failed to create sampler")).value(); // create present engine resources m_submission_resources = std::vector {}; @@ -342,14 +315,12 @@ class Application: public base::Application { for (auto _ : range(BUFFERING_COUNT)) { m_submission_resources.push_back({ .in_flight = gpu::Fence::create_signaled(m_device) - .transform_error(core::monadic:: - assert("Failed to create swapchain image " - "in flight fence")) + .transform_error(core::monadic::assert("Failed to create swapchain image " + "in flight fence")) .value(), .image_available = gpu::Semaphore::create(m_device) - .transform_error(core::monadic:: - assert("Failed to create present " - "wait semaphore")) + .transform_error(core::monadic::assert("Failed to create present " + "wait semaphore")) .value(), .render_cmb = m_command_pool->create_command_buffer() .transform_error(monadic::assert("Failed to create " @@ -362,12 +333,10 @@ class Application: public base::Application { .size = sizeof(ViewerData), }, true) - .transform_error(monadic:: - assert("Failed to allocate gpu viewer buffer")) + .transform_error(monadic::assert("Failed to allocate gpu viewer buffer")) .value(), .descriptor_set = m_descriptor_pool->create_descriptor_set(m_descriptor_set_layout) - .transform_error(monadic:: - assert("Failed to create descriptor set")) + .transform_error(monadic::assert("Failed to create descriptor set")) .value(), }); auto& res = m_submission_resources.back(); @@ -390,11 +359,10 @@ class Application: public base::Application { const auto& images = m_swapchain->images(); - const auto image_count = stdr::size(images); - auto transition_cmbs - = m_command_pool->create_command_buffers(image_count) - .transform_error(monadic::assert("Failed to create transition command buffers")) - .value(); + const auto image_count = stdr::size(images); + auto transition_cmbs = m_command_pool->create_command_buffers(image_count) + .transform_error(monadic::assert("Failed to create transition command buffers")) + .value(); m_image_resources = std::vector {}; m_image_resources.reserve(stdr::size(images)); @@ -402,35 +370,28 @@ class Application: public base::Application { auto image_index = 0u; for (const auto& swap_image : images) { auto view = gpu::ImageView::create(m_device, swap_image) - .transform_error(core::monadic:: - assert("Failed to create swapchain image view")) + .transform_error(core::monadic::assert("Failed to create swapchain image view")) .value(); - auto depth_image - = gpu::Image::create(m_device, - gpu::Image::CreateInfo { - .extent = swap_image.extent(), - .format = depth_format, - .usages = gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT, - .property = gpu::MemoryPropertyFlag::DEVICE_LOCAL }) - .transform_error(core::monadic::assert("Failed to create depth image")) - .value(); + auto depth_image = gpu::Image::create(m_device, + gpu::Image::CreateInfo { + .extent = swap_image.extent(), + .format = depth_format, + .usages = gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT, + .property = gpu::MemoryPropertyFlag::DEVICE_LOCAL }) + .transform_error(core::monadic::assert("Failed to create depth image")) + .value(); auto depth_view = gpu::ImageView::create(m_device, depth_image, gpu::ImageViewType::T2D, { .aspect_mask = depth_aspect_flag }) - .transform_error(core::monadic:: - assert("Failed to create depth image view")) + .transform_error(core::monadic::assert("Failed to create depth image view")) .value(); - auto framebuffer = m_render_pass - ->create_frame_buffer(m_device, - window_extent, - to_refs(view, depth_view)) - .transform_error(core::monadic::assert( - std::format("Failed to create framebuffer for image {}", - image_index))) + auto framebuffer = m_render_pass->create_frame_buffer(m_device, window_extent, to_refs(view, depth_view)) + .transform_error(core::monadic::assert(std::format("Failed to create framebuffer for image {}", + image_index))) .value(); m_image_resources.push_back({ @@ -449,21 +410,17 @@ class Application: public base::Application { auto& transition_cmb = transition_cmbs[image_index]; *transition_cmb.begin(true) - .transform_error(monadic:: - assert("Failed to begin texture transition command buffer")) + .transform_error(monadic::assert("Failed to begin texture transition command buffer")) .value() ->begin_debug_region(std::format("transition image {}", image_index)) - .transition_image_layout(swap_image, - gpu::ImageLayout::UNDEFINED, - gpu::ImageLayout::PRESENT_SRC) + .transition_image_layout(swap_image, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::PRESENT_SRC) .transition_image_layout(resources.depth_image, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL, { .aspect_mask = depth_aspect_flag }) .end_debug_region() .end() - .transform_error(monadic:: - assert("Failed to begin texture transition command buffer")) + .transform_error(monadic::assert("Failed to begin texture transition command buffer")) .transform(monadic::discard()); ++image_index; @@ -480,37 +437,30 @@ class Application: public base::Application { // setup vertex buffer m_vertex_buffer = gpu::Buffer::create(m_device, - { .usages = gpu::BufferUsageFlag::VERTEX - | gpu::BufferUsageFlag::TRANSFER_DST, + { .usages = gpu::BufferUsageFlag::VERTEX | gpu::BufferUsageFlag::TRANSFER_DST, .size = VERTICES_SIZE, .property = gpu::MemoryPropertyFlag::DEVICE_LOCAL }) - .transform_error(monadic:: - assert("Failed to allocate gpu vertex buffer")) + .transform_error(monadic::assert("Failed to allocate gpu vertex buffer")) .value(); { - auto staging_buffer - = gpu::Buffer::create(m_device, - { .usages = gpu::BufferUsageFlag::TRANSFER_SRC, - .size = VERTICES_SIZE }) - .transform_error(monadic::assert("Failed to allocate gpu vertex staging buffer")) - .value(); + auto staging_buffer = gpu::Buffer::create(m_device, + { .usages = gpu::BufferUsageFlag::TRANSFER_SRC, .size = VERTICES_SIZE }) + .transform_error(monadic::assert("Failed to allocate gpu vertex staging buffer")) + .value(); staging_buffer.upload(VERTICES) .transform_error(monadic::assert("Failed to upload vertex data to staging buffer")) .value(); - auto - cpy_fence = gpu::Fence::create(m_device) - .transform_error(monadic:: - assert("Failed to create copy vertex buffer fence")) - .value(); + auto cpy_fence = gpu::Fence::create(m_device) + .transform_error(monadic::assert("Failed to create copy vertex buffer fence")) + .value(); - auto - copy_cmb = m_command_pool->create_command_buffer() - .transform_error(monadic::assert("Failed to allocate copy vertex buffer " - "commandbuffer")) - .value(); + auto copy_cmb = m_command_pool->create_command_buffer() + .transform_error(monadic::assert("Failed to allocate copy vertex buffer " + "commandbuffer")) + .value(); copy_cmb.begin() .transform_error(monadic::assert("Failed to begin vertices upload command buffer")) @@ -535,14 +485,9 @@ class Application: public base::Application { const auto window_extent = m_window->extent(); const auto window_extent_f32 = window_extent.to(); auto viewer_data = ViewerData { - .proj = math::perspective(math::radians(45.f), - window_extent_f32.width / window_extent_f32.height, - 0.1f, - 100.f), - .view = math::look_at(math::vec3f { 0.f, 3.f, 5.f }, - { 0.f, 0.f, 0.f }, - { 0.f, 1.f, 0.f }), - .model = math::mat4f::identity(), + .proj = math::perspective(math::radians(45.f), window_extent_f32.width / window_extent_f32.height, 0.1f, 100.f), + .view = math::look_at(math::vec3f { 0.f, 3.f, 5.f }, { 0.f, 0.f, 0.f }, { 0.f, 1.f, 0.f }), + .model = math::mat4f::identity(), }; LOG_MODULE.flush(); @@ -554,23 +499,18 @@ class Application: public base::Application { const auto& wait = submission_resource.image_available; auto& in_flight = submission_resource.in_flight; - const auto acquire_next_image = bind_front(&gpu::SwapChain::acquire_next_image, - &*m_swapchain, - 100ms, - std::cref(wait)); + const auto acquire_next_image = bind_front(&gpu::SwapChain::acquire_next_image, &*m_swapchain, 100ms, std::cref(wait)); const auto extract_index = [](auto&& _result) static noexcept { auto&& [result, _image_index] = _result; return _image_index; }; - const auto - image_index = in_flight.wait() - .transform([&in_flight](auto&&) noexcept { in_flight.reset(); }) - .and_then(acquire_next_image) - .transform(extract_index) - .transform_error(monadic:: - assert("Failed to acquire next swapchain image")) - .value(); + const auto image_index = in_flight.wait() + .transform([&in_flight](auto&&) noexcept { in_flight.reset(); }) + .and_then(acquire_next_image) + .transform(extract_index) + .transform_error(monadic::assert("Failed to acquire next swapchain image")) + .value(); const auto& swapchain_image_resource = m_image_resources[image_index]; const auto& framebuffer = swapchain_image_resource.framebuffer; @@ -578,9 +518,7 @@ class Application: public base::Application { // update viewer data and upload const auto time = stdc::duration_cast(current_time - m_start_time).count(); - viewer_data.model = math::rotate(math::mat4f::identity(), - time * math::radians(90.f), - math::vec3f { 0.f, 1.f, 0.f }); + viewer_data.model = math::rotate(math::mat4f::identity(), time * math::radians(90.f), math::vec3f { 0.f, 1.f, 0.f }); auto& viewer_buffer = submission_resource.viewer_buffer; viewer_buffer.upload(viewer_data); @@ -594,9 +532,7 @@ class Application: public base::Application { gpu::ClearDepthStencil {} }; static constexpr auto OFFSETS = std::array { 0_u64 }; - static constexpr auto PIPELINE_FLAGS = std::array { - gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT - }; + static constexpr auto PIPELINE_FLAGS = std::array { gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT }; render_cmb.reset() .transform_error(monadic::assert("Failed to reset render command buffer")) @@ -615,11 +551,7 @@ class Application: public base::Application { .end() .transform_error(monadic::assert("Failed to end render command buffer")) .value() - ->submit(m_raster_queue, - as_refs(wait), - PIPELINE_FLAGS, - as_refs(signal), - as_ref(in_flight)) + ->submit(m_raster_queue, as_refs(wait), PIPELINE_FLAGS, as_refs(signal), as_ref(in_flight)) .transform_error(monadic::assert("Failed to submit render command buffer")) .value(); diff --git a/examples/gpu/textured_cube/xmake.lua b/examples/gpu/textured_cube/xmake.lua index f16e33fd1..fc1db3a6d 100644 --- a/examples/gpu/textured_cube/xmake.lua +++ b/examples/gpu/textured_cube/xmake.lua @@ -1,13 +1,4 @@ -if is_plat("linux") then - add_requires( - "nzsl", - { configs = { toolchains = "gcc", runtimes = "stdc++_shared", fs_watcher = false, link = {} } } - ) -elseif is_plat("windows") then - add_requires("nzsl", { configs = { toolchains = "msvc", runtimes = "MD", fs_watcher = false, links = {} } }) -else - add_requires("nzsl", { configs = { fs_watcher = false, links = {} } }) -end +-- add_requires("nzsl", { configs = { fs_watcher = false, kind = "binary" } }) target("textured_cube", function() set_kind("binary") diff --git a/examples/gpu/triangle/src/main.cpp b/examples/gpu/triangle/src/main.cpp index 4f8bdfac8..6870849a5 100644 --- a/examples/gpu/triangle/src/main.cpp +++ b/examples/gpu/triangle/src/main.cpp @@ -41,15 +41,11 @@ class Application: public base::Application { public: auto init_example() { // load shaders - m_vertex_shader = gpu::Shader::load_from_file(m_device, - SHADER_DIR "/triangle.spv", - gpu::ShaderStageFlag::VERTEX) + m_vertex_shader = gpu::Shader::load_from_file(m_device, SHADER_DIR "/triangle.spv", gpu::ShaderStageFlag::VERTEX) .transform_error(monadic::assert("Failed to load vertex shader")) .value(); - m_fragment_shader = gpu::Shader::load_from_file(m_device, - SHADER_DIR "/triangle.spv", - gpu::ShaderStageFlag::FRAGMENT) + m_fragment_shader = gpu::Shader::load_from_file(m_device, SHADER_DIR "/triangle.spv", gpu::ShaderStageFlag::FRAGMENT) .transform_error(monadic::assert("Failed to load fragment shader")) .value(); @@ -58,14 +54,12 @@ class Application: public base::Application { .value(); // initialize render pass - m_render_pass - = gpu::RenderPass:: - create(m_device, - { .attachments = { { .format = m_swapchain->pixel_format() } }, - .subpasses = { { .bind_point = gpu::PipelineBindPoint::GRAPHICS, - .color_attachment_refs = { { .attachment_id = 0u } } } } }) - .transform_error(monadic::assert("Failed to create render pass")) - .value(); + m_render_pass = gpu::RenderPass::create(m_device, + { .attachments = { { .format = m_swapchain->pixel_format() } }, + .subpasses = { { .bind_point = gpu::PipelineBindPoint::GRAPHICS, + .color_attachment_refs = { { .attachment_id = 0u } } } } }) + .transform_error(monadic::assert("Failed to create render pass")) + .value(); const auto window_extent = m_window->extent(); @@ -104,9 +98,8 @@ class Application: public base::Application { for (auto _ : range(BUFFERING_COUNT)) { out.push_back({ .in_flight = gpu::Fence::create_signaled(m_device) - .transform_error(monadic:: - assert("Failed to create swapchain image " - "in flight fence")) + .transform_error(monadic::assert("Failed to create swapchain image " + "in flight fence")) .value(), .image_available = gpu::Semaphore::create(m_device) .transform_error(monadic::assert("Failed to create " @@ -123,24 +116,20 @@ class Application: public base::Application { // transition swapchain image to present image const auto& images = m_swapchain->images(); - const auto image_count = stdr::size(images); - auto transition_cmbs - = m_command_pool->create_command_buffers(image_count) - .transform_error(monadic::assert("Failed to create transition command buffers")) - .value(); + const auto image_count = stdr::size(images); + auto transition_cmbs = m_command_pool->create_command_buffers(image_count) + .transform_error(monadic::assert("Failed to create transition command buffers")) + .value(); m_image_resources.reserve(stdr::size(images)); auto image_index = 0u; for (const auto& swap_image : images) { auto view = gpu::ImageView::create(m_device, swap_image) - .transform_error(core::monadic:: - assert("Failed to create swapchain image view")) + .transform_error(core::monadic::assert("Failed to create swapchain image view")) .value(); - auto framebuffer = m_render_pass - ->create_frame_buffer(m_device, window_extent, to_refs(view)) - .transform_error(core::monadic::assert( - std::format("Failed to create framebuffer for image {}", - image_index))) + auto framebuffer = m_render_pass->create_frame_buffer(m_device, window_extent, to_refs(view)) + .transform_error(core::monadic::assert(std::format("Failed to create framebuffer for image {}", + image_index))) .value(); m_image_resources.push_back({ @@ -155,13 +144,10 @@ class Application: public base::Application { auto& transition_cmb = transition_cmbs[image_index]; *transition_cmb.begin(true) - .transform_error(monadic:: - assert("Failed to begin texture transition command buffer")) + .transform_error(monadic::assert("Failed to begin texture transition command buffer")) .value() ->begin_debug_region(std::format("transition image {}", image_index)) - .transition_image_layout(swap_image, - gpu::ImageLayout::UNDEFINED, - gpu::ImageLayout::PRESENT_SRC) + .transition_image_layout(swap_image, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::PRESENT_SRC) .end_debug_region() .end() .transform_error(monadic::assert("Failed to begin texture transition command " @@ -193,31 +179,24 @@ class Application: public base::Application { const auto& wait = submission_resource.image_available; auto& in_flight = submission_resource.in_flight; - const auto acquire_next_image = bind_front(&gpu::SwapChain::acquire_next_image, - &*m_swapchain, - 100ms, - std::cref(wait)); + const auto acquire_next_image = bind_front(&gpu::SwapChain::acquire_next_image, &*m_swapchain, 100ms, std::cref(wait)); const auto extract_index = [](auto&& _result) static noexcept { auto&& [result, _image_index] = _result; return _image_index; }; - const auto - image_index = in_flight.wait() - .transform([&in_flight](auto&&) mutable noexcept { in_flight.reset(); }) - .and_then(acquire_next_image) - .transform(extract_index) - .transform_error(monadic:: - assert("Failed to acquire next swapchain image")) - .value(); + const auto image_index = in_flight.wait() + .transform([&in_flight](auto&&) mutable noexcept { in_flight.reset(); }) + .and_then(acquire_next_image) + .transform(extract_index) + .transform_error(monadic::assert("Failed to acquire next swapchain image")) + .value(); const auto& swapchain_image_resource = m_image_resources[image_index]; const auto& framebuffer = swapchain_image_resource.framebuffer; const auto& signal = swapchain_image_resource.render_finished; - static constexpr auto PIPELINE_FLAGS = std::array { - gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT - }; + static constexpr auto PIPELINE_FLAGS = std::array { gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT }; // render in it auto& render_cmb = submission_resource.render_cmb; @@ -236,11 +215,7 @@ class Application: public base::Application { .end() .transform_error(monadic::assert("Failed to end render command buffer")) .value() - ->submit(m_raster_queue, - as_refs(wait), - PIPELINE_FLAGS, - as_refs(signal), - as_ref(in_flight)) + ->submit(m_raster_queue, as_refs(wait), PIPELINE_FLAGS, as_refs(signal), as_ref(in_flight)) .transform_error(monadic::assert("Failed to submit render command buffer")); // present it diff --git a/examples/gpu/triangle/xmake.lua b/examples/gpu/triangle/xmake.lua index 7069fe24b..ac0e95fac 100644 --- a/examples/gpu/triangle/xmake.lua +++ b/examples/gpu/triangle/xmake.lua @@ -1,13 +1,18 @@ -if is_plat("linux") then - add_requires( - "nzsl", - { configs = { toolchains = "gcc", runtimes = "stdc++_shared", fs_watcher = false, link = {} } } - ) -elseif is_plat("windows") then - add_requires("nzsl", { configs = { toolchains = "msvc", runtimes = "MD", fs_watcher = false, links = {} } }) -else - add_requires("nzsl", { configs = { fs_watcher = false, links = {} } }) +-- if is_plat("windows") then +-- add_requires("nzsl", { configs = { toolchains = "msvc", runtimes = "MD", fs_watcher = false, links = {} } }) +-- else +-- add_requires("nzsl", { configs = { fs_watcher = false } }) +-- end +local runtimes +local toolchain +if is_plat("windows") then + runtimes = "MD" + toolchain = "msvc" +elseif is_plat("linux") then + runtimes = "stdc++_shared" + toolchain = "gcc" end +add_requires("nzsl", { configs = { fs_watcher = false, kind = "binary", toolchains = toolchain, runtimes = runtimes } }) target("triangle", function() set_kind("binary") diff --git a/examples/wsi/events/src/main.cpp b/examples/wsi/events/src/main.cpp index b43c56d2f..1557b1191 100644 --- a/examples/wsi/events/src/main.cpp +++ b/examples/wsi/events/src/main.cpp @@ -5,6 +5,7 @@ import std; import stormkit.core; +import stormkit.main; import stormkit.log; import stormkit.wsi; @@ -40,84 +41,72 @@ auto main(std::span args) -> int { auto foo = 0; window - .on(wsi::ResizedEventFunc { [](const math::Extent2& extent) static noexcept { - ilog("Resize event: {}", extent); - } }, + .on(wsi::ResizedEventFunc { [](const math::Extent2& extent) static noexcept { ilog("Resize event: {}", extent); } }, wsi::MonitorChangedEventFunc { [](const wsi::Monitor& monitor) noexcept { ilog("Monitor changed event: {}", monitor); } }, wsi::MouseMovedEventFunc { [](u8 /*id*/, const math::vec2i& position) noexcept { ilog("Mouse move event: {}", position); } }, - wsi::MouseButtonDownEventFunc { - [](u8 /*id*/, wsi::MouseButton button, const math::vec2i& position) noexcept { - ilog("Mouse button down event: {} {}", button, position); - } }, - wsi::MouseButtonUpEventFunc { - [](u8 /*id*/, wsi::MouseButton button, const math::vec2i& position) noexcept { - ilog("Mouse button up event: {} {}", button, position); - } }, + wsi::MouseButtonDownEventFunc { [](u8 /*id*/, wsi::MouseButton button, const math::vec2i& position) noexcept { + ilog("Mouse button down event: {} {}", button, position); + } }, + wsi::MouseButtonUpEventFunc { [](u8 /*id*/, wsi::MouseButton button, const math::vec2i& position) noexcept { + ilog("Mouse button up event: {} {}", button, position); + } }, wsi::RestoredEventFunc { [] noexcept { ilog("Restored event"); } }, wsi::MinimizedEventFunc { [] noexcept { ilog("Minimized event"); } }, wsi::ActivateEventFunc { [] noexcept { ilog("Activate event"); } }, wsi::DeactivateEventFunc { [] noexcept { ilog("Deactivate event"); } }, - wsi::KeyDownEventFunc { - [&window, &foo](u8 /*id*/, wsi::Key key, char c) mutable noexcept { - switch (key) { - case wsi::Key::ESCAPE: - window.close(); - ilog("Closing window"); - break; - case wsi::Key::W: { - auto extent = window.extent(); - extent.width += 10; - window.set_extent(extent); - } break; - case wsi::Key::T: { - window - .set_title(std::format("StormKit WSI Events Example | T pressed {} times", - ++foo)); - } break; - case wsi::Key::H: { - auto extent = window.extent(); - extent.height += 10; - window.set_extent(extent); - } break; - case wsi::Key::F11: - window.toggle_fullscreen(); - ilog("Toggling fullscreen to {}", window.fullscreen()); - break; - case wsi::Key::F1: - window.toggle_hidden_mouse(); - ilog("Toggling hidden mouse to {}", window.is_mouse_hidden()); - break; - case wsi::Key::F2: - window.toggle_locked_mouse(); - ilog("Toggling locked mouse to {}", window.is_mouse_locked()); - break; - case wsi::Key::F3: - window.toggle_confined_mouse(); - ilog("Toggling confined mouse to {}", window.is_mouse_confined()); - break; - case wsi::Key::F4: - window.toggle_relative_mouse(); - ilog("Toggling relative mouse to {}", window.is_mouse_relative()); - break; - case wsi::Key::F5: - window.toggle_key_repeat(); - ilog("Toggling key repeat to {}", window.is_key_repeat_enabled()); - break; - default: break; - } + wsi::KeyDownEventFunc { [&window, &foo](u8 /*id*/, wsi::Key key, char c) mutable noexcept { + switch (key) { + case wsi::Key::ESCAPE: + window.close(); + ilog("Closing window"); + break; + case wsi::Key::W: { + auto extent = window.extent(); + extent.width += 10; + window.set_extent(extent); + } break; + case wsi::Key::T: { + window.set_title(std::format("StormKit WSI Events Example | T pressed {} times", ++foo)); + } break; + case wsi::Key::H: { + auto extent = window.extent(); + extent.height += 10; + window.set_extent(extent); + } break; + case wsi::Key::F11: + window.toggle_fullscreen(); + ilog("Toggling fullscreen to {}", window.fullscreen()); + break; + case wsi::Key::F1: + window.toggle_hidden_mouse(); + ilog("Toggling hidden mouse to {}", window.is_mouse_hidden()); + break; + case wsi::Key::F2: + window.toggle_locked_mouse(); + ilog("Toggling locked mouse to {}", window.is_mouse_locked()); + break; + case wsi::Key::F3: + window.toggle_confined_mouse(); + ilog("Toggling confined mouse to {}", window.is_mouse_confined()); + break; + case wsi::Key::F4: + window.toggle_relative_mouse(); + ilog("Toggling relative mouse to {}", window.is_mouse_relative()); + break; + case wsi::Key::F5: + window.toggle_key_repeat(); + ilog("Toggling key repeat to {}", window.is_key_repeat_enabled()); + break; + default: break; + } - ilog("Key down --\n code: {}\n value: '{}'\n raw_value: 0x{:0x})", - key, - c, - c); - } }, - wsi::KeyUpEventFunc { [](u8 /*id*/, wsi::Key key, char /*c*/) noexcept { - ilog("Key up --\n code: {}", key); - } }); + ilog("Key down --\n code: {}\n value: '{}'\n raw_value: 0x{:0x})", key, c, c); + } }, + wsi::KeyUpEventFunc { [](u8 /*id*/, wsi::Key key, char /*c*/) noexcept { ilog("Key up --\n code: {}", key); } }); window.event_loop([&] mutable { window.clear(); }); diff --git a/examples/wsi/framebuffer/src/main.cpp b/examples/wsi/framebuffer/src/main.cpp index 0560211c6..92ddd0487 100644 --- a/examples/wsi/framebuffer/src/main.cpp +++ b/examples/wsi/framebuffer/src/main.cpp @@ -18,9 +18,7 @@ using namespace std::literals; namespace stdr = std::ranges; -auto update_pixels(stormkit::ThreadPool& pool, - std::vector>& pixels, - const auto& extent) noexcept { +auto update_pixels(stormkit::ThreadPool& pool, std::vector>& pixels, const auto& extent) noexcept { const auto rect_width = extent.width / 5; const auto rect_height = extent.height / 5; @@ -34,27 +32,24 @@ auto update_pixels(stormkit::ThreadPool& pool, pixels.resize(extent.height * extent.width, colors::RED); auto data = std::mdspan { stdr::data(pixels), extent.height, extent.width }; - parallel_for(pool, - range(extent.width * extent.height), - [&rect, data, &extent](auto x_y) mutable noexcept { - const auto x = as(x_y % extent.width); - const auto y = as(x_y / extent.width); - - if (math::AABB({ as(x), as(y) }, rect)) - data[y, x] = colors::BLACK; - else { - const auto color_id = as(x) / as(extent.width); - if (color_id >= 0.8) data[y, x] = colors::BLUE; - else if (color_id >= 0.6) - data[y, x] = colors::GREEN; - else if (color_id >= 0.4) - data[y, x] = colors::WHITE; - else if (color_id >= 0.2) - data[y, x] = colors::YELLOW; - else - data[y, x] = colors::RED; - } - }); + parallel_for(pool, range(extent.width * extent.height), [&rect, data, &extent](auto x_y) mutable noexcept { + const auto x = as(x_y % extent.width); + const auto y = as(x_y / extent.width); + + if (math::AABB({ as(x), as(y) }, rect)) data[y, x] = colors::BLACK; + else { + const auto color_id = as(x) / as(extent.width); + if (color_id >= 0.8) data[y, x] = colors::BLUE; + else if (color_id >= 0.6) + data[y, x] = colors::GREEN; + else if (color_id >= 0.4) + data[y, x] = colors::WHITE; + else if (color_id >= 0.2) + data[y, x] = colors::YELLOW; + else + data[y, x] = colors::RED; + } + }); } auto main(std::span args) -> int { @@ -66,25 +61,22 @@ auto main(std::span args) -> int { ilog("--- Monitors ---"); ilog("{}", monitors); - auto window = wsi::Window::open("Hello world", - { .width = 800_u32, .height = 600_u32 }, - wsi::WindowFlag::RESIZEABLE); + auto window = wsi::Window::open("Hello world", { .width = 800_u32, .height = 600_u32 }, wsi::WindowFlag::RESIZEABLE); ilog("wm: {}", window.wm()); auto pool = core::ThreadPool {}; auto pixels = std::vector> {}; update_pixels(pool, pixels, window.extent()); auto active = true; - window - .on(wsi::ResizedEventFunc { [&](const math::Extent2& extent) mutable noexcept { - update_pixels(pool, pixels, extent); - window.fill_framebuffer(pixels); - } }, - wsi::RestoredEventFunc { [&active] mutable noexcept { active = true; } }, - wsi::MinimizedEventFunc { [&active] mutable noexcept { active = false; } }, - wsi::KeyDownEventFunc { [&window](u8 /*id*/, wsi::Key key, char /*c*/) mutable noexcept { - if (key == wsi::Key::ESCAPE) window.close(); - } }); + window.on(wsi::ResizedEventFunc { [&](const math::Extent2& extent) mutable noexcept { + update_pixels(pool, pixels, extent); + window.fill_framebuffer(pixels); + } }, + wsi::RestoredEventFunc { [&active] mutable noexcept { active = true; } }, + wsi::MinimizedEventFunc { [&active] mutable noexcept { active = false; } }, + wsi::KeyDownEventFunc { [&window](u8 /*id*/, wsi::Key key, char /*c*/) mutable noexcept { + if (key == wsi::Key::ESCAPE) window.close(); + } }); window.event_loop([&] noexcept { if (not active) std::this_thread::yield(); diff --git a/modules/stormkit.mpp b/modules/stormkit.mpp index 9eb2ba2d8..b19c4ce20 100644 --- a/modules/stormkit.mpp +++ b/modules/stormkit.mpp @@ -29,3 +29,6 @@ export import stormkit.wsi; #ifdef STORMKIT_LIB_GPU_ENABLED export import stormkit.gpu; #endif +#ifdef STORMKIT_LIB_LUAU_ENABLED +export import stormkit.luau; +#endif diff --git a/modules/stormkit/core/console/style.mpp b/modules/stormkit/core/console/style.mpp index 5424cc3eb..04e9dfb4a 100644 --- a/modules/stormkit/core/console/style.mpp +++ b/modules/stormkit/core/console/style.mpp @@ -84,11 +84,9 @@ export { namespace std { template - struct formatter, CharT> - : formatter, CharT> { + struct formatter, CharT>: formatter, CharT> { template - auto format(const stormkit::core::Stylized& stylized, - FormatContext& ctx) const noexcept -> decltype(ctx.out()); + auto format(const stormkit::core::Stylized& stylized, FormatContext& ctx) const noexcept -> decltype(ctx.out()); }; } // namespace std } @@ -162,9 +160,7 @@ namespace stormkit { inline namespace core { auto out = std::string {}; const auto size = [this] noexcept { if constexpr (requires { stdr::size(value); }) return stdr::size(value); - else if constexpr (requires { - std::char_traits>::length(value); - }) + else if constexpr (requires { std::char_traits>::length(value); }) return std::char_traits>::length(value); else { (void)this; @@ -179,8 +175,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - constexpr auto Stylized::render_into(stdr::output_range auto& out) const noexcept - -> void { + constexpr auto Stylized::render_into(stdr::output_range auto& out) const noexcept -> void { if (fg) out.append_range(ecma48::FOREGROUND.at(*fg)); if (bg) out.append_range(ecma48::BACKGROUND.at(*bg)); if (check_flag_bit(modifiers, StyleModifier::BOLD)) out.append(ecma48::BOLD); @@ -202,8 +197,7 @@ namespace std { template template STORMKIT_FORCE_INLINE - auto formatter, CharT>::format(const Stylized& stylized, - FormatContext& ctx) const noexcept + auto formatter, CharT>::format(const Stylized& stylized, FormatContext& ctx) const noexcept -> decltype(ctx.out()) { auto&& out = ctx.out(); return format_to(out, "{}", stylized.render()); diff --git a/modules/stormkit/core/containers.mpp b/modules/stormkit/core/containers.mpp index 38bb4e972..fbfbf8e45 100644 --- a/modules/stormkit/core/containers.mpp +++ b/modules/stormkit/core/containers.mpp @@ -31,8 +31,7 @@ namespace std { //////////////////////////////////////// template template - constexpr auto formatter, CharT>::parse(ParseContext& ctx) noexcept - -> decltype(ctx.begin()) { + constexpr auto formatter, CharT>::parse(ParseContext& ctx) noexcept -> decltype(ctx.begin()) { return ctx.begin(); } @@ -40,8 +39,7 @@ namespace std { //////////////////////////////////////// template template - inline auto formatter, CharT>::format(const std::variant& variant, - FormatContext& ctx) const + inline auto formatter, CharT>::format(const std::variant& variant, FormatContext& ctx) const -> decltype(ctx.out()) { return std::visit( [&ctx](auto&& value) mutable noexcept { diff --git a/modules/stormkit/core/containers/multi_buffer.mpp b/modules/stormkit/core/containers/multi_buffer.mpp index 3b2e678cb..e624b2140 100644 --- a/modules/stormkit/core/containers/multi_buffer.mpp +++ b/modules/stormkit/core/containers/multi_buffer.mpp @@ -50,8 +50,7 @@ export namespace stormkit { inline namespace core { template [[nodiscard]] - constexpr auto range(this Self& self) noexcept - -> std::span>; + constexpr auto range(this Self& self) noexcept -> std::span>; private: std::array m_ranges_sizes; @@ -120,8 +119,7 @@ namespace stormkit { inline namespace core { template template STORMKIT_FORCE_INLINE - constexpr auto MultiBuffer::data(this Self& self) noexcept - -> const meta::ForwardConst* { + constexpr auto MultiBuffer::data(this Self& self) noexcept -> const meta::ForwardConst* { return stdr::data(self.m_data); } @@ -140,28 +138,24 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template template - constexpr auto MultiBuffer::init_range(V&& init_data) noexcept - -> std::span { - static_assert(TYPE_INDEX < sizeof...(T), "Index is out of bounds"); - auto span = std::span { stdr::data(m_data) + m_ranges_begin[TYPE_INDEX], - m_ranges_sizes[TYPE_INDEX] }; - - auto begin = stdr::begin(span); - for (auto&& bytes : - std::forward(init_data) | stdv::transform(monadic::as_bytes(Force {}))) { - stdr::copy(bytes, begin); - begin += as(stdr::size(bytes)); - } + constexpr auto MultiBuffer::init_range(V&& init_data) noexcept -> std::span { + static_assert(TYPE_INDEX < sizeof...(T), "Index is out of bounds"); + auto span = std::span { stdr::data(m_data) + m_ranges_begin[TYPE_INDEX], m_ranges_sizes[TYPE_INDEX] }; + + auto begin = stdr::begin(span); + for (auto&& bytes : std::forward(init_data) | stdv::transform(monadic::as_bytes(Force {}))) { + stdr::copy(bytes, begin); + begin += as(stdr::size(bytes)); + } - return range(); - } + return range(); + } ///////////////////////////////////// ///////////////////////////////////// template template - constexpr auto MultiBuffer::range(this Self& self) noexcept - -> std::span> { + constexpr auto MultiBuffer::range(this Self& self) noexcept -> std::span> { static_assert(meta::IsOneOf, "U should be a type contained by MultiBuffer"); static constexpr auto TYPE_INDEX = meta::find_type_index_of(); return self.template range(); @@ -171,20 +165,18 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template template - constexpr auto MultiBuffer::range(this Self& self) noexcept - -> std::span> { - static_assert(TYPE_INDEX < sizeof...(T), "Index is out of bounds"); - using U = T...[TYPE_INDEX]; - using OutType = meta::ForwardConst; - const auto ptr = stdr::begin(self.m_data) + as(self.m_ranges_begin[TYPE_INDEX]); - return std::span { + constexpr auto MultiBuffer::range(this Self& self) noexcept -> std::span> { + static_assert(TYPE_INDEX < sizeof...(T), "Index is out of bounds"); + using U = T...[TYPE_INDEX]; + using OutType = meta::ForwardConst; + const auto ptr = stdr::begin(self.m_data) + as(self.m_ranges_begin[TYPE_INDEX]); + return std::span { #if defined(__cpp_lib_start_lifetime_as) and __cpp_lib_start_lifetime_as >= 202207L - std::start_lifetime_as_array(ptr, - self.m_ranges_sizes[TYPE_INDEX] / sizeof(U)), + std::start_lifetime_as_array(ptr, self.m_ranges_sizes[TYPE_INDEX] / sizeof(U)), #else - std::launder(std::bit_cast(ptr)), + std::launder(std::bit_cast(ptr)), #endif - self.m_ranges_sizes[TYPE_INDEX] / sizeof(U) - }; - } + self.m_ranges_sizes[TYPE_INDEX] / sizeof(U) + }; + } }} // namespace stormkit::core diff --git a/modules/stormkit/core/containers/raii_capsule.mpp b/modules/stormkit/core/containers/raii_capsule.mpp index efa14877c..f018d4434 100644 --- a/modules/stormkit/core/containers/raii_capsule.mpp +++ b/modules/stormkit/core/containers/raii_capsule.mpp @@ -26,8 +26,7 @@ export namespace stormkit { inline namespace core { requires meta::Is, T>; template static constexpr auto create(Args&&... args) noexcept -> decltype(auto) - requires meta::IsSpecializationOf, - std::expected>; + requires meta::IsSpecializationOf, std::expected>; static constexpr auto take(T&& value) noexcept -> RAIICapsule; static constexpr auto empty() noexcept -> RAIICapsule; @@ -65,8 +64,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template template - constexpr auto RAIICapsule:: - create(Args&&... args) noexcept -> RAIICapsule + constexpr auto RAIICapsule::create(Args&&... args) noexcept -> RAIICapsule requires meta::Is, T> { return RAIICapsule { Constructor(std::forward(args)...) }; @@ -76,10 +74,8 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template template - constexpr auto RAIICapsule:: - create(Args&&... args) noexcept -> decltype(auto) - requires meta::IsSpecializationOf, - std::expected> + constexpr auto RAIICapsule::create(Args&&... args) noexcept -> decltype(auto) + requires meta::IsSpecializationOf, std::expected> { return Constructor(std::forward(args)...).transform(monadic::init()); } @@ -88,9 +84,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto RAIICapsule::take(T&& - value) noexcept - -> RAIICapsule { + constexpr auto RAIICapsule::take(T&& value) noexcept -> RAIICapsule { return RAIICapsule { std::move(value) }; } @@ -98,8 +92,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto RAIICapsule::empty() noexcept - -> RAIICapsule { + constexpr auto RAIICapsule::empty() noexcept -> RAIICapsule { return RAIICapsule { RELEASE_VALUE }; } @@ -115,8 +108,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr RAIICapsule:: - RAIICapsule(RAIICapsule&& other) noexcept { + constexpr RAIICapsule::RAIICapsule(RAIICapsule&& other) noexcept { m_handle = other.release(); } @@ -124,8 +116,8 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto RAIICapsule:: - operator=(RAIICapsule&& other) noexcept -> RAIICapsule& { + constexpr auto RAIICapsule::operator=(RAIICapsule&& other) noexcept + -> RAIICapsule& { m_handle = other.release(); return *this; } @@ -134,8 +126,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr RAIICapsule::operator T() - const noexcept { + constexpr RAIICapsule::operator T() const noexcept { return m_handle; } @@ -143,8 +134,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto RAIICapsule::handle() noexcept - -> T& { + constexpr auto RAIICapsule::handle() noexcept -> T& { return m_handle; } @@ -152,8 +142,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto RAIICapsule::handle() const noexcept - -> T { + constexpr auto RAIICapsule::handle() const noexcept -> T { return m_handle; } @@ -161,8 +150,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto RAIICapsule::release() noexcept - -> T { + constexpr auto RAIICapsule::release() noexcept -> T { auto tmp = std::exchange(m_handle, RELEASE_VALUE); return tmp; } @@ -171,8 +159,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto RAIICapsule:: - reset(T handle) noexcept -> void { + constexpr auto RAIICapsule::reset(T handle) noexcept -> void { destroy(); m_handle = handle; } @@ -181,8 +168,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto RAIICapsule::destroy() noexcept - -> void { + constexpr auto RAIICapsule::destroy() noexcept -> void { if (m_handle != RELEASE_VALUE) { Deleter(release()); } } @@ -190,8 +176,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr RAIICapsule:: - RAIICapsule(T handle) noexcept { + constexpr RAIICapsule::RAIICapsule(T handle) noexcept { m_handle = handle; } @@ -199,6 +184,6 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr RAIICapsule:: - RAIICapsule() noexcept = default; + constexpr RAIICapsule::RAIICapsule() noexcept + = default; }} // namespace stormkit::core diff --git a/modules/stormkit/core/containers/ringbuffer.mpp b/modules/stormkit/core/containers/ringbuffer.mpp index 5e459f05d..be740f6f5 100644 --- a/modules/stormkit/core/containers/ringbuffer.mpp +++ b/modules/stormkit/core/containers/ringbuffer.mpp @@ -53,8 +53,7 @@ export namespace stormkit { inline namespace core { auto push(U&& value) noexcept(std::is_nothrow_constructible_v) -> void; template - auto emplace(Args&&... values) noexcept(std::is_nothrow_constructible_v) - -> void; + auto emplace(Args&&... values) noexcept(std::is_nothrow_constructible_v) -> void; auto next() noexcept -> void; @@ -212,8 +211,7 @@ namespace stormkit { inline namespace core { template template requires meta::Is> - auto RingBuffer::push(U&& value) noexcept(std::is_nothrow_constructible_v) - -> void { + auto RingBuffer::push(U&& value) noexcept(std::is_nothrow_constructible_v) -> void { emplace(std::forward(value)); } @@ -221,9 +219,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template template - auto RingBuffer< - T>::emplace(Args&&... values) noexcept(std::is_nothrow_constructible_v) - -> void { + auto RingBuffer::emplace(Args&&... values) noexcept(std::is_nothrow_constructible_v) -> void { if (m_count == m_capacity) pop(); new (&m_buffer[m_write * sizeof(ValueType)]) ValueType { std::forward(values)... }; diff --git a/modules/stormkit/core/containers/shmbuffer.mpp b/modules/stormkit/core/containers/shmbuffer.mpp index b226194d3..07a8fec42 100644 --- a/modules/stormkit/core/containers/shmbuffer.mpp +++ b/modules/stormkit/core/containers/shmbuffer.mpp @@ -32,8 +32,7 @@ export namespace stormkit { inline namespace core { WRITE = 2, }; - static auto create(usize size, std::string name) noexcept - -> std::expected; + static auto create(usize size, std::string name) noexcept -> std::expected; static auto create_with_access(usize size, std::string name, Access access) noexcept -> std::expected; @@ -86,8 +85,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - auto SHMBuffer::create(usize size, std::string name) noexcept - -> std::expected { + auto SHMBuffer::create(usize size, std::string name) noexcept -> std::expected { return create_with_access(size, std::move(name), Access::READ | Access::WRITE); } @@ -103,10 +101,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr SHMBuffer::SHMBuffer(usize size, - std::string name, - Access access, - PrivateFuncTag) noexcept + constexpr SHMBuffer::SHMBuffer(usize size, std::string name, Access access, PrivateFuncTag) noexcept : m_access { access }, m_size { size }, m_name { std::move(name) } { } @@ -114,8 +109,10 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// STORMKIT_FORCE_INLINE inline SHMBuffer::SHMBuffer(SHMBuffer&& other) noexcept - : m_access { other.access() }, m_handle { std::exchange(other.m_handle, nullptr) }, - m_size { std::exchange(other.m_size, 0u) }, m_name { std::exchange(other.m_name, {}) }, + : m_access { other.access() }, + m_handle { std::exchange(other.m_handle, nullptr) }, + m_size { std::exchange(other.m_size, 0u) }, + m_name { std::exchange(other.m_name, {}) }, m_data { std::exchange(other.m_data, {}) } { } @@ -173,8 +170,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - auto SHMBuffer::operator[](this Self& self, usize index) noexcept - -> meta::ForwardConst& { + auto SHMBuffer::operator[](this Self& self, usize index) noexcept -> meta::ForwardConst& { EXPECTS(self.m_handle); EXPECTS(index < self.m_size); return std::forward(self).m_data[index]; diff --git a/modules/stormkit/core/containers/tree.mpp b/modules/stormkit/core/containers/tree.mpp index c627e40b0..f7981b82e 100644 --- a/modules/stormkit/core/containers/tree.mpp +++ b/modules/stormkit/core/containers/tree.mpp @@ -75,9 +75,7 @@ export namespace stormkit { inline namespace core { auto getFreeNode() -> TreeNodeIndexType; - auto insert(TreeNodeType&& node, - TreeNodeIndexType parent_index, - TreeNodeIndexType previous_sibling) -> TreeNodeIndexType; + auto insert(TreeNodeType&& node, TreeNodeIndexType parent_index, TreeNodeIndexType previous_sibling) -> TreeNodeIndexType; auto remove(TreeNodeIndexType index) -> void; auto markDirty(TreeNodeIndexType index, TreeNodeDirtyBitType bits) -> void; @@ -106,14 +104,12 @@ export namespace stormkit { inline namespace core { [[nodiscard]] auto dirties() const noexcept -> std::span; - auto genDotFile(std::filesystem::path filepath, - std::function colorize_node) const + auto genDotFile(std::filesystem::path filepath, std::function colorize_node) const -> void; auto genDotFile(std::filesystem::path filepath, core::u32 highlight, - std::function colorize_node) const - -> void; + std::function colorize_node) const -> void; private: TreeNodeIndexType m_first_free_index = 0; @@ -203,8 +199,7 @@ namespace stormkit { inline namespace core { Tree::Tree() { m_tree.resize(DEFAULT_PREALLOCATED_TREE_SIZE); - for (auto i : range(std::size(m_tree) - 1u)) - m_tree[i].set_next_sibling(i + 1u); + for (auto i : range(std::size(m_tree) - 1u)) m_tree[i].set_next_sibling(i + 1u); } //////////////////////////////////////// @@ -258,9 +253,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - auto Tree::insert(TreeNodeType&& node, - TreeNodeIndexType parent_index, - TreeNodeIndexType previous_sibling) -> TreeNodeIndexType { + auto Tree::insert(TreeNodeType&& node, TreeNodeIndexType parent_index, TreeNodeIndexType previous_sibling) + -> TreeNodeIndexType { const auto index = getFreeNode(); auto& _node = m_tree[index]; @@ -273,8 +267,7 @@ namespace stormkit { inline namespace core { auto& parent_node = *(std::ranges::begin(m_tree) + parent_index); // new node is first child - if (parent_node.first_child() == TreeNode::INVALID_INDEX) - parent_node.set_first_child(index); + if (parent_node.first_child() == TreeNode::INVALID_INDEX) parent_node.set_first_child(index); else if (previous_sibling == TreeNode::INVALID_INDEX) { // insert a beginning of childs _node.set_next_sibling(parent_node.first_child()); parent_node.set_first_child(index); @@ -331,8 +324,7 @@ namespace stormkit { inline namespace core { node.invalidate(); - if (last_index != TreeNode::INVALID_INDEX) - m_tree[last_index].set_next_sibling(current_index); + if (last_index != TreeNode::INVALID_INDEX) m_tree[last_index].set_next_sibling(current_index); last_index = current_index; } @@ -344,8 +336,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - auto Tree::markDirty(TreeNodeIndexType index, TreeNodeDirtyBitType bits) - -> void { + auto Tree::markDirty(TreeNodeIndexType index, TreeNodeDirtyBitType bits) -> void { auto& node = m_tree[index]; if (not node.dirty_bits()) { m_dirties.emplace_back(index); @@ -368,8 +359,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - auto Tree::operator[](TreeNodeIndexType index) const noexcept - -> const TreeNodeType& { + auto Tree::operator[](TreeNodeIndexType index) const noexcept -> const TreeNodeType& { EXPECTS(index < std::size(m_tree)); return m_tree[index]; @@ -445,9 +435,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - auto Tree::genDotFile(std::filesystem::path filepath, - std::function - colorize_node) const -> void { + auto Tree::genDotFile(std::filesystem::path filepath, + std::function colorize_node) const -> void { auto stream = std::fstream(filepath, std::ios::out); stream @@ -478,15 +467,9 @@ namespace stormkit { inline namespace core { for (auto i : range(m_first_free_index)) { if (operator[](i).first_child() == TreeNodeClass::INVALID_INDEX) continue; - for (auto current = operator[](i).first_child(); - current != TreeNodeClass::INVALID_INDEX; - current = operator[](current).next_sibling()) { - stream - << " \"node" - << i - << "\" -> \"node" - << current - << "\" [color=seagreen] ;\n"; + for (auto current = operator[](i).first_child(); current != TreeNodeClass::INVALID_INDEX; + current = operator[](current).next_sibling()) { + stream << " \"node" << i << "\" -> \"node" << current << "\" [color=seagreen] ;\n"; } } @@ -498,10 +481,9 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - auto Tree::genDotFile(std::filesystem::path filepath, - core::u32 highlight, - std::function - colorize_node) const -> void { + auto Tree::genDotFile(std::filesystem::path filepath, + core::u32 highlight, + std::function colorize_node) const -> void { std::fstream stream(filepath.string(), std::ios::out); stream @@ -546,15 +528,9 @@ namespace stormkit { inline namespace core { for (auto i : range(m_first_free_index)) { if (operator[](i).first_child() == TreeNodeClass::INVALID_INDEX) continue; - for (auto current = operator[](i).first_child(); - current != TreeNodeClass::INVALID_INDEX; - current = operator[](current).next_sibling()) { - stream - << " \"node" - << i - << "\" -> \"nodeNode" - << current - << "\" [color=seagreen] ;\n"; + for (auto current = operator[](i).first_child(); current != TreeNodeClass::INVALID_INDEX; + current = operator[](current).next_sibling()) { + stream << " \"node" << i << "\" -> \"nodeNode" << current << "\" [color=seagreen] ;\n"; } } diff --git a/modules/stormkit/core/containers/utils.mpp b/modules/stormkit/core/containers/utils.mpp index 33920b6ac..1ab6b2c3e 100644 --- a/modules/stormkit/core/containers/utils.mpp +++ b/modules/stormkit/core/containers/utils.mpp @@ -28,15 +28,13 @@ export namespace stormkit { inline namespace core { constexpr auto merge(Out& output, const Inputs&... ranges) noexcept -> void; template typename Out = std::vector, stdr::input_range... Inputs> - constexpr auto concat(const Inputs&... inputs) noexcept - -> Out>>; + constexpr auto concat(const Inputs&... inputs) noexcept -> Out>>; template constexpr auto move_and_merge(Out& output, Inputs&&... ranges) noexcept -> void; template typename Out = std::vector, stdr::input_range... Inputs> - constexpr auto move_and_concat(Inputs&&... inputs) noexcept - -> Out>>; + constexpr auto move_and_concat(Inputs&&... inputs) noexcept -> Out>>; using std::to_array; @@ -45,8 +43,7 @@ export namespace stormkit { inline namespace core { template requires(sizeof...(Args) > 0) - constexpr auto into_array(Args&&... args) noexcept - -> std::array, sizeof...(Args)>; + constexpr auto into_array(Args&&... args) noexcept -> std::array, sizeof...(Args)>; template requires(sizeof...(Args) > 0) @@ -54,8 +51,7 @@ export namespace stormkit { inline namespace core { template requires(sizeof...(Args) > 0) - constexpr auto into_dyn_array(Args&&... args) noexcept - -> std::vector>; + constexpr auto into_dyn_array(Args&&... args) noexcept -> std::vector>; template requires(sizeof...(Args) > 0) @@ -69,12 +65,10 @@ export namespace stormkit { inline namespace core { constexpr auto as_view(T& value) noexcept -> std::span; template - constexpr auto as_view(T& range) noexcept - -> std::span>>; + constexpr auto as_view(T& range) noexcept -> std::span>>; template - constexpr auto as_view(T& range, Force) noexcept - -> std::span>>; + constexpr auto as_view(T& range, Force) noexcept -> std::span>>; }} // namespace stormkit::core //////////////////////////////////////////////////////////////////// @@ -84,7 +78,7 @@ export namespace stormkit { inline namespace core { namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - template typename Container = std::vector, typename T> + template typename Container, typename T> STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto filled_with(usize size, T value) noexcept -> Container { auto out = Container {}; @@ -115,11 +109,10 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - template typename Out = std::vector, stdr::input_range... Inputs> + template typename Out, stdr::input_range... Inputs> STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto concat(const Inputs&... inputs) noexcept - -> Out>> { + constexpr auto concat(const Inputs&... inputs) noexcept -> Out>> { auto output = Out>> {}; merge(output, inputs...); @@ -138,11 +131,10 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - template typename Out = std::vector, stdr::input_range... Inputs> + template typename Out, stdr::input_range... Inputs> STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto move_and_concat(Inputs&&... inputs) noexcept - -> Out>> { + constexpr auto move_and_concat(Inputs&&... inputs) noexcept -> Out>> { auto output = Out>> {}; move_and_merge(output, std::forward(inputs)...); @@ -164,8 +156,7 @@ namespace stormkit { inline namespace core { requires(sizeof...(Args) > 0) STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto into_array(Args&&... args) noexcept - -> std::array, sizeof...(Args)> { + constexpr auto into_array(Args&&... args) noexcept -> std::array, sizeof...(Args)> { static_assert((not meta::IsLValueReference and ...), "lvalue reference can't be passed to into_ functions as it take " "ownership"); @@ -190,8 +181,7 @@ namespace stormkit { inline namespace core { template requires(sizeof...(Args) > 0) STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto into_dyn_array(Args&&... args) noexcept - -> std::vector> { + constexpr auto into_dyn_array(Args&&... args) noexcept -> std::vector> { static_assert((not meta::IsLValueReference and ...), "lvalue reference can't be passed to into_ functions as it take " "ownership"); @@ -232,8 +222,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto as_view(T& range) noexcept - -> std::span>> { + constexpr auto as_view(T& range) noexcept -> std::span>> { return { range }; } @@ -241,8 +230,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto as_view(T& range, Force) noexcept - -> std::span>> { + constexpr auto as_view(T& range, Force) noexcept -> std::span>> { return { range }; } }} // namespace stormkit::core diff --git a/modules/stormkit/core/coroutines.mpp b/modules/stormkit/core/coroutines.mpp index fa92ed69b..00ff16359 100644 --- a/modules/stormkit/core/coroutines.mpp +++ b/modules/stormkit/core/coroutines.mpp @@ -9,14 +9,11 @@ export module stormkit.core:coroutines; export import std; -#if not defined(__cpp_lib_generator) \ - or (defined(__cpp_lib_generator) and (__cpp_lib_generator < 202207L)) +#if not defined(__cpp_lib_generator) or (defined(__cpp_lib_generator) and (__cpp_lib_generator < 202207L)) export namespace std { struct use_allocator_arg {}; - template, - typename _Allocator = use_allocator_arg> + template, typename _Allocator = use_allocator_arg> class generator; namespace ranges { @@ -131,10 +128,8 @@ namespace std { } // namespace ranges template - static constexpr bool __allocator_needs_to_be_stored = !std::allocator_traits< - _Alloc>::is_always_equal::value - || !std::is_default_constructible_v< - _Alloc>; + static constexpr bool __allocator_needs_to_be_stored = !std::allocator_traits<_Alloc>::is_always_equal::value + || !std::is_default_constructible_v<_Alloc>; // Round s up to next multiple of a. constexpr size_t __aligned_allocation_size(size_t s, size_t a) { @@ -152,44 +147,32 @@ namespace std { } static _Alloc& __get_allocator(void* __frame, std::size_t __frameSize) noexcept { - return *reinterpret_cast<_Alloc*>(static_cast(__frame) - + __offset_of_allocator(__frameSize)); + return *reinterpret_cast<_Alloc*>(static_cast(__frame) + __offset_of_allocator(__frameSize)); } public: template - static void* operator new(std::size_t __frameSize, - std::allocator_arg_t, - _Alloc __alloc, - _Args&...) { + static void* operator new(std::size_t __frameSize, std::allocator_arg_t, _Alloc __alloc, _Args&...) { void* __frame = __alloc.allocate(__padded_frame_size(__frameSize)); // Store allocator at end of the coroutine frame. // Assuming the allocator's move constructor is non-throwing (a requirement for // allocators) - ::new (static_cast(std::addressof(__get_allocator(__frame, __frameSize)))) - _Alloc(std::move(__alloc)); + ::new (static_cast(std::addressof(__get_allocator(__frame, __frameSize)))) _Alloc(std::move(__alloc)); return __frame; } template - static void* operator new(std::size_t __frameSize, - _This&, - std::allocator_arg_t, - _Alloc __alloc, - _Args&...) { - return __promise_base_alloc::operator new(__frameSize, - std::allocator_arg, - std::move(__alloc)); + static void* operator new(std::size_t __frameSize, _This&, std::allocator_arg_t, _Alloc __alloc, _Args&...) { + return __promise_base_alloc::operator new(__frameSize, std::allocator_arg, std::move(__alloc)); } static void operator delete(void* __ptr, std::size_t __frameSize) noexcept { _Alloc& __alloc = __get_allocator(__ptr, __frameSize); _Alloc __localAlloc(std::move(__alloc)); __alloc.~Alloc(); - __localAlloc - .deallocate(static_cast(__ptr), __padded_frame_size(__frameSize)); + __localAlloc.deallocate(static_cast(__ptr), __padded_frame_size(__frameSize)); } }; @@ -223,8 +206,7 @@ namespace std { __manual_lifetime __exception_; __manual_lifetime<_Ref> __value_; - explicit __generator_promise_base(std::coroutine_handle<> thisCoro) noexcept - : __root_(this), __parentOrLeaf_(thisCoro) {} + explicit __generator_promise_base(std::coroutine_handle<> thisCoro) noexcept : __root_(this), __parentOrLeaf_(thisCoro) {} ~__generator_promise_base() { if (__root_ != this) { @@ -268,16 +250,14 @@ namespace std { __final_awaiter final_suspend() noexcept { return {}; } - std::suspend_always yield_value(_Ref&& __x) noexcept(std::is_nothrow_move_constructible_v< - _Ref>) { + std::suspend_always yield_value(_Ref&& __x) noexcept(std::is_nothrow_move_constructible_v<_Ref>) { __root_->__value_.construct((_Ref&&)__x); return {}; } template requires(!std::is_reference_v<_Ref>) && std::is_convertible_v<_T, _Ref> - std::suspend_always yield_value(_T&& - __x) noexcept(std::is_nothrow_constructible_v<_Ref, _T>) { + std::suspend_always yield_value(_T&& __x) noexcept(std::is_nothrow_constructible_v<_Ref, _T>) { __root_->__value_.construct((_T&&)__x); return {}; } @@ -316,21 +296,20 @@ namespace std { void await_resume() { __generator_promise_base& __nestedPromise = *__gen_.__get_promise(); - if (__nestedPromise.__exception_.get()) { - std::rethrow_exception(std::move(__nestedPromise.__exception_.get())); - } + if (__nestedPromise.__exception_.get()) { std::rethrow_exception(std::move(__nestedPromise.__exception_.get())); } } }; template - __yield_sequence_awaiter> - yield_value(std::ranges::elements_of> __g) noexcept { + __yield_sequence_awaiter> yield_value(std::ranges::elements_of< + generator<_Ref, _OValue, _OAlloc>> __g) noexcept { return std::move(__g).get(); } template - __yield_sequence_awaiter, _Allocator>> - yield_value(std::ranges::elements_of<_Rng, _Allocator>&& __x) { + __yield_sequence_awaiter, _Allocator>> yield_value(std::ranges::elements_of< + _Rng, + _Allocator>&& __x) { return [](allocator_arg_t, [[maybe_unused]] _Allocator alloc, @@ -348,28 +327,21 @@ namespace std { template struct __generator_promise; - template - struct __generator_promise, _ByteAllocator, _ExplicitAllocator> - final: public __generator_promise_base<_Ref>, public __promise_base_alloc<_ByteAllocator> { + template + struct __generator_promise, _ByteAllocator, _ExplicitAllocator> final + : public __generator_promise_base<_Ref>, + public __promise_base_alloc<_ByteAllocator> { __generator_promise() noexcept - : __generator_promise_base< - _Ref>(std::coroutine_handle<__generator_promise>::from_promise(*this)) {} + : __generator_promise_base<_Ref>(std::coroutine_handle<__generator_promise>::from_promise(*this)) {} generator<_Ref, _Value, _Alloc> get_return_object() noexcept { - return generator<_Ref, _Value, _Alloc> { - std::coroutine_handle<__generator_promise>::from_promise(*this) - }; + return generator<_Ref, _Value, _Alloc> { std::coroutine_handle<__generator_promise>::from_promise(*this) }; } using __generator_promise_base<_Ref>::yield_value; template - typename __generator_promise_base<_Ref>::template __yield_sequence_awaiter< - generator<_Ref, _Value, _Alloc>> + typename __generator_promise_base<_Ref>::template __yield_sequence_awaiter> yield_value(std::ranges::elements_of<_Rng>&& __x) { static_assert(!_ExplicitAllocator, "This coroutine has an explicit allocator specified with " @@ -382,14 +354,12 @@ namespace std { }; template - using __byte_allocator_t = typename std::allocator_traits< - std::remove_cvref_t<_Alloc>>::template rebind_alloc; + using __byte_allocator_t = typename std::allocator_traits>::template rebind_alloc; // Type-erased allocator with default allocator behaviour. template struct coroutine_traits, _Args...> { - using promise_type = __generator_promise, - std::allocator>; + using promise_type = __generator_promise, std::allocator>; }; // Type-erased allocator with std::allocator_arg parameter @@ -399,9 +369,7 @@ namespace std { using __byte_allocator = __byte_allocator_t<_Alloc>; public: - using promise_type = __generator_promise, - __byte_allocator, - true /*explicit Allocator*/>; + using promise_type = __generator_promise, __byte_allocator, true /*explicit Allocator*/>; }; // Type-erased allocator with std::allocator_arg parameter (non-static member functions) @@ -411,9 +379,7 @@ namespace std { using __byte_allocator = __byte_allocator_t<_Alloc>; public: - using promise_type = __generator_promise, - __byte_allocator, - true /*explicit Allocator*/>; + using promise_type = __generator_promise, __byte_allocator, true /*explicit Allocator*/>; }; // Generator with specified allocator type @@ -441,8 +407,7 @@ namespace std { generator() noexcept = default; generator(generator&& __other) noexcept - : __coro_(std::exchange(__other.__coro_, {})), - __started_(std::exchange(__other.__started_, false)) {} + : __coro_(std::exchange(__other.__coro_, {})), __started_(std::exchange(__other.__started_, false)) {} ~generator() noexcept { if (__coro_) { @@ -483,9 +448,7 @@ namespace std { ~iterator() {} - friend bool operator==(const iterator& it, sentinel) noexcept { - return it.__coro_.done(); - } + friend bool operator==(const iterator& it, sentinel) noexcept { return it.__coro_.done(); } iterator& operator++() { __coro_.promise().__value_.destruct(); @@ -495,9 +458,7 @@ namespace std { void operator++(int) { (void)operator++(); } - reference operator*() const noexcept { - return static_cast(__coro_.promise().__value_.get()); - } + reference operator*() const noexcept { return static_cast(__coro_.promise().__value_.get()); } private: friend generator; @@ -575,8 +536,7 @@ namespace std { iterator(const iterator&) = delete; iterator(iterator&& __other) noexcept - : __promise_(std::exchange(__other.__promise_, nullptr)), - __coro_(std::exchange(__other.__coro_, {})) {} + : __promise_(std::exchange(__other.__promise_, nullptr)), __coro_(std::exchange(__other.__coro_, {})) {} iterator& operator=(iterator&& __other) { __promise_ = std::exchange(__other.__promise_, nullptr); @@ -586,9 +546,7 @@ namespace std { ~iterator() = default; - friend bool operator==(const iterator& it, sentinel) noexcept { - return it.__coro_.done(); - } + friend bool operator==(const iterator& it, sentinel) noexcept { return it.__coro_.done(); } iterator& operator++() { __promise_->__value_.destruct(); @@ -598,9 +556,7 @@ namespace std { void operator++(int) { (void)operator++(); } - reference operator*() const noexcept { - return static_cast(__promise_->__value_.get()); - } + reference operator*() const noexcept { return static_cast(__promise_->__value_.get()); } private: friend generator; diff --git a/modules/stormkit/core/errors.mpp b/modules/stormkit/core/errors.mpp index ddd671a1f..65ecd9576 100644 --- a/modules/stormkit/core/errors.mpp +++ b/modules/stormkit/core/errors.mpp @@ -36,9 +36,7 @@ export { constexpr auto final_suspend() const noexcept -> std::suspend_never { return {}; } - constexpr auto get_return_object() noexcept -> Expected { - return Expected { this }; - } + constexpr auto get_return_object() noexcept -> Expected { return Expected { this }; } template constexpr auto return_value(Args&&... args) noexcept { @@ -61,9 +59,7 @@ export { Expected* expected_ptr = nullptr; }; - constexpr Expected(promise_type* promise) noexcept : Expected {} { - promise->expected_ptr = this; - } + constexpr Expected(promise_type* promise) noexcept : Expected {} { promise->expected_ptr = this; } constexpr auto await_ready() const noexcept -> bool { return this->has_value(); } @@ -112,8 +108,7 @@ export { template struct formatter, CharT>: formatter { template - auto format(const stormkit::core::Error&, FormatContext& ctx) const - -> decltype(ctx.out()); + auto format(const stormkit::core::Error&, FormatContext& ctx) const -> decltype(ctx.out()); }; template @@ -122,8 +117,7 @@ export { constexpr auto parse(ParseContext& ctx) noexcept -> decltype(ctx.begin()); template - auto format(const stormkit::core::DecoratedError&, FormatContext& ctx) const - -> decltype(ctx.out()); + auto format(const stormkit::core::DecoratedError&, FormatContext& ctx) const -> decltype(ctx.out()); }; } // namespace std } @@ -170,9 +164,8 @@ namespace std { template template STORMKIT_FORCE_INLINE - inline auto formatter, - CharT>::format(const stormkit::core::Error& error, - FormatContext& ctx) const -> decltype(ctx.out()) { + inline auto formatter, CharT>::format(const stormkit::core::Error& error, + FormatContext& ctx) const -> decltype(ctx.out()) { return formatter::format(error.code, ctx); } @@ -181,8 +174,8 @@ namespace std { template template STORMKIT_FORCE_INLINE - constexpr auto formatter, - CharT>::parse(ParseContext& ctx) noexcept -> decltype(ctx.begin()) { + constexpr auto formatter, CharT>::parse(ParseContext& ctx) noexcept + -> decltype(ctx.begin()) { return ctx.begin(); } @@ -191,9 +184,8 @@ namespace std { template template STORMKIT_FORCE_INLINE - inline auto formatter, - CharT>::format(const stormkit::core::DecoratedError& error, - FormatContext& ctx) const -> decltype(ctx.out()) { + inline auto formatter, CharT>::format(const stormkit::core::DecoratedError& error, + FormatContext& ctx) const -> decltype(ctx.out()) { auto&& out = ctx.out(); return format_to("message: {}, code: {}", error.message, error.error.code); } diff --git a/modules/stormkit/core/functional/error_handling.mpp b/modules/stormkit/core/functional/error_handling.mpp index add1958f7..5b81d8963 100644 --- a/modules/stormkit/core/functional/error_handling.mpp +++ b/modules/stormkit/core/functional/error_handling.mpp @@ -17,19 +17,16 @@ import :utils.contract; export namespace stormkit { inline namespace core { namespace monadic { [[nodiscard]] - constexpr auto assert(std::optional message = std::nullopt, - std::source_location location = std::source_location::current()) noexcept - -> decltype(auto); + constexpr auto assert(std::optional message = std::nullopt, + std::source_location location = std::source_location::current()) noexcept -> decltype(auto); template [[nodiscard]] - constexpr auto assert(std::optional message = std::nullopt, - std::source_location location = std::source_location::current()) noexcept - -> decltype(auto); + constexpr auto assert(std::optional message = std::nullopt, + std::source_location location = std::source_location::current()) noexcept -> decltype(auto); [[nodiscard]] - constexpr auto log(std::invocable auto&& logger, std::string&& message) noexcept - -> decltype(auto); + constexpr auto log(std::invocable auto&& logger, std::string&& message) noexcept -> decltype(auto); [[nodiscard]] constexpr auto throw_as_exception() noexcept -> decltype(auto); @@ -50,42 +47,35 @@ namespace stormkit { inline namespace core { namespace monadic { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto assert(std::optional message, - std::source_location location) noexcept -> decltype(auto) { - return - [message = std::move(message), location = std::move(location)] NORETURN_LAMBDA() -> T { - if (message.has_value()) core::assert(false, *message, std::move(location)); - else - core::assert(false, std::move(location)); - - std::unreachable(); - }; + constexpr auto assert(std::optional message, std::source_location location) noexcept -> decltype(auto) { + return [message = std::move(message), location = std::move(location)] NORETURN_LAMBDA() -> T { + if (message.has_value()) core::assert(false, *message, std::move(location)); + else + core::assert(false, std::move(location)); + + std::unreachable(); + }; } //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto assert(std::optional message, - std::source_location location) noexcept -> decltype(auto) { - return - [message = std::move(message), location = std::move(location)] - NORETURN_LAMBDA(const E& error) -> E { - if (message.has_value()) - core::assert(false, std::format("{} ({})", *message, error), std::move(location)); - else - core::assert(false, std::format("{}", error), std::move(location)); - - std::unreachable(); - }; + constexpr auto assert(std::optional message, std::source_location location) noexcept -> decltype(auto) { + return [message = std::move(message), location = std::move(location)] NORETURN_LAMBDA(const E& error) -> E { + if (message.has_value()) core::assert(false, std::format("{} ({})", *message, error), std::move(location)); + else + core::assert(false, std::format("{}", error), std::move(location)); + + std::unreachable(); + }; } //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto log(std::invocable auto&& logger, std::string&& message) noexcept - -> decltype(auto) { - return [logger = std::forward, message = std::move(message)](auto&& error) - -> std::expected> { + constexpr auto log(std::invocable auto&& logger, std::string&& message) noexcept -> decltype(auto) { + return [logger = std::forward, + message = std::move(message)](auto&& error) -> std::expected> { logger(message, error); return {}; @@ -96,8 +86,7 @@ namespace stormkit { inline namespace core { namespace monadic { //////////////////////////////////////// STORMKIT_FORCE_INLINE constexpr auto throw_as_exception() noexcept -> decltype(auto) { - return [] NORETURN_LAMBDA(auto&& error) static - -> std::expected> { + return [] NORETURN_LAMBDA(auto&& error) static -> std::expected> { throw std::forward(error); }; } diff --git a/modules/stormkit/core/functional/monadic.mpp b/modules/stormkit/core/functional/monadic.mpp index 71cb92e66..6c51e6552 100644 --- a/modules/stormkit/core/functional/monadic.mpp +++ b/modules/stormkit/core/functional/monadic.mpp @@ -36,8 +36,7 @@ export namespace stormkit { inline namespace core { namespace monadic { constexpr auto value() noexcept -> decltype(auto); template [[nodiscard]] - constexpr auto as(const std::source_location& - location = std::source_location::current()) noexcept -> decltype(auto); + constexpr auto as(const std::source_location& location = std::source_location::current()) noexcept -> decltype(auto); template [[nodiscard]] constexpr auto narrow() noexcept -> decltype(auto); @@ -75,9 +74,7 @@ export namespace stormkit { inline namespace core { namespace monadic { [[nodiscard]] constexpr auto noop() noexcept -> decltype(auto); - template First, - std::invocable> Second> + template First, std::invocable> Second> [[nodiscard]] constexpr auto map(First&& first, Second&& second) noexcept -> decltype(auto); @@ -85,8 +82,7 @@ export namespace stormkit { inline namespace core { namespace monadic { constexpr auto map(auto&& first, auto&& second) noexcept -> decltype(auto); [[nodiscard]] - constexpr auto either(std::regular_invocable auto&&... visitors) noexcept - -> decltype(auto); + constexpr auto either(std::regular_invocable auto&&... visitors) noexcept -> decltype(auto); template [[nodiscard]] @@ -146,9 +142,7 @@ namespace stormkit { inline namespace core { namespace monadic { [[nodiscard]] STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto identity(T&& value) noexcept -> decltype(auto) { - return [value = std::forward(value)] mutable noexcept -> decltype(auto) { - return std::forward_like(value); - }; + return [value = std::forward(value)] mutable noexcept -> decltype(auto) { return std::forward_like(value); }; } ///////////////////////////////////// @@ -157,18 +151,15 @@ namespace stormkit { inline namespace core { namespace monadic { [[nodiscard]] STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto consume(T&& value) noexcept -> decltype(auto) { - return [value = std::move(value)](auto&&...) mutable noexcept -> meta::CanonicalType { - return std::move(value); - }; + return [value = std::move(value)](auto&&...) mutable noexcept -> meta::CanonicalType { return std::move(value); }; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto value() noexcept -> decltype(auto) { - return [](T&& value) static noexcept -> decltype(auto) { - return std::forward_like(value.get()); - }; + return + [](T&& value) static noexcept -> decltype(auto) { return std::forward_like(value.get()); }; } ///////////////////////////////////// @@ -177,9 +168,7 @@ namespace stormkit { inline namespace core { namespace monadic { STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto as(const std::source_location& location) noexcept -> decltype(auto) { - return [location](U&& value) noexcept -> T { - return core::as(std::forward(value), location); - }; + return [location](U&& value) noexcept -> T { return core::as(std::forward(value), location); }; } ///////////////////////////////////// @@ -188,9 +177,7 @@ namespace stormkit { inline namespace core { namespace monadic { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto narrow() noexcept -> decltype(auto) { - return [](U&& value) static noexcept -> decltype(auto) { - return core::narrow(std::forward(value)); - }; + return [](U&& value) static noexcept -> decltype(auto) { return core::narrow(std::forward(value)); }; } //////////////////////////////////////// @@ -199,18 +186,14 @@ namespace stormkit { inline namespace core { namespace monadic { STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto is_equal(T&& value) noexcept -> decltype(auto) { - return [value = std::forward(value)](U&& other) { - return core::is_equal(value, std::forward(other)); - }; + return [value = std::forward(value)](U&& other) { return core::is_equal(value, std::forward(other)); }; } //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto append_to(std::ranges::range auto& range) noexcept -> decltype(auto) { - return [&range](T&& val) noexcept { - range.emplace(std::ranges::cend(range), std::forward(val)); - }; + return [&range](T&& val) noexcept { range.emplace(std::ranges::cend(range), std::forward(val)); }; } //////////////////////////////////////// @@ -219,8 +202,9 @@ namespace stormkit { inline namespace core { namespace monadic { STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto wrap(T&& func) noexcept { - return [func = std::forward(func)](Args&&... args) noexcept - -> decltype(auto) { return std::invoke(func, std::forward(args)...); }; + return [func = std::forward(func)](Args&&... args) noexcept -> decltype(auto) { + return std::invoke(func, std::forward(args)...); + }; } //////////////////////////////////////// @@ -286,9 +270,7 @@ namespace stormkit { inline namespace core { namespace monadic { STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto unpack_tuple_to(T&& func) noexcept -> decltype(auto) { - return [func = std::forward(func)](U&& arg) noexcept { - return std::apply(func, std::forward(arg)); - }; + return [func = std::forward(func)](U&& arg) noexcept { return std::apply(func, std::forward(arg)); }; } //////////////////////////////////////// @@ -309,30 +291,22 @@ namespace stormkit { inline namespace core { namespace monadic { ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto set(auto& output) noexcept -> decltype(auto) { - return [&output](T&& value) mutable noexcept -> void { - output = std::forward(value); - }; + return [&output](T&& value) mutable noexcept -> void { output = std::forward(value); }; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto emplace_to(std::ranges::range auto& container) noexcept -> decltype(auto) { - return [&container](T&& value) noexcept -> void { - container.emplace_back(std::forward(value)); - }; + return [&container](T&& value) noexcept -> void { container.emplace_back(std::forward(value)); }; } template - constexpr auto - is_noexcept = noexcept(std::declval< - Second>()(std::declval()(std::declval()...))); + constexpr auto is_noexcept = noexcept(std::declval()(std::declval()(std::declval()...))); ///////////////////////////////////// ///////////////////////////////////// - template First, - std::invocable> Second> + template First, std::invocable> Second> STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto map(First&& first, Second&& second) noexcept -> decltype(auto) { @@ -349,8 +323,9 @@ namespace stormkit { inline namespace core { namespace monadic { using SecondP = meta::CanonicalType; return [first = std::forward(first), second = std::forward(second)]< - typename... Args>(Args&&... args) noexcept(is_noexcept) - -> decltype(auto) { return second(first(std::forward(args)...)); }; + typename... Args>(Args&&... args) noexcept(is_noexcept) -> decltype(auto) { + return second(first(std::forward(args)...)); + }; } ///////////////////////////////////// @@ -375,9 +350,7 @@ namespace stormkit { inline namespace core { namespace monadic { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto get() noexcept -> decltype(auto) { - return [](U&& value) static noexcept -> decltype(auto) { - return std::get(std::forward(value)); - }; + return [](U&& value) static noexcept -> decltype(auto) { return std::get(std::forward(value)); }; } ///////////////////////////////////// @@ -395,8 +368,7 @@ namespace stormkit { inline namespace core { namespace monadic { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto is() noexcept -> decltype(auto) { - return - [](U&& value) static noexcept { return core::is(std::forward(value)); }; + return [](U&& value) static noexcept { return core::is(std::forward(value)); }; } ///////////////////////////////////// @@ -405,22 +377,17 @@ namespace stormkit { inline namespace core { namespace monadic { STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto either(Args&&... visitors) noexcept -> decltype(auto) { - return - [... visitors = std::forward(visitors)](T&& variant) mutable noexcept - -> decltype(auto) { - return std::visit(core::Overloaded { std::forward(visitors)... }, - std::forward(variant)); - }; + return [... visitors = std::forward(visitors)](T&& variant) mutable noexcept -> decltype(auto) { + return std::visit(core::Overloaded { std::forward(visitors)... }, std::forward(variant)); + }; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto clone() noexcept -> decltype(auto) { - return - [](T&& value) static noexcept(noexcept(std::is_nothrow_copy_constructible_v< - meta::CanonicalType>)) - -> decltype(auto) { return auto(std::forward(value)); }; + return [](T&& value) static noexcept(noexcept(std::is_nothrow_copy_constructible_v>)) + -> decltype(auto) { return auto(std::forward(value)); }; } ///////////////////////////////////// @@ -429,10 +396,8 @@ namespace stormkit { inline namespace core { namespace monadic { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto init() noexcept -> decltype(auto) { - return [](Args&&... args) static noexcept( - noexcept(std::is_nothrow_constructible_v)) -> decltype(auto) { - return T { std::forward(args)... }; - }; + return [](Args&&... args) static noexcept(noexcept(std::is_nothrow_constructible_v)) + -> decltype(auto) { return T { std::forward(args)... }; }; } ///////////////////////////////////// @@ -441,10 +406,8 @@ namespace stormkit { inline namespace core { namespace monadic { STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto init(Args&&... args) noexcept -> decltype(auto) { - return - [... args = std::forward< - Args>(args)]() mutable noexcept(noexcept(std::is_nothrow_constructible_v)) - -> decltype(auto) { return T { std::forward(args)... }; }; + return [... args = std::forward(args)]() mutable noexcept(noexcept(std::is_nothrow_constructible_v)) + -> decltype(auto) { return T { std::forward(args)... }; }; } ///////////////////////////////////// @@ -462,35 +425,28 @@ namespace stormkit { inline namespace core { namespace monadic { ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto as_ref() noexcept -> decltype(auto) { - return [](T&& value) static noexcept -> decltype(auto) { - return core::as_ref(std::forward(value)); - }; + return [](T&& value) static noexcept -> decltype(auto) { return core::as_ref(std::forward(value)); }; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto as_ref_mut() noexcept -> decltype(auto) { - return [](T&& value) static noexcept -> decltype(auto) { - return core::as_ref_mut(std::forward(value)); - }; + return [](T&& value) static noexcept -> decltype(auto) { return core::as_ref_mut(std::forward(value)); }; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto unref() noexcept -> decltype(auto) { - return - [](const auto& value) static noexcept -> decltype(auto) { return core::unref(value); }; + return [](const auto& value) static noexcept -> decltype(auto) { return core::unref(value); }; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto unref_mut() noexcept -> decltype(auto) { - return [](const auto& value) static noexcept -> decltype(auto) { - return core::unref_mut(value); - }; + return [](const auto& value) static noexcept -> decltype(auto) { return core::unref_mut(value); }; } ///////////////////////////////////// @@ -499,8 +455,6 @@ namespace stormkit { inline namespace core { namespace monadic { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto forward_like() noexcept -> decltype(auto) { - return [](auto&& value) static noexcept -> decltype(auto) { - return std::forward_like(value); - }; + return [](auto&& value) static noexcept -> decltype(auto) { return std::forward_like(value); }; } }}} // namespace stormkit::core::monadic diff --git a/modules/stormkit/core/functional/utils.mpp b/modules/stormkit/core/functional/utils.mpp index 11cda0e43..0c2084cb0 100644 --- a/modules/stormkit/core/functional/utils.mpp +++ b/modules/stormkit/core/functional/utils.mpp @@ -15,9 +15,7 @@ import :meta; namespace stormkit { inline namespace core { namespace details { struct EitherFunc { [[nodiscard]] - static constexpr auto operator()(bool condition, - std::invocable auto&& true_, - std::invocable auto&& false_) noexcept + static constexpr auto operator()(bool condition, std::invocable auto&& true_, std::invocable auto&& false_) noexcept -> decltype(false_()); template @@ -27,16 +25,14 @@ namespace stormkit { inline namespace core { namespace details { [[nodiscard]] static constexpr auto operator()(T value, std::invocable&> auto&& true_, - std::invocable auto&& false_) noexcept - -> decltype(false_()); + std::invocable auto&& false_) noexcept -> decltype(false_()); template requires(meta::IsConvertibleTo) [[nodiscard]] static constexpr auto operator()(T&& value, std::invocable> auto&& true_, - std::invocable auto&& false_) noexcept - -> decltype(false_()); + std::invocable auto&& false_) noexcept -> decltype(false_()); }; }}} // namespace stormkit::core::details @@ -47,8 +43,7 @@ export namespace stormkit { inline namespace core { using std::bind_front; template - requires(std::invocable - and meta::Is, void>) + requires(std::invocable and meta::Is, void>) [[nodiscard]] constexpr auto init_by(Func&& func, Args&&... args) noexcept -> T; }} // namespace stormkit::core @@ -62,9 +57,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto EitherFunc::operator()(bool condition, - std::invocable auto&& true_, - std::invocable auto&& false_) noexcept + constexpr auto EitherFunc::operator()(bool condition, std::invocable auto&& true_, std::invocable auto&& false_) noexcept -> decltype(false_()) { if (condition) return true_(); return false_(); @@ -76,8 +69,7 @@ namespace stormkit { inline namespace core { STORMKIT_FORCE_INLINE constexpr auto EitherFunc::operator()(T value, std::invocable&> auto&& true_, - std::invocable auto&& false_) noexcept - -> decltype(false_()) { + std::invocable auto&& false_) noexcept -> decltype(false_()) { if (static_cast(value)) return true_(*value); return false_(); } @@ -89,8 +81,7 @@ namespace stormkit { inline namespace core { STORMKIT_FORCE_INLINE constexpr auto EitherFunc::operator()(T&& value, std::invocable> auto&& true_, - std::invocable auto&& false_) noexcept - -> decltype(false_()) { + std::invocable auto&& false_) noexcept -> decltype(false_()) { if (static_cast(value)) return true_(std::forward_like(*value)); return false_(); } @@ -104,21 +95,15 @@ namespace stormkit { inline namespace core { constexpr auto bind_back(Args&&... args) noexcept -> decltype(auto) { return std::bind_back(std::forward(args)...); using FuncType = decltype(Func); - if constexpr (meta::IsPointer or std::is_member_pointer_v) - static_assert(Func != nullptr); + if constexpr (meta::IsPointer or std::is_member_pointer_v) static_assert(Func != nullptr); return [... bound_args(std::forward(args))]( this Self&&, - CallArgs&&... call_args) noexcept(std:: - is_nothrow_invocable_v< - FuncType, - CallArgs..., - meta::ForwardLike>...>) + CallArgs&&... call_args) noexcept(std::is_nothrow_invocable_v>...>) -> decltype(auto) { - return std::invoke(Func, - std::forward(call_args)..., - std::forward_like(bound_args)...); + return std::invoke(Func, std::forward(call_args)..., std::forward_like(bound_args)...); }; } #endif @@ -126,8 +111,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - requires(std::invocable - and meta::Is, void>) + requires(std::invocable and meta::Is, void>) STORMKIT_CONST STORMKIT_FORCE_INLINE constexpr auto init_by(Func&& func, Args&&... args) noexcept -> T { auto out = T {}; diff --git a/modules/stormkit/core/hash/base.mpp b/modules/stormkit/core/hash/base.mpp index c408a2cbe..ea676d52f 100644 --- a/modules/stormkit/core/hash/base.mpp +++ b/modules/stormkit/core/hash/base.mpp @@ -55,7 +55,7 @@ namespace stormkit { inline namespace core { constexpr auto hash_combine(HashValue auto& hash, Args&&... args) noexcept { #if defined(__cpp_expansion_statements) and __cpp_expansion_statements >= 202500L template for (constexpr auto elem : { std::forward(args)... }) - hash_combine(hash, std::forward(elem)); + hash_combine(hash, std::forward(elem)); #else (hash_combine(hash, std::forward(args)), ...); #endif diff --git a/modules/stormkit/core/hash/string.mpp b/modules/stormkit/core/hash/string.mpp index 1d2ec0254..ae26de816 100644 --- a/modules/stormkit/core/hash/string.mpp +++ b/modules/stormkit/core/hash/string.mpp @@ -35,19 +35,14 @@ export namespace stormkit { inline namespace core { map, std::remove_cvref_t, StringHash, std::equal_to<>>; template - using FrozenStringHashMap = frozen::unordered_map, - std::remove_cvref_t, - Size, - StringHash, - std::equal_to<>>; + using FrozenStringHashMap = frozen:: + unordered_map, std::remove_cvref_t, Size, StringHash, std::equal_to<>>; template - using StringHashSet = ankerl::unordered_dense:: - set, StringHash, std::equal_to<>>; + using StringHashSet = ankerl::unordered_dense::set, StringHash, std::equal_to<>>; template - using FrozenStringHashSet = frozen:: - unordered_set, Size, StringHash, std::equal_to<>>; + using FrozenStringHashSet = frozen::unordered_set, Size, StringHash, std::equal_to<>>; }} // namespace stormkit::core //////////////////////////////////////////////////////////////////// @@ -68,10 +63,7 @@ namespace stormkit { inline namespace core { STORMKIT_FORCE_INLINE constexpr auto bytes_4(std::span bytes) noexcept -> void { - const auto val = u64(bytes[0]) << 0 - | u64(bytes[1]) << 8 - | u64(bytes[2]) << 16 - | u64(bytes[3]) << 24; + const auto val = u64(bytes[0]) << 0 | u64(bytes[1]) << 8 | u64(bytes[2]) << 16 | u64(bytes[3]) << 24; dword(val); } @@ -101,10 +93,7 @@ namespace stormkit { inline namespace core { template STORMKIT_FORCE_INLINE - constexpr auto hash_selected_characters(u8 mask, - Hasher& hasher, - CZString s, - usize size) noexcept -> void { + constexpr auto hash_selected_characters(u8 mask, Hasher& hasher, CZString s, usize size) noexcept -> void { if (std::popcount(mask) == 4) { auto dword = u64 { 0 }; auto i = i32 { 0 }; diff --git a/modules/stormkit/core/math/combinatoric.mpp b/modules/stormkit/core/math/combinatoric.mpp index b567cab6e..a9f3a41ac 100644 --- a/modules/stormkit/core/math/combinatoric.mpp +++ b/modules/stormkit/core/math/combinatoric.mpp @@ -25,9 +25,8 @@ export namespace stormkit { inline namespace core { namespace math { namespace stormkit { inline namespace core { namespace math { namespace { - constexpr auto FTABLE = std::array { - 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800 - }; + constexpr auto FTABLE = std::array { 1, 1, 2, 6, 24, 120, 720, + 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800 }; } ///////////////////////////////////// diff --git a/modules/stormkit/core/math/extent.mpp b/modules/stormkit/core/math/extent.mpp index 0ed62b9ff..73c2efebf 100644 --- a/modules/stormkit/core/math/extent.mpp +++ b/modules/stormkit/core/math/extent.mpp @@ -35,8 +35,7 @@ export { constexpr auto narrow_to() const noexcept -> Extent; template - constexpr auto to(const std::source_location& = std::source_location::current()) - const noexcept -> Extent; + constexpr auto to(const std::source_location& = std::source_location::current()) const noexcept -> Extent; template constexpr auto to() const noexcept -> Extent; @@ -61,8 +60,7 @@ export { constexpr auto narrow_to() const noexcept -> Extent; template - constexpr auto to(const std::source_location& = std::source_location::current()) - const noexcept -> Extent; + constexpr auto to(const std::source_location& = std::source_location::current()) const noexcept -> Extent; template constexpr auto to() const noexcept -> Extent; @@ -107,8 +105,7 @@ export { /// @returns true if this extent is equal to `other`, otherwise returns false. template [[nodiscard]] - constexpr auto operator<=>(const Extent& first, const Extent& second) noexcept -> - typename Extent::OrderingType; + constexpr auto operator<=>(const Extent& first, const Extent& second) noexcept -> typename Extent::OrderingType; /// @output_section Publics operators members /// @brief ValueType the equality with an other extent. @@ -140,16 +137,14 @@ export { /// @returns A reference to this after the multiplication with `factor` template [[nodiscard]] - constexpr auto operator*=(Extent& extent, typename Extent::ElementType factor) noexcept - -> Extent&; + constexpr auto operator*=(Extent& extent, typename Extent::ElementType factor) noexcept -> Extent&; /// @brief Divide this extent with a factor. /// @param factor ElementType factor to divide /// @returns A reference to this after the division with `factor` template [[nodiscard]] - constexpr auto operator/=(Extent& extent, typename Extent::ElementType factor) noexcept - -> Extent&; + constexpr auto operator/=(Extent& extent, typename Extent::ElementType factor) noexcept -> Extent&; template auto to_string(Extent&& extent) noexcept -> std::string; @@ -158,15 +153,13 @@ export { template struct std::formatter>: std::formatter { template - auto format(const math::Extent& extent, FormatContext& ctx) const noexcept - -> decltype(ctx.out()); + auto format(const math::Extent& extent, FormatContext& ctx) const noexcept -> decltype(ctx.out()); }; template struct std::formatter>: std::formatter { template - auto format(const math::Extent& extent, FormatContext& ctx) const noexcept - -> decltype(ctx.out()); + auto format(const math::Extent& extent, FormatContext& ctx) const noexcept -> decltype(ctx.out()); }; template @@ -199,8 +192,7 @@ namespace stormkit { inline namespace core { namespace math { template template STORMKIT_PURE - constexpr auto Extent::to(const std::source_location& location) const noexcept - -> Extent { + constexpr auto Extent::to(const std::source_location& location) const noexcept -> Extent { return { .width = as(width, location), .height = as(height, location) }; } @@ -233,9 +225,7 @@ namespace stormkit { inline namespace core { namespace math { template STORMKIT_PURE constexpr auto Extent::narrow_to() const noexcept -> Extent { - return { .width = narrow(width), - .height = narrow(height), - .depth = narrow(depth) }; + return { .width = narrow(width), .height = narrow(height), .depth = narrow(depth) }; } ///////////////////////////////////// @@ -243,11 +233,8 @@ namespace stormkit { inline namespace core { namespace math { template template STORMKIT_PURE - constexpr auto Extent::to(const std::source_location& location) const noexcept - -> Extent { - return { .width = as(width, location), - .height = as(height, location), - .depth = as(depth, location) }; + constexpr auto Extent::to(const std::source_location& location) const noexcept -> Extent { + return { .width = as(width, location), .height = as(height, location), .depth = as(depth, location) }; } ///////////////////////////////////// @@ -277,8 +264,7 @@ namespace stormkit { inline namespace core { namespace math { ///////////////////////////////////// template STORMKIT_PURE - constexpr auto operator<=>(const Extent& first, const Extent& second) noexcept -> - typename Extent::OrderingType { + constexpr auto operator<=>(const Extent& first, const Extent& second) noexcept -> typename Extent::OrderingType { using Array = std::array; using OrderingType = typename Extent::OrderingType; static constexpr auto RANK = Extent::RANK; @@ -313,8 +299,7 @@ namespace stormkit { inline namespace core { namespace math { ///////////////////////////////////// template STORMKIT_PURE - constexpr auto operator*(Extent&& event, typename Extent::ElemenType factor) noexcept - -> core::meta::CanonicalType { + constexpr auto operator*(Extent&& event, typename Extent::ElemenType factor) noexcept -> core::meta::CanonicalType { return core::meta::CanonicalType { std::forward(event) } *= factor; } @@ -322,8 +307,7 @@ namespace stormkit { inline namespace core { namespace math { ///////////////////////////////////// template STORMKIT_PURE - constexpr auto operator/(Extent&& event, typename Extent::ElemenType factor) noexcept - -> core::meta::CanonicalType { + constexpr auto operator/(Extent&& event, typename Extent::ElemenType factor) noexcept -> core::meta::CanonicalType { return core::meta::CanonicalType { std::forward(event) } /= factor; } @@ -331,8 +315,7 @@ namespace stormkit { inline namespace core { namespace math { ///////////////////////////////////// template STORMKIT_PURE - constexpr auto operator*=(Extent& extent, typename Extent::ElementType factor) noexcept - -> Extent& { + constexpr auto operator*=(Extent& extent, typename Extent::ElementType factor) noexcept -> Extent& { using ElementType = typename Extent::ElementType; static constexpr auto RANK = Extent::RANK; auto& values = *std::bit_cast>(&extent); @@ -344,8 +327,7 @@ namespace stormkit { inline namespace core { namespace math { ///////////////////////////////////// template STORMKIT_PURE - constexpr auto operator/=(Extent& extent, typename Extent::ElementType factor) noexcept - -> Extent& { + constexpr auto operator/=(Extent& extent, typename Extent::ElementType factor) noexcept -> Extent& { using ElementType = typename Extent::ElementType; static constexpr auto RANK = Extent::RANK; auto& values = *std::bit_cast>(&extent); @@ -372,8 +354,7 @@ namespace stormkit { inline namespace core { namespace math { ///////////////////////////////////// template template -auto std::formatter>::format(const math::Extent& extent, - FormatContext& ctx) const noexcept +auto std::formatter>::format(const math::Extent& extent, FormatContext& ctx) const noexcept -> decltype(ctx.out()) { auto&& out = ctx.out(); format_to(out, "{{ .width = "); @@ -387,8 +368,7 @@ auto std::formatter>::format(const math::Extent& extent ///////////////////////////////////// template template -auto std::formatter>::format(const math::Extent& extent, - FormatContext& ctx) const noexcept +auto std::formatter>::format(const math::Extent& extent, FormatContext& ctx) const noexcept -> decltype(ctx.out()) { auto&& out = ctx.out(); format_to(out, "{{ .width = "); @@ -403,8 +383,7 @@ auto std::formatter>::format(const math::Extent& extent ///////////////////////////////////// ///////////////////////////////////// template -constexpr auto std::hash>::operator()(const math::Extent& - extent) noexcept { +constexpr auto std::hash>::operator()(const math::Extent& extent) noexcept { auto hash = hash64 { 0 }; hash_combine(hash, extent.width, extent.height); return hash; @@ -413,8 +392,7 @@ constexpr auto std::hash>::operator()(const math::Extent -constexpr auto std::hash>::operator()(const math::Extent& - extent) noexcept { +constexpr auto std::hash>::operator()(const math::Extent& extent) noexcept { auto hash = hash64 { 0 }; hash_combine(hash, extent.width, extent.height, extent.depth); return hash; diff --git a/modules/stormkit/core/math/geometry.mpp b/modules/stormkit/core/math/geometry.mpp index 1dec7c854..737f00310 100644 --- a/modules/stormkit/core/math/geometry.mpp +++ b/modules/stormkit/core/math/geometry.mpp @@ -57,8 +57,7 @@ export namespace stormkit { inline namespace core { namespace math { }; template - constexpr auto format_as(const bounding_rect& point, FormatContext& ctx) - -> decltype(ctx.out()); + constexpr auto format_as(const bounding_rect& point, FormatContext& ctx) -> decltype(ctx.out()); template constexpr auto to_bounding_rect(const rect& _rect) noexcept -> bounding_rect; @@ -146,15 +145,13 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto format_as(const bounding_rect& point, FormatContext& ctx) - -> decltype(ctx.out()) { - return std:: - format_to(ctx.out(), - "{{ bounding_rect: .left = {}, .top = {}, .right = {}, .bottom = {} }}", - point.left, - point.top, - point.right, - point.bottom); + constexpr auto format_as(const bounding_rect& point, FormatContext& ctx) -> decltype(ctx.out()) { + return std::format_to(ctx.out(), + "{{ bounding_rect: .left = {}, .top = {}, .right = {}, .bottom = {} }}", + point.left, + point.top, + point.right, + point.bottom); } //////////////////////////////////////// @@ -177,12 +174,8 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto AABB(const bounding_rect& rect1, const bounding_rect& rect2) noexcept - -> bool { - return rect1.left < rect2.right - and rect1.right > rect2.left - and rect1.top < rect2.bottom - and rect1.bottom > rect2.top; + constexpr auto AABB(const bounding_rect& rect1, const bounding_rect& rect2) noexcept -> bool { + return rect1.left < rect2.right and rect1.right > rect2.left and rect1.top < rect2.bottom and rect1.bottom > rect2.top; } //////////////////////////////////////// @@ -198,10 +191,7 @@ namespace stormkit { inline namespace core { namespace math { template STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto AABB(const vec2& pos, const bounding_rect& rect) noexcept -> bool { - return pos.x >= rect.left - and pos.x <= rect.right - and pos.y >= rect.top - and pos.y <= rect.bottom; + return pos.x >= rect.left and pos.x <= rect.right and pos.y >= rect.top and pos.y <= rect.bottom; } //////////////////////////////////////// diff --git a/modules/stormkit/core/math/linear-matrix.mpp b/modules/stormkit/core/math/linear-matrix.mpp index 2bb516572..6ae0e9ef8 100644 --- a/modules/stormkit/core/math/linear-matrix.mpp +++ b/modules/stormkit/core/math/linear-matrix.mpp @@ -33,8 +33,7 @@ export { template [[nodiscard]] - constexpr auto operator[](this Self&& self, size_type i) noexcept - -> core::meta::ForwardLike; + constexpr auto operator[](this Self&& self, size_type i) noexcept -> core::meta::ForwardLike; template [[nodiscard]] @@ -55,8 +54,7 @@ export { template [[nodiscard]] - constexpr auto data(this Self& self) noexcept - -> core::meta::ForwardConst*; + constexpr auto data(this Self& self) noexcept -> core::meta::ForwardConst*; [[nodiscard]] constexpr auto size() const noexcept -> size_type; @@ -271,8 +269,7 @@ export { template [[nodiscard]] - constexpr auto translate(const mat4x4& mat, const vec3& translation) noexcept - -> mat4x4; + constexpr auto translate(const mat4x4& mat, const vec3& translation) noexcept -> mat4x4; template [[nodiscard]] @@ -280,13 +277,11 @@ export { template [[nodiscard]] - constexpr auto rotate(const mat4x4& mat, Radian angle, const vec3& axis) noexcept - -> mat4x4; + constexpr auto rotate(const mat4x4& mat, Radian angle, const vec3& axis) noexcept -> mat4x4; template [[nodiscard]] - constexpr auto orthographique(T left, T right, T bottom, T top, T near, T far) noexcept - -> mat4x4; + constexpr auto orthographique(T left, T right, T bottom, T top, T near, T far) noexcept -> mat4x4; template [[nodiscard]] @@ -298,15 +293,12 @@ export { template [[nodiscard]] - constexpr auto look_at(const vec3& eye, - const vec3& center, - const vec3& up) noexcept -> mat4x4; + constexpr auto look_at(const vec3& eye, const vec3& center, const vec3& up) noexcept -> mat4x4; template [[nodiscard]] constexpr auto as_span(T& value) noexcept - -> std::span, - T::EXTENTS[0] * T::EXTENTS[1]>; + -> std::span, T::EXTENTS[0] * T::EXTENTS[1]>; template [[nodiscard]] @@ -316,8 +308,7 @@ export { template requires(not core::meta::IsConst) [[nodiscard]] - constexpr auto as_mdspan(T& value) noexcept - -> MatrixSpan; + constexpr auto as_mdspan(T& value) noexcept -> MatrixSpan; }}} // namespace stormkit::core::math namespace std { @@ -376,8 +367,7 @@ namespace stormkit { inline namespace core { namespace math { template template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto mat::operator[](this Self&& self, size_type i) noexcept - -> core::meta::ForwardLike { + constexpr auto mat::operator[](this Self&& self, size_type i) noexcept -> core::meta::ForwardLike { return std::forward(self).values[i]; } @@ -430,8 +420,7 @@ namespace stormkit { inline namespace core { namespace math { template template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto mat::data(this Self& self) noexcept - -> core::meta::ForwardConst* { + constexpr auto mat::data(this Self& self) noexcept -> core::meta::ForwardConst* { return stdr::data(self.values); } @@ -562,8 +551,7 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto translate(const mat4x4& mat, const vec3& translation) noexcept - -> mat4x4 { + constexpr auto translate(const mat4x4& mat, const vec3& translation) noexcept -> mat4x4 { auto out = mat4x4 {}; translate(as_mdspan(mat), as_mdspan(translation), as_mdspan_mut(out)); @@ -587,8 +575,7 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto rotate(const mat4x4& mat, Radian angle, const vec3& axis) noexcept - -> mat4x4 { + constexpr auto rotate(const mat4x4& mat, Radian angle, const vec3& axis) noexcept -> mat4x4 { auto out = mat4x4 {}; rotate(as_mdspan(mat), angle, as_mdspan(axis), as_mdspan_mut(out)); @@ -600,8 +587,7 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto orthographique(T left, T right, T bottom, T top, T near, T far) noexcept - -> mat4x4 { + constexpr auto orthographique(T left, T right, T bottom, T top, T near, T far) noexcept -> mat4x4 { auto out = mat4x4 {}; orthographique(left, right, bottom, top, near, far, as_mdspan_mut(out)); @@ -637,8 +623,7 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto look_at(const vec3& eye, const vec3& center, const vec3& up) noexcept - -> mat4x4 { + constexpr auto look_at(const vec3& eye, const vec3& center, const vec3& up) noexcept -> mat4x4 { auto out = mat4x4 {}; look_at(as_mdspan(eye), as_mdspan(center), as_mdspan(up), as_mdspan_mut(out)); @@ -651,23 +636,19 @@ namespace stormkit { inline namespace core { namespace math { template STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto as_span(T& value) noexcept - -> std::span, - T::EXTENTS[0] * T::EXTENTS[1]> { - return std::span, - T::EXTENTS[0] * T::EXTENTS[1]> { stdr::data(value), - T::EXTENTS[0] * T::EXTENTS[1] }; + -> std::span, T::EXTENTS[0] * T::EXTENTS[1]> { + return std::span, T::EXTENTS[0] * T::EXTENTS[1]> { + stdr::data(value), + T::EXTENTS[0] * T::EXTENTS[1] + }; } //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto as_mdspan(const T& value) noexcept - -> MatrixSpan { - return MatrixSpan { - stdr::data(value), - T::EXTENTS - }; + constexpr auto as_mdspan(const T& value) noexcept -> MatrixSpan { + return MatrixSpan { stdr::data(value), T::EXTENTS }; } //////////////////////////////////////// @@ -675,10 +656,8 @@ namespace stormkit { inline namespace core { namespace math { template requires(not core::meta::IsConst) STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto as_mdspan_mut(T& value) noexcept - -> MatrixSpan { - return MatrixSpan { stdr::data(value), - T::EXTENTS }; + constexpr auto as_mdspan_mut(T& value) noexcept -> MatrixSpan { + return MatrixSpan { stdr::data(value), T::EXTENTS }; } }}} // namespace stormkit::core::math @@ -699,8 +678,7 @@ auto std::hash::operator()(const T& mat) const noexcept -> stormkit::u64 { //////////////////////////////////////// template template -constexpr auto std::formatter::parse(ParseContext& ctx) noexcept - -> decltype(ctx.begin()) { +constexpr auto std::formatter::parse(ParseContext& ctx) noexcept -> decltype(ctx.begin()) { return ctx.begin(); } @@ -708,8 +686,7 @@ constexpr auto std::formatter::parse(ParseContext& ctx) noexcept //////////////////////////////////////// template template -inline auto std::formatter::format(const T& mat, FormatContext& ctx) const - -> decltype(ctx.out()) { +inline auto std::formatter::format(const T& mat, FormatContext& ctx) const -> decltype(ctx.out()) { auto out = ctx.out(); auto i = 0; @@ -724,8 +701,7 @@ inline auto std::formatter::format(const T& mat, FormatContext& ctx) c auto l = 0u; if constexpr (stormkit::meta::IsIntegral) { auto max_digit = 0u; - for (auto v : as_span(mat)) - max_digit = std::max(max_digit, v == 0 ? 2 : narrow(std::log10(v) + 2)); + for (auto v : as_span(mat)) max_digit = std::max(max_digit, v == 0 ? 2 : narrow(std::log10(v) + 2)); for (auto&& slice : mat | stdv::chunk_by(check_by_extent)) { format_to(out, "{}|{:n:>{}}|{}", @@ -737,9 +713,7 @@ inline auto std::formatter::format(const T& mat, FormatContext& ctx) c } } else { auto max_digit = 0u; - for (auto v : as_span(mat)) - max_digit = std::max(max_digit, - narrow(v) == 0 ? 2 : narrow(std::log10(v) + 2)); + for (auto v : as_span(mat)) max_digit = std::max(max_digit, narrow(v) == 0 ? 2 : narrow(std::log10(v) + 2)); for (auto&& slice : mat | stdv::chunk_by(check_by_extent)) { format_to(out, "{}| {:n:>{}.5f}|{}", diff --git a/modules/stormkit/core/math/linear-vector.mpp b/modules/stormkit/core/math/linear-vector.mpp index dbf3b6b97..e7d12fa5e 100644 --- a/modules/stormkit/core/math/linear-vector.mpp +++ b/modules/stormkit/core/math/linear-vector.mpp @@ -31,8 +31,7 @@ export { T y; template - constexpr auto operator[](this Self& self, usize i) noexcept - -> core::meta::ForwardConst; + constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst; template constexpr auto to() const noexcept -> vec2; @@ -63,8 +62,7 @@ export { T z; template - constexpr auto operator[](this Self& self, usize i) noexcept - -> core::meta::ForwardConst; + constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst; template constexpr auto to() const noexcept -> vec3; @@ -96,8 +94,7 @@ export { T w; template - constexpr auto operator[](this Self& self, usize i) noexcept - -> core::meta::ForwardConst; + constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst; template constexpr auto to() const noexcept -> vec4; @@ -160,14 +157,12 @@ export { template [[nodiscard]] - constexpr auto as_mdspan(const T& value) noexcept - -> VectorSpan; + constexpr auto as_mdspan(const T& value) noexcept -> VectorSpan; template requires(not core::meta::IsConst) [[nodiscard]] - constexpr auto as_mdspan_mut(T& value) noexcept - -> VectorSpan; + constexpr auto as_mdspan_mut(T& value) noexcept -> VectorSpan; }}} // namespace stormkit::core::math namespace std { @@ -181,8 +176,7 @@ export { struct formatter, CharT>: formatter { template [[nodiscard]] - auto format(const stormkit::math::vec2&, FormatContext& ctx) const - -> decltype(ctx.out()); + auto format(const stormkit::math::vec2&, FormatContext& ctx) const -> decltype(ctx.out()); }; template @@ -195,8 +189,7 @@ export { struct formatter, CharT>: formatter { template [[nodiscard]] - auto format(const stormkit::math::vec3&, FormatContext& ctx) const - -> decltype(ctx.out()); + auto format(const stormkit::math::vec3&, FormatContext& ctx) const -> decltype(ctx.out()); }; template @@ -209,8 +202,7 @@ export { struct formatter, CharT>: formatter { template [[nodiscard]] - auto format(const stormkit::math::vec4&, FormatContext& ctx) const - -> decltype(ctx.out()); + auto format(const stormkit::math::vec4&, FormatContext& ctx) const -> decltype(ctx.out()); }; } // namespace std } // namespace stormkit::core::math @@ -248,8 +240,7 @@ namespace stormkit { inline namespace core { namespace math { template template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto vec2::operator[](this Self& self, usize i) noexcept - -> core::meta::ForwardConst { + constexpr auto vec2::operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst { static constexpr auto* members = { &vec2::x, &vec2::y }; return std::forward_like(self->*members[i]); @@ -269,8 +260,7 @@ namespace stormkit { inline namespace core { namespace math { template template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto vec3::operator[](this Self& self, usize i) noexcept - -> core::meta::ForwardConst { + constexpr auto vec3::operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst { static constexpr auto* members = { &vec3::x, &vec3::y, &vec3::z }; return std::forward_like(self->*members[i]); @@ -290,8 +280,7 @@ namespace stormkit { inline namespace core { namespace math { template template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto vec4::operator[](this Self& self, usize i) noexcept - -> core::meta::ForwardConst { + constexpr auto vec4::operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst { static constexpr auto* members = { &vec4::x, &vec4::y, &vec4::z, &vec4::w }; return std::forward_like(self->*members[i]); @@ -390,8 +379,7 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto as_mdspan(const T& value) noexcept - -> VectorSpan { + constexpr auto as_mdspan(const T& value) noexcept -> VectorSpan { return VectorSpan { &value.x, T::EXTENT }; } @@ -400,8 +388,7 @@ namespace stormkit { inline namespace core { namespace math { template requires(not core::meta::IsConst) STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto as_mdspan_mut(T& value) noexcept - -> VectorSpan { + constexpr auto as_mdspan_mut(T& value) noexcept -> VectorSpan { return VectorSpan { &value.x, T::EXTENT }; } }}} // namespace stormkit::core::math @@ -409,8 +396,7 @@ namespace stormkit { inline namespace core { namespace math { namespace std { template STORMKIT_PURE STORMKIT_FORCE_INLINE - auto hash>::operator()(const stormkit::math::vec2& vec) - const noexcept -> stormkit::u64 { + auto hash>::operator()(const stormkit::math::vec2& vec) const noexcept -> stormkit::u64 { auto hash = stormkit::hash64 { 0 }; stormkit::hash_combine(hash, vec.x); @@ -421,9 +407,8 @@ namespace std { template template - inline auto formatter, - CharT>::format(const stormkit::math::vec2& vec, - FormatContext& ctx) const -> decltype(ctx.out()) { + inline auto formatter, CharT>::format(const stormkit::math::vec2& vec, FormatContext& ctx) const + -> decltype(ctx.out()) { auto out = ctx.out(); stdr::copy("{ vec2: .x = "sv, out); @@ -437,8 +422,7 @@ namespace std { template STORMKIT_PURE STORMKIT_FORCE_INLINE - auto hash>::operator()(const stormkit::math::vec3& vec) - const noexcept -> stormkit::u64 { + auto hash>::operator()(const stormkit::math::vec3& vec) const noexcept -> stormkit::u64 { auto hash = stormkit::hash64 { 0 }; stormkit::hash_combine(hash, vec.x, vec.y, vec.z); return hash; @@ -446,9 +430,8 @@ namespace std { template template - inline auto formatter, - CharT>::format(const stormkit::math::vec3& vec, - FormatContext& ctx) const -> decltype(ctx.out()) { + inline auto formatter, CharT>::format(const stormkit::math::vec3& vec, FormatContext& ctx) const + -> decltype(ctx.out()) { auto out = ctx.out(); stdr::copy("{ vec3: .x = "sv, out); @@ -464,8 +447,7 @@ namespace std { template STORMKIT_PURE STORMKIT_FORCE_INLINE - auto hash>::operator()(const stormkit::math::vec4& vec) - const noexcept -> stormkit::u64 { + auto hash>::operator()(const stormkit::math::vec4& vec) const noexcept -> stormkit::u64 { auto hash = stormkit::hash64 { 0 }; stormkit::hash_combine(hash, vec.x, vec.y, vec.z, vec.w); return hash; @@ -473,9 +455,8 @@ namespace std { template template - inline auto formatter, - CharT>::format(const stormkit::math::vec4& vec, - FormatContext& ctx) const -> decltype(ctx.out()) { + inline auto formatter, CharT>::format(const stormkit::math::vec4& vec, FormatContext& ctx) const + -> decltype(ctx.out()) { auto out = ctx.out(); stdr::copy("{ vec4: .x = "sv, out); diff --git a/modules/stormkit/core/math/linear.mpp b/modules/stormkit/core/math/linear.mpp index efb402d7d..9525a08ea 100644 --- a/modules/stormkit/core/math/linear.mpp +++ b/modules/stormkit/core/math/linear.mpp @@ -52,27 +52,22 @@ export namespace stormkit { inline namespace core { namespace math { template [[nodiscard]] - constexpr auto as_span(const TensorSpan& tensor) noexcept - -> std::span; + constexpr auto as_span(const TensorSpan& tensor) noexcept -> std::span; template requires(not core::meta::IsConst) [[nodiscard]] - constexpr auto as_span_mut(TensorSpan tensor) noexcept - -> std::span; + constexpr auto as_span_mut(TensorSpan tensor) noexcept -> std::span; template requires(core::meta::IsArithmetic>) [[nodiscard]] - constexpr auto as_mdspan(const T& data) noexcept - -> TensorSpan, Sizes...>; + constexpr auto as_mdspan(const T& data) noexcept -> TensorSpan, Sizes...>; template - requires(core::meta::IsArithmetic> - and not core::meta::IsConst>) + requires(core::meta::IsArithmetic> and not core::meta::IsConst>) [[nodiscard]] - constexpr auto as_mdspan_mut(T& data) noexcept - -> TensorSpan, Sizes...>; + constexpr auto as_mdspan_mut(T& data) noexcept -> TensorSpan, Sizes...>; template [[nodiscard]] @@ -96,15 +91,11 @@ export namespace stormkit { inline namespace core { namespace math { template requires(not core::meta::IsConst) - constexpr auto mul(const TensorSpan& a, - T b, - TensorSpan out) noexcept -> void; + constexpr auto mul(const TensorSpan& a, T b, TensorSpan out) noexcept -> void; template requires(not core::meta::IsConst) - constexpr auto div(const TensorSpan& a, - T b, - TensorSpan out) noexcept -> void; + constexpr auto div(const TensorSpan& a, T b, TensorSpan out) noexcept -> void; // TODO WAIT FOR SUBMDSPAN // template // constexpr auto normalize(TensorSpan a, @@ -113,24 +104,19 @@ export namespace stormkit { inline namespace core { namespace math { /* vector */ template requires(not core::meta::IsConst) - constexpr auto normalize(const VectorSpan& a, VectorSpan out) noexcept - -> void; + constexpr auto normalize(const VectorSpan& a, VectorSpan out) noexcept -> void; template requires(not core::meta::IsConst) - constexpr auto transpose(const VectorSpan& a, VectorSpan out) noexcept - -> void; + constexpr auto transpose(const VectorSpan& a, VectorSpan out) noexcept -> void; template [[nodiscard]] - constexpr auto dot(const VectorSpan& a, const VectorSpan& b) noexcept - -> T; + constexpr auto dot(const VectorSpan& a, const VectorSpan& b) noexcept -> T; template requires(not core::meta::IsConst) - constexpr auto cross(const VectorSpan& a, - const VectorSpan& b, - VectorSpan out) noexcept -> void; + constexpr auto cross(const VectorSpan& a, const VectorSpan& b, VectorSpan out) noexcept -> void; /* matrix */ template @@ -140,8 +126,7 @@ export namespace stormkit { inline namespace core { namespace math { template requires(not core::meta::IsConst) - constexpr auto transpose(const SquareMatrixSpan& a, - SquareMatrixSpan out) noexcept -> void; + constexpr auto transpose(const SquareMatrixSpan& a, SquareMatrixSpan out) noexcept -> void; template [[nodiscard]] @@ -149,8 +134,7 @@ export namespace stormkit { inline namespace core { namespace math { template requires(not core::meta::IsConst) - constexpr auto inverse(const SquareMatrixSpan& a, - SquareMatrixSpan out) noexcept -> void; + constexpr auto inverse(const SquareMatrixSpan& a, SquareMatrixSpan out) noexcept -> void; template [[nodiscard]] @@ -158,9 +142,8 @@ export namespace stormkit { inline namespace core { namespace math { template requires(not core::meta::IsConst) - constexpr auto mul(const MatrixSpan& a, - const MatrixSpan& b, - MatrixSpan out) noexcept -> void; + constexpr auto mul(const MatrixSpan& a, const MatrixSpan& b, MatrixSpan out) noexcept + -> void; template requires(not core::meta::IsConst) @@ -188,29 +171,15 @@ export namespace stormkit { inline namespace core { namespace math { /* graphics */ template requires(std::is_signed_v and not core::meta::IsConst) - constexpr auto orthographique(T left, - T right, - T bottom, - T top, - T near, - T far, - SquareMatrixSpan out) noexcept -> void; + constexpr auto orthographique(T left, T right, T bottom, T top, T near, T far, SquareMatrixSpan out) noexcept -> void; template requires(std::is_signed_v and not core::meta::IsConst) - constexpr auto orthographique(T left, - T right, - T bottom, - T top, - SquareMatrixSpan out) noexcept -> void; + constexpr auto orthographique(T left, T right, T bottom, T top, SquareMatrixSpan out) noexcept -> void; template requires(std::is_signed_v and not core::meta::IsConst) - constexpr auto perspective(Radian fov_y, - T aspect, - T near, - T far, - SquareMatrixSpan out) noexcept -> void; + constexpr auto perspective(Radian fov_y, T aspect, T near, T far, SquareMatrixSpan out) noexcept -> void; template requires(std::is_signed_v and not core::meta::IsConst) @@ -257,8 +226,7 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// template [[nodiscard]] - constexpr auto as_span(const TensorSpan& tensor) noexcept - -> std::span { + constexpr auto as_span(const TensorSpan& tensor) noexcept -> std::span { return std::span { tensor.data_handle(), (Sizes * ...) }; } @@ -267,8 +235,7 @@ namespace stormkit { inline namespace core { namespace math { template requires(not core::meta::IsConst) [[nodiscard]] - constexpr auto as_span_mut(TensorSpan tensor) noexcept - -> std::span { + constexpr auto as_span_mut(TensorSpan tensor) noexcept -> std::span { return std::span { tensor.data_handle(), (Sizes * ...) }; } @@ -277,8 +244,7 @@ namespace stormkit { inline namespace core { namespace math { template requires(core::meta::IsArithmetic>) STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto as_mdspan(const T& data) noexcept - -> TensorSpan, Sizes...> { + constexpr auto as_mdspan(const T& data) noexcept -> TensorSpan, Sizes...> { EXPECTS(stdr::size(data) == (Sizes * ...)); return TensorSpan, Sizes...> { stdr::data(data), Sizes... }; } @@ -286,11 +252,9 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// //////////////////////////////////////// template - requires(core::meta::IsArithmetic> - and not core::meta::IsConst>) + requires(core::meta::IsArithmetic> and not core::meta::IsConst>) STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto as_mdspan_mut(T& data) noexcept - -> TensorSpan, Sizes...> { + constexpr auto as_mdspan_mut(T& data) noexcept -> TensorSpan, Sizes...> { EXPECTS(stdr::size(data) == (Sizes * ...)); return TensorSpan, Sizes...> { stdr::data(data), Sizes... }; } @@ -349,9 +313,7 @@ namespace stormkit { inline namespace core { namespace math { template requires(not core::meta::IsConst) STORMKIT_FORCE_INLINE - constexpr auto mul(const TensorSpan& a, - T b, - TensorSpan out) noexcept -> void { + constexpr auto mul(const TensorSpan& a, T b, TensorSpan out) noexcept -> void { EXPECTS(a.data_handle() != out.data_handle()); const auto a_linear = as_span(a); auto out_linear = as_span_mut(out); @@ -363,9 +325,7 @@ namespace stormkit { inline namespace core { namespace math { template requires(not core::meta::IsConst) STORMKIT_FORCE_INLINE - constexpr auto div(const TensorSpan& a, - T b, - TensorSpan out) noexcept -> void { + constexpr auto div(const TensorSpan& a, T b, TensorSpan out) noexcept -> void { EXPECTS(a.data_handle() != out.data_handle()); const auto a_linear = as_span(a); auto out_linear = as_span_mut(out); @@ -377,8 +337,7 @@ namespace stormkit { inline namespace core { namespace math { template requires(not core::meta::IsConst) STORMKIT_FORCE_INLINE - constexpr auto normalize(const VectorSpan& a, VectorSpan out) noexcept - -> void { + constexpr auto normalize(const VectorSpan& a, VectorSpan out) noexcept -> void { EXPECTS(a.data_handle() != out.data_handle()); const auto sum = init_by([&a](auto& out) noexcept { for (auto i = 0u; i < N; ++i) out += (a[i] * a[i]); @@ -392,8 +351,7 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto dot(const VectorSpan& a, const VectorSpan& b) noexcept - -> T { + constexpr auto dot(const VectorSpan& a, const VectorSpan& b) noexcept -> T { auto out = T { 0 }; for (auto i = 0u; i < N; ++i) out += (a[i] * b[i]); return out; @@ -404,9 +362,8 @@ namespace stormkit { inline namespace core { namespace math { template requires(not core::meta::IsConst) STORMKIT_FORCE_INLINE - constexpr auto cross(const VectorSpan& a, - const VectorSpan& b, - VectorSpan out) noexcept -> void { + constexpr auto cross(const VectorSpan& a, const VectorSpan& b, VectorSpan out) noexcept + -> void { EXPECTS(a.data_handle() != out.data_handle()); EXPECTS(b.data_handle() != out.data_handle()); @@ -419,8 +376,7 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// template requires(not core::meta::IsConst) - constexpr auto cofactor(const SquareMatrixSpan& mat, - SquareMatrixSpan out) noexcept -> void { + constexpr auto cofactor(const SquareMatrixSpan& mat, SquareMatrixSpan out) noexcept -> void { static constexpr auto N = M - 1u; for (auto i = 0u; i < M; ++i) @@ -438,8 +394,7 @@ namespace stormkit { inline namespace core { namespace math { } }); - out[i, j] = narrow(std::pow(T { -1 }, i + j)) - * determinant(as_mdspan(submatrix)); + out[i, j] = narrow(std::pow(T { -1 }, i + j)) * determinant(as_mdspan(submatrix)); } } @@ -487,8 +442,7 @@ namespace stormkit { inline namespace core { namespace math { template requires(not core::meta::IsConst) STORMKIT_FORCE_INLINE - constexpr auto transpose(const SquareMatrixSpan& a, - SquareMatrixSpan out) noexcept -> void { + constexpr auto transpose(const SquareMatrixSpan& a, SquareMatrixSpan out) noexcept -> void { EXPECTS(a.data_handle() != out.data_handle()); for (auto i = 0u; i < N; ++i) @@ -513,14 +467,11 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// template requires(not core::meta::IsConst) - constexpr auto inverse(const SquareMatrixSpan& a, - SquareMatrixSpan out) noexcept -> void { + constexpr auto inverse(const SquareMatrixSpan& a, SquareMatrixSpan out) noexcept -> void { EXPECTS(a.data_handle() != out.data_handle()); EXPECTS(is_inversible(a)); - const auto factor = init_by>([&a](auto& out) noexcept { - cofactor(a, as_mdspan_mut(out)); - }); + const auto factor = init_by>([&a](auto& out) noexcept { cofactor(a, as_mdspan_mut(out)); }); const auto transposed = init_by>([&factor](auto& out) noexcept { transpose(as_mdspan(factor), as_mdspan_mut(out)); @@ -531,9 +482,7 @@ namespace stormkit { inline namespace core { namespace math { const auto one_over_determinant = T { 1 } / determinant(a); for (auto i = 0u; i < N; ++i) - for (auto j = 0u; j < N; ++j) { - out[i, j] = transposed_mat[i, j] * one_over_determinant; - } + for (auto j = 0u; j < N; ++j) { out[i, j] = transposed_mat[i, j] * one_over_determinant; } } //////////////////////////////////////// @@ -571,9 +520,8 @@ namespace stormkit { inline namespace core { namespace math { template requires(not core::meta::IsConst) STORMKIT_FORCE_INLINE - constexpr auto mul(const MatrixSpan& a, - const MatrixSpan& b, - MatrixSpan out) noexcept -> void { + constexpr auto mul(const MatrixSpan& a, const MatrixSpan& b, MatrixSpan out) noexcept + -> void { stdr::fill(as_span_mut(out), T { 0 }); for (auto i = 0u; i < M; ++i) for (auto j = 0u; j < K; ++j) @@ -591,9 +539,7 @@ namespace stormkit { inline namespace core { namespace math { EXPECTS(a.data_handle() != out.data_handle()); EXPECTS(b.data_handle() != out.data_handle()); - const auto inverted = init_by>([&b](auto& out) noexcept { - inverse(b, as_mdspan_mut(out)); - }); + const auto inverted = init_by>([&b](auto& out) noexcept { inverse(b, as_mdspan_mut(out)); }); mul(a, as_mdspan(inverted), out); } @@ -610,22 +556,10 @@ namespace stormkit { inline namespace core { namespace math { for (auto i = 0u; i < 3; ++i) for (auto j = 0u; j < 3; ++j) out[i, j] = a[i, j]; - out[3, 0] = a[0, 0] * translation[0] - + a[1, 0] * translation[1] - + a[2, 0] * translation[2] - + a[3, 0]; - out[3, 1] = a[0, 1] * translation[0] - + a[1, 1] * translation[1] - + a[2, 1] * translation[2] - + a[3, 1]; - out[3, 2] = a[0, 2] * translation[0] - + a[1, 2] * translation[1] - + a[2, 2] * translation[2] - + a[3, 2]; - out[3, 3] = a[0, 3] * translation[0] - + a[1, 3] * translation[1] - + a[2, 3] * translation[2] - + a[3, 3]; + out[3, 0] = a[0, 0] * translation[0] + a[1, 0] * translation[1] + a[2, 0] * translation[2] + a[3, 0]; + out[3, 1] = a[0, 1] * translation[0] + a[1, 1] * translation[1] + a[2, 1] * translation[2] + a[3, 1]; + out[3, 2] = a[0, 2] * translation[0] + a[1, 2] * translation[1] + a[2, 2] * translation[2] + a[3, 2]; + out[3, 3] = a[0, 3] * translation[0] + a[1, 3] * translation[1] + a[2, 3] * translation[2] + a[3, 3]; } //////////////////////////////////////// @@ -717,13 +651,7 @@ namespace stormkit { inline namespace core { namespace math { template requires(std::is_signed_v and not core::meta::IsConst) STORMKIT_FORCE_INLINE - constexpr auto orthographique(T left, - T right, - T bottom, - T top, - T near, - T far, - SquareMatrixSpan out) noexcept -> void { + constexpr auto orthographique(T left, T right, T bottom, T top, T near, T far, SquareMatrixSpan out) noexcept -> void { (void)left; (void)right; (void)bottom; @@ -738,11 +666,7 @@ namespace stormkit { inline namespace core { namespace math { template requires(std::is_signed_v and not core::meta::IsConst) STORMKIT_FORCE_INLINE - constexpr auto orthographique(T left, - T right, - T bottom, - T top, - SquareMatrixSpan out) noexcept -> void { + constexpr auto orthographique(T left, T right, T bottom, T top, SquareMatrixSpan out) noexcept -> void { (void)left; (void)right; (void)bottom; @@ -755,11 +679,7 @@ namespace stormkit { inline namespace core { namespace math { template requires(std::is_signed_v and not core::meta::IsConst) STORMKIT_FORCE_INLINE - constexpr auto perspective(Radian fov_y, - T aspect, - T near, - T far, - SquareMatrixSpan out) noexcept -> void { + constexpr auto perspective(Radian fov_y, T aspect, T near, T far, SquareMatrixSpan out) noexcept -> void { EXPECTS(not is_equal(aspect, T { 0 })); EXPECTS(not is_equal(near, far)); diff --git a/modules/stormkit/core/meta/algorithms.mpp b/modules/stormkit/core/meta/algorithms.mpp index 46d5c9b19..435f3c570 100644 --- a/modules/stormkit/core/meta/algorithms.mpp +++ b/modules/stormkit/core/meta/algorithms.mpp @@ -20,8 +20,7 @@ export namespace stormkit { inline namespace core { namespace meta { using Select = std::conditional_t; template class Variant, typename... Ts> - constexpr auto variant_type_find_if(const Variant&, Predicate&& predicate) noexcept - -> std::size_t; + constexpr auto variant_type_find_if(const Variant&, Predicate&& predicate) noexcept -> std::size_t; }}} // namespace stormkit::core::meta //////////////////////////////////////////////////////////////////// @@ -37,14 +36,9 @@ namespace stormkit { inline namespace core { namespace meta { auto found = std::variant_npos; [&](std::index_sequence) noexcept { if constexpr ((requires { - { - std::forward(predicate) - .template operator() - } -> IsBooleanTestable; + { std::forward(predicate).template operator() } -> IsBooleanTestable; } and ...)) - (((std::forward(predicate).template operator()()) - and (found = Indices, true)) - or ...); + (((std::forward(predicate).template operator()()) and (found = Indices, true)) or ...); else static_assert(false, "Type not found"); }(std::index_sequence_for()); @@ -55,8 +49,7 @@ namespace stormkit { inline namespace core { namespace meta { ///////////////////////////////////// template class Variant, typename... Ts> STORMKIT_FORCE_INLINE - constexpr auto variant_type_find_if(const Variant&, Predicate&& predicate) noexcept - -> std::size_t { + constexpr auto variant_type_find_if(const Variant&, Predicate&& predicate) noexcept -> std::size_t { return variant_type_find_if_impl(std::forward(predicate)); } }}} // namespace stormkit::core::meta diff --git a/modules/stormkit/core/meta/concepts.mpp b/modules/stormkit/core/meta/concepts.mpp index 7ea1f1dd7..eb6e81e70 100644 --- a/modules/stormkit/core/meta/concepts.mpp +++ b/modules/stormkit/core/meta/concepts.mpp @@ -16,20 +16,17 @@ namespace stormkit { inline namespace core { namespace meta::details { } template class T, typename T2, auto... Args> - constexpr auto is_specialization_of_with_nttp_helper(const T&) noexcept - -> std::true_type { + constexpr auto is_specialization_of_with_nttp_helper(const T&) noexcept -> std::true_type { return {}; } template class T, typename T1, auto... Args> - constexpr auto is_specialization_of_helper_nttp_tv(const T&) noexcept - -> std::true_type { + constexpr auto is_specialization_of_helper_nttp_tv(const T&) noexcept -> std::true_type { return {}; } template typename T, typename T1, typename T2, auto... Args> - constexpr auto is_specialization_of_helper_nttp_ttv(const T&) noexcept - -> std::true_type { + constexpr auto is_specialization_of_helper_nttp_ttv(const T&) noexcept -> std::true_type { return {}; } }}} // namespace stormkit::core::meta::details @@ -69,9 +66,7 @@ export namespace stormkit { inline namespace core { namespace meta { concept IsConvertibleTo = std::convertible_to; template - concept IsHashable = requires(std::remove_cvref_t& a) { - std::hash> {}(a); - }; + concept IsHashable = requires(std::remove_cvref_t& a) { std::hash> {}(a); }; template concept IsCanonical = IsStrict, std::remove_cvref_t>; @@ -148,8 +143,7 @@ export namespace stormkit { inline namespace core { namespace meta { concept IsMovedOwningPointer = IsOwningPointer and IsRValueReference; template - concept IsViewPointer = (IsOwningPointer> - and not IsMovedOwningPointer) + concept IsViewPointer = (IsOwningPointer> and not IsMovedOwningPointer) or IsNonOwningPointer>; template @@ -165,8 +159,7 @@ export namespace stormkit { inline namespace core { namespace meta { concept IsPolymorphic = std::is_polymorphic_v; template - concept IsPolymorphicPointer = IsPointer - and IsPolymorphic::element_type>; + concept IsPolymorphicPointer = IsPointer and IsPolymorphic::element_type>; template concept IsPolymorphicReference = IsReference and IsPolymorphic>; @@ -193,18 +186,15 @@ export namespace stormkit { inline namespace core { namespace meta { concept IsEnumeration = std::is_enum_v and IsNotByte; template - concept IsIntegral - = (std::integral and not IsStrict and not IsByte) - or Is>> - or Is>> + concept IsIntegral = (std::integral and not IsStrict and not IsByte) + or Is>> + or Is>> #if defined(STORMKIT_COMPILER_MSVC) - or Is - or Is; + or Is + or Is; #else - or Is - or Is; + or Is + or Is; #endif template @@ -214,9 +204,7 @@ export namespace stormkit { inline namespace core { namespace meta { concept IsFloatingPoint = std::floating_point; template - concept IsArithmetic = (IsIntegral or IsFloatingPoint) - and not IsPointer - and not IsEnumeration; + concept IsArithmetic = (IsIntegral or IsFloatingPoint) and not IsPointer and not IsEnumeration; template concept IsScalar = IsArithmetic or IsPointer or IsEnumeration; @@ -242,23 +230,17 @@ export namespace stormkit { inline namespace core { namespace meta { template typename T> concept IsSpecializationOfNTTP_TV = requires(S&& s) { - { - details::is_specialization_of_helper_nttp_tv(std::forward(s)) - } -> IsStrict; + { details::is_specialization_of_helper_nttp_tv(std::forward(s)) } -> IsStrict; }; template typename T> concept IsSpecializationOfNTTP_TTV = requires(S&& s) { - { - details::is_specialization_of_helper_nttp_ttv(std::forward(s)) - } -> IsStrict; + { details::is_specialization_of_helper_nttp_ttv(std::forward(s)) } -> IsStrict; }; template class T> concept IsSpecializationWithNTTPOf = requires(S&& s) { - { - details::is_specialization_of_with_nttp_helper(std::forward(s)) - } -> IsStrict; + { details::is_specialization_of_with_nttp_helper(std::forward(s)) } -> IsStrict; }; template @@ -286,8 +268,7 @@ export namespace stormkit { inline namespace core { namespace meta { concept IsBinaryPredicate = IsPredicate; template - concept IsHashFunc = std::regular_invocable - and std::convertible_to, std::uint64_t>; + concept IsHashFunc = std::regular_invocable and std::convertible_to, std::uint64_t>; // doesn't work atm template @@ -295,8 +276,7 @@ export namespace stormkit { inline namespace core { namespace meta { // val); }; template - concept IsCharacter - = IsOneOf; + concept IsCharacter = IsOneOf; template concept IsCharType = IsOneOf; @@ -344,38 +324,27 @@ export namespace stormkit { inline namespace core { namespace meta { concept IsSameSigneness = (IsSigned and IsSigned) or (IsUnsigned and IsUnsigned); template - concept IsSignNarrowing = (IsSigned ? not IsSigned - : IsSigned and sizeof(From) == sizeof(To)); + concept IsSignNarrowing = (IsSigned ? not IsSigned : IsSigned and sizeof(From) == sizeof(To)); template - concept IsByteNarrowing = ((IsArithmetic and IsByte) - or (IsByte and IsArithmetic)) + concept IsByteNarrowing = ((IsArithmetic and IsByte) or (IsByte and IsArithmetic)) and (IsByte and sizeof(To) != sizeof(From)); template concept IsNarrowing = (IsFloatingPoint and IsIntegral) - or (IsFloatingPoint - and IsFloatingPoint - and sizeof(From) > sizeof(To)) + or (IsFloatingPoint and IsFloatingPoint and sizeof(From) > sizeof(To)) or (IsIntegralOrEnumeration and IsFloatingPoint) - or (IsIntegral - and IsIntegral - and (sizeof(From) > sizeof(To) or IsSignNarrowing)) + or (IsIntegral and IsIntegral and (sizeof(From) > sizeof(To) or IsSignNarrowing)) or (IsEnumeration and IsIntegral - and (sizeof(From) > sizeof(To) - or IsSignNarrowing, From>)) + and (sizeof(From) > sizeof(To) or IsSignNarrowing, From>)) or (IsPointer and Is); template - concept IsUnsafePointerConvertion = IsPointer - and IsPointer - and not requires(To to, From from) { to = from; }; + concept IsUnsafePointerConvertion = IsPointer and IsPointer and not requires(To to, From from) { to = from; }; template - concept IsSafeNarrowing = IsArithmetic - and IsArithmetic - and not is_safe_narrowing(from); + concept IsSafeNarrowing = IsArithmetic and IsArithmetic and not is_safe_narrowing(from); template concept HasEqualityOperator = requires(const T1& first, const T2& second) { @@ -385,9 +354,7 @@ export namespace stormkit { inline namespace core { namespace meta { static_assert(HasEqualityOperator); template - concept EnableCtor = sizeof...(Args) != 1 - || (sizeof...(Args) == 1 - && !Is::type>); + concept EnableCtor = sizeof...(Args) != 1 || (sizeof...(Args) == 1 && !Is::type>); template concept IsNoexceptDefaultConstructible = std::is_nothrow_default_constructible_v; diff --git a/modules/stormkit/core/meta/type_query.mpp b/modules/stormkit/core/meta/type_query.mpp index 8c8e3379a..255874300 100644 --- a/modules/stormkit/core/meta/type_query.mpp +++ b/modules/stormkit/core/meta/type_query.mpp @@ -78,9 +78,7 @@ namespace stormkit { inline namespace core { namespace meta { using UnderlyingType = details::UnderlyingType::Type; template - using ArithmeticOrderingType = Select, - std::strong_ordering, - std::weak_ordering>; + using ArithmeticOrderingType = Select, std::strong_ordering, std::weak_ordering>; template constexpr auto enumerate() noexcept -> decltype(auto) = delete; @@ -101,8 +99,7 @@ namespace stormkit { inline namespace core { namespace meta { constexpr auto is_greater() noexcept { using Type = decltype(T {} + V {}); - return static_cast(std::numeric_limits::max()) - > static_cast(std::numeric_limits::max()); + return static_cast(std::numeric_limits::max()) > static_cast(std::numeric_limits::max()); } //////////////////////////////////////// @@ -132,10 +129,9 @@ namespace stormkit { inline namespace core { namespace meta { static_assert(start < end); constexpr auto name = function.substr(start, (end - start)); - static constexpr auto res = - [](std::string_view str, std::index_sequence) { - return std::array { str[Idxs]... }; - }(name, std::make_index_sequence {}); + static constexpr auto res = [](std::string_view str, std::index_sequence) { + return std::array { str[Idxs]... }; + }(name, std::make_index_sequence {}); return std::string_view { res.data(), res.size() }; } diff --git a/modules/stormkit/core/parallelism/locked.mpp b/modules/stormkit/core/parallelism/locked.mpp index 223a8f78c..97ff4bf6d 100644 --- a/modules/stormkit/core/parallelism/locked.mpp +++ b/modules/stormkit/core/parallelism/locked.mpp @@ -25,11 +25,12 @@ namespace stormkit { inline namespace core { namespace details { export namespace stormkit { inline namespace core { enum class LockAccessMode : core::u8 { Read_Only, - Read_Write + Read_Write, }; template - class STORMKIT_API Locked { + class STORMKIT_API + Locked { public: using ValueType = T; using ReferenceType = ValueType&; @@ -56,8 +57,7 @@ export namespace stormkit { inline namespace core { Locked() noexcept(noexcept(std::is_nothrow_default_constructible_v)); template - explicit Locked(Args&&... args) noexcept( - noexcept(std::is_nothrow_constructible_v)); + explicit Locked(Args&&... args) noexcept(noexcept(std::is_nothrow_constructible_v)); Locked(const Locked&) = delete; auto operator=(const Locked&) -> Locked& = delete; @@ -78,12 +78,13 @@ export namespace stormkit { inline namespace core { auto copy(LockArgs&&... lock_args) const noexcept -> ValueType; template class Lock = details::DefaultReadWriteLock, typename... LockArgs> - auto assign(ConstReferenceType value, LockArgs&&... lock_args) noexcept( - noexcept(std::is_nothrow_assignable_v)) -> void; + auto assign(ConstReferenceType value, + LockArgs&&... lock_args) noexcept(noexcept(std::is_nothrow_assignable_v)) + -> void; template class Lock = details::DefaultReadWriteLock, typename... LockArgs> - auto assign(ValueType&& value, LockArgs&&... lock_args) noexcept( - noexcept(std::is_nothrow_assignable_v)) -> void; + auto assign(ValueType&& value, + LockArgs&&... lock_args) noexcept(noexcept(std::is_nothrow_assignable_v)) -> void; template auto unsafe(this Self& self) noexcept -> meta::ForwardConst; @@ -94,11 +95,8 @@ export namespace stormkit { inline namespace core { template class Lock, LockAccessMode Mode> class Access { public: - using ValueType - = std::conditional_t; - using RefContainerType = std::conditional_t, - Ref>; + using ValueType = std::conditional_t; + using RefContainerType = std::conditional_t, Ref>; using ReferenceType = ValueType&; using PointerType = ValueType*; @@ -139,16 +137,16 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - STORMKIT_FORCE_INLINE Locked::Locked() noexcept( - noexcept(std::is_nothrow_default_constructible_v)) - = default; + STORMKIT_FORCE_INLINE + Locked::Locked() noexcept(noexcept(std::is_nothrow_default_constructible_v)) + = default; //////////////////////////////////////// //////////////////////////////////////// template template - STORMKIT_FORCE_INLINE Locked::Locked(Args&&... args) noexcept( - noexcept(std::is_nothrow_constructible_v)) + STORMKIT_FORCE_INLINE + Locked::Locked(Args&&... args) noexcept(noexcept(std::is_nothrow_constructible_v)) : m_value { std::forward(args)... } { } @@ -156,11 +154,9 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template template class Lock, typename... LockArgs, class Self> - STORMKIT_FORCE_INLINE auto Locked::access(this Self& self, - LockArgs&&... lock_args) noexcept - -> Access { - static_assert(not(Mode == LockAccessMode::Read_Only - and not std::is_const_v>), + STORMKIT_FORCE_INLINE + auto Locked::access(this Self& self, LockArgs&&... lock_args) noexcept -> Access { + static_assert(not(Mode == LockAccessMode::Read_Only and not std::is_const_v>), "can't get read access on const Locked"); using AccessType = Access; return AccessType { self, std::forward(lock_args)... }; @@ -170,8 +166,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template template class Lock, typename... LockArgs> - STORMKIT_FORCE_INLINE auto Locked::read(LockArgs&&... lock_args) const noexcept - -> ReadAccess { + STORMKIT_FORCE_INLINE + auto Locked::read(LockArgs&&... lock_args) const noexcept -> ReadAccess { return access(std::forward(lock_args)...); } @@ -179,8 +175,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template template class Lock, typename... LockArgs> - STORMKIT_FORCE_INLINE auto Locked::write(LockArgs&&... lock_args) noexcept - -> WriteAccess { + STORMKIT_FORCE_INLINE + auto Locked::write(LockArgs&&... lock_args) noexcept -> WriteAccess { return access(std::forward(lock_args)...); } @@ -188,8 +184,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template template class Lock, typename... LockArgs> - STORMKIT_FORCE_INLINE auto Locked::copy(LockArgs&&... lock_args) const noexcept - -> ValueType { + STORMKIT_FORCE_INLINE + auto Locked::copy(LockArgs&&... lock_args) const noexcept -> ValueType { return *read(std::forward(lock_args)...); } @@ -197,9 +193,11 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template template class Lock, typename... LockArgs> - STORMKIT_FORCE_INLINE auto - Locked::assign(ConstReferenceType value, LockArgs&&... lock_args) noexcept( - noexcept(std::is_nothrow_assignable_v)) -> void { + STORMKIT_FORCE_INLINE + auto Locked::assign(ConstReferenceType value, + LockArgs&&... lock_args) noexcept(noexcept(std::is_nothrow_assignable_v)) + -> void { *write(std::forward(lock_args)...) = value; } @@ -207,9 +205,11 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template template class Lock, typename... LockArgs> - STORMKIT_FORCE_INLINE auto - Locked::assign(ValueType&& value, LockArgs&&... lock_args) noexcept( - noexcept(std::is_nothrow_assignable_v)) -> void { + STORMKIT_FORCE_INLINE + auto Locked::assign(ValueType&& value, + LockArgs&&... lock_args) noexcept(noexcept(std::is_nothrow_assignable_v)) + -> void { *write(std::forward(lock_args)...) = std::move(value); } @@ -217,15 +217,16 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template template - STORMKIT_FORCE_INLINE auto Locked::unsafe(this Self& self) noexcept - -> meta::ForwardConst { + STORMKIT_FORCE_INLINE + auto Locked::unsafe(this Self& self) noexcept -> meta::ForwardConst { return self.m_value; } //////////////////////////////////////// //////////////////////////////////////// template - STORMKIT_FORCE_INLINE auto Locked::mutex() const noexcept -> const MutexType& { + STORMKIT_FORCE_INLINE + auto Locked::mutex() const noexcept -> const MutexType& { return m_mutex; } @@ -235,9 +236,7 @@ namespace stormkit { inline namespace core { template class Lock, LockAccessMode Mode> template STORMKIT_FORCE_INLINE - Locked::Access::Access(ReferenceType value, - MutexType& mutex, - LockArgs&&... lock_args) noexcept + Locked::Access::Access(ReferenceType value, MutexType& mutex, LockArgs&&... lock_args) noexcept : lock { mutex, std::forward(lock_args)... }, m_value { as_ref_like(value) } { } @@ -247,8 +246,7 @@ namespace stormkit { inline namespace core { template class Lock, LockAccessMode Mode> template STORMKIT_FORCE_INLINE - Locked::Access::Access(const Locked& locked, - LockArgs&&... lock_args) noexcept + Locked::Access::Access(const Locked& locked, LockArgs&&... lock_args) noexcept : Access { locked.m_value, locked.m_mutex, std::forward(lock_args)... } { } @@ -267,9 +265,8 @@ namespace stormkit { inline namespace core { template template class Lock, LockAccessMode Mode> template - STORMKIT_FORCE_INLINE auto - Locked::Access::operator->(this Self&& self) noexcept - -> meta::ForwardConst { + STORMKIT_FORCE_INLINE + auto Locked::Access::operator->(this Self&& self) noexcept -> meta::ForwardConst { return self.m_value.get(); } @@ -278,9 +275,8 @@ namespace stormkit { inline namespace core { template template class Lock, LockAccessMode Mode> template - STORMKIT_FORCE_INLINE auto - Locked::Access::operator*(this Self&& self) noexcept - -> meta::ForwardConst { + STORMKIT_FORCE_INLINE + auto Locked::Access::operator*(this Self&& self) noexcept -> meta::ForwardConst { return *self.m_value; } }} // namespace stormkit::core diff --git a/modules/stormkit/core/parallelism/threadpool.mpp b/modules/stormkit/core/parallelism/threadpool.mpp index 2ff79ecd7..e50a78682 100644 --- a/modules/stormkit/core/parallelism/threadpool.mpp +++ b/modules/stormkit/core/parallelism/threadpool.mpp @@ -56,8 +56,7 @@ export namespace stormkit { inline namespace core { Task() = default; - inline Task(Type _type, std::function _work) - : type { _type }, work { std::move(_work) } {} + inline Task(Type _type, std::function _work) : type { _type }, work { std::move(_work) } {} Task(Task&&) noexcept = default; auto operator=(Task&&) noexcept -> Task& = default; @@ -87,8 +86,7 @@ export namespace stormkit { inline namespace core { auto parallel_for(ThreadPool& pool, Range&& range, F&& f) noexcept -> void; template&> F> - auto parallel_for_async(ThreadPool& pool, Range& range, F&& f) noexcept - -> std::vector>; + auto parallel_for_async(ThreadPool& pool, Range& range, F&& f) noexcept -> std::vector>; }} // namespace stormkit::core //////////////////////////////////////////////////////////////////// @@ -131,8 +129,7 @@ namespace stormkit { inline namespace core { STORMKIT_FORCE_INLINE inline auto ThreadPool::set_name(std::string_view name) noexcept -> void { // for (auto&& [i, worker] : stdv::enumerate(m_workers)) - for (auto i : range(m_worker_count)) - set_thread_name(m_workers[i], std::format("{}:{}", name, i)); + for (auto i : range(m_worker_count)) set_thread_name(m_workers[i], std::format("{}:{}", name, i)); } //////////////////////////////////////// @@ -198,8 +195,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template&> F> - inline auto parallel_for_async(ThreadPool& pool, Range& range, F&& f) noexcept - -> std::vector> { + inline auto parallel_for_async(ThreadPool& pool, Range& range, F&& f) noexcept -> std::vector> { const auto size = stdr::size(range); const auto chunk_size = size / pool.worker_count(); const auto chunk_count = size / chunk_size; diff --git a/modules/stormkit/core/string/encodings.mpp b/modules/stormkit/core/string/encodings.mpp index 77f63e4e0..3e204bafe 100644 --- a/modules/stormkit/core/string/encodings.mpp +++ b/modules/stormkit/core/string/encodings.mpp @@ -52,11 +52,7 @@ namespace stormkit { inline namespace core { auto len = 0ull; auto input_it = stdr::data(input); - while ((len = std::mbrtoc16(std::bit_cast(stdr::data(output)), - input_it, - MB_CUR_MAX, - &state)) - > 0ull) + while ((len = std::mbrtoc16(std::bit_cast(stdr::data(output)), input_it, MB_CUR_MAX, &state)) > 0ull) input_it += len; #else output = std::bit_cast(stdr::data(input)); @@ -73,8 +69,7 @@ namespace stormkit { inline namespace core { auto state = std::mbstate_t {}; output.resize(stdr::size(input)); - for (const auto& c : input) - std::c16rtomb(std::bit_cast(stdr::data(output)), c, &state); + for (const auto& c : input) std::c16rtomb(std::bit_cast(stdr::data(output)), c, &state); #else output = std::bit_cast(stdr::data(input)); #endif @@ -86,31 +81,27 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// inline auto ascii_to_wide(std::string_view input) -> std::wstring { [[maybe_unused]] - auto state = std::mbstate_t {}; + auto state + = std::mbstate_t {}; auto output = std::wstring {}; output.resize(stdr::size(input)); [[maybe_unused]] - auto len = 0ull; + auto len + = 0ull; [[maybe_unused]] - auto input_it = stdr::data(input); + auto input_it + = stdr::data(input); [[maybe_unused]] - auto i = 0; + auto i + = 0; #if defined(STORMKIT_COMPILER_MSVC) - while ((len = std::mbrtoc16(std::bit_cast(stdr::data(output)) + i++, - input_it, - MB_CUR_MAX, - &state)) - > 0u) + while ((len = std::mbrtoc16(std::bit_cast(stdr::data(output)) + i++, input_it, MB_CUR_MAX, &state)) > 0u) input_it += len; #elif defined(STORMKIT_COMPILER_CLANG) output = std::bit_cast(stdr::data(input)); #else - while ((len = std::mbrtoc8(std::bit_cast(stdr::data(output)) + i++, - input_it, - MB_CUR_MAX, - &state)) - > 0ull) + while ((len = std::mbrtoc8(std::bit_cast(stdr::data(output)) + i++, input_it, MB_CUR_MAX, &state)) > 0ull) input_it += len; #endif @@ -121,9 +112,11 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// inline auto wide_to_ascii(std::wstring_view input) -> std::string { [[maybe_unused]] - auto state = std::mbstate_t {}; + auto state + = std::mbstate_t {}; [[maybe_unused]] - auto output = std::string {}; + auto output + = std::string {}; output.resize(stdr::size(input)); #if defined(STORMKIT_COMPILER_MSVC) @@ -141,7 +134,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// inline auto ascii_to_utf8(std::string_view input) -> std::u8string { [[maybe_unused]] - auto output = std::u8string {}; + auto output + = std::u8string {}; output.resize(stdr::size(input) * narrow(MB_LEN_MAX)); #if defined(STORMKIT_COMPILER_MSVC) @@ -153,11 +147,7 @@ namespace stormkit { inline namespace core { auto len = 0ull; auto input_it = stdr::data(input); auto i = 0; - while ((len = std::mbrtoc8(std::bit_cast(stdr::data(output)) + i++, - input_it, - MB_CUR_MAX, - &state)) - > 0ull) + while ((len = std::mbrtoc8(std::bit_cast(stdr::data(output)) + i++, input_it, MB_CUR_MAX, &state)) > 0ull) input_it += len; #endif @@ -170,7 +160,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// inline auto utf8_to_ascii(std::u8string_view input) -> std::string { [[maybe_unused]] - auto output = std::string {}; + auto output + = std::string {}; output.resize(stdr::size(input)); #if defined(STORMKIT_COMPILER_MSVC) diff --git a/modules/stormkit/core/string/format.mpp b/modules/stormkit/core/string/format.mpp index d8cdd09fe..12c2d8389 100644 --- a/modules/stormkit/core/string/format.mpp +++ b/modules/stormkit/core/string/format.mpp @@ -26,21 +26,17 @@ export { inline constexpr auto DISABLE_DEFAULT_FORMATTER_FOR_ENUM = false; template - concept IsDefaultFormattedEnumeration = IsEnumeration - and not DISABLE_DEFAULT_FORMATTER_FOR_ENUM; + concept IsDefaultFormattedEnumeration = IsEnumeration and not DISABLE_DEFAULT_FORMATTER_FOR_ENUM; template concept HasFormatAs = requires(const T& val) { - { - format_as(val, std::declval()) - } -> Is; + { format_as(val, std::declval()) } -> Is; }; } // namespace meta inline constexpr struct { template - static constexpr auto operator()(const T& value, FormatContext& ctx) noexcept - -> FormatContext::iterator { + static constexpr auto operator()(const T& value, FormatContext& ctx) noexcept -> FormatContext::iterator { return format_as(value, ctx); } } format_fn = {}; @@ -82,8 +78,7 @@ export { }; template - struct std::formatter - : public formatter, CharT> { + struct std::formatter: public formatter, CharT> { template [[nodiscard]] auto format(const std::error_code&, FormatContext&) const -> FormatContext::iterator; @@ -127,8 +122,7 @@ using namespace stormkit; ///////////////////////////////////// template template -constexpr auto std::formatter::parse(ParseContext& ctx) noexcept - -> ParseContext::iterator { +constexpr auto std::formatter::parse(ParseContext& ctx) noexcept -> ParseContext::iterator { return ctx.begin(); } @@ -136,8 +130,7 @@ constexpr auto std::formatter::parse(ParseContext& ctx) noexcept ///////////////////////////////////// template template -auto std::formatter::format(const T& value, FormatContext& ctx) const noexcept - -> FormatContext::iterator { +auto std::formatter::format(const T& value, FormatContext& ctx) const noexcept -> FormatContext::iterator { return core::format_fn(value, ctx); } @@ -145,8 +138,7 @@ auto std::formatter::format(const T& value, FormatContext& ctx) const ///////////////////////////////////// template template -constexpr auto std::formatter::parse(ParseContext& ctx) noexcept - -> ParseContext::iterator { +constexpr auto std::formatter::parse(ParseContext& ctx) noexcept -> ParseContext::iterator { return ctx.begin(); } @@ -154,8 +146,7 @@ constexpr auto std::formatter::parse(ParseContext& ctx) noexcept ///////////////////////////////////// template template -auto std::formatter::format(const T& value, FormatContext& ctx) const - -> FormatContext::iterator { +auto std::formatter::format(const T& value, FormatContext& ctx) const -> FormatContext::iterator { auto&& out = ctx.out(); if constexpr (requires { { as_string(value) } -> meta::Is; @@ -170,8 +161,7 @@ auto std::formatter::format(const T& value, FormatContext& ctx) const ///////////////////////////////////// template template -auto std::formatter::format(const T& value, FormatContext& ctx) const - -> FormatContext::iterator { +auto std::formatter::format(const T& value, FormatContext& ctx) const -> FormatContext::iterator { auto&& out = ctx.out(); return format_to(out, "{:#0x}", std::bit_cast(std::to_address(value))); } @@ -180,8 +170,7 @@ auto std::formatter::format(const T& value, FormatContext& ctx) const ///////////////////////////////////// template template -auto std::formatter::format(const std::error_code& code, - FormatContext& ctx) const +auto std::formatter::format(const std::error_code& code, FormatContext& ctx) const -> FormatContext::iterator { auto&& out = ctx.out(); const auto message = code.message(); @@ -192,8 +181,7 @@ auto std::formatter::format(const std::error_code& code, ///////////////////////////////////// template template -auto std::formatter::format(const std::errc& code, FormatContext& ctx) const - -> FormatContext::iterator { +auto std::formatter::format(const std::errc& code, FormatContext& ctx) const -> FormatContext::iterator { auto&& out = ctx.out(); const auto message = make_error_code(code).message(); return format_to(out, "{}", message); diff --git a/modules/stormkit/core/string/operations.mpp b/modules/stormkit/core/string/operations.mpp index d19dc78c4..b0e9f89a7 100644 --- a/modules/stormkit/core/string/operations.mpp +++ b/modules/stormkit/core/string/operations.mpp @@ -25,8 +25,7 @@ namespace stdv = std::views; export namespace stormkit { inline namespace core { [[nodiscard]] - constexpr auto split(std::string_view string, std::string_view delim) noexcept - -> std::vector; + constexpr auto split(std::string_view string, std::string_view delim) noexcept -> std::vector; [[nodiscard]] constexpr auto to_lower(std::string_view string) noexcept -> std::string; [[nodiscard]] @@ -37,21 +36,22 @@ export namespace stormkit { inline namespace core { auto to_upper(std::string_view string, const std::locale& locale) noexcept -> std::string; [[nodiscard]] - constexpr auto replace(std::string_view in, - std::string_view pattern, - std::string_view replacement) noexcept -> std::string; + constexpr auto replace(std::string_view in, std::string_view pattern, std::string_view replacement) noexcept -> std::string; template [[nodiscard]] - constexpr auto as_string(T) noexcept -> std::string_view = delete; + constexpr auto as_string(T) noexcept -> std::string_view + = delete; template [[nodiscard]] - constexpr auto to_string(T) noexcept -> std::string = delete; + constexpr auto to_string(T) noexcept -> std::string + = delete; template [[nodiscard]] - constexpr auto from_string(std::string_view) noexcept -> T = delete; + constexpr auto from_string(std::string_view) noexcept -> T + = delete; template requires(as_string(std::declval())) @@ -60,23 +60,19 @@ export namespace stormkit { inline namespace core { template [[nodiscard]] - constexpr auto to_string(T value, i32 base = 10) noexcept - -> std::expected; + constexpr auto to_string(T value, i32 base = 10) noexcept -> std::expected; template [[nodiscard]] - auto to_string(T value, std::chars_format fmt = std::chars_format::general) noexcept - -> std::expected; + auto to_string(T value, std::chars_format fmt = std::chars_format::general) noexcept -> std::expected; template [[nodiscard]] - constexpr auto from_string(std::string_view data, i32 base = 10) noexcept - -> std::expected; + constexpr auto from_string(std::string_view data, i32 base = 10) noexcept -> std::expected; template [[nodiscard]] - auto from_string(std::string_view data, - std::chars_format fmt = std::chars_format::general) noexcept + auto from_string(std::string_view data, std::chars_format fmt = std::chars_format::general) noexcept -> std::expected; [[nodiscard]] @@ -114,8 +110,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - constexpr auto split(std::string_view string, std::string_view delim) noexcept - -> std::vector { + constexpr auto split(std::string_view string, std::string_view delim) noexcept -> std::vector { return std::string_view { string } | stdv::split(delim) | stdv::transform([](auto&& subrange) { @@ -135,8 +130,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - inline auto to_lower(std::string_view string, const std::locale& locale) noexcept - -> std::string { + inline auto to_lower(std::string_view string, const std::locale& locale) noexcept -> std::string { auto result = std::string { string }; auto& facet = std::use_facet>(locale); facet.tolower(&result[0], &result[0] + stdr::size(result)); @@ -155,8 +149,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - inline auto to_upper(std::string_view string, const std::locale& locale) noexcept - -> std::string { + inline auto to_upper(std::string_view string, const std::locale& locale) noexcept -> std::string { auto result = std::string { string }; auto& facet = std::use_facet>(locale); facet.toupper(&result[0], &result[0] + stdr::size(result)); @@ -166,9 +159,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - inline constexpr auto replace(std::string_view in, - std::string_view pattern, - std::string_view replacement) noexcept -> std::string { + inline constexpr auto replace(std::string_view in, std::string_view pattern, std::string_view replacement) noexcept + -> std::string { return in | stdv::split(pattern) | stdv::transform([replacement](auto&& substr) noexcept { @@ -198,10 +190,7 @@ namespace stormkit { inline namespace core { constexpr auto to_string(T value, int base) noexcept -> std::expected { auto out = std::expected { std::in_place }; out->resize(16); - auto&& [ptr, errc] = std::to_chars(stdr::data(*out), - stdr::data(*out) + stdr::size(*out), - value, - base); + auto&& [ptr, errc] = std::to_chars(stdr::data(*out), stdr::data(*out) + stdr::size(*out), value, base); if (errc != std::errc {}) [[unlikely]] out = std::unexpected { std::in_place, std::move(errc) }; else { @@ -217,15 +206,11 @@ namespace stormkit { inline namespace core { // TODO add an argument to customize string buffer size template [[nodiscard]] - auto to_string(T value, std::chars_format fmt) noexcept - -> std::expected { + auto to_string(T value, std::chars_format fmt) noexcept -> std::expected { auto out = std::expected { std::in_place }; out->resize(16, '\0'); - auto&& [ptr, errc] = std::to_chars(stdr::data(*out), - stdr::data(*out) + stdr::size(*out), - value, - fmt); + auto&& [ptr, errc] = std::to_chars(stdr::data(*out), stdr::data(*out) + stdr::size(*out), value, fmt); if (errc != std::errc {}) [[unlikely]] out = std::unexpected { std::in_place, std::move(errc) }; else { @@ -239,13 +224,9 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - inline constexpr auto from_string(std::string_view data, i32 base) noexcept - -> std::expected { + inline constexpr auto from_string(std::string_view data, i32 base) noexcept -> std::expected { auto value = T {}; - auto&& [_, errc] = std::from_chars(stdr::data(data), - stdr::data(data) + stdr::size(data), - value, - base); + auto&& [_, errc] = std::from_chars(stdr::data(data), stdr::data(data) + stdr::size(data), value, base); if (errc != std::errc {}) [[unlikely]] return std::unexpected { std::in_place, std::move(errc) }; @@ -255,13 +236,9 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - inline auto from_string(std::string_view data, std::chars_format fmt) noexcept - -> std::expected { + inline auto from_string(std::string_view data, std::chars_format fmt) noexcept -> std::expected { auto value = T {}; - auto&& [_, errc] = std::from_chars(stdr::data(data), - stdr::data(data) + stdr::size(data), - value, - fmt); + auto&& [_, errc] = std::from_chars(stdr::data(data), stdr::data(data) + stdr::size(data), value, fmt); if (errc != std::errc {}) [[unlikely]] return std::unexpected { std::in_place, std::move(errc) }; diff --git a/modules/stormkit/core/typesafe/checked_value.mpp b/modules/stormkit/core/typesafe/checked_value.mpp index 1a85ba89c..f2bd27164 100644 --- a/modules/stormkit/core/typesafe/checked_value.mpp +++ b/modules/stormkit/core/typesafe/checked_value.mpp @@ -26,12 +26,10 @@ namespace stormkit { inline namespace core { namespace meta { template - concept IsCheckedValueArithmetic = meta::IsArithmetic< - meta::UnderlyingType>>; + concept IsCheckedValueArithmetic = meta::IsArithmetic>>; template - concept IsCheckedValueValueType = meta::PlainIs>>; + concept IsCheckedValueValueType = meta::PlainIs>>; } // namespace meta }} // namespace stormkit::core @@ -49,64 +47,52 @@ export namespace stormkit { inline namespace core { constexpr operator T() noexcept; - constexpr auto operator+(meta::PlainIs auto&& other) const noexcept - -> CheckedValue + constexpr auto operator+(meta::PlainIs auto&& other) const noexcept -> CheckedValue requires(meta::IsArithmetic); - constexpr auto operator+(meta::PlainIs auto&& other) const noexcept - -> CheckedValue + constexpr auto operator+(meta::PlainIs auto&& other) const noexcept -> CheckedValue requires(meta::IsArithmetic); constexpr auto operator+=(meta::PlainIs auto&& other) noexcept -> CheckedValue& requires(meta::IsArithmetic); - constexpr auto operator+=(meta::PlainIs auto&& other) noexcept - -> CheckedValue& + constexpr auto operator+=(meta::PlainIs auto&& other) noexcept -> CheckedValue& requires(meta::IsArithmetic); - constexpr auto operator-(meta::PlainIs auto&& other) const noexcept - -> CheckedValue + constexpr auto operator-(meta::PlainIs auto&& other) const noexcept -> CheckedValue requires(meta::IsArithmetic); - constexpr auto operator-(meta::PlainIs auto&& other) const noexcept - -> CheckedValue + constexpr auto operator-(meta::PlainIs auto&& other) const noexcept -> CheckedValue requires(meta::IsArithmetic); constexpr auto operator-=(meta::PlainIs auto&& other) noexcept -> CheckedValue& requires(meta::IsArithmetic); - constexpr auto operator-=(meta::PlainIs auto&& other) noexcept - -> CheckedValue& + constexpr auto operator-=(meta::PlainIs auto&& other) noexcept -> CheckedValue& requires(meta::IsArithmetic); - constexpr auto operator*(meta::PlainIs auto&& other) const noexcept - -> CheckedValue + constexpr auto operator*(meta::PlainIs auto&& other) const noexcept -> CheckedValue requires(meta::IsArithmetic); - constexpr auto operator*(meta::PlainIs auto&& other) const noexcept - -> CheckedValue + constexpr auto operator*(meta::PlainIs auto&& other) const noexcept -> CheckedValue requires(meta::IsArithmetic); constexpr auto operator*=(meta::PlainIs auto&& other) noexcept -> CheckedValue& requires(meta::IsArithmetic); - constexpr auto operator*=(meta::PlainIs auto&& other) noexcept - -> CheckedValue& + constexpr auto operator*=(meta::PlainIs auto&& other) noexcept -> CheckedValue& requires(meta::IsArithmetic); - constexpr auto operator/(meta::PlainIs auto&& other) const noexcept - -> CheckedValue + constexpr auto operator/(meta::PlainIs auto&& other) const noexcept -> CheckedValue requires(meta::IsArithmetic); - constexpr auto operator/(meta::PlainIs auto&& other) const noexcept - -> CheckedValue + constexpr auto operator/(meta::PlainIs auto&& other) const noexcept -> CheckedValue requires(meta::IsArithmetic); constexpr auto operator/=(meta::PlainIs auto&& other) noexcept -> CheckedValue& requires(meta::IsArithmetic); - constexpr auto operator/=(meta::PlainIs auto&& other) noexcept - -> CheckedValue& + constexpr auto operator/=(meta::PlainIs auto&& other) noexcept -> CheckedValue& requires(meta::IsArithmetic); T value; @@ -125,27 +111,22 @@ export namespace stormkit { inline namespace core { template requires(meta::IsCheckedValueArithmetic) - constexpr auto operator+(meta::IsCheckedValueValueType auto&& first, T&& second) noexcept - -> meta::ToPlainType; + constexpr auto operator+(meta::IsCheckedValueValueType auto&& first, T&& second) noexcept -> meta::ToPlainType; template requires(meta::IsCheckedValueArithmetic) - constexpr auto operator-(meta::IsCheckedValueValueType auto&& first, T&& second) noexcept - -> meta::ToPlainType; + constexpr auto operator-(meta::IsCheckedValueValueType auto&& first, T&& second) noexcept -> meta::ToPlainType; template requires(meta::IsCheckedValueArithmetic) - constexpr auto operator*(meta::IsCheckedValueValueType auto&& first, T&& second) noexcept - -> meta::ToPlainType; + constexpr auto operator*(meta::IsCheckedValueValueType auto&& first, T&& second) noexcept -> meta::ToPlainType; template requires(meta::IsCheckedValueArithmetic) - constexpr auto operator/(meta::IsCheckedValueValueType auto&& first, T&& second) noexcept - -> meta::ToPlainType; + constexpr auto operator/(meta::IsCheckedValueValueType auto&& first, T&& second) noexcept -> meta::ToPlainType; template - constexpr auto format_as(const CheckedValue& val, FormatContext& ctx) - -> decltype(ctx.out()); + constexpr auto format_as(const CheckedValue& val, FormatContext& ctx) -> decltype(ctx.out()); }} // namespace stormkit::core //////////////////////////////////////////////////////////////////// @@ -186,8 +167,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto CheckedValue::operator+(meta::PlainIs auto&& other) - const noexcept -> CheckedValue + constexpr auto CheckedValue::operator+(meta::PlainIs auto&& other) const noexcept -> CheckedValue requires(meta::IsArithmetic) { return { value + std::forward(other) }; @@ -197,8 +177,8 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto CheckedValue::operator+(meta::PlainIs auto&& - other) const noexcept -> CheckedValue + constexpr auto CheckedValue::operator+(meta::PlainIs auto&& other) const noexcept + -> CheckedValue requires(meta::IsArithmetic) { return operator+(std::forward_like(other.value)); @@ -208,8 +188,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto CheckedValue::operator+=(meta::PlainIs auto&& - other) noexcept -> CheckedValue& + constexpr auto CheckedValue::operator+=(meta::PlainIs auto&& other) noexcept -> CheckedValue& requires(meta::IsArithmetic) { value += std::forward(other); @@ -220,8 +199,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto CheckedValue::operator+=(meta::PlainIs auto&& - other) noexcept -> CheckedValue& + constexpr auto CheckedValue::operator+=(meta::PlainIs auto&& other) noexcept -> CheckedValue& requires(meta::IsArithmetic) { return operator+=(std::forward_like(other.value)); @@ -231,8 +209,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto CheckedValue::operator-(meta::PlainIs auto&& other) - const noexcept -> CheckedValue + constexpr auto CheckedValue::operator-(meta::PlainIs auto&& other) const noexcept -> CheckedValue requires(meta::IsArithmetic) { return { value - std::forward(other) }; @@ -242,8 +219,8 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto CheckedValue::operator-(meta::PlainIs auto&& - other) const noexcept -> CheckedValue + constexpr auto CheckedValue::operator-(meta::PlainIs auto&& other) const noexcept + -> CheckedValue requires(meta::IsArithmetic) { return operator-(std::forward_like(other.value)); @@ -253,8 +230,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto CheckedValue::operator-=(meta::PlainIs auto&& - other) noexcept -> CheckedValue& + constexpr auto CheckedValue::operator-=(meta::PlainIs auto&& other) noexcept -> CheckedValue& requires(meta::IsArithmetic) { value -= std::forward(other); @@ -265,8 +241,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto CheckedValue::operator-=(meta::PlainIs auto&& - other) noexcept -> CheckedValue& + constexpr auto CheckedValue::operator-=(meta::PlainIs auto&& other) noexcept -> CheckedValue& requires(meta::IsArithmetic) { return operator-=(std::forward_like(other.value)); @@ -276,8 +251,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto CheckedValue::operator*(meta::PlainIs auto&& other) - const noexcept -> CheckedValue + constexpr auto CheckedValue::operator*(meta::PlainIs auto&& other) const noexcept -> CheckedValue requires(meta::IsArithmetic) { return { value * std::forward(other) }; @@ -287,8 +261,8 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto CheckedValue::operator*(meta::PlainIs auto&& - other) const noexcept -> CheckedValue + constexpr auto CheckedValue::operator*(meta::PlainIs auto&& other) const noexcept + -> CheckedValue requires(meta::IsArithmetic) { return operator*(std::forward_like(other.value)); @@ -298,8 +272,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto CheckedValue::operator*=(meta::PlainIs auto&& - other) noexcept -> CheckedValue& + constexpr auto CheckedValue::operator*=(meta::PlainIs auto&& other) noexcept -> CheckedValue& requires(meta::IsArithmetic) { value *= std::forward(other); @@ -310,8 +283,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto CheckedValue::operator*=(meta::PlainIs auto&& - other) noexcept -> CheckedValue& + constexpr auto CheckedValue::operator*=(meta::PlainIs auto&& other) noexcept -> CheckedValue& requires(meta::IsArithmetic) { return operator*=(std::forward_like(other.value)); @@ -321,8 +293,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto CheckedValue::operator/(meta::PlainIs auto&& other) - const noexcept -> CheckedValue + constexpr auto CheckedValue::operator/(meta::PlainIs auto&& other) const noexcept -> CheckedValue requires(meta::IsArithmetic) { return { value / std::forward(other) }; @@ -332,8 +303,8 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto CheckedValue::operator/(meta::PlainIs auto&& - other) const noexcept -> CheckedValue + constexpr auto CheckedValue::operator/(meta::PlainIs auto&& other) const noexcept + -> CheckedValue requires(meta::IsArithmetic) { return operator/(std::forward_like(other.value)); @@ -343,8 +314,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto CheckedValue::operator/=(meta::PlainIs auto&& - other) noexcept -> CheckedValue& + constexpr auto CheckedValue::operator/=(meta::PlainIs auto&& other) noexcept -> CheckedValue& requires(meta::IsArithmetic) { value /= std::forward(other); @@ -355,8 +325,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto CheckedValue::operator/=(meta::PlainIs auto&& - other) noexcept -> CheckedValue& + constexpr auto CheckedValue::operator/=(meta::PlainIs auto&& other) noexcept -> CheckedValue& requires(meta::IsArithmetic) { return operator/=(std::forward_like(other.value)); @@ -367,8 +336,7 @@ namespace stormkit { inline namespace core { template requires(meta::IsCheckedValueArithmetic) STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto operator+(meta::IsCheckedValueValueType auto&& first, T&& second) noexcept - -> meta::ToPlainType { + constexpr auto operator+(meta::IsCheckedValueValueType auto&& first, T&& second) noexcept -> meta::ToPlainType { return std::forward(second).operator+(std::forward(first)); } @@ -377,8 +345,7 @@ namespace stormkit { inline namespace core { template requires(meta::IsCheckedValueArithmetic) STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto operator-(meta::IsCheckedValueValueType auto&& first, T&& second) noexcept - -> meta::ToPlainType { + constexpr auto operator-(meta::IsCheckedValueValueType auto&& first, T&& second) noexcept -> meta::ToPlainType { return std::forward(second).operator-(std::forward(first)); } @@ -387,8 +354,7 @@ namespace stormkit { inline namespace core { template requires(meta::IsCheckedValueArithmetic) STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto operator*(meta::IsCheckedValueValueType auto&& first, T&& second) noexcept - -> meta::ToPlainType { + constexpr auto operator*(meta::IsCheckedValueValueType auto&& first, T&& second) noexcept -> meta::ToPlainType { return std::forward(second).operator*(std::forward(first)); } @@ -397,8 +363,7 @@ namespace stormkit { inline namespace core { template requires(meta::IsCheckedValueArithmetic) STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto operator/(meta::IsCheckedValueValueType auto&& first, T&& second) noexcept - -> meta::ToPlainType { + constexpr auto operator/(meta::IsCheckedValueValueType auto&& first, T&& second) noexcept -> meta::ToPlainType { return std::forward(second).operator/(std::forward(first)); } @@ -406,8 +371,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto format_as(const CheckedValue& val, FormatContext& ctx) - -> decltype(ctx.out()) { + constexpr auto format_as(const CheckedValue& val, FormatContext& ctx) -> decltype(ctx.out()) { auto&& out = ctx.out(); return std::format_to(out, "{}", val.value); } diff --git a/modules/stormkit/core/typesafe/flags.mpp b/modules/stormkit/core/typesafe/flags.mpp index f0269c1a0..7813581c0 100644 --- a/modules/stormkit/core/typesafe/flags.mpp +++ b/modules/stormkit/core/typesafe/flags.mpp @@ -33,8 +33,7 @@ export { namespace meta { template - concept IsFlag = (IsScopedEnumeration> - and core::details::BITMASK_OPERATORS_ENABLED) + concept IsFlag = (IsScopedEnumeration> and core::details::BITMASK_OPERATORS_ENABLED) or IsPlainEnumeration>; } @@ -52,20 +51,14 @@ export { constexpr auto next_value(const T& value) noexcept -> T; template - consteval auto generate_substitutions_as_string_for(std::string_view prefix, - const std::array< - std::pair, - N>& mapping, - char separator = '|') noexcept - -> decltype(auto); + consteval auto generate_substitutions_as_string_for(std::string_view prefix, + const std::array, N>& mapping, + char separator = '|') noexcept -> decltype(auto); template - consteval auto generate_substitutions_as_string_for(std::string_view prefix, - const std::array< - std::pair, - N>& mapping, - char separator = '|') noexcept - -> decltype(auto); + consteval auto generate_substitutions_as_string_for(std::string_view prefix, + const std::array, N>& mapping, + char separator = '|') noexcept -> decltype(auto); }} // namespace stormkit::core template @@ -119,10 +112,8 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - consteval auto generate_substitutions_as_string_for(std::string_view prefix, - const std::array< - std::pair, - N>& mapping, + consteval auto generate_substitutions_as_string_for(std::string_view prefix, + const std::array, N>& mapping, char separator) noexcept -> decltype(auto) { constexpr auto OUT_SIZE = [] { auto res = 0uz; @@ -130,11 +121,9 @@ namespace stormkit { inline namespace core { constexpr auto n_fact = math::factoriel(N); if constexpr (static_cast(DEFAULT_VALUE) == 0) - for (auto R = 0uz; R < (N - 1); ++R) - res += n_fact / (math::factoriel(N - R) * math::factoriel(R)); + for (auto R = 0uz; R < (N - 1); ++R) res += n_fact / (math::factoriel(N - R) * math::factoriel(R)); else - for (auto R = 0uz; R < N; ++R) - res += n_fact / (math::factoriel(N - R) * math::factoriel(R)); + for (auto R = 0uz; R < N; ++R) res += n_fact / (math::factoriel(N - R) * math::factoriel(R)); return res + 1; }(); @@ -165,8 +154,7 @@ namespace stormkit { inline namespace core { } if (key != DEFAULT_VALUE) { for (const auto& [k, v] : mapping) { - const auto has_key = stdr::any_of(queue, - ([_k = k | key](auto&& tuple) noexcept { + const auto has_key = stdr::any_of(queue, ([_k = k | key](auto&& tuple) noexcept { const auto& [_key, _, _] = tuple; return _key == _k; })); @@ -191,17 +179,14 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - consteval auto generate_substitutions_as_string_for(std::string_view prefix, - const std::array< - std::pair, - N>& mapping, + consteval auto generate_substitutions_as_string_for(std::string_view prefix, + const std::array, N>& mapping, char separator) noexcept -> decltype(auto) { constexpr auto OUT_SIZE = [] { auto res = 0uz; constexpr auto n_fact = math::factoriel(N); - for (auto R = 0uz; R < N; ++R) - res += n_fact / (math::factoriel(N - R) * math::factoriel(R)); + for (auto R = 0uz; R < N; ++R) res += n_fact / (math::factoriel(N - R) * math::factoriel(R)); return res; }(); @@ -236,11 +221,7 @@ namespace stormkit { inline namespace core { return _key == _k; }); - if (not has_key) - queue.emplace(stdr::begin(queue), - key | k, - string + " " + separator + " " + v, - false); + if (not has_key) queue.emplace(stdr::begin(queue), key | k, string + " " + separator + " " + v, false); } queue.pop_back(); } diff --git a/modules/stormkit/core/typesafe/float.mpp b/modules/stormkit/core/typesafe/float.mpp index b221f5a7f..7260a6842 100644 --- a/modules/stormkit/core/typesafe/float.mpp +++ b/modules/stormkit/core/typesafe/float.mpp @@ -6,9 +6,7 @@ module; #include -#if not defined(__STDCPP_FLOAT32_T__) \ - or not defined(__STDCPP_FLOAT64_T__) \ - or not defined(__STDCPP_FLOAT128_T__) +#if not defined(__STDCPP_FLOAT32_T__) or not defined(__STDCPP_FLOAT64_T__) or not defined(__STDCPP_FLOAT128_T__) #ifdef STORMKIT_GLIBC #include #endif diff --git a/modules/stormkit/core/typesafe/ref.mpp b/modules/stormkit/core/typesafe/ref.mpp index b3512d0e5..8427c0758 100644 --- a/modules/stormkit/core/typesafe/ref.mpp +++ b/modules/stormkit/core/typesafe/ref.mpp @@ -89,10 +89,9 @@ export { constexpr auto operator>=(std::nullptr_t) const noexcept -> bool; [[nodiscard]] constexpr auto operator<=>(std::nullptr_t) const noexcept - -> std::compare_three_way_result_t::PointerType, - typename Ref::PointerType> - requires std::three_way_comparable::PointerType, - typename Ref::PointerType>; + -> std::compare_three_way_result_t::PointerType, typename Ref::PointerType> + requires std::three_way_comparable::PointerType, typename Ref::PointerType> + ; [[nodiscard]] constexpr auto operator==(std::nullopt_t) const noexcept -> bool @@ -111,10 +110,8 @@ export { requires(Optional == true); [[nodiscard]] constexpr auto operator<=>(std::nullopt_t) const noexcept - -> std::compare_three_way_result_t::PointerType, - typename Ref::PointerType> - requires(std::three_way_comparable::PointerType, - typename Ref::PointerType> + -> std::compare_three_way_result_t::PointerType, typename Ref::PointerType> + requires(std::three_way_comparable::PointerType, typename Ref::PointerType> and Optional == true); template @@ -137,8 +134,7 @@ export { typename Ref::PointerType> [[nodiscard]] constexpr auto operator<=>(const Ref& other) const noexcept - -> std::compare_three_way_result_t::PointerType, - typename Ref::PointerType>; + -> std::compare_three_way_result_t::PointerType, typename Ref::PointerType>; [[nodiscard]] constexpr operator std::reference_wrapper() const noexcept; @@ -336,7 +332,8 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr Ref::~Ref() noexcept = default; + constexpr Ref::~Ref() noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// @@ -363,8 +360,7 @@ namespace stormkit { inline namespace core { template template U, bool OptionalU> requires(not(meta::IsConst and not meta::IsConst)) - constexpr auto Ref::operator=(Ref&& other) noexcept - -> decltype(auto) { + constexpr auto Ref::operator=(Ref&& other) noexcept -> decltype(auto) { if constexpr (meta::IsStrict) if (&other == this) return *this; @@ -477,14 +473,11 @@ namespace stormkit { inline namespace core { template STORMKIT_FORCE_INLINE constexpr auto Ref::operator<=>(std::nullptr_t) const noexcept - -> std::compare_three_way_result_t::PointerType, - typename Ref::PointerType> - requires std::three_way_comparable::PointerType, - typename Ref::PointerType> + -> std::compare_three_way_result_t::PointerType, typename Ref::PointerType> + requires std::three_way_comparable::PointerType, typename Ref::PointerType> { - return std::compare_three_way {}(m_value, - static_cast::pointer>(nullptr)); + return std::compare_three_way {}(m_value, static_cast::pointer>(nullptr)); } ///////////////////////////////////// @@ -492,8 +485,7 @@ namespace stormkit { inline namespace core { template template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator==(const Ref& other) const noexcept - -> bool { + constexpr auto Ref::operator==(const Ref& other) const noexcept -> bool { return m_value == other.value(); } @@ -502,11 +494,9 @@ namespace stormkit { inline namespace core { template template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator<(const Ref& other) const noexcept - -> bool { + constexpr auto Ref::operator<(const Ref& other) const noexcept -> bool { return std::less< - std::common_type_t::PointerType, - typename Ref::PointerType>> {}(m_value, other.m_value); + std::common_type_t::PointerType, typename Ref::PointerType>> {}(m_value, other.m_value); } ///////////////////////////////////// @@ -514,8 +504,7 @@ namespace stormkit { inline namespace core { template template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator<=(const Ref& other) const noexcept - -> bool { + constexpr auto Ref::operator<=(const Ref& other) const noexcept -> bool { return !(other < *this); } @@ -524,8 +513,7 @@ namespace stormkit { inline namespace core { template template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator>(const Ref& other) const noexcept - -> bool { + constexpr auto Ref::operator>(const Ref& other) const noexcept -> bool { return other < *this; } @@ -534,8 +522,7 @@ namespace stormkit { inline namespace core { template template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator>=(const Ref& other) const noexcept - -> bool { + constexpr auto Ref::operator>=(const Ref& other) const noexcept -> bool { return !(*this < other); } @@ -543,12 +530,10 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template template - requires std::three_way_comparable::PointerType, - typename Ref::PointerType> + requires std::three_way_comparable::PointerType, typename Ref::PointerType> STORMKIT_FORCE_INLINE constexpr auto Ref::operator<=>(const Ref& other) const noexcept - -> std::compare_three_way_result_t::PointerType, - typename Ref::PointerType> { + -> std::compare_three_way_result_t::PointerType, typename Ref::PointerType> { return m_value <=> other.m_value; } @@ -693,7 +678,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template typename Out = std::array, typename... Args> + template typename Out, typename... Args> requires(not std::ranges::range and ...) STORMKIT_FORCE_INLINE constexpr auto as_refs(Args&&... args) noexcept -> decltype(auto) { @@ -711,7 +696,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template typename Out = std::array, typename... Args> + template typename Out, typename... Args> requires(not std::ranges::range and ...) STORMKIT_FORCE_INLINE constexpr auto as_ref_muts(Args&&... args) noexcept -> decltype(auto) { @@ -729,7 +714,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template class Out = std::vector, std::ranges::range T> + template class Out, std::ranges::range T> requires(std::ranges::range>) STORMKIT_FORCE_INLINE constexpr auto to_refs(const T& range) noexcept -> decltype(auto) { @@ -742,7 +727,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template class Out = std::vector, std::ranges::range T> + template class Out, std::ranges::range T> requires(std::ranges::range>) STORMKIT_FORCE_INLINE constexpr auto to_mut_refs(T& range) noexcept -> decltype(auto) { @@ -755,7 +740,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template typename Out = std::array, typename... Args> + template typename Out, typename... Args> requires(not std::ranges::range and ...) STORMKIT_FORCE_INLINE constexpr auto as_opt_refs(Args&&... args) noexcept -> decltype(auto) { @@ -773,7 +758,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template typename Out = std::array, typename... Args> + template typename Out, typename... Args> requires(not std::ranges::range and ...) STORMKIT_FORCE_INLINE constexpr auto as_opt_ref_muts(Args&&... args) noexcept -> decltype(auto) { @@ -791,7 +776,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template class Out = std::vector, std::ranges::range T> + template class Out, std::ranges::range T> requires(std::ranges::range>) STORMKIT_FORCE_INLINE constexpr auto to_opt_refs(const T& range) noexcept -> decltype(auto) { @@ -804,7 +789,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template class Out = std::vector, std::ranges::range T> + template class Out, std::ranges::range T> requires(std::ranges::range>) STORMKIT_FORCE_INLINE constexpr auto to_mut_opt_refs(T& range) noexcept -> decltype(auto) { diff --git a/modules/stormkit/core/typesafe/safecasts.mpp b/modules/stormkit/core/typesafe/safecasts.mpp index 51c02926e..3d3fe2bb5 100644 --- a/modules/stormkit/core/typesafe/safecasts.mpp +++ b/modules/stormkit/core/typesafe/safecasts.mpp @@ -22,7 +22,8 @@ export { namespace stormkit { inline namespace core { template [[nodiscard]] - constexpr auto is_equal_impl(Args...) noexcept -> bool = delete + constexpr auto is_equal_impl(Args...) noexcept -> bool + = delete #if defined(STORMKIT_COMPILER_MSVC) ; #else @@ -31,7 +32,8 @@ export { template [[nodiscard]] - constexpr auto is_impl(Args...) noexcept -> bool = delete + constexpr auto is_impl(Args...) noexcept -> bool + = delete #if defined(STORMKIT_COMPILER_MSVC) ; #else @@ -40,7 +42,8 @@ export { template [[nodiscard]] - constexpr auto as_impl(Args..., const std::source_location&) noexcept -> T = delete + constexpr auto as_impl(Args..., const std::source_location&) noexcept -> T + = delete #if defined(STORMKIT_COMPILER_MSVC) ; #else @@ -49,7 +52,8 @@ export { template [[nodiscard]] - constexpr auto narrow_impl(Args...) noexcept -> T = delete + constexpr auto narrow_impl(Args...) noexcept -> T + = delete #if defined(STORMKIT_COMPILER_MSVC) ; #else @@ -109,9 +113,8 @@ export { struct AsFn final { template [[nodiscard]] - static constexpr auto operator()(U&& value, - const std::source_location& - location = std::source_location::current()) noexcept + static constexpr auto operator()(U&& value, + const std::source_location& location = std::source_location::current()) noexcept -> decltype(auto); }; @@ -201,8 +204,7 @@ export { template requires(meta::Same) [[nodiscard]] - constexpr auto as_impl(U value, const std::source_location&) noexcept - -> meta::UnderlyingType; + constexpr auto as_impl(U value, const std::source_location&) noexcept -> meta::UnderlyingType; template requires(meta::Same, U>) @@ -235,8 +237,7 @@ export { template [[nodiscard]] - constexpr auto as_impl(U&& value, const std::source_location&) noexcept - -> meta::ForwardLike; + constexpr auto as_impl(U&& value, const std::source_location&) noexcept -> meta::ForwardLike; }} // namespace stormkit::core } @@ -248,16 +249,13 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - requires((meta::IsArithmetic or meta::IsByte) - and (meta::IsArithmetic or meta::IsByte)) + requires((meta::IsArithmetic or meta::IsByte) and (meta::IsArithmetic or meta::IsByte)) constexpr auto isSafeNarrowing(const From& from) noexcept -> Boolean { - if constexpr ((meta::IsArithmetic and meta::IsByte) - or (meta::IsByte and meta::IsArithmetic)) + if constexpr ((meta::IsArithmetic and meta::IsByte) or (meta::IsByte and meta::IsArithmetic)) return (static_cast(static_cast(from)) == from); else if constexpr (meta::IsArithmetic and meta::IsArithmetic) return (static_cast(static_cast(from)) == from) - or (meta::IsSigned != meta::IsUnsigned - and ((static_cast(from) < To {}) == (from < From {}))); + or (meta::IsSigned != meta::IsUnsigned and ((static_cast(from) < To {}) == (from < From {}))); std::unreachable(); } @@ -291,8 +289,7 @@ namespace stormkit { inline namespace core { template template STORMKIT_FORCE_INLINE - constexpr auto AsFn::operator()(U&& value, const std::source_location& location) noexcept - -> decltype(auto) { + constexpr auto AsFn::operator()(U&& value, const std::source_location& location) noexcept -> decltype(auto) { return as_impl(std::forward(value), location); } @@ -375,8 +372,7 @@ namespace stormkit { inline namespace core { template T, meta::ConvertibleTo U> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto is_equal_impl(T&& first, U&& second) noexcept -> bool { - return std::string_view { std::forward(first) } - == std::string_view { std::forward(second) }; + return std::string_view { std::forward(first) } == std::string_view { std::forward(second) }; } ///////////////////////////////////// @@ -465,8 +461,7 @@ namespace stormkit { inline namespace core { template requires(meta::Same) STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto as_impl(U value, const std::source_location&) noexcept - -> meta::UnderlyingType { + constexpr auto as_impl(U value, const std::source_location&) noexcept -> meta::UnderlyingType { // TODO WHEN REFLEXION IS IMPLEMENTED, CHECK IF `value` IS A VALID ENUMERATION VALUE return as>(value); } @@ -529,8 +524,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto as_impl(U&& value, const std::source_location&) noexcept - -> meta::ForwardLike { + constexpr auto as_impl(U&& value, const std::source_location&) noexcept -> meta::ForwardLike { return std::forward_like(std::get(value)); } @@ -539,12 +533,9 @@ namespace stormkit { inline namespace core { #define STORMKIT_API #endif -#define IS_EQUAL_INSTANCIATE(t1, t2) \ - template STORMKIT_API auto is_equal_impl(t1, t2) noexcept -> bool; -#define IS_EQUAL_INSTANCIATE_F1(t1, t2) \ - template STORMKIT_API auto is_equal_impl(t1, t2, t1) noexcept -> bool; -#define IS_EQUAL_INSTANCIATE_F2(t1, t2) \ - template STORMKIT_API auto is_equal_impl(t1, t2, t2) noexcept -> bool +#define IS_EQUAL_INSTANCIATE(t1, t2) template STORMKIT_API auto is_equal_impl(t1, t2) noexcept -> bool; +#define IS_EQUAL_INSTANCIATE_F1(t1, t2) template STORMKIT_API auto is_equal_impl(t1, t2, t1) noexcept -> bool; +#define IS_EQUAL_INSTANCIATE_F2(t1, t2) template STORMKIT_API auto is_equal_impl(t1, t2, t2) noexcept -> bool IS_EQUAL_INSTANCIATE(u8, u8); IS_EQUAL_INSTANCIATE(u8, i8); @@ -718,10 +709,9 @@ namespace stormkit { inline namespace core { #undef IS_EQUAL_INSTANCIATE_F1 #undef IS_EQUAL_INSTANCIATE_F2 -#define AS_NARROW_INSTANCIATE(t1, t2) \ - template STORMKIT_API auto stormkit::as_impl(t2, const std::source_location&) noexcept \ - -> t1; \ - template STORMKIT_API auto stormkit::narrow_impl(t2) noexcept -> t1 +#define AS_NARROW_INSTANCIATE(t1, t2) \ + template STORMKIT_API auto as_impl(t2, const std::source_location&) noexcept -> t1; \ + template STORMKIT_API auto narrow_impl(t2) noexcept -> t1 AS_NARROW_INSTANCIATE(u8, u8); AS_NARROW_INSTANCIATE(u8, i8); diff --git a/modules/stormkit/core/typesafe/strong_type.mpp b/modules/stormkit/core/typesafe/strong_type.mpp index a36071fe8..78ea5f9d3 100644 --- a/modules/stormkit/core/typesafe/strong_type.mpp +++ b/modules/stormkit/core/typesafe/strong_type.mpp @@ -19,61 +19,49 @@ export { using Type = meta::UnderlyingType>; template - constexpr auto operator+(this Self&& self, - meta::PlainIs> auto&& other) noexcept + constexpr auto operator+(this Self&& self, meta::PlainIs> auto&& other) noexcept -> meta::ToPlainType { - return meta::ToPlainType { std::forward(self).get() - + std::forward(other) }; + return meta::ToPlainType { std::forward(self).get() + std::forward(other) }; } template - constexpr auto operator+=(this Self& self, - meta::PlainIs> auto&& other) noexcept -> Self& { + constexpr auto operator+=(this Self& self, meta::PlainIs> auto&& other) noexcept -> Self& { self.get() += std::forward(other); return self; } template - constexpr auto operator-(this Self&& self, - meta::PlainIs> auto&& other) noexcept + constexpr auto operator-(this Self&& self, meta::PlainIs> auto&& other) noexcept -> meta::ToPlainType { - return meta::ToPlainType { std::forward(self).get() - - std::forward(other) }; + return meta::ToPlainType { std::forward(self).get() - std::forward(other) }; } template - constexpr auto operator-=(this Self& self, - meta::PlainIs> auto&& other) noexcept -> Self& { + constexpr auto operator-=(this Self& self, meta::PlainIs> auto&& other) noexcept -> Self& { self.get() -= std::forward(other); return self; } template - constexpr auto operator*(this Self&& self, - meta::PlainIs> auto&& other) noexcept + constexpr auto operator*(this Self&& self, meta::PlainIs> auto&& other) noexcept -> meta::ToPlainType { - return meta::ToPlainType { std::forward(self).get() - * std::forward(other) }; + return meta::ToPlainType { std::forward(self).get() * std::forward(other) }; } template - constexpr auto operator*=(this Self& self, - meta::PlainIs> auto&& other) noexcept -> Self& { + constexpr auto operator*=(this Self& self, meta::PlainIs> auto&& other) noexcept -> Self& { self.get() *= std::forward(other); return self; } template - constexpr auto operator/(this Self&& self, - meta::PlainIs> auto&& other) noexcept + constexpr auto operator/(this Self&& self, meta::PlainIs> auto&& other) noexcept -> meta::ToPlainType { - return meta::ToPlainType { std::forward(self).get() - / std::forward(other) }; + return meta::ToPlainType { std::forward(self).get() / std::forward(other) }; } template - constexpr auto operator/=(this Self& self, - meta::PlainIs> auto&& other) noexcept -> Self& { + constexpr auto operator/=(this Self& self, meta::PlainIs> auto&& other) noexcept -> Self& { self.get() /= std::forward(other); return self; } @@ -100,34 +88,30 @@ export { template requires(meta::IsStrongType>) - constexpr auto operator+(meta::PlainIs> auto&& first, - T&& second) noexcept -> meta::ToPlainType { - return meta::ToPlainType { std::forward(second).get() - + std::forward(first) }; + constexpr auto operator+(meta::PlainIs> auto&& first, T&& second) noexcept + -> meta::ToPlainType { + return meta::ToPlainType { std::forward(second).get() + std::forward(first) }; } template requires(meta::IsStrongType>) - constexpr auto operator-(meta::PlainIs> auto&& first, - T&& second) noexcept -> meta::ToPlainType { - return meta::ToPlainType { std::forward(second).get() - - std::forward(first) }; + constexpr auto operator-(meta::PlainIs> auto&& first, T&& second) noexcept + -> meta::ToPlainType { + return meta::ToPlainType { std::forward(second).get() - std::forward(first) }; } template requires(meta::IsStrongType>) - constexpr auto operator*(meta::PlainIs> auto&& first, - T&& second) noexcept -> meta::ToPlainType { - return meta::ToPlainType { std::forward(second).get() - * std::forward(first) }; + constexpr auto operator*(meta::PlainIs> auto&& first, T&& second) noexcept + -> meta::ToPlainType { + return meta::ToPlainType { std::forward(second).get() * std::forward(first) }; } template requires(meta::IsStrongType>) - constexpr auto operator/(meta::PlainIs> auto&& first, - T&& second) noexcept -> meta::ToPlainType { - return meta::ToPlainType { std::forward(second).get() - / std::forward(first) }; + constexpr auto operator/(meta::PlainIs> auto&& first, T&& second) noexcept + -> meta::ToPlainType { + return meta::ToPlainType { std::forward(second).get() / std::forward(first) }; } template @@ -135,41 +119,31 @@ export { public: using ValueType = T; - constexpr explicit StrongType(ValueType value) noexcept(meta::IsNoexceptConstructible< - ValueType, - ValueType>); + constexpr explicit StrongType(ValueType value) noexcept(meta::IsNoexceptConstructible); template constexpr explicit(sizeof...(Args) == 1) - StrongType(std::in_place_t, - Args&&... args) noexcept(meta::IsNoexceptConstructible) + StrongType(std::in_place_t, Args&&... args) noexcept(meta::IsNoexceptConstructible) requires(meta::IsConstructible); constexpr ~StrongType() noexcept(meta::IsNoexceptDestructible); - constexpr StrongType(const StrongType&) noexcept(meta::IsNoexceptCopyConstructible< - ValueType>) + constexpr StrongType(const StrongType&) noexcept(meta::IsNoexceptCopyConstructible) requires(meta::IsCopyConstructible); - constexpr auto operator=(const StrongType&) noexcept(meta::IsNoexceptCopyAssignable< - ValueType>) -> StrongType& + constexpr auto operator=(const StrongType&) noexcept(meta::IsNoexceptCopyAssignable) -> StrongType& requires(meta::IsCopyAssignable); - constexpr StrongType(StrongType&&) noexcept(meta::IsNoexceptMoveConstructible< - ValueType>) + constexpr StrongType(StrongType&&) noexcept(meta::IsNoexceptMoveConstructible) requires(meta::IsMoveConstructible); - constexpr auto operator=(StrongType&&) noexcept(meta::IsNoexceptMoveAssignable< - ValueType>) -> StrongType& + constexpr auto operator=(StrongType&&) noexcept(meta::IsNoexceptMoveAssignable) -> StrongType& requires(meta::IsMoveAssignable); template [[nodiscard]] - constexpr explicit(not meta::HasImplicitConvertionCapability< - Capabilities...>) operator T(this Self&& self) noexcept; + constexpr explicit(not meta::HasImplicitConvertionCapability) operator T(this Self&& self) noexcept; [[nodiscard]] - constexpr explicit(not meta::HasImplicitConvertionCapability< - Capabilities...>) operator T&() & noexcept; + constexpr explicit(not meta::HasImplicitConvertionCapability) operator T&() & noexcept; [[nodiscard]] - constexpr explicit(not meta::HasImplicitConvertionCapability< - Capabilities...>) operator const T&() const & noexcept; + constexpr explicit(not meta::HasImplicitConvertionCapability) operator const T&() const & noexcept; [[nodiscard]] constexpr auto get(this auto&& self) noexcept -> decltype(auto); @@ -232,8 +206,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr StrongType:: - StrongType(ValueType value) noexcept(meta::IsNoexceptConstructible) + constexpr StrongType::StrongType(ValueType value) noexcept(meta::IsNoexceptConstructible) : m_value { value } { } @@ -243,8 +217,7 @@ namespace stormkit { inline namespace core { template STORMKIT_FORCE_INLINE constexpr StrongType:: - StrongType(std::in_place_t, - Args&&... args) noexcept(meta::IsNoexceptConstructible) + StrongType(std::in_place_t, Args&&... args) noexcept(meta::IsNoexceptConstructible) requires(meta::IsConstructible) : m_value { std::forward(args)... } { } @@ -253,15 +226,15 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr StrongType:: - ~StrongType() noexcept(meta::IsNoexceptDestructible) = default; + constexpr StrongType::~StrongType() noexcept(meta::IsNoexceptDestructible) + = default; //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr StrongType:: - StrongType(const StrongType&) noexcept(meta::IsNoexceptCopyConstructible) + constexpr StrongType::StrongType(const StrongType&) noexcept(meta::IsNoexceptCopyConstructible< + ValueType>) requires(meta::IsCopyConstructible) = default; @@ -269,9 +242,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto StrongType:: - operator=(const StrongType&) noexcept(meta::IsNoexceptCopyAssignable) - -> StrongType& + constexpr auto StrongType::operator=(const StrongType&) noexcept(meta::IsNoexceptCopyAssignable< + ValueType>) -> StrongType& requires(meta::IsCopyAssignable) = default; @@ -279,8 +251,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr StrongType:: - StrongType(StrongType&&) noexcept(meta::IsNoexceptMoveConstructible) + constexpr StrongType::StrongType(StrongType&&) noexcept(meta::IsNoexceptMoveConstructible) requires(meta::IsMoveConstructible) = default; @@ -288,8 +259,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto StrongType:: - operator=(StrongType&&) noexcept(meta::IsNoexceptMoveAssignable) -> StrongType& + constexpr auto StrongType::operator=(StrongType&&) noexcept(meta::IsNoexceptMoveAssignable< + ValueType>) -> StrongType& requires(meta::IsMoveAssignable) = default; @@ -322,8 +293,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto StrongType::get(this auto&& self) noexcept - -> decltype(auto) { + constexpr auto StrongType::get(this auto&& self) noexcept -> decltype(auto) { return std::forward_like(self.m_value); } @@ -353,8 +323,7 @@ inline auto std::hash::operator()(const T& value) const noexcept -> std::uint template template STORMKIT_FORCE_INLINE -auto std::formatter::format(const T& data, FormatContext& ctx) const noexcept - -> decltype(ctx.out()) { +auto std::formatter::format(const T& data, FormatContext& ctx) const noexcept -> decltype(ctx.out()) { auto&& out = ctx.out(); return std::format_to(out, "{}", data.get()); } diff --git a/modules/stormkit/core/utils/algorithms.mpp b/modules/stormkit/core/utils/algorithms.mpp index 572842982..135a81cf8 100644 --- a/modules/stormkit/core/utils/algorithms.mpp +++ b/modules/stormkit/core/utils/algorithms.mpp @@ -9,13 +9,11 @@ import std; import :meta; export namespace stormkit { inline namespace core { - template::value_type> Predicate> + template::value_type> Predicate> [[nodiscard]] constexpr auto copy_if(Range&& input, Predicate&& predicate) noexcept; - template::value_type&> Lambda> + template::value_type&> Lambda> [[nodiscard]] constexpr auto transform(Range&& input, Lambda&& lambda) noexcept; @@ -25,16 +23,11 @@ export namespace stormkit { inline namespace core { [[nodiscard]] constexpr auto transform_if(Range&& input, Predicate&& predicate, Lambda&& lambda) noexcept; - template< - std::ranges::input_range Range, - meta::IsUnaryPredicate::value_type> Predicate, - std::invocable::value_type&> Lambda, - std::output_iterator< - std::invoke_result_t::value_type&>> - Iterator> - constexpr auto - transform_if(Range&& input, Iterator&& it, Predicate&& predicate, Lambda&& lambda) noexcept - -> void; + template::value_type> Predicate, + std::invocable::value_type&> Lambda, + std::output_iterator::value_type&>> Iterator> + constexpr auto transform_if(Range&& input, Iterator&& it, Predicate&& predicate, Lambda&& lambda) noexcept -> void; }} // namespace stormkit::core //////////////////////////////////////////////////////////////////// @@ -44,8 +37,7 @@ export namespace stormkit { inline namespace core { namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template::value_type> Predicate> + template::value_type> Predicate> constexpr auto copy_if(Range&& input, Predicate&& predicate) noexcept { auto output = std::vector::value_type> {}; @@ -59,12 +51,10 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template::value_type&> Lambda> + template::value_type&> Lambda> constexpr auto transform(Range&& input, Lambda&& lambda) noexcept { auto output = std::vector< - std::invoke_result_t, - const typename std::remove_cvref_t::value_type&>> {}; + std::invoke_result_t, const typename std::remove_cvref_t::value_type&>> {}; output.reserve(std::size(input)); std::ranges::transform(input, std::back_inserter(output), lambda); @@ -79,8 +69,7 @@ namespace stormkit { inline namespace core { std::invocable::value_type&> Lambda> constexpr auto transform_if(Range&& input, Predicate&& predicate, Lambda&& lambda) noexcept { auto output = std::vector< - std::invoke_result_t, - const typename std::remove_cvref_t::value_type&>> {}; + std::invoke_result_t, const typename std::remove_cvref_t::value_type&>> {}; output.reserve(std::size(input)); std::ranges::for_each(input, [&](auto& elem) { @@ -93,16 +82,11 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template< - std::ranges::input_range Range, - meta::IsUnaryPredicate::value_type> Predicate, - std::invocable::value_type&> Lambda, - std::output_iterator< - std::invoke_result_t::value_type&>> - Iterator> - constexpr auto - transform_if(Range&& input, Iterator&& it, Predicate&& predicate, Lambda&& lambda) noexcept - -> void { + template::value_type> Predicate, + std::invocable::value_type&> Lambda, + std::output_iterator::value_type&>> Iterator> + constexpr auto transform_if(Range&& input, Iterator&& it, Predicate&& predicate, Lambda&& lambda) noexcept -> void { std::ranges::for_each(input, [&](auto& elem) { if (predicate(elem)) *it++ = lambda(elem); }); diff --git a/modules/stormkit/core/utils/allocation.mpp b/modules/stormkit/core/utils/allocation.mpp index 80632bae4..f39c5c762 100644 --- a/modules/stormkit/core/utils/allocation.mpp +++ b/modules/stormkit/core/utils/allocation.mpp @@ -23,8 +23,7 @@ export namespace stormkit { inline namespace core { }; template - auto format_as(const MemoryAllocationError&, FormatContext&) noexcept - -> FormatContext::iterator; + auto format_as(const MemoryAllocationError&, FormatContext&) noexcept -> FormatContext::iterator; template using Heap = std::unique_ptr; @@ -36,16 +35,14 @@ export namespace stormkit { inline namespace core { -> std::expected, MemoryAllocationError>; template - auto allocate_unsafe(Args&&... args) noexcept(noexcept(T(std::forward(args)...))) - -> Heap; + auto allocate_unsafe(Args&&... args) noexcept(noexcept(T(std::forward(args)...))) -> Heap; template auto allocate_counted(Args&&... args) noexcept(noexcept(T(std::forward(args)...))) -> std::expected, MemoryAllocationError>; template - auto allocate_counted_unsafe(Args&&... args) noexcept(noexcept(T(std::forward(args)...))) - -> HeapCounted; + auto allocate_counted_unsafe(Args&&... args) noexcept(noexcept(T(std::forward(args)...))) -> HeapCounted; }} // namespace stormkit::core //////////////////////////////////////////////////////////////////// @@ -56,8 +53,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - auto format_as(const MemoryAllocationError& error, FormatContext& ctx) noexcept - -> FormatContext::iterator { + auto format_as(const MemoryAllocationError& error, FormatContext& ctx) noexcept -> FormatContext::iterator { auto&& out = ctx.out(); return std::format_to(out, "Failed to allocate type {} of {} byte{}", @@ -74,8 +70,7 @@ namespace stormkit { inline namespace core { -> std::expected, MemoryAllocationError> { auto value = Heap { new (std::nothrow) T(std::forward(args)...) }; if (not value) [[unlikely]] - return std::unexpected(MemoryAllocationError { .type = typeid(T).name(), - .size = sizeof(T) }); + return std::unexpected(MemoryAllocationError { .type = typeid(T).name(), .size = sizeof(T) }); return std::expected, MemoryAllocationError> { std::in_place, std::move(value) }; } @@ -83,8 +78,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - auto allocate_unsafe(Args&&... args) noexcept(noexcept(T(std::forward(args)...))) - -> Heap { + auto allocate_unsafe(Args&&... args) noexcept(noexcept(T(std::forward(args)...))) -> Heap { return Heap { new (std::nothrow) T(std::forward(args)...) }; } @@ -96,18 +90,15 @@ namespace stormkit { inline namespace core { -> std::expected, MemoryAllocationError> { auto value = HeapCounted { new (std::nothrow) T(std::forward(args)...) }; if (not value) [[unlikely]] - return std::unexpected(MemoryAllocationError { .type = typeid(T).name(), - .size = sizeof(T) }); - return std::expected, MemoryAllocationError> { std::in_place, - std::move(value) }; + return std::unexpected(MemoryAllocationError { .type = typeid(T).name(), .size = sizeof(T) }); + return std::expected, MemoryAllocationError> { std::in_place, std::move(value) }; } //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_FORCE_INLINE - auto allocate_counted_unsafe(Args&&... args) noexcept(noexcept(T(std::forward(args)...))) - -> HeapCounted { + auto allocate_counted_unsafe(Args&&... args) noexcept(noexcept(T(std::forward(args)...))) -> HeapCounted { return HeapCounted { new (std::nothrow) T(std::forward(args)...) }; } }} // namespace stormkit::core diff --git a/modules/stormkit/core/utils/color.mpp b/modules/stormkit/core/utils/color.mpp index 039774593..3494f2a2b 100644 --- a/modules/stormkit/core/utils/color.mpp +++ b/modules/stormkit/core/utils/color.mpp @@ -48,14 +48,10 @@ export namespace stormkit { inline namespace core { struct color; template - constexpr auto to_layout(const color& color) noexcept - -> stormkit::color; + constexpr auto to_layout(const color& color) noexcept -> stormkit::color; - template - constexpr auto to_storage(const color& color) noexcept - -> stormkit::color; + template + constexpr auto to_storage(const color& color) noexcept -> stormkit::color; template struct color { @@ -255,17 +251,13 @@ export namespace stormkit { inline namespace core { template inline constexpr auto YELLOW = details::ImplicitConverter { - .c = { .r = ColorComponent::max(), - .g = ColorComponent::max(), - .b = 0, - .a = ColorComponent::max() } + .c = { .r = ColorComponent::max(), .g = ColorComponent::max(), .b = 0, .a = ColorComponent::max() } }; } // namespace colors namespace RGBColorDef { template - inline constexpr auto - BLACK = RGBColor { T { 0 }, T { 0 }, T { 0 }, max_color_component_value() }; + inline constexpr auto BLACK = RGBColor { T { 0 }, T { 0 }, T { 0 }, max_color_component_value() }; template inline constexpr auto Gray = RGBColor { max_color_component_value() / T { 2 }, @@ -377,18 +369,11 @@ export namespace stormkit { inline namespace core { } // namespace RGBColorDef template - constexpr auto format_as(const RGBColor&, FormatContext& ctx) noexcept - -> decltype(ctx.out()); + constexpr auto format_as(const RGBColor&, FormatContext& ctx) noexcept -> decltype(ctx.out()); }} // namespace stormkit::core export { - TEMPLATED_HASH_EQUAL_FUNC(stormkit::core::RGBColor, - stormkit::meta::IsColorComponent, - T, - value.r, - value.g, - value.b, - value.a) + TEMPLATED_HASH_EQUAL_FUNC(stormkit::core::RGBColor, stormkit::meta::IsColorComponent, T, value.r, value.g, value.b, value.a) } //////////////////////////////////////////////////////////////////// @@ -411,8 +396,7 @@ namespace stormkit { inline namespace core { out.g = in.g; if constexpr (OutColor::COMPONENTS_COUNT > 2 and InColor::COMPONENTS_COUNT > 2) { out.b = in.b; - if constexpr (OutColor::COMPONENTS_COUNT > 3 and InColor::COMPONENTS_COUNT > 3) - out.a = in.a; + if constexpr (OutColor::COMPONENTS_COUNT > 3 and InColor::COMPONENTS_COUNT > 3) out.a = in.a; } } @@ -422,11 +406,8 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template - constexpr auto to_storage(const color& in) noexcept - -> stormkit::color { + template + constexpr auto to_storage(const color& in) noexcept -> stormkit::color { if constexpr (meta::IsStrict) return in; else { using OutColor = color; @@ -480,8 +461,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template constexpr auto as_impl(ColorComponent component) noexcept -> ColorComponent { - if constexpr (meta::IsStrict) - return ColorComponent { as(component.value) / 255.f }; + if constexpr (meta::IsStrict) return ColorComponent { as(component.value) / 255.f }; else return ColorComponent { as(component.value) * 255.f }; } @@ -497,10 +477,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - constexpr RGBColor::RGBColor(ValueType _red, - ValueType _green, - ValueType _blue, - ValueType _alpha) noexcept + constexpr RGBColor::RGBColor(ValueType _red, ValueType _green, ValueType _blue, ValueType _alpha) noexcept : red { _red }, green { _green }, blue { _blue }, alpha { _alpha } { } @@ -508,8 +485,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template constexpr RGBColor::RGBColor(const math::vec3& vector) noexcept - : red { vector.r }, green { vector.g }, blue { vector.b }, - alpha(max_color_component_value()) { + : red { vector.r }, green { vector.g }, blue { vector.b }, alpha(max_color_component_value()) { } ///////////////////////////////////// @@ -527,8 +503,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - constexpr auto RGBColor::operator=(const RGBColor& other) noexcept - -> RGBColor& = default; + constexpr auto RGBColor::operator=(const RGBColor& other) noexcept -> RGBColor& = default; ///////////////////////////////////// ///////////////////////////////////// @@ -538,16 +513,17 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - constexpr auto RGBColor::operator=(RGBColor&& other) noexcept - -> RGBColor& = default; + constexpr auto RGBColor::operator=(RGBColor&& other) noexcept -> RGBColor& = default; ///////////////////////////////////// ///////////////////////////////////// template template constexpr RGBColor::RGBColor(const RGBColor& other) noexcept - : red { color_component_as(other.red) }, green { color_component_as(other.green) }, - blue { color_component_as(other.blue) }, alpha { color_component_as(other.alpha) } { + : red { color_component_as(other.red) }, + green { color_component_as(other.green) }, + blue { color_component_as(other.blue) }, + alpha { color_component_as(other.alpha) } { } ///////////////////////////////////// @@ -600,8 +576,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto format_as(const RGBColor& color, FormatContext& ctx) noexcept - -> decltype(ctx.out()) { + constexpr auto format_as(const RGBColor& color, FormatContext& ctx) noexcept -> decltype(ctx.out()) { if constexpr (meta::Is) return std::format_to(ctx.out(), "{{red: {}, green: {}, blue: {}, alpha: {}}}", diff --git a/modules/stormkit/core/utils/contract.mpp b/modules/stormkit/core/utils/contract.mpp index 7a3cb8949..a50155259 100644 --- a/modules/stormkit/core/utils/contract.mpp +++ b/modules/stormkit/core/utils/contract.mpp @@ -32,42 +32,30 @@ export namespace stormkit { inline namespace core { constexpr auto to_string(AssertType type) noexcept -> std::string; STORMKIT_API - auto assert_base(bool cond, - AssertType type, - std::string_view message, - const std::source_location& - location = std::source_location::current()) noexcept -> void; - - consteval auto consteval_assert_base(bool cond, - AssertType type, - std::string_view message) noexcept -> void; - - constexpr auto assert(bool cond, - std::string_view message, - const std::source_location& - location = std::source_location::current()) noexcept -> void; - - constexpr auto assert(bool cond, - const std::source_location& - location = std::source_location::current()) noexcept -> void; - - constexpr auto expects(bool cond, - std::string_view message, - const std::source_location& - location = std::source_location::current()) noexcept -> void; - - constexpr auto expects(bool cond, - const std::source_location& - location = std::source_location::current()) noexcept -> void; - - constexpr auto ensures(bool cond, - std::string_view message, - const std::source_location& - location = std::source_location::current()) noexcept -> void; - - constexpr auto ensures(bool cond, - const std::source_location& - location = std::source_location::current()) noexcept -> void; + auto assert_base(bool cond, + AssertType type, + std::string_view message, + const std::source_location& location = std::source_location::current()) noexcept -> void; + + consteval auto consteval_assert_base(bool cond, AssertType type, std::string_view message) noexcept -> void; + + constexpr auto assert(bool cond, + std::string_view message, + const std::source_location& location = std::source_location::current()) noexcept -> void; + + constexpr auto assert(bool cond, const std::source_location& location = std::source_location::current()) noexcept -> void; + + constexpr auto expects(bool cond, + std::string_view message, + const std::source_location& location = std::source_location::current()) noexcept -> void; + + constexpr auto expects(bool cond, const std::source_location& location = std::source_location::current()) noexcept -> void; + + constexpr auto ensures(bool cond, + std::string_view message, + const std::source_location& location = std::source_location::current()) noexcept -> void; + + constexpr auto ensures(bool cond, const std::source_location& location = std::source_location::current()) noexcept -> void; namespace casts::core { template To> @@ -84,15 +72,14 @@ using namespace std::literals; using namespace frozen::string_literals; namespace stormkit { inline namespace core { - namespace casts::core { namespace { - constexpr auto - AssertTypeToContractName = frozen::make_unordered_map({ - { AssertType::Assertion, "Contract check"_s }, - { AssertType::PreCondition, "Pre condition check"_s }, - { AssertType::PostCondition, "Post condition check"_s }, + namespace casts::core { + constexpr auto AssertTypeToContractName = frozen::make_unordered_map({ + { AssertType::Assertion, "Contract check"_s }, + { AssertType::PreCondition, "Pre condition check"_s }, + { AssertType::PostCondition, "Post condition check"_s }, }); - }} // namespace casts::core + } // namespace casts::core struct StringLiteral { std::array buff; @@ -121,8 +108,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - consteval auto generateConstevalMessage(AssertType type, std::string_view message) noexcept - -> StringLiteral { + consteval auto generateConstevalMessage(AssertType type, std::string_view message) noexcept -> StringLiteral { auto result = StringLiteral {}; const auto str = "[Assertion]"s + to_string(type) + ": " + std::string { message }; std::ranges::copy(str, std::begin(result.buff)); @@ -133,18 +119,15 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - consteval auto consteval_assert_base(bool cond, - AssertType type, - std::string_view message) noexcept -> void { + consteval auto consteval_assert_base(bool cond, AssertType type, std::string_view message) noexcept -> void { if (not cond) [[unlikely]] { constevalFailure(generateConstevalMessage(type, message)); } } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto assert(bool cond, - std::string_view message, - [[maybe_unused]] const std::source_location& location) noexcept -> void { + constexpr auto assert(bool cond, std::string_view message, [[maybe_unused]] const std::source_location& location) noexcept + -> void { #ifdef STORMKIT_COMPILER_MSVC if constexpr (std::is_constant_evaluated()) { #else @@ -166,9 +149,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto expects(bool cond, - std::string_view message, - const std::source_location& location) noexcept -> void { + constexpr auto expects(bool cond, std::string_view message, const std::source_location& location) noexcept -> void { #ifdef STORMKIT_COMPILER_MSVC if constexpr (std::is_constant_evaluated()) { #else @@ -190,9 +171,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto ensures(bool cond, - std::string_view message, - const std::source_location& location) noexcept -> void { + constexpr auto ensures(bool cond, std::string_view message, const std::source_location& location) noexcept -> void { #ifdef STORMKIT_COMPILER_MSVC if constexpr (std::is_constant_evaluated()) { #else diff --git a/modules/stormkit/core/utils/deferinit.mpp b/modules/stormkit/core/utils/deferinit.mpp index 5a3b7de28..f8282bf9c 100644 --- a/modules/stormkit/core/utils/deferinit.mpp +++ b/modules/stormkit/core/utils/deferinit.mpp @@ -36,23 +36,17 @@ export namespace stormkit { inline namespace core { DeferInit(const DeferInit& other) = delete; auto operator=(const DeferInit& other) -> DeferInit& = delete; - constexpr DeferInit(DeferInit&& - other) noexcept(noexcept(std::is_nothrow_move_constructible_v)); - constexpr auto operator=(DeferInit&& - other) noexcept(noexcept(std::is_nothrow_move_assignable_v)) - -> DeferInit&; + constexpr DeferInit(DeferInit&& other) noexcept(noexcept(std::is_nothrow_move_constructible_v)); + constexpr auto operator=(DeferInit&& other) noexcept(noexcept(std::is_nothrow_move_assignable_v)) -> DeferInit&; template - constexpr auto construct(Args&&... args) noexcept(noexcept(std::is_nothrow_constructible_v< - T, - Args...>)) -> void; + constexpr auto construct(Args&&... args) noexcept(noexcept(std::is_nothrow_constructible_v)) -> void; template - constexpr auto construct_with_narrowing(Args&&... args) noexcept( - noexcept(std::is_nothrow_constructible_v)) -> void; + constexpr auto construct_with_narrowing(Args&&... args) noexcept(noexcept(std::is_nothrow_constructible_v)) + -> void; - constexpr auto operator=(T&& value) noexcept(noexcept(std::is_nothrow_move_constructible_v< - T>)) -> void; + constexpr auto operator=(T&& value) noexcept(noexcept(std::is_nothrow_move_constructible_v)) -> void; constexpr auto get(this auto&& self) noexcept -> decltype(auto); constexpr auto operator->(this auto& self) noexcept -> decltype(auto); @@ -93,8 +87,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr DeferInit:: - DeferInit(DeferInit&& other) noexcept(noexcept(std::is_nothrow_move_constructible_v)) { + constexpr DeferInit::DeferInit(DeferInit&& other) noexcept(noexcept(std::is_nothrow_move_constructible_v)) { reset(); if (other.initialized()) [[likely]] { @@ -108,9 +101,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto DeferInit:: - operator=(DeferInit&& other) noexcept(noexcept(std::is_nothrow_move_assignable_v)) - -> DeferInit& { + constexpr auto DeferInit::operator=(DeferInit&& other) noexcept(noexcept(std::is_nothrow_move_assignable_v)) + -> DeferInit& { if (&other == this) [[unlikely]] return *this; @@ -130,9 +122,9 @@ namespace stormkit { inline namespace core { template template STORMKIT_FORCE_INLINE - constexpr auto DeferInit:: - construct(Args&&... args) noexcept(noexcept(std::is_nothrow_constructible_v)) - -> void { + constexpr auto DeferInit::construct(Args&&... args) noexcept(noexcept(std::is_nothrow_constructible_v)) + -> void { reset(); m_pointer = new (std::data(m_data)) T { std::forward(args)... }; @@ -143,8 +135,8 @@ namespace stormkit { inline namespace core { template template STORMKIT_FORCE_INLINE - constexpr auto DeferInit::construct_with_narrowing(Args&&... args) noexcept( - noexcept(std::is_nothrow_constructible_v)) -> void { + constexpr auto DeferInit:: + construct_with_narrowing(Args&&... args) noexcept(noexcept(std::is_nothrow_constructible_v)) -> void { reset(); m_pointer = new (std::data(m_data)) T(std::forward(args)...); @@ -154,8 +146,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto DeferInit:: - operator=(T&& value) noexcept(noexcept(std::is_nothrow_move_constructible_v)) -> void { + constexpr auto DeferInit::operator=(T&& value) noexcept(noexcept(std::is_nothrow_move_constructible_v)) + -> void { reset(); m_pointer = new (std::data(m_data)) T { std::move(value) }; diff --git a/modules/stormkit/core/utils/dynamic_loader.mpp b/modules/stormkit/core/utils/dynamic_loader.mpp index 50ccbb802..f9a176d1d 100644 --- a/modules/stormkit/core/utils/dynamic_loader.mpp +++ b/modules/stormkit/core/utils/dynamic_loader.mpp @@ -35,8 +35,7 @@ export namespace stormkit { inline namespace core { static auto load(std::filesystem::path filepath) noexcept -> Expected; [[nodiscard]] - static auto allocate_and_load(std::filesystem::path filepath) noexcept - -> Expected>; + static auto allocate_and_load(std::filesystem::path filepath) noexcept -> Expected>; template [[nodiscard]] @@ -68,21 +67,20 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - DynamicLoader::DynamicLoader() noexcept + inline DynamicLoader::DynamicLoader() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - DynamicLoader::DynamicLoader(DynamicLoader&& other) noexcept - : m_filepath { std::move(other.m_filepath) }, - m_library_handle { std::exchange(other.m_library_handle, nullptr) } { + inline DynamicLoader::DynamicLoader(DynamicLoader&& other) noexcept + : m_filepath { std::move(other.m_filepath) }, m_library_handle { std::exchange(other.m_library_handle, nullptr) } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - auto DynamicLoader::operator=(DynamicLoader&& other) noexcept -> DynamicLoader& { + inline auto DynamicLoader::operator=(DynamicLoader&& other) noexcept -> DynamicLoader& { if (&other == this) [[unlikely]] return *this; @@ -94,8 +92,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - inline auto DynamicLoader::load(std::filesystem::path filepath) noexcept - -> Expected { + inline auto DynamicLoader::load(std::filesystem::path filepath) noexcept -> Expected { auto loader = DynamicLoader {}; return loader.do_load(std::move(filepath)).transform([&]() { return std::move(loader); }); @@ -105,34 +102,31 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// inline auto DynamicLoader::allocate_and_load(std::filesystem::path filepath) noexcept -> Expected> { - return load(std::move(filepath)).transform([](auto&& loader) { - return std::make_unique(std::move(loader)); - }); + return load(std::move(filepath)) + .transform([](auto&& loader) { return std::make_unique(std::move(loader)); }); } ///////////////////////////////////// ///////////////////////////////////// template - auto DynamicLoader::func(std::string_view name) const noexcept - -> Expected> { - return c_func(name).transform([](T&& value) { - return std::function { std::forward(value) }; - }); + inline auto DynamicLoader::func(std::string_view name) const noexcept -> Expected> { + return c_func(name) + .transform([](T&& value) { return std::function { std::forward(value) }; }); } ///////////////////////////////////// ///////////////////////////////////// template - auto DynamicLoader::c_func(std::string_view name) const noexcept -> Expected { + inline auto DynamicLoader::c_func(std::string_view name) const noexcept -> Expected { EXPECTS(not std::empty(name)); - return do_get_func(name).transform([](T&& value) { - return std::bit_cast(std::forward(value)); - }); + return do_get_func(name) + .transform([](T&& value) { return std::bit_cast(std::forward(value)); }); } ///////////////////////////////////// ///////////////////////////////////// + STORMKIT_FORCE_INLINE inline auto DynamicLoader::filepath() const noexcept -> const std::filesystem::path& { return m_filepath; } diff --git a/modules/stormkit/core/utils/filesystem.mpp b/modules/stormkit/core/utils/filesystem.mpp index 0456dd258..444f5410f 100644 --- a/modules/stormkit/core/utils/filesystem.mpp +++ b/modules/stormkit/core/utils/filesystem.mpp @@ -177,7 +177,8 @@ namespace stormkit { inline namespace core { namespace io { const auto // err = _sopen_s(&ret, stdr::data(p), posix_access | text_mode, _SH_DENYNO, // win32_access); - err = _sopen_s(&ret, stdr::data(p), posix_access | text_mode, _SH_SECURE, win32_access); + err + = _sopen_s(&ret, stdr::data(p), posix_access | text_mode, _SH_SECURE, win32_access); if (err != 0) return std::unexpected { SystemError::from_errno() }; #else const auto ret = ::open(stdr::data(p), posix_access); diff --git a/modules/stormkit/core/utils/handle.mpp b/modules/stormkit/core/utils/handle.mpp index d2f81c4e8..be3232dec 100644 --- a/modules/stormkit/core/utils/handle.mpp +++ b/modules/stormkit/core/utils/handle.mpp @@ -27,7 +27,7 @@ export { [[nodiscard]] constexpr auto operator<=>(const Handle&) const noexcept -> std::strong_ordering - = default; + = default; template U> constexpr operator Handle() const noexcept; @@ -58,8 +58,7 @@ export { template struct std::hash> { [[nodiscard]] - constexpr auto operator()(stormkit::core::Handle handle) const noexcept - -> stormkit::core::hash64; + constexpr auto operator()(stormkit::core::Handle handle) const noexcept -> stormkit::core::hash64; }; } @@ -128,7 +127,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template -constexpr stormkit::core::hash64 std::hash>::operator()( - stormkit::core::Handle handle) const noexcept { +constexpr stormkit::core::hash64 std::hash>::operator()(stormkit::core::Handle handle) + const noexcept { return stormkit::core::as(handle.id); } diff --git a/modules/stormkit/core/utils/numeric_range.mpp b/modules/stormkit/core/utils/numeric_range.mpp index 88add312f..e15dde211 100644 --- a/modules/stormkit/core/utils/numeric_range.mpp +++ b/modules/stormkit/core/utils/numeric_range.mpp @@ -76,8 +76,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - auto range_implementation(T a, U b) noexcept - -> std::generator> { + auto range_implementation(T a, U b) noexcept -> std::generator> { FOR(i, a) FOR(j, b) YIELD(i, j) @@ -96,12 +95,9 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template - auto range_implementation(T a, U b, V c, W d) noexcept -> std::generator< - std::tuple> { + template + auto range_implementation(T a, U b, V c, W d) noexcept + -> std::generator> { FOR(i, a) FOR(j, b) FOR(k, c) @@ -116,12 +112,8 @@ namespace stormkit { inline namespace core { meta::IsNumericsRange V, meta::IsNumericsRange W, meta::IsNumericsRange X> - auto range_implementation(T a, U b, V c, W d, X e) noexcept - -> std::generator> { + auto range_implementation(T a, U b, V c, W d, X e) noexcept -> std::generator< + std::tuple> { FOR(i, a) FOR(j, b) FOR(k, c) @@ -138,13 +130,9 @@ namespace stormkit { inline namespace core { meta::IsNumericsRange W, meta::IsNumericsRange X, meta::IsNumericsRange Y> - auto range_implementation(T a, U b, V c, W d, X e, Y f) noexcept - -> std::generator> { + auto range_implementation(T a, U b, V c, W d, X e, Y f) noexcept -> std::generator< + std:: + tuple> { FOR(i, a) FOR(j, b) FOR(k, c) @@ -239,9 +227,7 @@ namespace stormkit { inline namespace core { return old; } - constexpr auto operator==(const Iterator& other) const noexcept { - return m_val == other.m_val; - } + constexpr auto operator==(const Iterator& other) const noexcept { return m_val == other.m_val; } constexpr auto operator==(const Sentinel& end) const noexcept -> bool { if (m_step > 0) return m_val >= end.val; @@ -249,9 +235,7 @@ namespace stormkit { inline namespace core { return m_val <= end.val; } - constexpr auto operator!=(const Iterator& other) const noexcept { - return m_val != other.m_val; - } + constexpr auto operator!=(const Iterator& other) const noexcept { return m_val != other.m_val; } constexpr auto operator*() const noexcept -> const Type& { return m_val; } @@ -260,12 +244,9 @@ namespace stormkit { inline namespace core { Type m_step; }; - constexpr explicit Range(meta::IsStrict auto&& range) - : m_range { std::forward(range) } {} + constexpr explicit Range(meta::IsStrict auto&& range) : m_range { std::forward(range) } {} - constexpr auto begin() const noexcept -> Iterator { - return { m_range.begin, m_range.step }; - } + constexpr auto begin() const noexcept -> Iterator { return { m_range.begin, m_range.step }; } constexpr auto cbegin() const noexcept -> Iterator { return begin(); } @@ -290,9 +271,7 @@ namespace stormkit { inline namespace core { STORMKIT_FORCE_INLINE constexpr auto range(const T& begin, const U& end, const V& step) noexcept -> decltype(auto) { using Type = meta::SafeNarrowHelperType, V>; - return range(NumericsRange { .begin = as(begin), - .end = as(end), - .step = as(step) }); + return range(NumericsRange { .begin = as(begin), .end = as(end), .step = as(step) }); } ///////////////////////////////////// diff --git a/modules/stormkit/core/utils/signal_handler.mpp b/modules/stormkit/core/utils/signal_handler.mpp index fcf3ee7e4..b7bd585fe 100644 --- a/modules/stormkit/core/utils/signal_handler.mpp +++ b/modules/stormkit/core/utils/signal_handler.mpp @@ -10,7 +10,8 @@ import std; import :utils.stracktrace; export namespace stormkit { inline namespace core { - STORMKIT_API auto setup_signal_handler() noexcept -> void; + STORMKIT_API + auto setup_signal_handler() noexcept -> void; }} // namespace stormkit::core //////////////////////////////////////////////////////////////////// diff --git a/modules/stormkit/core/utils/singleton.mpp b/modules/stormkit/core/utils/singleton.mpp index 9bf1307cc..d94f8076a 100644 --- a/modules/stormkit/core/utils/singleton.mpp +++ b/modules/stormkit/core/utils/singleton.mpp @@ -40,9 +40,7 @@ namespace stormkit { inline namespace core { template template auto Singleton::instance(Args&&... args) noexcept(std::is_nothrow_constructible_v) -> T& { - auto lambdas = [](Args&&... args) mutable { - m_instance = std::make_unique(std::forward(args)...); - }; + auto lambdas = [](Args&&... args) mutable { m_instance = std::make_unique(std::forward(args)...); }; std::call_once(once_flag(), lambdas, std::forward(args)...); diff --git a/modules/stormkit/core/utils/stacktrace.mpp b/modules/stormkit/core/utils/stacktrace.mpp index 04568b5df..ce6d3005f 100644 --- a/modules/stormkit/core/utils/stacktrace.mpp +++ b/modules/stormkit/core/utils/stacktrace.mpp @@ -9,5 +9,6 @@ import std; import :parallelism.threadutils; export namespace stormkit { inline namespace core { - STORMKIT_API auto print_stacktrace(int ignore_count = 0) noexcept -> void; + STORMKIT_API + auto print_stacktrace(int ignore_count = 0) noexcept -> void; }} // namespace stormkit::core diff --git a/modules/stormkit/entities.mpp b/modules/stormkit/entities.mpp index 1a06e70f1..e34427357 100644 --- a/modules/stormkit/entities.mpp +++ b/modules/stormkit/entities.mpp @@ -43,9 +43,7 @@ export namespace stormkit::entities { namespace meta { template - concept IsComponentType = core::meta::Is and requires(T&& component) { - T::TYPE; - }; + concept IsComponentType = core::meta::Is and requires(T&& component) { T::TYPE; }; template concept IsSystem = core::meta::Is; @@ -121,12 +119,10 @@ export namespace stormkit::entities { struct Predicate { #ifdef STORMKIT_COMPILER_MSVC [[nodiscard]] - auto operator()(const std::unique_ptr& s1, - const std::unique_ptr& s2) const noexcept + auto operator()(const std::unique_ptr& s1, const std::unique_ptr& s2) const noexcept #else [[nodiscard]] - static auto operator()(const std::unique_ptr& s1, - const std::unique_ptr& s2) noexcept + static auto operator()(const std::unique_ptr& s1, const std::unique_ptr& s2) noexcept #endif -> bool { return s1->priority() < s2->priority(); @@ -185,12 +181,10 @@ export namespace stormkit::entities { auto getComponent(this Self& self, Entity entity) -> core::meta::ForwardConst; template - auto components(this Self& self, Entity entity) - -> std::vector>>; + auto components(this Self& self, Entity entity) -> std::vector>>; template - auto components_of_type(this Self& self) noexcept - -> std::vector>>; + auto components_of_type(this Self& self) noexcept -> std::vector>>; template auto add_system(Args&&... args) -> T&; @@ -199,8 +193,7 @@ export namespace stormkit::entities { auto has_system() const noexcept -> bool; template - auto systems(this Self& self) noexcept - -> std::vector>>; + auto systems(this Self& self) noexcept -> std::vector>>; template auto get_system(this Self& self) noexcept -> core::meta::ForwardConst; @@ -214,8 +207,7 @@ export namespace stormkit::entities { private: using ComponentKey = u64; - static constexpr auto component_key_for(Entity e, Component::Type type) noexcept - -> ComponentKey; + static constexpr auto component_key_for(Entity e, Component::Type type) noexcept -> ComponentKey; static constexpr auto is_key_entity(Entity e, ComponentKey key) noexcept -> bool; auto purpose_to_systems(Entity e) -> void; @@ -256,17 +248,14 @@ namespace stormkit::entities { constexpr auto component_hash(std::string_view str) noexcept -> Result { return std::empty(str) ? 0xcbf29ce484222325UL - : (as(str[0]) ^ component_hash(str.substr(1, std::size(str) - 1))) - * 0x100000001b3UL; + : (as(str[0]) ^ component_hash(str.substr(1, std::size(str) - 1))) * 0x100000001b3UL; } ///////////////////////////////////// ///////////////////////////////////// constexpr auto component_hash(CZString str, usize size) noexcept -> Component::Type { - return size == 0 - ? 0xcbf29ce484222325UL - : (as(str[0]) ^ component_hash(std::string_view { str + 1, size - 1 })) - * 0x100000001b3UL; + return size == 0 ? 0xcbf29ce484222325UL + : (as(str[0]) ^ component_hash(std::string_view { str + 1, size - 1 })) * 0x100000001b3UL; } ///////////////////////////////////// @@ -366,8 +355,7 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// template - auto EntityManager::getComponent(this Self& self, Entity entity) - -> core::meta::ForwardConst { + auto EntityManager::getComponent(this Self& self, Entity entity) -> core::meta::ForwardConst { EXPECTS(self.template has_component(entity)); EXPECTS(self.has_entity(entity)); @@ -396,8 +384,7 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// template - auto EntityManager::components_of_type(this Self& self) noexcept - -> std::vector>> { + auto EntityManager::components_of_type(this Self& self) noexcept -> std::vector>> { // clang-format off return self.m_entities | stdv::filter(bind_front(&EntityManager::has_component, &self)) @@ -431,8 +418,7 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// template - auto EntityManager::systems(this Self& self) noexcept - -> std::vector>> { + auto EntityManager::systems(this Self& self) noexcept -> std::vector>> { constexpr auto as_refer = [] { if constexpr (core::meta::IsConst) return monadic::as_ref(); else @@ -461,8 +447,7 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - constexpr auto EntityManager::component_key_for(Entity e, Component::Type type) noexcept - -> ComponentKey { + constexpr auto EntityManager::component_key_for(Entity e, Component::Type type) noexcept -> ComponentKey { return (static_cast(e) << 32) | static_cast(type); } diff --git a/modules/stormkit/gpu.mpp b/modules/stormkit/gpu.mpp index 019a4b993..dd5fa1cc5 100644 --- a/modules/stormkit/gpu.mpp +++ b/modules/stormkit/gpu.mpp @@ -8,4 +8,4 @@ export module stormkit.gpu; export import stormkit.gpu.core; export import stormkit.gpu.execution; export import stormkit.gpu.resource; -export ; +export; diff --git a/modules/stormkit/gpu/core/device.mpp b/modules/stormkit/gpu/core/device.mpp index 878aafaff..18e00b7a7 100644 --- a/modules/stormkit/gpu/core/device.mpp +++ b/modules/stormkit/gpu/core/device.mpp @@ -46,11 +46,10 @@ export { static auto create(const PhysicalDevice& physical_device, const Instance& instance, - const Info& info = { true, false }) noexcept -> Expected; + const Info& info = { true, false }) noexcept -> Expected; static auto allocate(const PhysicalDevice& physical_device, const Instance& instance, - const Info& info = { true, false }) noexcept - -> Expected>; + const Info& info = { true, false }) noexcept -> Expected>; ~Device() noexcept; Device(const Device&) = delete; @@ -63,16 +62,13 @@ export { auto wait_for_fences(std::span> fences, bool wait_all = true, - const std::chrono::milliseconds& - timeout = std::chrono::milliseconds::max()) const noexcept + const std::chrono::milliseconds& timeout = std::chrono::milliseconds::max()) const noexcept -> Expected; - auto wait_for_fence(const Fence& fence, - const std::chrono::milliseconds& - timeout = std::chrono::milliseconds::max()) const noexcept + auto wait_for_fence(const Fence& fence, + const std::chrono::milliseconds& timeout = std::chrono::milliseconds::max()) const noexcept -> Expected; - auto reset_fences(std::span> fences) const noexcept - -> Expected; + auto reset_fences(std::span> fences) const noexcept -> Expected; auto reset_fence(const Fence& fence) const noexcept -> Expected; [[nodiscard]] @@ -93,8 +89,7 @@ export { template auto set_object_name(const T& object, std::string_view name) const -> Expected; - auto set_object_name(u64 object, DebugObjectType type, std::string_view name) const - -> Expected; + auto set_object_name(u64 object, DebugObjectType type, std::string_view name) const -> Expected; [[nodiscard]] auto native_handle() const noexcept -> VkDevice; @@ -119,9 +114,7 @@ export { VolkDeviceTable m_vk_device_table = zeroed(); VkRAIIHandle m_vk_handle = { [](auto) static noexcept {} }; VmaVulkanFunctions m_vma_function_table = zeroed(); - VkRAIIHandle m_vma_allocator = { [](auto handle) static noexcept { - vmaDestroyAllocator(handle); - } }; + VkRAIIHandle m_vma_allocator = { [](auto handle) static noexcept { vmaDestroyAllocator(handle); } }; }; STORMKIT_API @@ -136,8 +129,7 @@ export { template [[nodiscard]] - auto format(const gpu::Device::QueueEntry& queue, FormatContext& ctx) const noexcept - -> decltype(ctx.out()); + auto format(const gpu::Device::QueueEntry& queue, FormatContext& ctx) const noexcept -> decltype(ctx.out()); }; } @@ -163,9 +155,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::create(const PhysicalDevice& physical_device, - const Instance& instance, - const Info& info) noexcept -> Expected { + inline auto Device::create(const PhysicalDevice& physical_device, const Instance& instance, const Info& info) noexcept + -> Expected { auto device = Device { physical_device, PrivateFuncTag {} }; return device.do_init(instance, info).transform(core::monadic::consume(device)); } @@ -173,9 +164,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::allocate(const PhysicalDevice& physical_device, - const Instance& instance, - const Info& info) noexcept -> Expected> { + inline auto Device::allocate(const PhysicalDevice& physical_device, const Instance& instance, const Info& info) noexcept + -> Expected> { auto device = core::allocate_unsafe(physical_device, PrivateFuncTag {}); return device->do_init(instance, info).transform(core::monadic::consume(device)); } @@ -200,8 +190,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::wait_for_fence(const Fence& fence, - const std::chrono::milliseconds& timeout) const noexcept + inline auto Device::wait_for_fence(const Fence& fence, const std::chrono::milliseconds& timeout) const noexcept -> Expected { return wait_for_fences(as_refs(fence), true, timeout); } @@ -263,14 +252,11 @@ namespace stormkit::gpu { ///////////////////////////////////// template - inline auto Device::set_object_name(const T& object, std::string_view name) const - -> Expected { + inline auto Device::set_object_name(const T& object, std::string_view name) const -> Expected { if (not vkSetDebugUtilsObjectNameEXT) return {}; auto&& vk_object = to_vk(object); - return set_object_name(std::bit_cast(static_cast(vk_object)), - T::DEBUG_TYPE, - name); + return set_object_name(std::bit_cast(static_cast(vk_object)), T::DEBUG_TYPE, name); } ///////////////////////////////////// @@ -298,20 +284,14 @@ namespace stormkit::gpu { template template -constexpr auto std::formatter::parse(ParseContext& ctx) noexcept - -> ParseContext::iterator { +constexpr auto std::formatter::parse(ParseContext& ctx) noexcept -> ParseContext::iterator { return ctx.begin(); } template template auto std::formatter::format(const gpu::Device::QueueEntry& queue, - FormatContext& ctx) const noexcept - -> decltype(ctx.out()) { + FormatContext& ctx) const noexcept -> decltype(ctx.out()) { auto&& out = ctx.out(); - return format_to(out, - "[Device::QueueEntry: .id = {}, .count = {}, .flags = {}]", - queue.id, - queue.count, - queue.flags); + return format_to(out, "[Device::QueueEntry: .id = {}, .count = {}, .flags = {}]", queue.id, queue.count, queue.flags); } diff --git a/modules/stormkit/gpu/core/instance.mpp b/modules/stormkit/gpu/core/instance.mpp index 4e63674a8..2ac495960 100644 --- a/modules/stormkit/gpu/core/instance.mpp +++ b/modules/stormkit/gpu/core/instance.mpp @@ -31,12 +31,10 @@ export { static constexpr auto DEBUG_TYPE = DebugObjectType::INSTANCE; [[nodiscard]] - static auto create(std::string app_name = "", - bool verbose = (STORMKIT_BUILD_TYPE == "DEBUG")) noexcept + static auto create(std::string app_name = "", bool verbose = (STORMKIT_BUILD_TYPE == "DEBUG")) noexcept -> Expected; [[nodiscard]] - static auto allocate(std::string app_name = "", - bool verbose = (STORMKIT_BUILD_TYPE == "DEBUG")) noexcept + static auto allocate(std::string app_name = "", bool verbose = (STORMKIT_BUILD_TYPE == "DEBUG")) noexcept -> Expected>; ~Instance(); @@ -66,12 +64,8 @@ export { std::vector m_extensions; std::vector m_physical_devices; - VkRAIIHandle m_vk_handle = { [](auto handle) static noexcept { - vkDestroyInstance(handle, nullptr); - } }; - VkRAIIHandle m_vk_debug_utils_handle = { - [](auto) static noexcept {} - }; + VkRAIIHandle m_vk_handle = { [](auto handle) static noexcept { vkDestroyInstance(handle, nullptr); } }; + VkRAIIHandle m_vk_debug_utils_handle = { [](auto) static noexcept {} }; }; [[nodiscard]] @@ -93,11 +87,9 @@ export { [[nodiscard]] auto check_extension_support(std::string_view extension) const noexcept -> bool; [[nodiscard]] - auto check_extension_support(std::span extensions) - const noexcept -> bool; + auto check_extension_support(std::span extensions) const noexcept -> bool; [[nodiscard]] - auto check_extension_support(std::span extensions) const noexcept - -> bool; + auto check_extension_support(std::span extensions) const noexcept -> bool; [[nodiscard]] auto info() const noexcept -> const PhysicalDeviceInfo&; @@ -113,8 +105,7 @@ export { auto extensions() const noexcept -> const std::vector&; [[nodiscard]] - auto formats_properties() const noexcept - -> const std::vector>&; + auto formats_properties() const noexcept -> const std::vector>&; [[nodiscard]] auto native_handle() const noexcept -> VkPhysicalDevice; @@ -157,11 +148,9 @@ export { #endif [[nodiscard]] - static auto create_from_window(const Instance& instance, - const wsi::Window& window) noexcept -> Expected; + static auto create_from_window(const Instance& instance, const wsi::Window& window) noexcept -> Expected; [[nodiscard]] - static auto allocate_from_window(const Instance& instance, - const wsi::Window& window) noexcept + static auto allocate_from_window(const Instance& instance, const wsi::Window& window) noexcept -> Expected>; [[nodiscard]] @@ -171,8 +160,7 @@ export { private: auto do_init_offscreen(const Instance&) noexcept -> Expected; - auto do_init_from_window(const Instance&, const wsi::Window&) noexcept - -> Expected; + auto do_init_from_window(const Instance&, const wsi::Window&) noexcept -> Expected; VkInstance m_vk_instance = nullptr; VkRAIIHandle m_vk_handle = { [](auto) static noexcept {} }; @@ -190,8 +178,7 @@ export { template STORMKIT_FORCE_INLINE - auto format(const stormkit::gpu::PhysicalDevice& device, FormatContext& ctx) const - -> decltype(auto) { + auto format(const stormkit::gpu::PhysicalDevice& device, FormatContext& ctx) const -> decltype(auto) { auto&& out = ctx.out(); const auto& info = device.info(); return format_to(out, @@ -219,17 +206,14 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr Instance::Instance(std::string app_name, - bool enable_validation, - PrivateFuncTag) noexcept + constexpr Instance::Instance(std::string app_name, bool enable_validation, PrivateFuncTag) noexcept : m_app_name { std::move(app_name) }, m_validation_layers_enabled { enable_validation } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Instance::create(std::string app_name, bool enable_validation) noexcept - -> Expected { + inline auto Instance::create(std::string app_name, bool enable_validation) noexcept -> Expected { auto instance = Instance { std::move(app_name), enable_validation, PrivateFuncTag {} }; return instance.do_init().transform(core::monadic::consume(instance)); } @@ -237,23 +221,22 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Instance::allocate(std::string app_name, bool enable_validation) noexcept - -> Expected> { - auto instance = core::allocate_unsafe(std::move(app_name), - enable_validation, - PrivateFuncTag {}); + inline auto Instance::allocate(std::string app_name, bool enable_validation) noexcept -> Expected> { + auto instance = core::allocate_unsafe(std::move(app_name), enable_validation, PrivateFuncTag {}); return instance->do_init().transform(core::monadic::consume(instance)); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Instance::~Instance() = default; + inline Instance::~Instance() + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Instance::Instance(Instance&&) noexcept = default; + inline Instance::Instance(Instance&&) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// @@ -292,8 +275,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::memory_types() const noexcept - -> const std::vector& { + inline auto PhysicalDevice::memory_types() const noexcept -> const std::vector& { return m_memory_types; } @@ -336,12 +318,14 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Surface::~Surface() = default; + inline Surface::~Surface() + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Surface::Surface(Surface&&) noexcept = default; + inline Surface::Surface(Surface&&) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// @@ -369,23 +353,18 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Surface::create_from_window(const Instance& instance, - const wsi::Window& window) noexcept - -> Expected { + inline auto Surface::create_from_window(const Instance& instance, const wsi::Window& window) noexcept -> Expected { auto surface = Surface { PrivateFuncTag {} }; - return surface.do_init_from_window(instance, window) - .transform(core::monadic::consume(surface)); + return surface.do_init_from_window(instance, window).transform(core::monadic::consume(surface)); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Surface::allocate_from_window(const Instance& instance, - const wsi::Window& window) noexcept + inline auto Surface::allocate_from_window(const Instance& instance, const wsi::Window& window) noexcept -> Expected> { auto surface = core::allocate_unsafe(PrivateFuncTag {}); - return surface->do_init_from_window(instance, window) - .transform(core::monadic::consume(surface)); + return surface->do_init_from_window(instance, window).transform(core::monadic::consume(surface)); } ///////////////////////////////////// diff --git a/modules/stormkit/gpu/core/structs.mpp b/modules/stormkit/gpu/core/structs.mpp index 1cbeaaf40..369168951 100644 --- a/modules/stormkit/gpu/core/structs.mpp +++ b/modules/stormkit/gpu/core/structs.mpp @@ -305,9 +305,7 @@ export { [[nodiscard]] constexpr auto compute_mip_level(const math::Extent2& extent) noexcept -> u32; [[nodiscard]] - constexpr auto compute_uniform_buffer_offset_align(usize size, - const RenderCapabilities& - capabilities) noexcept -> usize; + constexpr auto compute_uniform_buffer_offset_align(usize size, const RenderCapabilities& capabilities) noexcept -> usize; [[nodiscard]] auto to_string(const PhysicalDeviceInfo& data) noexcept; @@ -333,9 +331,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto compute_uniform_buffer_offset_align(usize size, - const RenderCapabilities& - capabilities) noexcept -> usize { + constexpr auto compute_uniform_buffer_offset_align(usize size, const RenderCapabilities& capabilities) noexcept -> usize { const auto min_ubo_align = capabilities.limits.min_uniform_buffer_offset_alignment; if (min_ubo_align > 0) size = (size + min_ubo_align - 1) & ~(min_ubo_align - 1); diff --git a/modules/stormkit/gpu/core/sync.mpp b/modules/stormkit/gpu/core/sync.mpp index 4ff9f5b92..540c49d16 100644 --- a/modules/stormkit/gpu/core/sync.mpp +++ b/modules/stormkit/gpu/core/sync.mpp @@ -38,8 +38,7 @@ export namespace stormkit::gpu { [[nodiscard]] static auto create_signaled(const Device& device) noexcept -> Expected; [[nodiscard]] - static auto allocate(const Device& device, bool signaled = false) noexcept - -> Expected>; + static auto allocate(const Device& device, bool signaled = false) noexcept -> Expected>; [[nodiscard]] static auto allocate_signaled(const Device& device) noexcept -> Expected>; ~Fence(); @@ -51,8 +50,7 @@ export namespace stormkit::gpu { auto operator=(Fence&&) noexcept -> Fence&; [[nodiscard]] - auto wait(const std::chrono::milliseconds& wait_for = std::chrono::milliseconds::max()) - const -> Expected; + auto wait(const std::chrono::milliseconds& wait_for = std::chrono::milliseconds::max()) const -> Expected; auto reset() -> Expected; [[nodiscard]] @@ -114,8 +112,7 @@ namespace stormkit::gpu { inline Fence::Fence(const Device& device, PrivateFuncTag) noexcept : m_vk_device { device.native_handle() }, m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { [vk_device_table = *m_vk_device_table, - vk_device = m_vk_device](auto handle) noexcept { + m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { vk_device_table.vkDestroyFence(vk_device, handle, nullptr); } } { } @@ -138,8 +135,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Fence::allocate(const Device& device, bool signaled) noexcept - -> Expected> { + inline auto Fence::allocate(const Device& device, bool signaled) noexcept -> Expected> { auto fence = core::allocate_unsafe(device, PrivateFuncTag {}); return fence->do_init(signaled).transform(core::monadic::consume(fence)); } @@ -154,12 +150,14 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Fence::~Fence() = default; + inline Fence::~Fence() + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Fence::Fence(Fence&&) noexcept = default; + inline Fence::Fence(Fence&&) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// @@ -171,10 +169,7 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto Fence::status() const noexcept -> Expected { static constexpr auto POSSIBLE_RESULTS = std::array { VK_SUCCESS, VK_NOT_READY }; - return vk_call(m_vk_device_table->vkGetFenceStatus, - as_view(POSSIBLE_RESULTS), - m_vk_device, - m_vk_handle) + return vk_call(m_vk_device_table->vkGetFenceStatus, as_view(POSSIBLE_RESULTS), m_vk_device, m_vk_handle) .transform([](auto&& result) static noexcept { if (result == VK_NOT_READY) return Status::UNSIGNALED; return Status::SIGNALED; @@ -193,8 +188,7 @@ namespace stormkit::gpu { 1u, &m_vk_handle.value(), true, - std::chrono::duration_cast(wait_for) - .count()) + std::chrono::duration_cast(wait_for).count()) .transform(monadic::from_vk()) .transform_error(monadic::from_vk()); } @@ -219,17 +213,13 @@ namespace stormkit::gpu { ///////////////////////////////////// STORMKIT_FORCE_INLINE inline auto Fence::do_init(bool signaled) noexcept -> Expected { - const auto flags = (signaled) ? VkFenceCreateFlags { VK_FENCE_CREATE_SIGNALED_BIT } - : VkFenceCreateFlags {}; + const auto flags = (signaled) ? VkFenceCreateFlags { VK_FENCE_CREATE_SIGNALED_BIT } : VkFenceCreateFlags {}; const auto create_info = VkFenceCreateInfo { .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, .pNext = nullptr, .flags = flags }; - return vk_call(m_vk_device_table->vkCreateFence, - m_vk_device, - &create_info, - nullptr) + return vk_call(m_vk_device_table->vkCreateFence, m_vk_device, &create_info, nullptr) .transform(core::monadic::set(m_vk_handle)) .transform_error(monadic::from_vk()); } @@ -240,8 +230,7 @@ namespace stormkit::gpu { inline Semaphore::Semaphore(const Device& device, PrivateFuncTag) noexcept : m_vk_device { device.native_handle() }, m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { [vk_device_table = *m_vk_device_table, - vk_device = m_vk_device](auto handle) noexcept { + m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { vk_device_table.vkDestroySemaphore(vk_device, handle, nullptr); } } { } @@ -265,12 +254,14 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Semaphore::~Semaphore() = default; + inline Semaphore::~Semaphore() + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Semaphore::Semaphore(Semaphore&&) noexcept = default; + inline Semaphore::Semaphore(Semaphore&&) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// @@ -295,10 +286,7 @@ namespace stormkit::gpu { .flags = 0, }; - return vk_call(m_vk_device_table->vkCreateSemaphore, - m_vk_device, - &create_info, - nullptr) + return vk_call(m_vk_device_table->vkCreateSemaphore, m_vk_device, &create_info, nullptr) .transform(core::monadic::set(m_vk_handle)) .transform_error(monadic::from_vk()); } diff --git a/modules/stormkit/gpu/core/vulkan/enums.mpp b/modules/stormkit/gpu/core/vulkan/enums.mpp index 79348add0..fdc31b94c 100644 --- a/modules/stormkit/gpu/core/vulkan/enums.mpp +++ b/modules/stormkit/gpu/core/vulkan/enums.mpp @@ -25,8 +25,7 @@ export { namespace meta { template - concept IsVulkanEnumeration = core::meta::IsEnumeration - and details::IS_VULKAN_ENUMERATION; + concept IsVulkanEnumeration = core::meta::IsEnumeration and details::IS_VULKAN_ENUMERATION; } inline constexpr auto QUEUE_FAMILY_IGNORED = std::numeric_limits::max(); @@ -305,8 +304,7 @@ export { = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT, SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT, - SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER - = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT, + SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT, SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT, STORAGE_IMAGE = VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT, @@ -377,21 +375,19 @@ export { inline constexpr auto details::IS_VULKAN_ENUMERATION = true; enum class ImageLayout : u32 { - COLOR_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL - = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, - DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL - = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, - DEPTH_STENCIL_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - DEPTH_STENCIL_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, - GENERAL = VK_IMAGE_LAYOUT_GENERAL, - PREINITIALIZED = VK_IMAGE_LAYOUT_PREINITIALIZED, - PRESENT_SRC = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - SHADER_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - SHARED_PRESENT = VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, - TRANSFER_DST_OPTIMAL = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - TRANSFER_SRC_OPTIMAL = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - UNDEFINED = VK_IMAGE_LAYOUT_UNDEFINED, + COLOR_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, + DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, + DEPTH_STENCIL_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + DEPTH_STENCIL_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, + GENERAL = VK_IMAGE_LAYOUT_GENERAL, + PREINITIALIZED = VK_IMAGE_LAYOUT_PREINITIALIZED, + PRESENT_SRC = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + SHADER_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + SHARED_PRESENT = VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, + TRANSFER_DST_OPTIMAL = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + TRANSFER_SRC_OPTIMAL = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + UNDEFINED = VK_IMAGE_LAYOUT_UNDEFINED, }; template<> @@ -766,8 +762,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ, stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE, @@ -793,24 +788,17 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::AccessFlag - value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::AccessFlag value) noexcept -> std::string_view { switch (value) { - case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: - return "AccessFlag::COLOR_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: - return "AccessFlag::COLOR_ATTACHMENT_WRITE"; - case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ: - return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE: - return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE"; + case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: return "AccessFlag::COLOR_ATTACHMENT_WRITE"; + case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE"; case stormkit::gpu::AccessFlag::HOST_READ: return "AccessFlag::HOST_READ"; case stormkit::gpu::AccessFlag::HOST_WRITE: return "AccessFlag::HOST_WRITE"; - case stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ: - return "AccessFlag::INDIRECT_COMMAND_READ"; - case stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ: - return "AccessFlag::INPUT_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ: return "AccessFlag::INDIRECT_COMMAND_READ"; + case stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ: return "AccessFlag::INPUT_ATTACHMENT_READ"; case stormkit::gpu::AccessFlag::MEMORY_READ: return "AccessFlag::MEMORY_READ"; case stormkit::gpu::AccessFlag::MEMORY_WRITE: return "AccessFlag::MEMORY_WRITE"; case stormkit::gpu::AccessFlag::NONE: return "AccessFlag::NONE"; @@ -819,8 +807,7 @@ export { case stormkit::gpu::AccessFlag::TRANSFER_READ: return "AccessFlag::TRANSFER_READ"; case stormkit::gpu::AccessFlag::TRANSFER_WRITE: return "AccessFlag::TRANSFER_WRITE"; case stormkit::gpu::AccessFlag::UNIFORM_READ: return "AccessFlag::UNIFORM_READ"; - case stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ: - return "AccessFlag::VERTEX_ATTRIBUTE_READ"; + case stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ: return "AccessFlag::VERTEX_ATTRIBUTE_READ"; } std::unreachable(); } @@ -828,24 +815,16 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::AccessFlag - value) noexcept - -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::AccessFlag value) noexcept -> std::string { switch (value) { - case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: - return "AccessFlag::COLOR_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: - return "AccessFlag::COLOR_ATTACHMENT_WRITE"; - case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ: - return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE: - return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE"; + case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: return "AccessFlag::COLOR_ATTACHMENT_WRITE"; + case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE"; case stormkit::gpu::AccessFlag::HOST_READ: return "AccessFlag::HOST_READ"; case stormkit::gpu::AccessFlag::HOST_WRITE: return "AccessFlag::HOST_WRITE"; - case stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ: - return "AccessFlag::INDIRECT_COMMAND_READ"; - case stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ: - return "AccessFlag::INPUT_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ: return "AccessFlag::INDIRECT_COMMAND_READ"; + case stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ: return "AccessFlag::INPUT_ATTACHMENT_READ"; case stormkit::gpu::AccessFlag::MEMORY_READ: return "AccessFlag::MEMORY_READ"; case stormkit::gpu::AccessFlag::MEMORY_WRITE: return "AccessFlag::MEMORY_WRITE"; case stormkit::gpu::AccessFlag::NONE: return "AccessFlag::NONE"; @@ -854,8 +833,7 @@ export { case stormkit::gpu::AccessFlag::TRANSFER_READ: return "AccessFlag::TRANSFER_READ"; case stormkit::gpu::AccessFlag::TRANSFER_WRITE: return "AccessFlag::TRANSFER_WRITE"; case stormkit::gpu::AccessFlag::UNIFORM_READ: return "AccessFlag::UNIFORM_READ"; - case stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ: - return "AccessFlag::VERTEX_ATTRIBUTE_READ"; + case stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ: return "AccessFlag::VERTEX_ATTRIBUTE_READ"; } std::unreachable(); } @@ -864,8 +842,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate< - stormkit::gpu::AttachmentLoadOperation>() noexcept -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::AttachmentLoadOperation::CLEAR, stormkit::gpu::AttachmentLoadOperation::DONT_CARE, @@ -877,16 +854,12 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::AttachmentLoadOperation>(stormkit::gpu::AttachmentLoadOperation value) noexcept - -> std::string_view { + constexpr auto stormkit::core::as_string(stormkit::gpu::AttachmentLoadOperation + value) noexcept -> std::string_view { switch (value) { - case stormkit::gpu::AttachmentLoadOperation::CLEAR: - return "AttachmentLoadOperation::CLEAR"; - case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: - return "AttachmentLoadOperation::DONT_CARE"; - case stormkit::gpu::AttachmentLoadOperation::LOAD: - return "AttachmentLoadOperation::LOAD"; + case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; + case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; + case stormkit::gpu::AttachmentLoadOperation::LOAD: return "AttachmentLoadOperation::LOAD"; } std::unreachable(); } @@ -894,16 +867,12 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::AttachmentLoadOperation>(stormkit::gpu::AttachmentLoadOperation value) noexcept - -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentLoadOperation + value) noexcept -> std::string { switch (value) { - case stormkit::gpu::AttachmentLoadOperation::CLEAR: - return "AttachmentLoadOperation::CLEAR"; - case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: - return "AttachmentLoadOperation::DONT_CARE"; - case stormkit::gpu::AttachmentLoadOperation::LOAD: - return "AttachmentLoadOperation::LOAD"; + case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; + case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; + case stormkit::gpu::AttachmentLoadOperation::LOAD: return "AttachmentLoadOperation::LOAD"; } std::unreachable(); } @@ -912,8 +881,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate< - stormkit::gpu::AttachmentStoreOperation>() noexcept -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::AttachmentStoreOperation::DONT_CARE, stormkit::gpu::AttachmentStoreOperation::STORE, @@ -924,14 +892,11 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::AttachmentStoreOperation>(stormkit::gpu::AttachmentStoreOperation - value) noexcept -> std::string_view { + constexpr auto stormkit::core::as_string(stormkit::gpu::AttachmentStoreOperation + value) noexcept -> std::string_view { switch (value) { - case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: - return "AttachmentStoreOperation::DONT_CARE"; - case stormkit::gpu::AttachmentStoreOperation::STORE: - return "AttachmentStoreOperation::STORE"; + case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; + case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; } std::unreachable(); } @@ -939,14 +904,11 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::AttachmentStoreOperation>(stormkit::gpu::AttachmentStoreOperation - value) noexcept -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentStoreOperation + value) noexcept -> std::string { switch (value) { - case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: - return "AttachmentStoreOperation::DONT_CARE"; - case stormkit::gpu::AttachmentStoreOperation::STORE: - return "AttachmentStoreOperation::STORE"; + case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; + case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; } std::unreachable(); } @@ -955,8 +917,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::BlendFactor::CONSTANT_ALPHA, stormkit::gpu::BlendFactor::CONSTANT_COLOR, @@ -984,8 +945,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::BlendFactor - value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::BlendFactor value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::BlendFactor::CONSTANT_ALPHA: return "BlendFactor::CONSTANT_ALPHA"; @@ -993,27 +953,18 @@ export { case stormkit::gpu::BlendFactor::DST_ALPHA: return "BlendFactor::DST_ALPHA"; case stormkit::gpu::BlendFactor::DST_COLOR: return "BlendFactor::DST_COLOR"; case stormkit::gpu::BlendFactor::ONE: return "BlendFactor::ONE"; - case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: - return "BlendFactor::ONE_MINUS_CONSTANT_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR: - return "BlendFactor::ONE_MINUS_CONSTANT_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA: - return "BlendFactor::ONE_MINUS_DST_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR: - return "BlendFactor::ONE_MINUS_DST_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA: - return "BlendFactor::ONE_MINUS_SRC1_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR: - return "BlendFactor::ONE_MINUS_SRC1_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA: - return "BlendFactor::ONE_MINUS_SRC_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR: - return "BlendFactor::ONE_MINUS_SRC_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: return "BlendFactor::ONE_MINUS_CONSTANT_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR: return "BlendFactor::ONE_MINUS_CONSTANT_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA: return "BlendFactor::ONE_MINUS_DST_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR: return "BlendFactor::ONE_MINUS_DST_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA: return "BlendFactor::ONE_MINUS_SRC1_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR: return "BlendFactor::ONE_MINUS_SRC1_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA: return "BlendFactor::ONE_MINUS_SRC_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR: return "BlendFactor::ONE_MINUS_SRC_COLOR"; case stormkit::gpu::BlendFactor::SRC1_ALPHA: return "BlendFactor::SRC1_ALPHA"; case stormkit::gpu::BlendFactor::SRC1_COLOR: return "BlendFactor::SRC1_COLOR"; case stormkit::gpu::BlendFactor::SRC_ALPHA: return "BlendFactor::SRC_ALPHA"; - case stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE: - return "BlendFactor::SRC_ALPHA_SATURATE"; + case stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE: return "BlendFactor::SRC_ALPHA_SATURATE"; case stormkit::gpu::BlendFactor::SRC_COLOR: return "BlendFactor::SRC_COLOR"; case stormkit::gpu::BlendFactor::ZERO: return "BlendFactor::ZERO"; } @@ -1023,8 +974,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::BlendFactor - value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::BlendFactor value) noexcept -> std::string { switch (value) { case stormkit::gpu::BlendFactor::CONSTANT_ALPHA: return "BlendFactor::CONSTANT_ALPHA"; @@ -1032,27 +982,18 @@ export { case stormkit::gpu::BlendFactor::DST_ALPHA: return "BlendFactor::DST_ALPHA"; case stormkit::gpu::BlendFactor::DST_COLOR: return "BlendFactor::DST_COLOR"; case stormkit::gpu::BlendFactor::ONE: return "BlendFactor::ONE"; - case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: - return "BlendFactor::ONE_MINUS_CONSTANT_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR: - return "BlendFactor::ONE_MINUS_CONSTANT_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA: - return "BlendFactor::ONE_MINUS_DST_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR: - return "BlendFactor::ONE_MINUS_DST_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA: - return "BlendFactor::ONE_MINUS_SRC1_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR: - return "BlendFactor::ONE_MINUS_SRC1_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA: - return "BlendFactor::ONE_MINUS_SRC_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR: - return "BlendFactor::ONE_MINUS_SRC_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: return "BlendFactor::ONE_MINUS_CONSTANT_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR: return "BlendFactor::ONE_MINUS_CONSTANT_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA: return "BlendFactor::ONE_MINUS_DST_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR: return "BlendFactor::ONE_MINUS_DST_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA: return "BlendFactor::ONE_MINUS_SRC1_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR: return "BlendFactor::ONE_MINUS_SRC1_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA: return "BlendFactor::ONE_MINUS_SRC_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR: return "BlendFactor::ONE_MINUS_SRC_COLOR"; case stormkit::gpu::BlendFactor::SRC1_ALPHA: return "BlendFactor::SRC1_ALPHA"; case stormkit::gpu::BlendFactor::SRC1_COLOR: return "BlendFactor::SRC1_COLOR"; case stormkit::gpu::BlendFactor::SRC_ALPHA: return "BlendFactor::SRC_ALPHA"; - case stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE: - return "BlendFactor::SRC_ALPHA_SATURATE"; + case stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE: return "BlendFactor::SRC_ALPHA_SATURATE"; case stormkit::gpu::BlendFactor::SRC_COLOR: return "BlendFactor::SRC_COLOR"; case stormkit::gpu::BlendFactor::ZERO: return "BlendFactor::ZERO"; } @@ -1063,13 +1004,10 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::BlendOperation::ADD, - stormkit::gpu::BlendOperation::MAX, - stormkit::gpu::BlendOperation::MIN, - stormkit::gpu::BlendOperation::REVERSE_SUBTRACT, + stormkit::gpu::BlendOperation::ADD, stormkit::gpu::BlendOperation::MAX, + stormkit::gpu::BlendOperation::MIN, stormkit::gpu::BlendOperation::REVERSE_SUBTRACT, stormkit::gpu::BlendOperation::SUBTRACT, }; @@ -1078,15 +1016,13 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::BlendOperation>(stormkit::gpu::BlendOperation value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::BlendOperation value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::BlendOperation::ADD: return "BlendOperation::ADD"; case stormkit::gpu::BlendOperation::MAX: return "BlendOperation::MAX"; case stormkit::gpu::BlendOperation::MIN: return "BlendOperation::MIN"; - case stormkit::gpu::BlendOperation::REVERSE_SUBTRACT: - return "BlendOperation::REVERSE_SUBTRACT"; + case stormkit::gpu::BlendOperation::REVERSE_SUBTRACT: return "BlendOperation::REVERSE_SUBTRACT"; case stormkit::gpu::BlendOperation::SUBTRACT: return "BlendOperation::SUBTRACT"; } std::unreachable(); @@ -1095,14 +1031,13 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::BlendOperation>(stormkit::gpu::BlendOperation value) noexcept -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::BlendOperation value) noexcept + -> std::string { switch (value) { case stormkit::gpu::BlendOperation::ADD: return "BlendOperation::ADD"; case stormkit::gpu::BlendOperation::MAX: return "BlendOperation::MAX"; case stormkit::gpu::BlendOperation::MIN: return "BlendOperation::MIN"; - case stormkit::gpu::BlendOperation::REVERSE_SUBTRACT: - return "BlendOperation::REVERSE_SUBTRACT"; + case stormkit::gpu::BlendOperation::REVERSE_SUBTRACT: return "BlendOperation::REVERSE_SUBTRACT"; case stormkit::gpu::BlendOperation::SUBTRACT: return "BlendOperation::SUBTRACT"; } std::unreachable(); @@ -1112,15 +1047,11 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK, - stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE, - stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK, - stormkit::gpu::BorderColor::INT_OPAQUE_BLACK, - stormkit::gpu::BorderColor::INT_OPAQUE_WHITE, - stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK, + stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK, stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE, + stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK, stormkit::gpu::BorderColor::INT_OPAQUE_BLACK, + stormkit::gpu::BorderColor::INT_OPAQUE_WHITE, stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK, }; } @@ -1128,22 +1059,15 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::BorderColor - value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::BorderColor value) noexcept -> std::string_view { switch (value) { - case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: - return "BorderColor::FLOAT_OPAQUE_BLACK"; - case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: - return "BorderColor::FLOAT_OPAQUE_WHITE"; - case stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK: - return "BorderColor::FLOAT_TRANSPARENT_BLACK"; - case stormkit::gpu::BorderColor::INT_OPAQUE_BLACK: - return "BorderColor::INT_OPAQUE_BLACK"; - case stormkit::gpu::BorderColor::INT_OPAQUE_WHITE: - return "BorderColor::INT_OPAQUE_WHITE"; - case stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK: - return "BorderColor::INT_TRANSPARENT_BLACK"; + case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: return "BorderColor::FLOAT_OPAQUE_BLACK"; + case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: return "BorderColor::FLOAT_OPAQUE_WHITE"; + case stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK: return "BorderColor::FLOAT_TRANSPARENT_BLACK"; + case stormkit::gpu::BorderColor::INT_OPAQUE_BLACK: return "BorderColor::INT_OPAQUE_BLACK"; + case stormkit::gpu::BorderColor::INT_OPAQUE_WHITE: return "BorderColor::INT_OPAQUE_WHITE"; + case stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK: return "BorderColor::INT_TRANSPARENT_BLACK"; } std::unreachable(); } @@ -1151,22 +1075,15 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::BorderColor - value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::BorderColor value) noexcept -> std::string { switch (value) { - case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: - return "BorderColor::FLOAT_OPAQUE_BLACK"; - case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: - return "BorderColor::FLOAT_OPAQUE_WHITE"; - case stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK: - return "BorderColor::FLOAT_TRANSPARENT_BLACK"; - case stormkit::gpu::BorderColor::INT_OPAQUE_BLACK: - return "BorderColor::INT_OPAQUE_BLACK"; - case stormkit::gpu::BorderColor::INT_OPAQUE_WHITE: - return "BorderColor::INT_OPAQUE_WHITE"; - case stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK: - return "BorderColor::INT_TRANSPARENT_BLACK"; + case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: return "BorderColor::FLOAT_OPAQUE_BLACK"; + case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: return "BorderColor::FLOAT_OPAQUE_WHITE"; + case stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK: return "BorderColor::FLOAT_TRANSPARENT_BLACK"; + case stormkit::gpu::BorderColor::INT_OPAQUE_BLACK: return "BorderColor::INT_OPAQUE_BLACK"; + case stormkit::gpu::BorderColor::INT_OPAQUE_WHITE: return "BorderColor::INT_OPAQUE_WHITE"; + case stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK: return "BorderColor::INT_TRANSPARENT_BLACK"; } std::unreachable(); } @@ -1175,17 +1092,12 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::BufferUsageFlag::INDEX, - stormkit::gpu::BufferUsageFlag::INDIRECT, - stormkit::gpu::BufferUsageFlag::STORAGE, - stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL, - stormkit::gpu::BufferUsageFlag::TRANSFER_DST, - stormkit::gpu::BufferUsageFlag::TRANSFER_SRC, - stormkit::gpu::BufferUsageFlag::UNIFORM, - stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL, + stormkit::gpu::BufferUsageFlag::INDEX, stormkit::gpu::BufferUsageFlag::INDIRECT, + stormkit::gpu::BufferUsageFlag::STORAGE, stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL, + stormkit::gpu::BufferUsageFlag::TRANSFER_DST, stormkit::gpu::BufferUsageFlag::TRANSFER_SRC, + stormkit::gpu::BufferUsageFlag::UNIFORM, stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL, stormkit::gpu::BufferUsageFlag::VERTEX, }; @@ -1194,22 +1106,17 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::BufferUsageFlag>(stormkit::gpu::BufferUsageFlag value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::BufferUsageFlag value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::BufferUsageFlag::INDEX: return "BufferUsageFlag::INDEX"; case stormkit::gpu::BufferUsageFlag::INDIRECT: return "BufferUsageFlag::INDIRECT"; case stormkit::gpu::BufferUsageFlag::STORAGE: return "BufferUsageFlag::STORAGE"; - case stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL: - return "BufferUsageFlag::STORAGE_TEXEL"; - case stormkit::gpu::BufferUsageFlag::TRANSFER_DST: - return "BufferUsageFlag::TRANSFER_DST"; - case stormkit::gpu::BufferUsageFlag::TRANSFER_SRC: - return "BufferUsageFlag::TRANSFER_SRC"; + case stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL: return "BufferUsageFlag::STORAGE_TEXEL"; + case stormkit::gpu::BufferUsageFlag::TRANSFER_DST: return "BufferUsageFlag::TRANSFER_DST"; + case stormkit::gpu::BufferUsageFlag::TRANSFER_SRC: return "BufferUsageFlag::TRANSFER_SRC"; case stormkit::gpu::BufferUsageFlag::UNIFORM: return "BufferUsageFlag::UNIFORM"; - case stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL: - return "BufferUsageFlag::UNIFORM_TEXEL"; + case stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL: return "BufferUsageFlag::UNIFORM_TEXEL"; case stormkit::gpu::BufferUsageFlag::VERTEX: return "BufferUsageFlag::VERTEX"; } std::unreachable(); @@ -1218,22 +1125,17 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::BufferUsageFlag>(stormkit::gpu::BufferUsageFlag value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::BufferUsageFlag value) noexcept -> std::string { switch (value) { case stormkit::gpu::BufferUsageFlag::INDEX: return "BufferUsageFlag::INDEX"; case stormkit::gpu::BufferUsageFlag::INDIRECT: return "BufferUsageFlag::INDIRECT"; case stormkit::gpu::BufferUsageFlag::STORAGE: return "BufferUsageFlag::STORAGE"; - case stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL: - return "BufferUsageFlag::STORAGE_TEXEL"; - case stormkit::gpu::BufferUsageFlag::TRANSFER_DST: - return "BufferUsageFlag::TRANSFER_DST"; - case stormkit::gpu::BufferUsageFlag::TRANSFER_SRC: - return "BufferUsageFlag::TRANSFER_SRC"; + case stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL: return "BufferUsageFlag::STORAGE_TEXEL"; + case stormkit::gpu::BufferUsageFlag::TRANSFER_DST: return "BufferUsageFlag::TRANSFER_DST"; + case stormkit::gpu::BufferUsageFlag::TRANSFER_SRC: return "BufferUsageFlag::TRANSFER_SRC"; case stormkit::gpu::BufferUsageFlag::UNIFORM: return "BufferUsageFlag::UNIFORM"; - case stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL: - return "BufferUsageFlag::UNIFORM_TEXEL"; + case stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL: return "BufferUsageFlag::UNIFORM_TEXEL"; case stormkit::gpu::BufferUsageFlag::VERTEX: return "BufferUsageFlag::VERTEX"; } std::unreachable(); @@ -1243,8 +1145,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::ColorComponentFlag::A, stormkit::gpu::ColorComponentFlag::B, stormkit::gpu::ColorComponentFlag::G, stormkit::gpu::ColorComponentFlag::NONE, @@ -1257,8 +1158,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::ColorComponentFlag>(stormkit::gpu::ColorComponentFlag value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::ColorComponentFlag value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::ColorComponentFlag::A: return "ColorComponentFlag::A"; @@ -1276,8 +1176,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::ColorComponentFlag>(stormkit::gpu::ColorComponentFlag value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::ColorComponentFlag value) noexcept -> std::string { switch (value) { case stormkit::gpu::ColorComponentFlag::A: return "ColorComponentFlag::A"; @@ -1296,8 +1195,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::ColorSpace::ADOBERGB_LINEAR, stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR, @@ -1322,28 +1220,21 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ColorSpace - value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::ColorSpace value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; - case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: - return "ColorSpace::ADOBERGB_NONLINEAR"; + case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: return "ColorSpace::ADOBERGB_NONLINEAR"; case stormkit::gpu::ColorSpace::BT2020_LINEAR: return "ColorSpace::BT2020_LINEAR"; case stormkit::gpu::ColorSpace::BT709_LINEAR: return "ColorSpace::BT709_LINEAR"; case stormkit::gpu::ColorSpace::BT709_NONLINEAR: return "ColorSpace::BT709_NONLINEAR"; case stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR: return "ColorSpace::DCI_P3_NONLINEAR"; - case stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD: - return "ColorSpace::DISPLAY_NATIVE_AMD"; - case stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR: - return "ColorSpace::DISPLAY_P3_LINEAR"; - case stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR: - return "ColorSpace::DISPLAY_P3_NONLINEAR"; + case stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD: return "ColorSpace::DISPLAY_NATIVE_AMD"; + case stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR: return "ColorSpace::DISPLAY_P3_LINEAR"; + case stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR: return "ColorSpace::DISPLAY_P3_NONLINEAR"; case stormkit::gpu::ColorSpace::DOLBYVISION: return "ColorSpace::DOLBYVISION"; - case stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR: - return "ColorSpace::EXTENDED_SRGB_LINEAR"; - case stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR: - return "ColorSpace::EXTENDED_SRGB_NONLINEAR"; + case stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR: return "ColorSpace::EXTENDED_SRGB_LINEAR"; + case stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR: return "ColorSpace::EXTENDED_SRGB_NONLINEAR"; case stormkit::gpu::ColorSpace::HDR10_HLG: return "ColorSpace::HDR10_HLG"; case stormkit::gpu::ColorSpace::HDR10_ST2084: return "ColorSpace::HDR10_ST2084"; case stormkit::gpu::ColorSpace::PASS_THROUGH: return "ColorSpace::PASS_THROUGH"; @@ -1355,28 +1246,20 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ColorSpace - value) noexcept - -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::ColorSpace value) noexcept -> std::string { switch (value) { case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; - case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: - return "ColorSpace::ADOBERGB_NONLINEAR"; + case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: return "ColorSpace::ADOBERGB_NONLINEAR"; case stormkit::gpu::ColorSpace::BT2020_LINEAR: return "ColorSpace::BT2020_LINEAR"; case stormkit::gpu::ColorSpace::BT709_LINEAR: return "ColorSpace::BT709_LINEAR"; case stormkit::gpu::ColorSpace::BT709_NONLINEAR: return "ColorSpace::BT709_NONLINEAR"; case stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR: return "ColorSpace::DCI_P3_NONLINEAR"; - case stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD: - return "ColorSpace::DISPLAY_NATIVE_AMD"; - case stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR: - return "ColorSpace::DISPLAY_P3_LINEAR"; - case stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR: - return "ColorSpace::DISPLAY_P3_NONLINEAR"; + case stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD: return "ColorSpace::DISPLAY_NATIVE_AMD"; + case stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR: return "ColorSpace::DISPLAY_P3_LINEAR"; + case stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR: return "ColorSpace::DISPLAY_P3_NONLINEAR"; case stormkit::gpu::ColorSpace::DOLBYVISION: return "ColorSpace::DOLBYVISION"; - case stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR: - return "ColorSpace::EXTENDED_SRGB_LINEAR"; - case stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR: - return "ColorSpace::EXTENDED_SRGB_NONLINEAR"; + case stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR: return "ColorSpace::EXTENDED_SRGB_LINEAR"; + case stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR: return "ColorSpace::EXTENDED_SRGB_NONLINEAR"; case stormkit::gpu::ColorSpace::HDR10_HLG: return "ColorSpace::HDR10_HLG"; case stormkit::gpu::ColorSpace::HDR10_ST2084: return "ColorSpace::HDR10_ST2084"; case stormkit::gpu::ColorSpace::PASS_THROUGH: return "ColorSpace::PASS_THROUGH"; @@ -1389,8 +1272,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::CommandBufferLevel::PRIMARY, stormkit::gpu::CommandBufferLevel::SECONDARY, @@ -1401,13 +1283,11 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::CommandBufferLevel>(stormkit::gpu::CommandBufferLevel value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::CommandBufferLevel value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::CommandBufferLevel::PRIMARY: return "CommandBufferLevel::PRIMARY"; - case stormkit::gpu::CommandBufferLevel::SECONDARY: - return "CommandBufferLevel::SECONDARY"; + case stormkit::gpu::CommandBufferLevel::SECONDARY: return "CommandBufferLevel::SECONDARY"; } std::unreachable(); } @@ -1415,13 +1295,11 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::CommandBufferLevel>(stormkit::gpu::CommandBufferLevel value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::CommandBufferLevel value) noexcept -> std::string { switch (value) { case stormkit::gpu::CommandBufferLevel::PRIMARY: return "CommandBufferLevel::PRIMARY"; - case stormkit::gpu::CommandBufferLevel::SECONDARY: - return "CommandBufferLevel::SECONDARY"; + case stormkit::gpu::CommandBufferLevel::SECONDARY: return "CommandBufferLevel::SECONDARY"; } std::unreachable(); } @@ -1430,17 +1308,12 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::CompareOperation::ALWAYS, - stormkit::gpu::CompareOperation::EQUAL, - stormkit::gpu::CompareOperation::GREATER, - stormkit::gpu::CompareOperation::GREATER_OR_EQUAL, - stormkit::gpu::CompareOperation::LESS, - stormkit::gpu::CompareOperation::LESS_OR_EQUAL, - stormkit::gpu::CompareOperation::NEVER, - stormkit::gpu::CompareOperation::NOT_EQUAL, + stormkit::gpu::CompareOperation::ALWAYS, stormkit::gpu::CompareOperation::EQUAL, + stormkit::gpu::CompareOperation::GREATER, stormkit::gpu::CompareOperation::GREATER_OR_EQUAL, + stormkit::gpu::CompareOperation::LESS, stormkit::gpu::CompareOperation::LESS_OR_EQUAL, + stormkit::gpu::CompareOperation::NEVER, stormkit::gpu::CompareOperation::NOT_EQUAL, }; } @@ -1448,18 +1321,15 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::CompareOperation>(stormkit::gpu::CompareOperation value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::CompareOperation value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::CompareOperation::ALWAYS: return "CompareOperation::ALWAYS"; case stormkit::gpu::CompareOperation::EQUAL: return "CompareOperation::EQUAL"; case stormkit::gpu::CompareOperation::GREATER: return "CompareOperation::GREATER"; - case stormkit::gpu::CompareOperation::GREATER_OR_EQUAL: - return "CompareOperation::GREATER_OR_EQUAL"; + case stormkit::gpu::CompareOperation::GREATER_OR_EQUAL: return "CompareOperation::GREATER_OR_EQUAL"; case stormkit::gpu::CompareOperation::LESS: return "CompareOperation::LESS"; - case stormkit::gpu::CompareOperation::LESS_OR_EQUAL: - return "CompareOperation::LESS_OR_EQUAL"; + case stormkit::gpu::CompareOperation::LESS_OR_EQUAL: return "CompareOperation::LESS_OR_EQUAL"; case stormkit::gpu::CompareOperation::NEVER: return "CompareOperation::NEVER"; case stormkit::gpu::CompareOperation::NOT_EQUAL: return "CompareOperation::NOT_EQUAL"; } @@ -1469,18 +1339,15 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::CompareOperation>(stormkit::gpu::CompareOperation value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::CompareOperation value) noexcept -> std::string { switch (value) { case stormkit::gpu::CompareOperation::ALWAYS: return "CompareOperation::ALWAYS"; case stormkit::gpu::CompareOperation::EQUAL: return "CompareOperation::EQUAL"; case stormkit::gpu::CompareOperation::GREATER: return "CompareOperation::GREATER"; - case stormkit::gpu::CompareOperation::GREATER_OR_EQUAL: - return "CompareOperation::GREATER_OR_EQUAL"; + case stormkit::gpu::CompareOperation::GREATER_OR_EQUAL: return "CompareOperation::GREATER_OR_EQUAL"; case stormkit::gpu::CompareOperation::LESS: return "CompareOperation::LESS"; - case stormkit::gpu::CompareOperation::LESS_OR_EQUAL: - return "CompareOperation::LESS_OR_EQUAL"; + case stormkit::gpu::CompareOperation::LESS_OR_EQUAL: return "CompareOperation::LESS_OR_EQUAL"; case stormkit::gpu::CompareOperation::NEVER: return "CompareOperation::NEVER"; case stormkit::gpu::CompareOperation::NOT_EQUAL: return "CompareOperation::NOT_EQUAL"; } @@ -1491,8 +1358,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::CullModeFlag::BACK, stormkit::gpu::CullModeFlag::FRONT, @@ -1505,8 +1371,8 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::CullModeFlag>(stormkit::gpu::CullModeFlag value) noexcept -> std::string_view { + constexpr auto stormkit::core::as_string(stormkit::gpu::CullModeFlag value) noexcept + -> std::string_view { switch (value) { case stormkit::gpu::CullModeFlag::BACK: return "CullModeFlag::BACK"; case stormkit::gpu::CullModeFlag::FRONT: return "CullModeFlag::FRONT"; @@ -1519,8 +1385,8 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::CullModeFlag>(stormkit::gpu::CullModeFlag value) noexcept -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::CullModeFlag value) noexcept + -> std::string { switch (value) { case stormkit::gpu::CullModeFlag::BACK: return "CullModeFlag::BACK"; case stormkit::gpu::CullModeFlag::FRONT: return "CullModeFlag::FRONT"; @@ -1534,8 +1400,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::DebugObjectType::BUFFER, stormkit::gpu::DebugObjectType::BUFFER_VIEW, @@ -1574,27 +1439,19 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::DebugObjectType>(stormkit::gpu::DebugObjectType value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::DebugObjectType value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::DebugObjectType::BUFFER: return "DebugObjectType::BUFFER"; case stormkit::gpu::DebugObjectType::BUFFER_VIEW: return "DebugObjectType::BUFFER_VIEW"; - case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: - return "DebugObjectType::COMMAND_BUFFER"; - case stormkit::gpu::DebugObjectType::COMMAND_POOL: - return "DebugObjectType::COMMAND_POOL"; - case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: - return "DebugObjectType::DEBUG_REPORT_CALLBACK"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: - return "DebugObjectType::DESCRIPTOR_POOL"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: - return "DebugObjectType::DESCRIPTOR_SET"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: - return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; + case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: return "DebugObjectType::COMMAND_BUFFER"; + case stormkit::gpu::DebugObjectType::COMMAND_POOL: return "DebugObjectType::COMMAND_POOL"; + case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: return "DebugObjectType::DEBUG_REPORT_CALLBACK"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: return "DebugObjectType::DESCRIPTOR_POOL"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: return "DebugObjectType::DESCRIPTOR_SET"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; case stormkit::gpu::DebugObjectType::DEVICE: return "DebugObjectType::DEVICE"; - case stormkit::gpu::DebugObjectType::DEVICE_MEMORY: - return "DebugObjectType::DEVICE_MEMORY"; + case stormkit::gpu::DebugObjectType::DEVICE_MEMORY: return "DebugObjectType::DEVICE_MEMORY"; case stormkit::gpu::DebugObjectType::DISPLAY: return "DebugObjectType::DISPLAY"; case stormkit::gpu::DebugObjectType::EVENT: return "DebugObjectType::EVENT"; case stormkit::gpu::DebugObjectType::FENCE: return "DebugObjectType::FENCE"; @@ -1602,20 +1459,16 @@ export { case stormkit::gpu::DebugObjectType::IMAGE: return "DebugObjectType::IMAGE"; case stormkit::gpu::DebugObjectType::IMAGE_VIEW: return "DebugObjectType::IMAGE_VIEW"; case stormkit::gpu::DebugObjectType::INSTANCE: return "DebugObjectType::INSTANCE"; - case stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE: - return "DebugObjectType::PHYSICAL_DEVICE"; + case stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE: return "DebugObjectType::PHYSICAL_DEVICE"; case stormkit::gpu::DebugObjectType::PIPELINE: return "DebugObjectType::PIPELINE"; - case stormkit::gpu::DebugObjectType::PIPELINE_CACHE: - return "DebugObjectType::PIPELINE_CACHE"; - case stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT: - return "DebugObjectType::PIPELINE_LAYOUT"; + case stormkit::gpu::DebugObjectType::PIPELINE_CACHE: return "DebugObjectType::PIPELINE_CACHE"; + case stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT: return "DebugObjectType::PIPELINE_LAYOUT"; case stormkit::gpu::DebugObjectType::QUERY_POOL: return "DebugObjectType::QUERY_POOL"; case stormkit::gpu::DebugObjectType::QUEUE: return "DebugObjectType::QUEUE"; case stormkit::gpu::DebugObjectType::RENDER_PASS: return "DebugObjectType::RENDER_PASS"; case stormkit::gpu::DebugObjectType::SAMPLER: return "DebugObjectType::SAMPLER"; case stormkit::gpu::DebugObjectType::SEMAPHORE: return "DebugObjectType::SEMAPHORE"; - case stormkit::gpu::DebugObjectType::SHADER_MODULE: - return "DebugObjectType::SHADER_MODULE"; + case stormkit::gpu::DebugObjectType::SHADER_MODULE: return "DebugObjectType::SHADER_MODULE"; case stormkit::gpu::DebugObjectType::SURFACE: return "DebugObjectType::SURFACE"; case stormkit::gpu::DebugObjectType::SWAPCHAIN: return "DebugObjectType::SWAPCHAIN"; case stormkit::gpu::DebugObjectType::UNKNOWN: return "DebugObjectType::UNKNOWN"; @@ -1626,27 +1479,19 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::DebugObjectType>(stormkit::gpu::DebugObjectType value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::DebugObjectType value) noexcept -> std::string { switch (value) { case stormkit::gpu::DebugObjectType::BUFFER: return "DebugObjectType::BUFFER"; case stormkit::gpu::DebugObjectType::BUFFER_VIEW: return "DebugObjectType::BUFFER_VIEW"; - case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: - return "DebugObjectType::COMMAND_BUFFER"; - case stormkit::gpu::DebugObjectType::COMMAND_POOL: - return "DebugObjectType::COMMAND_POOL"; - case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: - return "DebugObjectType::DEBUG_REPORT_CALLBACK"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: - return "DebugObjectType::DESCRIPTOR_POOL"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: - return "DebugObjectType::DESCRIPTOR_SET"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: - return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; + case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: return "DebugObjectType::COMMAND_BUFFER"; + case stormkit::gpu::DebugObjectType::COMMAND_POOL: return "DebugObjectType::COMMAND_POOL"; + case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: return "DebugObjectType::DEBUG_REPORT_CALLBACK"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: return "DebugObjectType::DESCRIPTOR_POOL"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: return "DebugObjectType::DESCRIPTOR_SET"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; case stormkit::gpu::DebugObjectType::DEVICE: return "DebugObjectType::DEVICE"; - case stormkit::gpu::DebugObjectType::DEVICE_MEMORY: - return "DebugObjectType::DEVICE_MEMORY"; + case stormkit::gpu::DebugObjectType::DEVICE_MEMORY: return "DebugObjectType::DEVICE_MEMORY"; case stormkit::gpu::DebugObjectType::DISPLAY: return "DebugObjectType::DISPLAY"; case stormkit::gpu::DebugObjectType::EVENT: return "DebugObjectType::EVENT"; case stormkit::gpu::DebugObjectType::FENCE: return "DebugObjectType::FENCE"; @@ -1654,20 +1499,16 @@ export { case stormkit::gpu::DebugObjectType::IMAGE: return "DebugObjectType::IMAGE"; case stormkit::gpu::DebugObjectType::IMAGE_VIEW: return "DebugObjectType::IMAGE_VIEW"; case stormkit::gpu::DebugObjectType::INSTANCE: return "DebugObjectType::INSTANCE"; - case stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE: - return "DebugObjectType::PHYSICAL_DEVICE"; + case stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE: return "DebugObjectType::PHYSICAL_DEVICE"; case stormkit::gpu::DebugObjectType::PIPELINE: return "DebugObjectType::PIPELINE"; - case stormkit::gpu::DebugObjectType::PIPELINE_CACHE: - return "DebugObjectType::PIPELINE_CACHE"; - case stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT: - return "DebugObjectType::PIPELINE_LAYOUT"; + case stormkit::gpu::DebugObjectType::PIPELINE_CACHE: return "DebugObjectType::PIPELINE_CACHE"; + case stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT: return "DebugObjectType::PIPELINE_LAYOUT"; case stormkit::gpu::DebugObjectType::QUERY_POOL: return "DebugObjectType::QUERY_POOL"; case stormkit::gpu::DebugObjectType::QUEUE: return "DebugObjectType::QUEUE"; case stormkit::gpu::DebugObjectType::RENDER_PASS: return "DebugObjectType::RENDER_PASS"; case stormkit::gpu::DebugObjectType::SAMPLER: return "DebugObjectType::SAMPLER"; case stormkit::gpu::DebugObjectType::SEMAPHORE: return "DebugObjectType::SEMAPHORE"; - case stormkit::gpu::DebugObjectType::SHADER_MODULE: - return "DebugObjectType::SHADER_MODULE"; + case stormkit::gpu::DebugObjectType::SHADER_MODULE: return "DebugObjectType::SHADER_MODULE"; case stormkit::gpu::DebugObjectType::SURFACE: return "DebugObjectType::SURFACE"; case stormkit::gpu::DebugObjectType::SWAPCHAIN: return "DebugObjectType::SWAPCHAIN"; case stormkit::gpu::DebugObjectType::UNKNOWN: return "DebugObjectType::UNKNOWN"; @@ -1679,8 +1520,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::DependencyFlag::BY_REGION, stormkit::gpu::DependencyFlag::DEVICE_GROUP, @@ -1693,8 +1533,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::DependencyFlag>(stormkit::gpu::DependencyFlag value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::DependencyFlag value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::DependencyFlag::BY_REGION: return "DependencyFlag::BY_REGION"; @@ -1708,8 +1547,8 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::DependencyFlag>(stormkit::gpu::DependencyFlag value) noexcept -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::DependencyFlag value) noexcept + -> std::string { switch (value) { case stormkit::gpu::DependencyFlag::BY_REGION: return "DependencyFlag::BY_REGION"; case stormkit::gpu::DependencyFlag::DEVICE_GROUP: return "DependencyFlag::DEVICE_GROUP"; @@ -1723,19 +1562,13 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, - stormkit::gpu::DescriptorType::INPUT_ATTACHMENT, - stormkit::gpu::DescriptorType::SAMPLED_IMAGE, - stormkit::gpu::DescriptorType::SAMPLER, - stormkit::gpu::DescriptorType::STORAGE_BUFFER, - stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC, - stormkit::gpu::DescriptorType::STORAGE_IMAGE, - stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER, - stormkit::gpu::DescriptorType::UNIFORM_BUFFER, - stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC, + stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, stormkit::gpu::DescriptorType::INPUT_ATTACHMENT, + stormkit::gpu::DescriptorType::SAMPLED_IMAGE, stormkit::gpu::DescriptorType::SAMPLER, + stormkit::gpu::DescriptorType::STORAGE_BUFFER, stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC, + stormkit::gpu::DescriptorType::STORAGE_IMAGE, stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER, + stormkit::gpu::DescriptorType::UNIFORM_BUFFER, stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC, stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER, }; @@ -1744,31 +1577,20 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::DescriptorType>(stormkit::gpu::DescriptorType value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::DescriptorType value) noexcept -> std::string_view { switch (value) { - case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: - return "DescriptorType::COMBINED_IMAGE_SAMPLER"; - case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: - return "DescriptorType::INPUT_ATTACHMENT"; - case stormkit::gpu::DescriptorType::SAMPLED_IMAGE: - return "DescriptorType::SAMPLED_IMAGE"; + case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: return "DescriptorType::COMBINED_IMAGE_SAMPLER"; + case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: return "DescriptorType::INPUT_ATTACHMENT"; + case stormkit::gpu::DescriptorType::SAMPLED_IMAGE: return "DescriptorType::SAMPLED_IMAGE"; case stormkit::gpu::DescriptorType::SAMPLER: return "DescriptorType::SAMPLER"; - case stormkit::gpu::DescriptorType::STORAGE_BUFFER: - return "DescriptorType::STORAGE_BUFFER"; - case stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC: - return "DescriptorType::STORAGE_BUFFER_DYNAMIC"; - case stormkit::gpu::DescriptorType::STORAGE_IMAGE: - return "DescriptorType::STORAGE_IMAGE"; - case stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER: - return "DescriptorType::STORAGE_TEXEL_BUFFER"; - case stormkit::gpu::DescriptorType::UNIFORM_BUFFER: - return "DescriptorType::UNIFORM_BUFFER"; - case stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC: - return "DescriptorType::UNIFORM_BUFFER_DYNAMIC"; - case stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER: - return "DescriptorType::UNIFORM_TEXEL_BUFFER"; + case stormkit::gpu::DescriptorType::STORAGE_BUFFER: return "DescriptorType::STORAGE_BUFFER"; + case stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC: return "DescriptorType::STORAGE_BUFFER_DYNAMIC"; + case stormkit::gpu::DescriptorType::STORAGE_IMAGE: return "DescriptorType::STORAGE_IMAGE"; + case stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER: return "DescriptorType::STORAGE_TEXEL_BUFFER"; + case stormkit::gpu::DescriptorType::UNIFORM_BUFFER: return "DescriptorType::UNIFORM_BUFFER"; + case stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC: return "DescriptorType::UNIFORM_BUFFER_DYNAMIC"; + case stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER: return "DescriptorType::UNIFORM_TEXEL_BUFFER"; } std::unreachable(); } @@ -1776,30 +1598,20 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::DescriptorType>(stormkit::gpu::DescriptorType value) noexcept -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::DescriptorType value) noexcept + -> std::string { switch (value) { - case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: - return "DescriptorType::COMBINED_IMAGE_SAMPLER"; - case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: - return "DescriptorType::INPUT_ATTACHMENT"; - case stormkit::gpu::DescriptorType::SAMPLED_IMAGE: - return "DescriptorType::SAMPLED_IMAGE"; + case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: return "DescriptorType::COMBINED_IMAGE_SAMPLER"; + case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: return "DescriptorType::INPUT_ATTACHMENT"; + case stormkit::gpu::DescriptorType::SAMPLED_IMAGE: return "DescriptorType::SAMPLED_IMAGE"; case stormkit::gpu::DescriptorType::SAMPLER: return "DescriptorType::SAMPLER"; - case stormkit::gpu::DescriptorType::STORAGE_BUFFER: - return "DescriptorType::STORAGE_BUFFER"; - case stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC: - return "DescriptorType::STORAGE_BUFFER_DYNAMIC"; - case stormkit::gpu::DescriptorType::STORAGE_IMAGE: - return "DescriptorType::STORAGE_IMAGE"; - case stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER: - return "DescriptorType::STORAGE_TEXEL_BUFFER"; - case stormkit::gpu::DescriptorType::UNIFORM_BUFFER: - return "DescriptorType::UNIFORM_BUFFER"; - case stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC: - return "DescriptorType::UNIFORM_BUFFER_DYNAMIC"; - case stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER: - return "DescriptorType::UNIFORM_TEXEL_BUFFER"; + case stormkit::gpu::DescriptorType::STORAGE_BUFFER: return "DescriptorType::STORAGE_BUFFER"; + case stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC: return "DescriptorType::STORAGE_BUFFER_DYNAMIC"; + case stormkit::gpu::DescriptorType::STORAGE_IMAGE: return "DescriptorType::STORAGE_IMAGE"; + case stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER: return "DescriptorType::STORAGE_TEXEL_BUFFER"; + case stormkit::gpu::DescriptorType::UNIFORM_BUFFER: return "DescriptorType::UNIFORM_BUFFER"; + case stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC: return "DescriptorType::UNIFORM_BUFFER_DYNAMIC"; + case stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER: return "DescriptorType::UNIFORM_TEXEL_BUFFER"; } std::unreachable(); } @@ -1808,17 +1620,12 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::DynamicState::BLEND_CONSTANTS, - stormkit::gpu::DynamicState::DEPTH_BIAS, - stormkit::gpu::DynamicState::DEPTH_BOUNDS, - stormkit::gpu::DynamicState::LINE_WIDTH, - stormkit::gpu::DynamicState::SCISSOR, - stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK, - stormkit::gpu::DynamicState::STENCIL_REFERENCE, - stormkit::gpu::DynamicState::STENCIL_WRITE_MASK, + stormkit::gpu::DynamicState::BLEND_CONSTANTS, stormkit::gpu::DynamicState::DEPTH_BIAS, + stormkit::gpu::DynamicState::DEPTH_BOUNDS, stormkit::gpu::DynamicState::LINE_WIDTH, + stormkit::gpu::DynamicState::SCISSOR, stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK, + stormkit::gpu::DynamicState::STENCIL_REFERENCE, stormkit::gpu::DynamicState::STENCIL_WRITE_MASK, stormkit::gpu::DynamicState::VIEWPORT, }; @@ -1827,21 +1634,17 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::DynamicState>(stormkit::gpu::DynamicState value) noexcept -> std::string_view { + constexpr auto stormkit::core::as_string(stormkit::gpu::DynamicState value) noexcept + -> std::string_view { switch (value) { - case stormkit::gpu::DynamicState::BLEND_CONSTANTS: - return "DynamicState::BLEND_CONSTANTS"; + case stormkit::gpu::DynamicState::BLEND_CONSTANTS: return "DynamicState::BLEND_CONSTANTS"; case stormkit::gpu::DynamicState::DEPTH_BIAS: return "DynamicState::DEPTH_BIAS"; case stormkit::gpu::DynamicState::DEPTH_BOUNDS: return "DynamicState::DEPTH_BOUNDS"; case stormkit::gpu::DynamicState::LINE_WIDTH: return "DynamicState::LINE_WIDTH"; case stormkit::gpu::DynamicState::SCISSOR: return "DynamicState::SCISSOR"; - case stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK: - return "DynamicState::STENCIL_COMPARE_MASK"; - case stormkit::gpu::DynamicState::STENCIL_REFERENCE: - return "DynamicState::STENCIL_REFERENCE"; - case stormkit::gpu::DynamicState::STENCIL_WRITE_MASK: - return "DynamicState::STENCIL_WRITE_MASK"; + case stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK: return "DynamicState::STENCIL_COMPARE_MASK"; + case stormkit::gpu::DynamicState::STENCIL_REFERENCE: return "DynamicState::STENCIL_REFERENCE"; + case stormkit::gpu::DynamicState::STENCIL_WRITE_MASK: return "DynamicState::STENCIL_WRITE_MASK"; case stormkit::gpu::DynamicState::VIEWPORT: return "DynamicState::VIEWPORT"; } std::unreachable(); @@ -1850,21 +1653,17 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::DynamicState>(stormkit::gpu::DynamicState value) noexcept -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::DynamicState value) noexcept + -> std::string { switch (value) { - case stormkit::gpu::DynamicState::BLEND_CONSTANTS: - return "DynamicState::BLEND_CONSTANTS"; + case stormkit::gpu::DynamicState::BLEND_CONSTANTS: return "DynamicState::BLEND_CONSTANTS"; case stormkit::gpu::DynamicState::DEPTH_BIAS: return "DynamicState::DEPTH_BIAS"; case stormkit::gpu::DynamicState::DEPTH_BOUNDS: return "DynamicState::DEPTH_BOUNDS"; case stormkit::gpu::DynamicState::LINE_WIDTH: return "DynamicState::LINE_WIDTH"; case stormkit::gpu::DynamicState::SCISSOR: return "DynamicState::SCISSOR"; - case stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK: - return "DynamicState::STENCIL_COMPARE_MASK"; - case stormkit::gpu::DynamicState::STENCIL_REFERENCE: - return "DynamicState::STENCIL_REFERENCE"; - case stormkit::gpu::DynamicState::STENCIL_WRITE_MASK: - return "DynamicState::STENCIL_WRITE_MASK"; + case stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK: return "DynamicState::STENCIL_COMPARE_MASK"; + case stormkit::gpu::DynamicState::STENCIL_REFERENCE: return "DynamicState::STENCIL_REFERENCE"; + case stormkit::gpu::DynamicState::STENCIL_WRITE_MASK: return "DynamicState::STENCIL_WRITE_MASK"; case stormkit::gpu::DynamicState::VIEWPORT: return "DynamicState::VIEWPORT"; } std::unreachable(); @@ -1874,8 +1673,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::Filter::CUBIC_IMG, stormkit::gpu::Filter::LINEAR, @@ -1887,9 +1685,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::Filter - value) noexcept - -> std::string_view { + constexpr auto stormkit::core::as_string(stormkit::gpu::Filter value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; case stormkit::gpu::Filter::LINEAR: return "Filter::LINEAR"; @@ -1901,9 +1697,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::Filter - value) noexcept - -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::Filter value) noexcept -> std::string { switch (value) { case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; case stormkit::gpu::Filter::LINEAR: return "Filter::LINEAR"; @@ -1916,8 +1710,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::FormatFeatureFlag::BLIT_DST, stormkit::gpu::FormatFeatureFlag::BLIT_SRC, @@ -1930,13 +1723,10 @@ export { stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE, stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR, stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX, - stormkit::gpu::FormatFeatureFlag:: - SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT, - stormkit::gpu::FormatFeatureFlag:: - SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE, stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER, - stormkit::gpu::FormatFeatureFlag:: - SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER, stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE, stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC, stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER, @@ -1952,59 +1742,42 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::FormatFeatureFlag>(stormkit::gpu::FormatFeatureFlag value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::FormatFeatureFlag value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::FormatFeatureFlag::BLIT_DST: return "FormatFeatureFlag::BLIT_DST"; case stormkit::gpu::FormatFeatureFlag::BLIT_SRC: return "FormatFeatureFlag::BLIT_SRC"; - case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT: - return "FormatFeatureFlag::COLOR_ATTACHMENT"; - case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND: - return "FormatFeatureFlag::COLOR_ATTACHMENT_BLEND"; - case stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES: - return "FormatFeatureFlag::COSITED_CHROMA_SAMPLES"; - case stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT: - return "FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT"; + case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT: return "FormatFeatureFlag::COLOR_ATTACHMENT"; + case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND: return "FormatFeatureFlag::COLOR_ATTACHMENT_BLEND"; + case stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES: return "FormatFeatureFlag::COSITED_CHROMA_SAMPLES"; + case stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT: return "FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT"; case stormkit::gpu::FormatFeatureFlag::DISJOINT: return "FormatFeatureFlag::DISJOINT"; - case stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES: - return "FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE: - return "FormatFeatureFlag::SAMPLED_IMAGE"; + case stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES: return "FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE: return "FormatFeatureFlag::SAMPLED_IMAGE"; case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR: return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR"; case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX: return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX"; - case stormkit::gpu::FormatFeatureFlag:: - SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT: + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_" "EXPLICIT"; - case stormkit::gpu::FormatFeatureFlag:: - SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE: + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_" "EXPLICIT_FORCEABLE"; case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER"; - case stormkit::gpu::FormatFeatureFlag:: - SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER: + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_" "FILTER"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE: - return "FormatFeatureFlag::STORAGE_IMAGE"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC: - return "FormatFeatureFlag::STORAGE_IMAGE_ATOMIC"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER: - return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE: return "FormatFeatureFlag::STORAGE_IMAGE"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC: return "FormatFeatureFlag::STORAGE_IMAGE_ATOMIC"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER"; case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC"; - case stormkit::gpu::FormatFeatureFlag::TRANSFER_DST: - return "FormatFeatureFlag::TRANSFER_DST"; - case stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC: - return "FormatFeatureFlag::TRANSFER_SRC"; - case stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER: - return "FormatFeatureFlag::UNIFORM_TEXEL_BUFFER"; - case stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER: - return "FormatFeatureFlag::VERTEX_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::TRANSFER_DST: return "FormatFeatureFlag::TRANSFER_DST"; + case stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC: return "FormatFeatureFlag::TRANSFER_SRC"; + case stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER: return "FormatFeatureFlag::UNIFORM_TEXEL_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER: return "FormatFeatureFlag::VERTEX_BUFFER"; } std::unreachable(); } @@ -2012,59 +1785,42 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::FormatFeatureFlag>(stormkit::gpu::FormatFeatureFlag value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::FormatFeatureFlag value) noexcept -> std::string { switch (value) { case stormkit::gpu::FormatFeatureFlag::BLIT_DST: return "FormatFeatureFlag::BLIT_DST"; case stormkit::gpu::FormatFeatureFlag::BLIT_SRC: return "FormatFeatureFlag::BLIT_SRC"; - case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT: - return "FormatFeatureFlag::COLOR_ATTACHMENT"; - case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND: - return "FormatFeatureFlag::COLOR_ATTACHMENT_BLEND"; - case stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES: - return "FormatFeatureFlag::COSITED_CHROMA_SAMPLES"; - case stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT: - return "FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT"; + case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT: return "FormatFeatureFlag::COLOR_ATTACHMENT"; + case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND: return "FormatFeatureFlag::COLOR_ATTACHMENT_BLEND"; + case stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES: return "FormatFeatureFlag::COSITED_CHROMA_SAMPLES"; + case stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT: return "FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT"; case stormkit::gpu::FormatFeatureFlag::DISJOINT: return "FormatFeatureFlag::DISJOINT"; - case stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES: - return "FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE: - return "FormatFeatureFlag::SAMPLED_IMAGE"; + case stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES: return "FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE: return "FormatFeatureFlag::SAMPLED_IMAGE"; case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR: return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR"; case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX: return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX"; - case stormkit::gpu::FormatFeatureFlag:: - SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT: + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_" "EXPLICIT"; - case stormkit::gpu::FormatFeatureFlag:: - SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE: + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_" "EXPLICIT_FORCEABLE"; case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER"; - case stormkit::gpu::FormatFeatureFlag:: - SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER: + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_" "FILTER"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE: - return "FormatFeatureFlag::STORAGE_IMAGE"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC: - return "FormatFeatureFlag::STORAGE_IMAGE_ATOMIC"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER: - return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE: return "FormatFeatureFlag::STORAGE_IMAGE"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC: return "FormatFeatureFlag::STORAGE_IMAGE_ATOMIC"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER"; case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC"; - case stormkit::gpu::FormatFeatureFlag::TRANSFER_DST: - return "FormatFeatureFlag::TRANSFER_DST"; - case stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC: - return "FormatFeatureFlag::TRANSFER_SRC"; - case stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER: - return "FormatFeatureFlag::UNIFORM_TEXEL_BUFFER"; - case stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER: - return "FormatFeatureFlag::VERTEX_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::TRANSFER_DST: return "FormatFeatureFlag::TRANSFER_DST"; + case stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC: return "FormatFeatureFlag::TRANSFER_SRC"; + case stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER: return "FormatFeatureFlag::UNIFORM_TEXEL_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER: return "FormatFeatureFlag::VERTEX_BUFFER"; } std::unreachable(); } @@ -2073,8 +1829,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::FrontFace::CLOCKWISE, stormkit::gpu::FrontFace::COUNTER_CLOCKWISE, @@ -2085,8 +1840,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::FrontFace - value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::FrontFace value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; @@ -2098,9 +1852,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::FrontFace - value) noexcept - -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::FrontFace value) noexcept -> std::string { switch (value) { case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; case stormkit::gpu::FrontFace::COUNTER_CLOCKWISE: return "FrontFace::COUNTER_CLOCKWISE"; @@ -2112,8 +1864,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION, stormkit::gpu::GeometryFlag::OPAQUE, @@ -2124,8 +1875,8 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::GeometryFlag>(stormkit::gpu::GeometryFlag value) noexcept -> std::string_view { + constexpr auto stormkit::core::as_string(stormkit::gpu::GeometryFlag value) noexcept + -> std::string_view { switch (value) { case stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION: return "GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION"; @@ -2137,8 +1888,8 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::GeometryFlag>(stormkit::gpu::GeometryFlag value) noexcept -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryFlag value) noexcept + -> std::string { switch (value) { case stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION: return "GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION"; @@ -2151,8 +1902,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::GeometryType::AABBS, stormkit::gpu::GeometryType::INSTANCES, @@ -2164,8 +1914,8 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::GeometryType>(stormkit::gpu::GeometryType value) noexcept -> std::string_view { + constexpr auto stormkit::core::as_string(stormkit::gpu::GeometryType value) noexcept + -> std::string_view { switch (value) { case stormkit::gpu::GeometryType::AABBS: return "GeometryType::AABBS"; case stormkit::gpu::GeometryType::INSTANCES: return "GeometryType::INSTANCES"; @@ -2177,8 +1927,8 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::GeometryType>(stormkit::gpu::GeometryType value) noexcept -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryType value) noexcept + -> std::string { switch (value) { case stormkit::gpu::GeometryType::AABBS: return "GeometryType::AABBS"; case stormkit::gpu::GeometryType::INSTANCES: return "GeometryType::INSTANCES"; @@ -2191,8 +1941,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::ImageAspectFlag::COLOR, stormkit::gpu::ImageAspectFlag::DEPTH, @@ -2205,8 +1954,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::ImageAspectFlag>(stormkit::gpu::ImageAspectFlag value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageAspectFlag value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::ImageAspectFlag::COLOR: return "ImageAspectFlag::COLOR"; @@ -2220,8 +1968,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::ImageAspectFlag>(stormkit::gpu::ImageAspectFlag value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageAspectFlag value) noexcept -> std::string { switch (value) { case stormkit::gpu::ImageAspectFlag::COLOR: return "ImageAspectFlag::COLOR"; @@ -2236,8 +1983,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::ImageCreateFlag::ALIAS, stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE, @@ -2259,30 +2005,22 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::ImageCreateFlag>(stormkit::gpu::ImageCreateFlag value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageCreateFlag value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::ImageCreateFlag::ALIAS: return "ImageCreateFlag::ALIAS"; - case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: - return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; case stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE: return "ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE: - return "ImageCreateFlag::CUBE_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE: return "ImageCreateFlag::CUBE_COMPATIBLE"; case stormkit::gpu::ImageCreateFlag::DISJOINT: return "ImageCreateFlag::DISJOINT"; - case stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE: - return "ImageCreateFlag::EXTENDED_USAGE"; - case stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT: - return "ImageCreateFlag::MUTABLE_FORMAT"; + case stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE: return "ImageCreateFlag::EXTENDED_USAGE"; + case stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT: return "ImageCreateFlag::MUTABLE_FORMAT"; case stormkit::gpu::ImageCreateFlag::NONE: return "ImageCreateFlag::NONE"; case stormkit::gpu::ImageCreateFlag::PROTECTED: return "ImageCreateFlag::PROTECTED"; - case stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED: - return "ImageCreateFlag::SPARSE_ALIASED"; - case stormkit::gpu::ImageCreateFlag::SPARSE_BINDING: - return "ImageCreateFlag::SPARSE_BINDING"; - case stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY: - return "ImageCreateFlag::SPARSE_RESIDENCY"; + case stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED: return "ImageCreateFlag::SPARSE_ALIASED"; + case stormkit::gpu::ImageCreateFlag::SPARSE_BINDING: return "ImageCreateFlag::SPARSE_BINDING"; + case stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY: return "ImageCreateFlag::SPARSE_RESIDENCY"; case stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS: return "ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS"; } @@ -2292,30 +2030,22 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::ImageCreateFlag>(stormkit::gpu::ImageCreateFlag value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageCreateFlag value) noexcept -> std::string { switch (value) { case stormkit::gpu::ImageCreateFlag::ALIAS: return "ImageCreateFlag::ALIAS"; - case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: - return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; case stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE: return "ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE: - return "ImageCreateFlag::CUBE_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE: return "ImageCreateFlag::CUBE_COMPATIBLE"; case stormkit::gpu::ImageCreateFlag::DISJOINT: return "ImageCreateFlag::DISJOINT"; - case stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE: - return "ImageCreateFlag::EXTENDED_USAGE"; - case stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT: - return "ImageCreateFlag::MUTABLE_FORMAT"; + case stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE: return "ImageCreateFlag::EXTENDED_USAGE"; + case stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT: return "ImageCreateFlag::MUTABLE_FORMAT"; case stormkit::gpu::ImageCreateFlag::NONE: return "ImageCreateFlag::NONE"; case stormkit::gpu::ImageCreateFlag::PROTECTED: return "ImageCreateFlag::PROTECTED"; - case stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED: - return "ImageCreateFlag::SPARSE_ALIASED"; - case stormkit::gpu::ImageCreateFlag::SPARSE_BINDING: - return "ImageCreateFlag::SPARSE_BINDING"; - case stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY: - return "ImageCreateFlag::SPARSE_RESIDENCY"; + case stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED: return "ImageCreateFlag::SPARSE_ALIASED"; + case stormkit::gpu::ImageCreateFlag::SPARSE_BINDING: return "ImageCreateFlag::SPARSE_BINDING"; + case stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY: return "ImageCreateFlag::SPARSE_RESIDENCY"; case stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS: return "ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS"; } @@ -2326,8 +2056,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL, stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, @@ -2349,12 +2078,10 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageLayout - value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageLayout value) noexcept -> std::string_view { switch (value) { - case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: - return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; case stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: return "ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL"; case stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: @@ -2366,13 +2093,10 @@ export { case stormkit::gpu::ImageLayout::GENERAL: return "ImageLayout::GENERAL"; case stormkit::gpu::ImageLayout::PREINITIALIZED: return "ImageLayout::PREINITIALIZED"; case stormkit::gpu::ImageLayout::PRESENT_SRC: return "ImageLayout::PRESENT_SRC"; - case stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL: - return "ImageLayout::SHADER_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL: return "ImageLayout::SHADER_READ_ONLY_OPTIMAL"; case stormkit::gpu::ImageLayout::SHARED_PRESENT: return "ImageLayout::SHARED_PRESENT"; - case stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL: - return "ImageLayout::TRANSFER_DST_OPTIMAL"; - case stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL: - return "ImageLayout::TRANSFER_SRC_OPTIMAL"; + case stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL: return "ImageLayout::TRANSFER_DST_OPTIMAL"; + case stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL: return "ImageLayout::TRANSFER_SRC_OPTIMAL"; case stormkit::gpu::ImageLayout::UNDEFINED: return "ImageLayout::UNDEFINED"; } std::unreachable(); @@ -2381,12 +2105,10 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageLayout - value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageLayout value) noexcept -> std::string { switch (value) { - case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: - return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; case stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: return "ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL"; case stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: @@ -2398,13 +2120,10 @@ export { case stormkit::gpu::ImageLayout::GENERAL: return "ImageLayout::GENERAL"; case stormkit::gpu::ImageLayout::PREINITIALIZED: return "ImageLayout::PREINITIALIZED"; case stormkit::gpu::ImageLayout::PRESENT_SRC: return "ImageLayout::PRESENT_SRC"; - case stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL: - return "ImageLayout::SHADER_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL: return "ImageLayout::SHADER_READ_ONLY_OPTIMAL"; case stormkit::gpu::ImageLayout::SHARED_PRESENT: return "ImageLayout::SHARED_PRESENT"; - case stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL: - return "ImageLayout::TRANSFER_DST_OPTIMAL"; - case stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL: - return "ImageLayout::TRANSFER_SRC_OPTIMAL"; + case stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL: return "ImageLayout::TRANSFER_DST_OPTIMAL"; + case stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL: return "ImageLayout::TRANSFER_SRC_OPTIMAL"; case stormkit::gpu::ImageLayout::UNDEFINED: return "ImageLayout::UNDEFINED"; } std::unreachable(); @@ -2414,8 +2133,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::ImageTiling::LINEAR, stormkit::gpu::ImageTiling::OPTIMAL, @@ -2426,8 +2144,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageTiling - value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageTiling value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::ImageTiling::LINEAR: return "ImageTiling::LINEAR"; @@ -2439,8 +2156,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageTiling - value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageTiling value) noexcept -> std::string { switch (value) { case stormkit::gpu::ImageTiling::LINEAR: return "ImageTiling::LINEAR"; @@ -2453,8 +2169,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::ImageType::T1D, stormkit::gpu::ImageType::T2D, @@ -2466,8 +2181,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageType - value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageType value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; @@ -2480,9 +2194,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageType - value) noexcept - -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageType value) noexcept -> std::string { switch (value) { case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; case stormkit::gpu::ImageType::T2D: return "ImageType::T2D"; @@ -2495,17 +2207,12 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT, - stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT, - stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT, - stormkit::gpu::ImageUsageFlag::SAMPLED, - stormkit::gpu::ImageUsageFlag::STORAGE, - stormkit::gpu::ImageUsageFlag::TRANSFER_DST, - stormkit::gpu::ImageUsageFlag::TRANSFER_SRC, - stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT, + stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT, stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT, + stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT, stormkit::gpu::ImageUsageFlag::SAMPLED, + stormkit::gpu::ImageUsageFlag::STORAGE, stormkit::gpu::ImageUsageFlag::TRANSFER_DST, + stormkit::gpu::ImageUsageFlag::TRANSFER_SRC, stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT, }; } @@ -2513,22 +2220,17 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::ImageUsageFlag>(stormkit::gpu::ImageUsageFlag value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageUsageFlag value) noexcept -> std::string_view { switch (value) { - case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: - return "ImageUsageFlag::COLOR_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: - return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT: - return "ImageUsageFlag::INPUT_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: return "ImageUsageFlag::COLOR_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT: return "ImageUsageFlag::INPUT_ATTACHMENT"; case stormkit::gpu::ImageUsageFlag::SAMPLED: return "ImageUsageFlag::SAMPLED"; case stormkit::gpu::ImageUsageFlag::STORAGE: return "ImageUsageFlag::STORAGE"; case stormkit::gpu::ImageUsageFlag::TRANSFER_DST: return "ImageUsageFlag::TRANSFER_DST"; case stormkit::gpu::ImageUsageFlag::TRANSFER_SRC: return "ImageUsageFlag::TRANSFER_SRC"; - case stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT: - return "ImageUsageFlag::TRANSIENT_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT: return "ImageUsageFlag::TRANSIENT_ATTACHMENT"; } std::unreachable(); } @@ -2536,21 +2238,17 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::ImageUsageFlag>(stormkit::gpu::ImageUsageFlag value) noexcept -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageUsageFlag value) noexcept + -> std::string { switch (value) { - case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: - return "ImageUsageFlag::COLOR_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: - return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT: - return "ImageUsageFlag::INPUT_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: return "ImageUsageFlag::COLOR_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT: return "ImageUsageFlag::INPUT_ATTACHMENT"; case stormkit::gpu::ImageUsageFlag::SAMPLED: return "ImageUsageFlag::SAMPLED"; case stormkit::gpu::ImageUsageFlag::STORAGE: return "ImageUsageFlag::STORAGE"; case stormkit::gpu::ImageUsageFlag::TRANSFER_DST: return "ImageUsageFlag::TRANSFER_DST"; case stormkit::gpu::ImageUsageFlag::TRANSFER_SRC: return "ImageUsageFlag::TRANSFER_SRC"; - case stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT: - return "ImageUsageFlag::TRANSIENT_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT: return "ImageUsageFlag::TRANSIENT_ATTACHMENT"; } std::unreachable(); } @@ -2559,8 +2257,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::ImageViewType::CUBE, stormkit::gpu::ImageViewType::CUBE_ARRAY, stormkit::gpu::ImageViewType::T1D, stormkit::gpu::ImageViewType::T1D_ARRAY, @@ -2573,8 +2270,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::ImageViewType>(stormkit::gpu::ImageViewType value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageViewType value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::ImageViewType::CUBE: return "ImageViewType::CUBE"; @@ -2591,8 +2287,8 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::ImageViewType>(stormkit::gpu::ImageViewType value) noexcept -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageViewType value) noexcept + -> std::string { switch (value) { case stormkit::gpu::ImageViewType::CUBE: return "ImageViewType::CUBE"; case stormkit::gpu::ImageViewType::CUBE_ARRAY: return "ImageViewType::CUBE_ARRAY"; @@ -2609,25 +2305,16 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::LogicOperation::AND, - stormkit::gpu::LogicOperation::AND_INVERTED, - stormkit::gpu::LogicOperation::AND_REVERSE, - stormkit::gpu::LogicOperation::CLEAR, - stormkit::gpu::LogicOperation::COPY, - stormkit::gpu::LogicOperation::COPY_INVERTED, - stormkit::gpu::LogicOperation::EQUIVALENT, - stormkit::gpu::LogicOperation::INVERT, - stormkit::gpu::LogicOperation::NAND, - stormkit::gpu::LogicOperation::NO_OP, - stormkit::gpu::LogicOperation::NOR, - stormkit::gpu::LogicOperation::OR, - stormkit::gpu::LogicOperation::OR_INVERTED, - stormkit::gpu::LogicOperation::OR_REVERSE, - stormkit::gpu::LogicOperation::SET, - stormkit::gpu::LogicOperation::XOR, + stormkit::gpu::LogicOperation::AND, stormkit::gpu::LogicOperation::AND_INVERTED, + stormkit::gpu::LogicOperation::AND_REVERSE, stormkit::gpu::LogicOperation::CLEAR, + stormkit::gpu::LogicOperation::COPY, stormkit::gpu::LogicOperation::COPY_INVERTED, + stormkit::gpu::LogicOperation::EQUIVALENT, stormkit::gpu::LogicOperation::INVERT, + stormkit::gpu::LogicOperation::NAND, stormkit::gpu::LogicOperation::NO_OP, + stormkit::gpu::LogicOperation::NOR, stormkit::gpu::LogicOperation::OR, + stormkit::gpu::LogicOperation::OR_INVERTED, stormkit::gpu::LogicOperation::OR_REVERSE, + stormkit::gpu::LogicOperation::SET, stormkit::gpu::LogicOperation::XOR, }; } @@ -2635,8 +2322,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::LogicOperation>(stormkit::gpu::LogicOperation value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::LogicOperation value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::LogicOperation::AND: return "LogicOperation::AND"; @@ -2644,8 +2330,7 @@ export { case stormkit::gpu::LogicOperation::AND_REVERSE: return "LogicOperation::AND_REVERSE"; case stormkit::gpu::LogicOperation::CLEAR: return "LogicOperation::CLEAR"; case stormkit::gpu::LogicOperation::COPY: return "LogicOperation::COPY"; - case stormkit::gpu::LogicOperation::COPY_INVERTED: - return "LogicOperation::COPY_INVERTED"; + case stormkit::gpu::LogicOperation::COPY_INVERTED: return "LogicOperation::COPY_INVERTED"; case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; @@ -2663,16 +2348,15 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::LogicOperation>(stormkit::gpu::LogicOperation value) noexcept -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::LogicOperation value) noexcept + -> std::string { switch (value) { case stormkit::gpu::LogicOperation::AND: return "LogicOperation::AND"; case stormkit::gpu::LogicOperation::AND_INVERTED: return "LogicOperation::AND_INVERTED"; case stormkit::gpu::LogicOperation::AND_REVERSE: return "LogicOperation::AND_REVERSE"; case stormkit::gpu::LogicOperation::CLEAR: return "LogicOperation::CLEAR"; case stormkit::gpu::LogicOperation::COPY: return "LogicOperation::COPY"; - case stormkit::gpu::LogicOperation::COPY_INVERTED: - return "LogicOperation::COPY_INVERTED"; + case stormkit::gpu::LogicOperation::COPY_INVERTED: return "LogicOperation::COPY_INVERTED"; case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; @@ -2691,8 +2375,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL, stormkit::gpu::MemoryPropertyFlag::HOST_CACHED, @@ -2705,18 +2388,13 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::MemoryPropertyFlag>(stormkit::gpu::MemoryPropertyFlag value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::MemoryPropertyFlag value) noexcept -> std::string_view { switch (value) { - case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: - return "MemoryPropertyFlag::DEVICE_LOCAL"; - case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: - return "MemoryPropertyFlag::HOST_CACHED"; - case stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT: - return "MemoryPropertyFlag::HOST_COHERENT"; - case stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE: - return "MemoryPropertyFlag::HOST_VISIBLE"; + case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: return "MemoryPropertyFlag::DEVICE_LOCAL"; + case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: return "MemoryPropertyFlag::HOST_CACHED"; + case stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT: return "MemoryPropertyFlag::HOST_COHERENT"; + case stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE: return "MemoryPropertyFlag::HOST_VISIBLE"; } std::unreachable(); } @@ -2724,18 +2402,13 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::MemoryPropertyFlag>(stormkit::gpu::MemoryPropertyFlag value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::MemoryPropertyFlag value) noexcept -> std::string { switch (value) { - case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: - return "MemoryPropertyFlag::DEVICE_LOCAL"; - case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: - return "MemoryPropertyFlag::HOST_CACHED"; - case stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT: - return "MemoryPropertyFlag::HOST_COHERENT"; - case stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE: - return "MemoryPropertyFlag::HOST_VISIBLE"; + case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: return "MemoryPropertyFlag::DEVICE_LOCAL"; + case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: return "MemoryPropertyFlag::HOST_CACHED"; + case stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT: return "MemoryPropertyFlag::HOST_COHERENT"; + case stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE: return "MemoryPropertyFlag::HOST_VISIBLE"; } std::unreachable(); } @@ -2744,8 +2417,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::PhysicalDeviceType::CPU, stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU, @@ -2759,18 +2431,14 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::PhysicalDeviceType>(stormkit::gpu::PhysicalDeviceType value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::PhysicalDeviceType value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::PhysicalDeviceType::CPU: return "PhysicalDeviceType::CPU"; - case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: - return "PhysicalDeviceType::DISCRETE_GPU"; - case stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU: - return "PhysicalDeviceType::INTEGRATED_GPU"; + case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: return "PhysicalDeviceType::DISCRETE_GPU"; + case stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU: return "PhysicalDeviceType::INTEGRATED_GPU"; case stormkit::gpu::PhysicalDeviceType::OTHER: return "PhysicalDeviceType::OTHER"; - case stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU: - return "PhysicalDeviceType::VIRTUAL_GPU"; + case stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU: return "PhysicalDeviceType::VIRTUAL_GPU"; } std::unreachable(); } @@ -2778,18 +2446,14 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::PhysicalDeviceType>(stormkit::gpu::PhysicalDeviceType value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::PhysicalDeviceType value) noexcept -> std::string { switch (value) { case stormkit::gpu::PhysicalDeviceType::CPU: return "PhysicalDeviceType::CPU"; - case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: - return "PhysicalDeviceType::DISCRETE_GPU"; - case stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU: - return "PhysicalDeviceType::INTEGRATED_GPU"; + case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: return "PhysicalDeviceType::DISCRETE_GPU"; + case stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU: return "PhysicalDeviceType::INTEGRATED_GPU"; case stormkit::gpu::PhysicalDeviceType::OTHER: return "PhysicalDeviceType::OTHER"; - case stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU: - return "PhysicalDeviceType::VIRTUAL_GPU"; + case stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU: return "PhysicalDeviceType::VIRTUAL_GPU"; } std::unreachable(); } @@ -2798,8 +2462,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::PipelineBindPoint::COMPUTE, stormkit::gpu::PipelineBindPoint::GRAPHICS, @@ -2810,8 +2473,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::PipelineBindPoint>(stormkit::gpu::PipelineBindPoint value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::PipelineBindPoint value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::PipelineBindPoint::COMPUTE: return "PipelineBindPoint::COMPUTE"; @@ -2823,8 +2485,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::PipelineBindPoint>(stormkit::gpu::PipelineBindPoint value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineBindPoint value) noexcept -> std::string { switch (value) { case stormkit::gpu::PipelineBindPoint::COMPUTE: return "PipelineBindPoint::COMPUTE"; @@ -2837,8 +2498,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::PipelineStageFlag::ALL_COMMANDS, stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS, @@ -2864,42 +2524,28 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::PipelineStageFlag>(stormkit::gpu::PipelineStageFlag value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::PipelineStageFlag value) noexcept -> std::string_view { switch (value) { - case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: - return "PipelineStageFlag::ALL_COMMANDS"; - case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: - return "PipelineStageFlag::ALL_GRAPHICS"; - case stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE: - return "PipelineStageFlag::BOTTOM_OF_PIPE"; - case stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT: - return "PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT"; - case stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER: - return "PipelineStageFlag::COMPUTE_SHADER"; - case stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT: - return "PipelineStageFlag::DRAW_INDIRECT"; - case stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS: - return "PipelineStageFlag::EARLY_FRAGMENT_TESTS"; - case stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER: - return "PipelineStageFlag::FRAGMENT_SHADER"; - case stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER: - return "PipelineStageFlag::GEOMETRY_SHADER"; + case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: return "PipelineStageFlag::ALL_COMMANDS"; + case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: return "PipelineStageFlag::ALL_GRAPHICS"; + case stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE: return "PipelineStageFlag::BOTTOM_OF_PIPE"; + case stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT: return "PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT"; + case stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER: return "PipelineStageFlag::COMPUTE_SHADER"; + case stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT: return "PipelineStageFlag::DRAW_INDIRECT"; + case stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS: return "PipelineStageFlag::EARLY_FRAGMENT_TESTS"; + case stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER: return "PipelineStageFlag::FRAGMENT_SHADER"; + case stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER: return "PipelineStageFlag::GEOMETRY_SHADER"; case stormkit::gpu::PipelineStageFlag::HOST: return "PipelineStageFlag::HOST"; - case stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS: - return "PipelineStageFlag::LATE_FRAGMENT_TESTS"; + case stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS: return "PipelineStageFlag::LATE_FRAGMENT_TESTS"; case stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER: return "PipelineStageFlag::TESSELLATION_CONTROL_SHADER"; case stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER: return "PipelineStageFlag::TESSELLATION_EVALUATION_SHADER"; - case stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE: - return "PipelineStageFlag::TOP_OF_PIPE"; + case stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE: return "PipelineStageFlag::TOP_OF_PIPE"; case stormkit::gpu::PipelineStageFlag::TRANSFER: return "PipelineStageFlag::TRANSFER"; - case stormkit::gpu::PipelineStageFlag::VERTEX_INPUT: - return "PipelineStageFlag::VERTEX_INPUT"; - case stormkit::gpu::PipelineStageFlag::VERTEX_SHADER: - return "PipelineStageFlag::VERTEX_SHADER"; + case stormkit::gpu::PipelineStageFlag::VERTEX_INPUT: return "PipelineStageFlag::VERTEX_INPUT"; + case stormkit::gpu::PipelineStageFlag::VERTEX_SHADER: return "PipelineStageFlag::VERTEX_SHADER"; } std::unreachable(); } @@ -2907,42 +2553,28 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::PipelineStageFlag>(stormkit::gpu::PipelineStageFlag value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineStageFlag value) noexcept -> std::string { switch (value) { - case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: - return "PipelineStageFlag::ALL_COMMANDS"; - case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: - return "PipelineStageFlag::ALL_GRAPHICS"; - case stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE: - return "PipelineStageFlag::BOTTOM_OF_PIPE"; - case stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT: - return "PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT"; - case stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER: - return "PipelineStageFlag::COMPUTE_SHADER"; - case stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT: - return "PipelineStageFlag::DRAW_INDIRECT"; - case stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS: - return "PipelineStageFlag::EARLY_FRAGMENT_TESTS"; - case stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER: - return "PipelineStageFlag::FRAGMENT_SHADER"; - case stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER: - return "PipelineStageFlag::GEOMETRY_SHADER"; + case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: return "PipelineStageFlag::ALL_COMMANDS"; + case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: return "PipelineStageFlag::ALL_GRAPHICS"; + case stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE: return "PipelineStageFlag::BOTTOM_OF_PIPE"; + case stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT: return "PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT"; + case stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER: return "PipelineStageFlag::COMPUTE_SHADER"; + case stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT: return "PipelineStageFlag::DRAW_INDIRECT"; + case stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS: return "PipelineStageFlag::EARLY_FRAGMENT_TESTS"; + case stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER: return "PipelineStageFlag::FRAGMENT_SHADER"; + case stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER: return "PipelineStageFlag::GEOMETRY_SHADER"; case stormkit::gpu::PipelineStageFlag::HOST: return "PipelineStageFlag::HOST"; - case stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS: - return "PipelineStageFlag::LATE_FRAGMENT_TESTS"; + case stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS: return "PipelineStageFlag::LATE_FRAGMENT_TESTS"; case stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER: return "PipelineStageFlag::TESSELLATION_CONTROL_SHADER"; case stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER: return "PipelineStageFlag::TESSELLATION_EVALUATION_SHADER"; - case stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE: - return "PipelineStageFlag::TOP_OF_PIPE"; + case stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE: return "PipelineStageFlag::TOP_OF_PIPE"; case stormkit::gpu::PipelineStageFlag::TRANSFER: return "PipelineStageFlag::TRANSFER"; - case stormkit::gpu::PipelineStageFlag::VERTEX_INPUT: - return "PipelineStageFlag::VERTEX_INPUT"; - case stormkit::gpu::PipelineStageFlag::VERTEX_SHADER: - return "PipelineStageFlag::VERTEX_SHADER"; + case stormkit::gpu::PipelineStageFlag::VERTEX_INPUT: return "PipelineStageFlag::VERTEX_INPUT"; + case stormkit::gpu::PipelineStageFlag::VERTEX_SHADER: return "PipelineStageFlag::VERTEX_SHADER"; } std::unreachable(); } @@ -2951,8 +2583,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16, stormkit::gpu::PixelFormat::A2_RGB10I_PACK32, @@ -3032,34 +2663,23 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PixelFormat - value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::PixelFormat value) noexcept -> std::string_view { switch (value) { - case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: - return "PixelFormat::A1_RGB5_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: - return "PixelFormat::A2_RGB10I_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: - return "PixelFormat::A2_RGB10_SNORM_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: - return "PixelFormat::A2_RGB10_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: - return "PixelFormat::A2_RGB10U_PACK32"; - case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: - return "PixelFormat::B10_GR11UF_PACK32"; + case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; + case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; case stormkit::gpu::PixelFormat::DEPTH16_UNORM: return "PixelFormat::DEPTH16_UNORM"; - case stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U: - return "PixelFormat::DEPTH16_UNORM_STENCIL8U"; - case stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32: - return "PixelFormat::DEPTH24_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U: - return "PixelFormat::DEPTH24_UNORM_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U: return "PixelFormat::DEPTH16_UNORM_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32: return "PixelFormat::DEPTH24_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U: return "PixelFormat::DEPTH24_UNORM_STENCIL8U"; case stormkit::gpu::PixelFormat::DEPTH32F: return "PixelFormat::DEPTH32F"; - case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: - return "PixelFormat::DEPTH32F_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; @@ -3068,8 +2688,7 @@ export { case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; - case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: - return "PixelFormat::R5_G6_B5_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; @@ -3106,8 +2725,7 @@ export { case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; - case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: - return "PixelFormat::RGBA4_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; @@ -3126,34 +2744,23 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::PixelFormat - value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::PixelFormat value) noexcept -> std::string { switch (value) { - case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: - return "PixelFormat::A1_RGB5_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: - return "PixelFormat::A2_RGB10I_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: - return "PixelFormat::A2_RGB10_SNORM_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: - return "PixelFormat::A2_RGB10_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: - return "PixelFormat::A2_RGB10U_PACK32"; - case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: - return "PixelFormat::B10_GR11UF_PACK32"; + case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; + case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; case stormkit::gpu::PixelFormat::DEPTH16_UNORM: return "PixelFormat::DEPTH16_UNORM"; - case stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U: - return "PixelFormat::DEPTH16_UNORM_STENCIL8U"; - case stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32: - return "PixelFormat::DEPTH24_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U: - return "PixelFormat::DEPTH24_UNORM_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U: return "PixelFormat::DEPTH16_UNORM_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32: return "PixelFormat::DEPTH24_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U: return "PixelFormat::DEPTH24_UNORM_STENCIL8U"; case stormkit::gpu::PixelFormat::DEPTH32F: return "PixelFormat::DEPTH32F"; - case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: - return "PixelFormat::DEPTH32F_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; @@ -3162,8 +2769,7 @@ export { case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; - case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: - return "PixelFormat::R5_G6_B5_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; @@ -3200,8 +2806,7 @@ export { case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; - case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: - return "PixelFormat::RGBA4_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; @@ -3221,8 +2826,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::PolygonMode::FILL, stormkit::gpu::PolygonMode::LINE, @@ -3234,8 +2838,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PolygonMode - value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::PolygonMode value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::PolygonMode::FILL: return "PolygonMode::FILL"; @@ -3248,8 +2851,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::PolygonMode - value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::PolygonMode value) noexcept -> std::string { switch (value) { case stormkit::gpu::PolygonMode::FILL: return "PolygonMode::FILL"; @@ -3263,8 +2865,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::PresentMode::FIFO, stormkit::gpu::PresentMode::FIFO_RELAXED, @@ -3279,18 +2880,15 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PresentMode - value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::PresentMode value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::PresentMode::FIFO: return "PresentMode::FIFO"; case stormkit::gpu::PresentMode::FIFO_RELAXED: return "PresentMode::FIFO_RELAXED"; case stormkit::gpu::PresentMode::IMMEDIATE: return "PresentMode::IMMEDIATE"; case stormkit::gpu::PresentMode::MAILBOX: return "PresentMode::MAILBOX"; - case stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH: - return "PresentMode::SHARED_CONTINUOUS_REFRESH"; - case stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH: - return "PresentMode::SHARED_DEMAND_REFRESH"; + case stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH: return "PresentMode::SHARED_CONTINUOUS_REFRESH"; + case stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH: return "PresentMode::SHARED_DEMAND_REFRESH"; } std::unreachable(); } @@ -3298,18 +2896,15 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::PresentMode - value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::PresentMode value) noexcept -> std::string { switch (value) { case stormkit::gpu::PresentMode::FIFO: return "PresentMode::FIFO"; case stormkit::gpu::PresentMode::FIFO_RELAXED: return "PresentMode::FIFO_RELAXED"; case stormkit::gpu::PresentMode::IMMEDIATE: return "PresentMode::IMMEDIATE"; case stormkit::gpu::PresentMode::MAILBOX: return "PresentMode::MAILBOX"; - case stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH: - return "PresentMode::SHARED_CONTINUOUS_REFRESH"; - case stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH: - return "PresentMode::SHARED_DEMAND_REFRESH"; + case stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH: return "PresentMode::SHARED_CONTINUOUS_REFRESH"; + case stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH: return "PresentMode::SHARED_DEMAND_REFRESH"; } std::unreachable(); } @@ -3318,15 +2913,11 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PrimitiveTopology::LINE_LIST, - stormkit::gpu::PrimitiveTopology::LINE_STRIP, - stormkit::gpu::PrimitiveTopology::POINT_LIST, - stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN, - stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST, - stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP, + stormkit::gpu::PrimitiveTopology::LINE_LIST, stormkit::gpu::PrimitiveTopology::LINE_STRIP, + stormkit::gpu::PrimitiveTopology::POINT_LIST, stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN, + stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST, stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP, }; } @@ -3334,21 +2925,15 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::PrimitiveTopology>(stormkit::gpu::PrimitiveTopology value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::PrimitiveTopology value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::PrimitiveTopology::LINE_LIST: return "PrimitiveTopology::LINE_LIST"; - case stormkit::gpu::PrimitiveTopology::LINE_STRIP: - return "PrimitiveTopology::LINE_STRIP"; - case stormkit::gpu::PrimitiveTopology::POINT_LIST: - return "PrimitiveTopology::POINT_LIST"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN: - return "PrimitiveTopology::TRIANGLE_FAN"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST: - return "PrimitiveTopology::TRIANGLE_LIST"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP: - return "PrimitiveTopology::TRIANGLE_STRIP"; + case stormkit::gpu::PrimitiveTopology::LINE_STRIP: return "PrimitiveTopology::LINE_STRIP"; + case stormkit::gpu::PrimitiveTopology::POINT_LIST: return "PrimitiveTopology::POINT_LIST"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN: return "PrimitiveTopology::TRIANGLE_FAN"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST: return "PrimitiveTopology::TRIANGLE_LIST"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP: return "PrimitiveTopology::TRIANGLE_STRIP"; } std::unreachable(); } @@ -3356,21 +2941,15 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::PrimitiveTopology>(stormkit::gpu::PrimitiveTopology value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::PrimitiveTopology value) noexcept -> std::string { switch (value) { case stormkit::gpu::PrimitiveTopology::LINE_LIST: return "PrimitiveTopology::LINE_LIST"; - case stormkit::gpu::PrimitiveTopology::LINE_STRIP: - return "PrimitiveTopology::LINE_STRIP"; - case stormkit::gpu::PrimitiveTopology::POINT_LIST: - return "PrimitiveTopology::POINT_LIST"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN: - return "PrimitiveTopology::TRIANGLE_FAN"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST: - return "PrimitiveTopology::TRIANGLE_LIST"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP: - return "PrimitiveTopology::TRIANGLE_STRIP"; + case stormkit::gpu::PrimitiveTopology::LINE_STRIP: return "PrimitiveTopology::LINE_STRIP"; + case stormkit::gpu::PrimitiveTopology::POINT_LIST: return "PrimitiveTopology::POINT_LIST"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN: return "PrimitiveTopology::TRIANGLE_FAN"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST: return "PrimitiveTopology::TRIANGLE_LIST"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP: return "PrimitiveTopology::TRIANGLE_STRIP"; } std::unreachable(); } @@ -3379,12 +2958,10 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::QueueFlag::COMPUTE, stormkit::gpu::QueueFlag::GRAPHICS, - stormkit::gpu::QueueFlag::NONE, stormkit::gpu::QueueFlag::PROTECTED, - stormkit::gpu::QueueFlag::SPARSE_BINDING, stormkit::gpu::QueueFlag::TRANSFER, + stormkit::gpu::QueueFlag::COMPUTE, stormkit::gpu::QueueFlag::GRAPHICS, stormkit::gpu::QueueFlag::NONE, + stormkit::gpu::QueueFlag::PROTECTED, stormkit::gpu::QueueFlag::SPARSE_BINDING, stormkit::gpu::QueueFlag::TRANSFER, }; } @@ -3392,8 +2969,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::QueueFlag - value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::QueueFlag value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; @@ -3409,9 +2985,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::QueueFlag - value) noexcept - -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::QueueFlag value) noexcept -> std::string { switch (value) { case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; case stormkit::gpu::QueueFlag::GRAPHICS: return "QueueFlag::GRAPHICS"; @@ -3427,8 +3001,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::Result::ERROR_DEVICE_LOST, stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT, @@ -3473,61 +3046,41 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::Result - value) noexcept - -> std::string_view { + constexpr auto stormkit::core::as_string(stormkit::gpu::Result value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; - case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: - return "Result::ERROR_EXTENSION_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT: - return "Result::ERROR_FEATURE_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED: - return "Result::ERROR_FORMAT_NOT_SUPPORTED"; + case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: return "Result::ERROR_EXTENSION_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT: return "Result::ERROR_FEATURE_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED: return "Result::ERROR_FORMAT_NOT_SUPPORTED"; case stormkit::gpu::Result::ERROR_FRAGMENTATION: return "Result::ERROR_FRAGMENTATION"; - case stormkit::gpu::Result::ERROR_FRAGMENTED_POOL: - return "Result::ERROR_FRAGMENTED_POOL"; + case stormkit::gpu::Result::ERROR_FRAGMENTED_POOL: return "Result::ERROR_FRAGMENTED_POOL"; case stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST: return "Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST"; - case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY: - return "Result::ERROR_INCOMPATIBLE_DISPLAY"; - case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER: - return "Result::ERROR_INCOMPATIBLE_DRIVER"; - case stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED: - return "Result::ERROR_INITIALIZATION_FAILED"; - case stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE: - return "Result::ERROR_INVALID_EXTERNAL_HANDLE"; + case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY: return "Result::ERROR_INCOMPATIBLE_DISPLAY"; + case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER: return "Result::ERROR_INCOMPATIBLE_DRIVER"; + case stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED: return "Result::ERROR_INITIALIZATION_FAILED"; + case stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE: return "Result::ERROR_INVALID_EXTERNAL_HANDLE"; case stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: return "Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; - case stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT: - return "Result::ERROR_LAYER_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED: - return "Result::ERROR_MEMORY_MAP_FAILED"; - case stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE: - return "Result::ERROR_NATIVE_WINDOW_IN_USE"; + case stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT: return "Result::ERROR_LAYER_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED: return "Result::ERROR_MEMORY_MAP_FAILED"; + case stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE: return "Result::ERROR_NATIVE_WINDOW_IN_USE"; case stormkit::gpu::Result::ERROR_NOT_PERMITTED: return "Result::ERROR_NOT_PERMITTED"; case stormkit::gpu::Result::ERROR_OUT_OF_DATE: return "Result::ERROR_OUT_OF_DATE"; - case stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY: - return "Result::ERROR_OUT_OF_DEVICE_MEMORY"; - case stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY: - return "Result::ERROR_OUT_OF_HOST_MEMORY"; - case stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY: - return "Result::ERROR_OUT_OF_POOL_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY: return "Result::ERROR_OUT_OF_DEVICE_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY: return "Result::ERROR_OUT_OF_HOST_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY: return "Result::ERROR_OUT_OF_POOL_MEMORY"; case stormkit::gpu::Result::ERROR_SURFACE_LOST: return "Result::ERROR_SURFACE_LOST"; - case stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS: - return "Result::ERROR_TOO_MANY_OBJECTS"; + case stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS: return "Result::ERROR_TOO_MANY_OBJECTS"; case stormkit::gpu::Result::ERROR_UNKNOWN: return "Result::ERROR_UNKNOWN"; - case stormkit::gpu::Result::ERROR_VALIDATION_FAILED: - return "Result::ERROR_VALIDATION_FAILED"; + case stormkit::gpu::Result::ERROR_VALIDATION_FAILED: return "Result::ERROR_VALIDATION_FAILED"; case stormkit::gpu::Result::EVENT_RESET: return "Result::EVENT_RESET"; case stormkit::gpu::Result::EVENT_SET: return "Result::EVENT_SET"; case stormkit::gpu::Result::INCOMPLETE: return "Result::INCOMPLETE"; case stormkit::gpu::Result::NOT_READY: return "Result::NOT_READY"; case stormkit::gpu::Result::OPERATION_DEFERRED: return "Result::OPERATION_DEFERRED"; - case stormkit::gpu::Result::OPERATION_NOT_DEFERRED: - return "Result::OPERATION_NOT_DEFERRED"; - case stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED: - return "Result::PIPELINE_COMPILE_REQUIRED"; + case stormkit::gpu::Result::OPERATION_NOT_DEFERRED: return "Result::OPERATION_NOT_DEFERRED"; + case stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED: return "Result::PIPELINE_COMPILE_REQUIRED"; case stormkit::gpu::Result::SUBOPTIMAL: return "Result::SUBOPTIMAL"; case stormkit::gpu::Result::SUCCESS: return "Result::SUCCESS"; case stormkit::gpu::Result::THREAD_DONE: return "Result::THREAD_DONE"; @@ -3540,61 +3093,41 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::Result - value) noexcept - -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::Result value) noexcept -> std::string { switch (value) { case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; - case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: - return "Result::ERROR_EXTENSION_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT: - return "Result::ERROR_FEATURE_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED: - return "Result::ERROR_FORMAT_NOT_SUPPORTED"; + case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: return "Result::ERROR_EXTENSION_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT: return "Result::ERROR_FEATURE_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED: return "Result::ERROR_FORMAT_NOT_SUPPORTED"; case stormkit::gpu::Result::ERROR_FRAGMENTATION: return "Result::ERROR_FRAGMENTATION"; - case stormkit::gpu::Result::ERROR_FRAGMENTED_POOL: - return "Result::ERROR_FRAGMENTED_POOL"; + case stormkit::gpu::Result::ERROR_FRAGMENTED_POOL: return "Result::ERROR_FRAGMENTED_POOL"; case stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST: return "Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST"; - case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY: - return "Result::ERROR_INCOMPATIBLE_DISPLAY"; - case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER: - return "Result::ERROR_INCOMPATIBLE_DRIVER"; - case stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED: - return "Result::ERROR_INITIALIZATION_FAILED"; - case stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE: - return "Result::ERROR_INVALID_EXTERNAL_HANDLE"; + case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY: return "Result::ERROR_INCOMPATIBLE_DISPLAY"; + case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER: return "Result::ERROR_INCOMPATIBLE_DRIVER"; + case stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED: return "Result::ERROR_INITIALIZATION_FAILED"; + case stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE: return "Result::ERROR_INVALID_EXTERNAL_HANDLE"; case stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: return "Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; - case stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT: - return "Result::ERROR_LAYER_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED: - return "Result::ERROR_MEMORY_MAP_FAILED"; - case stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE: - return "Result::ERROR_NATIVE_WINDOW_IN_USE"; + case stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT: return "Result::ERROR_LAYER_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED: return "Result::ERROR_MEMORY_MAP_FAILED"; + case stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE: return "Result::ERROR_NATIVE_WINDOW_IN_USE"; case stormkit::gpu::Result::ERROR_NOT_PERMITTED: return "Result::ERROR_NOT_PERMITTED"; case stormkit::gpu::Result::ERROR_OUT_OF_DATE: return "Result::ERROR_OUT_OF_DATE"; - case stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY: - return "Result::ERROR_OUT_OF_DEVICE_MEMORY"; - case stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY: - return "Result::ERROR_OUT_OF_HOST_MEMORY"; - case stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY: - return "Result::ERROR_OUT_OF_POOL_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY: return "Result::ERROR_OUT_OF_DEVICE_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY: return "Result::ERROR_OUT_OF_HOST_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY: return "Result::ERROR_OUT_OF_POOL_MEMORY"; case stormkit::gpu::Result::ERROR_SURFACE_LOST: return "Result::ERROR_SURFACE_LOST"; - case stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS: - return "Result::ERROR_TOO_MANY_OBJECTS"; + case stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS: return "Result::ERROR_TOO_MANY_OBJECTS"; case stormkit::gpu::Result::ERROR_UNKNOWN: return "Result::ERROR_UNKNOWN"; - case stormkit::gpu::Result::ERROR_VALIDATION_FAILED: - return "Result::ERROR_VALIDATION_FAILED"; + case stormkit::gpu::Result::ERROR_VALIDATION_FAILED: return "Result::ERROR_VALIDATION_FAILED"; case stormkit::gpu::Result::EVENT_RESET: return "Result::EVENT_RESET"; case stormkit::gpu::Result::EVENT_SET: return "Result::EVENT_SET"; case stormkit::gpu::Result::INCOMPLETE: return "Result::INCOMPLETE"; case stormkit::gpu::Result::NOT_READY: return "Result::NOT_READY"; case stormkit::gpu::Result::OPERATION_DEFERRED: return "Result::OPERATION_DEFERRED"; - case stormkit::gpu::Result::OPERATION_NOT_DEFERRED: - return "Result::OPERATION_NOT_DEFERRED"; - case stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED: - return "Result::PIPELINE_COMPILE_REQUIRED"; + case stormkit::gpu::Result::OPERATION_NOT_DEFERRED: return "Result::OPERATION_NOT_DEFERRED"; + case stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED: return "Result::PIPELINE_COMPILE_REQUIRED"; case stormkit::gpu::Result::SUBOPTIMAL: return "Result::SUBOPTIMAL"; case stormkit::gpu::Result::SUCCESS: return "Result::SUCCESS"; case stormkit::gpu::Result::THREAD_DONE: return "Result::THREAD_DONE"; @@ -3608,12 +3141,10 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::SampleCountFlag::C1, stormkit::gpu::SampleCountFlag::C16, - stormkit::gpu::SampleCountFlag::C2, stormkit::gpu::SampleCountFlag::C32, - stormkit::gpu::SampleCountFlag::C4, stormkit::gpu::SampleCountFlag::C64, + stormkit::gpu::SampleCountFlag::C1, stormkit::gpu::SampleCountFlag::C16, stormkit::gpu::SampleCountFlag::C2, + stormkit::gpu::SampleCountFlag::C32, stormkit::gpu::SampleCountFlag::C4, stormkit::gpu::SampleCountFlag::C64, stormkit::gpu::SampleCountFlag::C8, }; @@ -3622,8 +3153,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::SampleCountFlag>(stormkit::gpu::SampleCountFlag value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::SampleCountFlag value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::SampleCountFlag::C1: return "SampleCountFlag::C1"; @@ -3640,8 +3170,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::SampleCountFlag>(stormkit::gpu::SampleCountFlag value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::SampleCountFlag value) noexcept -> std::string { switch (value) { case stormkit::gpu::SampleCountFlag::C1: return "SampleCountFlag::C1"; @@ -3659,8 +3188,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER, stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE, @@ -3674,18 +3202,13 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::SamplerAddressMode>(stormkit::gpu::SamplerAddressMode value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::SamplerAddressMode value) noexcept -> std::string_view { switch (value) { - case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: - return "SamplerAddressMode::CLAMP_TO_BORDER"; - case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: - return "SamplerAddressMode::CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: - return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: - return "SamplerAddressMode::MIRRORED_REPEAT"; + case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; + case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; } std::unreachable(); @@ -3694,18 +3217,13 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::SamplerAddressMode>(stormkit::gpu::SamplerAddressMode value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerAddressMode value) noexcept -> std::string { switch (value) { - case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: - return "SamplerAddressMode::CLAMP_TO_BORDER"; - case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: - return "SamplerAddressMode::CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: - return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: - return "SamplerAddressMode::MIRRORED_REPEAT"; + case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; + case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; } std::unreachable(); @@ -3715,8 +3233,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::SamplerMipmapMode::LINEAR, stormkit::gpu::SamplerMipmapMode::NEAREST, @@ -3727,8 +3244,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::SamplerMipmapMode>(stormkit::gpu::SamplerMipmapMode value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::SamplerMipmapMode value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::SamplerMipmapMode::LINEAR: return "SamplerMipmapMode::LINEAR"; @@ -3740,8 +3256,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::SamplerMipmapMode>(stormkit::gpu::SamplerMipmapMode value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerMipmapMode value) noexcept -> std::string { switch (value) { case stormkit::gpu::SamplerMipmapMode::LINEAR: return "SamplerMipmapMode::LINEAR"; @@ -3754,8 +3269,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::ShaderStageFlag::COMPUTE, stormkit::gpu::ShaderStageFlag::FRAGMENT, stormkit::gpu::ShaderStageFlag::GEOMETRY, stormkit::gpu::ShaderStageFlag::NONE, @@ -3767,8 +3281,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::ShaderStageFlag>(stormkit::gpu::ShaderStageFlag value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::ShaderStageFlag value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::ShaderStageFlag::COMPUTE: return "ShaderStageFlag::COMPUTE"; @@ -3783,8 +3296,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::ShaderStageFlag>(stormkit::gpu::ShaderStageFlag value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::ShaderStageFlag value) noexcept -> std::string { switch (value) { case stormkit::gpu::ShaderStageFlag::COMPUTE: return "ShaderStageFlag::COMPUTE"; @@ -3800,8 +3312,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::StencilFaceFlag::BACK, stormkit::gpu::StencilFaceFlag::FRONT, @@ -3813,14 +3324,12 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::StencilFaceFlag>(stormkit::gpu::StencilFaceFlag value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::StencilFaceFlag value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::StencilFaceFlag::BACK: return "StencilFaceFlag::BACK"; case stormkit::gpu::StencilFaceFlag::FRONT: return "StencilFaceFlag::FRONT"; - case stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK: - return "StencilFaceFlag::FRONT_AND_BACK"; + case stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK: return "StencilFaceFlag::FRONT_AND_BACK"; } std::unreachable(); } @@ -3828,14 +3337,12 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::StencilFaceFlag>(stormkit::gpu::StencilFaceFlag value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::StencilFaceFlag value) noexcept -> std::string { switch (value) { case stormkit::gpu::StencilFaceFlag::BACK: return "StencilFaceFlag::BACK"; case stormkit::gpu::StencilFaceFlag::FRONT: return "StencilFaceFlag::FRONT"; - case stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK: - return "StencilFaceFlag::FRONT_AND_BACK"; + case stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK: return "StencilFaceFlag::FRONT_AND_BACK"; } std::unreachable(); } @@ -3844,8 +3351,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::meta::enumerate() noexcept - -> decltype(auto) { + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { stormkit::gpu::VertexInputRate::INSTANCE, stormkit::gpu::VertexInputRate::VERTEX, @@ -3856,8 +3362,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string< - stormkit::gpu::VertexInputRate>(stormkit::gpu::VertexInputRate value) noexcept + constexpr auto stormkit::core::as_string(stormkit::gpu::VertexInputRate value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::VertexInputRate::INSTANCE: return "VertexInputRate::INSTANCE"; @@ -3869,8 +3374,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string< - stormkit::gpu::VertexInputRate>(stormkit::gpu::VertexInputRate value) noexcept + constexpr auto stormkit::core::to_string(stormkit::gpu::VertexInputRate value) noexcept -> std::string { switch (value) { case stormkit::gpu::VertexInputRate::INSTANCE: return "VertexInputRate::INSTANCE"; @@ -4168,283 +3672,210 @@ namespace stormkit::gpu { } } // namespace stormkit::gpu -template stormkit::gpu::AccessFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::AccessFlag stormkit::gpu::from_vk(VkAccessFlagBits); +template stormkit::gpu::AccessFlag stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::AccessFlag stormkit::gpu::from_vk(VkAccessFlagBits); template VkFlags stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); -template VkAccessFlagBits stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); - -template stormkit::gpu::AttachmentLoadOperation stormkit::gpu:: - from_vk(VkFlags); -template stormkit::gpu::AttachmentLoadOperation stormkit::gpu:: - from_vk(VkAttachmentLoadOp); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); -template VkAttachmentLoadOp stormkit::gpu::to_vk< - VkAttachmentLoadOp>(stormkit::gpu::AttachmentLoadOperation); - -template stormkit::gpu::AttachmentStoreOperation stormkit::gpu:: - from_vk(VkFlags); -template stormkit::gpu::AttachmentStoreOperation stormkit::gpu:: - from_vk(VkAttachmentStoreOp); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); -template VkAttachmentStoreOp stormkit::gpu::to_vk< - VkAttachmentStoreOp>(stormkit::gpu::AttachmentStoreOperation); - -template stormkit::gpu::BlendFactor stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::BlendFactor stormkit::gpu::from_vk(VkBlendFactor); +template VkAccessFlagBits stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); + +template stormkit::gpu::AttachmentLoadOperation stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::AttachmentLoadOperation stormkit::gpu::from_vk(VkAttachmentLoadOp); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); +template VkAttachmentLoadOp stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); + +template stormkit::gpu::AttachmentStoreOperation stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::AttachmentStoreOperation stormkit::gpu::from_vk(VkAttachmentStoreOp); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); +template VkAttachmentStoreOp stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); + +template stormkit::gpu::BlendFactor stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::BlendFactor stormkit::gpu::from_vk(VkBlendFactor); template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); template VkBlendFactor stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); -template stormkit::gpu::BlendOperation stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::BlendOperation stormkit::gpu::from_vk(VkBlendOp); +template stormkit::gpu::BlendOperation stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::BlendOperation stormkit::gpu::from_vk(VkBlendOp); template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); -template VkBlendOp stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); +template VkBlendOp stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); -template stormkit::gpu::BorderColor stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::BorderColor stormkit::gpu::from_vk(VkBorderColor); +template stormkit::gpu::BorderColor stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::BorderColor stormkit::gpu::from_vk(VkBorderColor); template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BorderColor); template VkBorderColor stormkit::gpu::to_vk(stormkit::gpu::BorderColor); +template stormkit::gpu::BufferUsageFlag stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::BufferUsageFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::BufferUsageFlag stormkit::gpu:: - from_vk(VkBufferUsageFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); -template VkBufferUsageFlagBits stormkit::gpu::to_vk< - VkBufferUsageFlagBits>(stormkit::gpu::BufferUsageFlag); + VkBufferUsageFlagBits>(VkBufferUsageFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); +template VkBufferUsageFlagBits stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); +template stormkit::gpu::ColorComponentFlag stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::ColorComponentFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ColorComponentFlag stormkit::gpu:: - from_vk(VkColorComponentFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); -template VkColorComponentFlagBits stormkit::gpu::to_vk< - VkColorComponentFlagBits>(stormkit::gpu::ColorComponentFlag); - -template stormkit::gpu::ColorSpace stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ColorSpace stormkit::gpu::from_vk(VkColorSpaceKHR); + VkColorComponentFlagBits>(VkColorComponentFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); +template VkColorComponentFlagBits stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); + +template stormkit::gpu::ColorSpace stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ColorSpace stormkit::gpu::from_vk(VkColorSpaceKHR); template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); template VkColorSpaceKHR stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); +template stormkit::gpu::CommandBufferLevel stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::CommandBufferLevel stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::CommandBufferLevel stormkit::gpu:: - from_vk(VkCommandBufferLevel); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); -template VkCommandBufferLevel stormkit::gpu::to_vk< - VkCommandBufferLevel>(stormkit::gpu::CommandBufferLevel); - -template stormkit::gpu::CompareOperation stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::CompareOperation stormkit::gpu::from_vk(VkCompareOp); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); -template VkCompareOp stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); - -template stormkit::gpu::CullModeFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::CullModeFlag stormkit::gpu::from_vk(VkCullModeFlagBits); + VkCommandBufferLevel>(VkCommandBufferLevel); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); +template VkCommandBufferLevel stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); + +template stormkit::gpu::CompareOperation stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::CompareOperation stormkit::gpu::from_vk(VkCompareOp); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); +template VkCompareOp stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); + +template stormkit::gpu::CullModeFlag stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::CullModeFlag stormkit::gpu::from_vk(VkCullModeFlagBits); template VkFlags stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); -template VkCullModeFlagBits stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); +template VkCullModeFlagBits stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); -template stormkit::gpu::DebugObjectType stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::DebugObjectType stormkit::gpu::from_vk(VkObjectType); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); -template VkObjectType stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); +template stormkit::gpu::DebugObjectType stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::DebugObjectType stormkit::gpu::from_vk(VkObjectType); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); +template VkObjectType stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); +template stormkit::gpu::DependencyFlag stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::DependencyFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::DependencyFlag stormkit::gpu:: - from_vk(VkDependencyFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); -template VkDependencyFlagBits stormkit::gpu::to_vk< - VkDependencyFlagBits>(stormkit::gpu::DependencyFlag); - -template stormkit::gpu::DescriptorType stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::DescriptorType stormkit::gpu::from_vk(VkDescriptorType); + VkDependencyFlagBits>(VkDependencyFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); +template VkDependencyFlagBits stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); + +template stormkit::gpu::DescriptorType stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::DescriptorType stormkit::gpu::from_vk(VkDescriptorType); template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); -template VkDescriptorType stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); +template VkDescriptorType stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); -template stormkit::gpu::DynamicState stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::DynamicState stormkit::gpu::from_vk(VkDynamicState); +template stormkit::gpu::DynamicState stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::DynamicState stormkit::gpu::from_vk(VkDynamicState); template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DynamicState); -template VkDynamicState stormkit::gpu::to_vk(stormkit::gpu::DynamicState); +template VkDynamicState stormkit::gpu::to_vk(stormkit::gpu::DynamicState); template stormkit::gpu::Filter stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::Filter stormkit::gpu::from_vk(VkFilter); template VkFlags stormkit::gpu::to_vk(stormkit::gpu::Filter); template VkFilter stormkit::gpu::to_vk(stormkit::gpu::Filter); +template stormkit::gpu::FormatFeatureFlag stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::FormatFeatureFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::FormatFeatureFlag stormkit::gpu:: - from_vk(VkFormatFeatureFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); -template VkFormatFeatureFlagBits stormkit::gpu::to_vk< - VkFormatFeatureFlagBits>(stormkit::gpu::FormatFeatureFlag); - -template stormkit::gpu::FrontFace stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::FrontFace stormkit::gpu::from_vk(VkFrontFace); + VkFormatFeatureFlagBits>(VkFormatFeatureFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); +template VkFormatFeatureFlagBits stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); + +template stormkit::gpu::FrontFace stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::FrontFace stormkit::gpu::from_vk(VkFrontFace); template VkFlags stormkit::gpu::to_vk(stormkit::gpu::FrontFace); template VkFrontFace stormkit::gpu::to_vk(stormkit::gpu::FrontFace); +template stormkit::gpu::GeometryFlag stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::GeometryFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::GeometryFlag stormkit::gpu:: - from_vk(VkGeometryFlagBitsKHR); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); -template VkGeometryFlagBitsKHR stormkit::gpu::to_vk< - VkGeometryFlagBitsKHR>(stormkit::gpu::GeometryFlag); - -template stormkit::gpu::GeometryType stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::GeometryType stormkit::gpu::from_vk(VkGeometryTypeKHR); + VkGeometryFlagBitsKHR>(VkGeometryFlagBitsKHR); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); +template VkGeometryFlagBitsKHR stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); + +template stormkit::gpu::GeometryType stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::GeometryType stormkit::gpu::from_vk(VkGeometryTypeKHR); template VkFlags stormkit::gpu::to_vk(stormkit::gpu::GeometryType); -template VkGeometryTypeKHR stormkit::gpu::to_vk(stormkit::gpu::GeometryType); +template VkGeometryTypeKHR stormkit::gpu::to_vk(stormkit::gpu::GeometryType); +template stormkit::gpu::ImageAspectFlag stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::ImageAspectFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageAspectFlag stormkit::gpu:: - from_vk(VkImageAspectFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); -template VkImageAspectFlagBits stormkit::gpu::to_vk< - VkImageAspectFlagBits>(stormkit::gpu::ImageAspectFlag); + VkImageAspectFlagBits>(VkImageAspectFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); +template VkImageAspectFlagBits stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); +template stormkit::gpu::ImageCreateFlag stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::ImageCreateFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageCreateFlag stormkit::gpu:: - from_vk(VkImageCreateFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); -template VkImageCreateFlagBits stormkit::gpu::to_vk< - VkImageCreateFlagBits>(stormkit::gpu::ImageCreateFlag); - -template stormkit::gpu::ImageLayout stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageLayout stormkit::gpu::from_vk(VkImageLayout); + VkImageCreateFlagBits>(VkImageCreateFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); +template VkImageCreateFlagBits stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); + +template stormkit::gpu::ImageLayout stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageLayout stormkit::gpu::from_vk(VkImageLayout); template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); template VkImageLayout stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); -template stormkit::gpu::ImageTiling stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageTiling stormkit::gpu::from_vk(VkImageTiling); +template stormkit::gpu::ImageTiling stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageTiling stormkit::gpu::from_vk(VkImageTiling); template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); template VkImageTiling stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); -template stormkit::gpu::ImageType stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageType stormkit::gpu::from_vk(VkImageType); +template stormkit::gpu::ImageType stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageType stormkit::gpu::from_vk(VkImageType); template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageType); template VkImageType stormkit::gpu::to_vk(stormkit::gpu::ImageType); +template stormkit::gpu::ImageUsageFlag stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::ImageUsageFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageUsageFlag stormkit::gpu:: - from_vk(VkImageUsageFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); -template VkImageUsageFlagBits stormkit::gpu::to_vk< - VkImageUsageFlagBits>(stormkit::gpu::ImageUsageFlag); - -template stormkit::gpu::ImageViewType stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageViewType stormkit::gpu::from_vk(VkImageViewType); + VkImageUsageFlagBits>(VkImageUsageFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); +template VkImageUsageFlagBits stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); + +template stormkit::gpu::ImageViewType stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageViewType stormkit::gpu::from_vk(VkImageViewType); template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); -template VkImageViewType stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); +template VkImageViewType stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); -template stormkit::gpu::LogicOperation stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::LogicOperation stormkit::gpu::from_vk(VkLogicOp); +template stormkit::gpu::LogicOperation stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::LogicOperation stormkit::gpu::from_vk(VkLogicOp); template VkFlags stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); -template VkLogicOp stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); +template VkLogicOp stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); +template stormkit::gpu::MemoryPropertyFlag stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::MemoryPropertyFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::MemoryPropertyFlag stormkit::gpu:: - from_vk(VkMemoryPropertyFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); -template VkMemoryPropertyFlagBits stormkit::gpu::to_vk< - VkMemoryPropertyFlagBits>(stormkit::gpu::MemoryPropertyFlag); + VkMemoryPropertyFlagBits>(VkMemoryPropertyFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); +template VkMemoryPropertyFlagBits stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); +template stormkit::gpu::PhysicalDeviceType stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::PhysicalDeviceType stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PhysicalDeviceType stormkit::gpu:: - from_vk(VkPhysicalDeviceType); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); -template VkPhysicalDeviceType stormkit::gpu::to_vk< - VkPhysicalDeviceType>(stormkit::gpu::PhysicalDeviceType); + VkPhysicalDeviceType>(VkPhysicalDeviceType); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); +template VkPhysicalDeviceType stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); +template stormkit::gpu::PipelineBindPoint stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::PipelineBindPoint stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PipelineBindPoint stormkit::gpu:: - from_vk(VkPipelineBindPoint); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); -template VkPipelineBindPoint stormkit::gpu::to_vk< - VkPipelineBindPoint>(stormkit::gpu::PipelineBindPoint); + VkPipelineBindPoint>(VkPipelineBindPoint); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); +template VkPipelineBindPoint stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); +template stormkit::gpu::PipelineStageFlag stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::PipelineStageFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PipelineStageFlag stormkit::gpu:: - from_vk(VkPipelineStageFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); -template VkPipelineStageFlagBits stormkit::gpu::to_vk< - VkPipelineStageFlagBits>(stormkit::gpu::PipelineStageFlag); - -template stormkit::gpu::PixelFormat stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PixelFormat stormkit::gpu::from_vk(VkFormat); + VkPipelineStageFlagBits>(VkPipelineStageFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); +template VkPipelineStageFlagBits stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); + +template stormkit::gpu::PixelFormat stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PixelFormat stormkit::gpu::from_vk(VkFormat); template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); template VkFormat stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); -template stormkit::gpu::PolygonMode stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PolygonMode stormkit::gpu::from_vk(VkPolygonMode); +template stormkit::gpu::PolygonMode stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PolygonMode stormkit::gpu::from_vk(VkPolygonMode); template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); template VkPolygonMode stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); -template stormkit::gpu::PresentMode stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PresentMode stormkit::gpu::from_vk(VkPresentModeKHR); +template stormkit::gpu::PresentMode stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PresentMode stormkit::gpu::from_vk(VkPresentModeKHR); template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PresentMode); -template VkPresentModeKHR stormkit::gpu::to_vk(stormkit::gpu::PresentMode); +template VkPresentModeKHR stormkit::gpu::to_vk(stormkit::gpu::PresentMode); +template stormkit::gpu::PrimitiveTopology stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::PrimitiveTopology stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PrimitiveTopology stormkit::gpu:: - from_vk(VkPrimitiveTopology); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); -template VkPrimitiveTopology stormkit::gpu::to_vk< - VkPrimitiveTopology>(stormkit::gpu::PrimitiveTopology); - -template stormkit::gpu::QueueFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::QueueFlag stormkit::gpu::from_vk(VkQueueFlagBits); + VkPrimitiveTopology>(VkPrimitiveTopology); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); +template VkPrimitiveTopology stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); + +template stormkit::gpu::QueueFlag stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::QueueFlag stormkit::gpu::from_vk(VkQueueFlagBits); template VkFlags stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); template VkQueueFlagBits stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); @@ -4453,49 +3884,38 @@ template stormkit::gpu::Result stormkit::gpu::from_vk(stormkit::gpu::Result); template VkResult stormkit::gpu::to_vk(stormkit::gpu::Result); +template stormkit::gpu::SampleCountFlag stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::SampleCountFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::SampleCountFlag stormkit::gpu:: - from_vk(VkSampleCountFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); -template VkSampleCountFlagBits stormkit::gpu::to_vk< - VkSampleCountFlagBits>(stormkit::gpu::SampleCountFlag); + VkSampleCountFlagBits>(VkSampleCountFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); +template VkSampleCountFlagBits stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); +template stormkit::gpu::SamplerAddressMode stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::SamplerAddressMode stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::SamplerAddressMode stormkit::gpu:: - from_vk(VkSamplerAddressMode); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); -template VkSamplerAddressMode stormkit::gpu::to_vk< - VkSamplerAddressMode>(stormkit::gpu::SamplerAddressMode); + VkSamplerAddressMode>(VkSamplerAddressMode); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); +template VkSamplerAddressMode stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); +template stormkit::gpu::SamplerMipmapMode stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::SamplerMipmapMode stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::SamplerMipmapMode stormkit::gpu:: - from_vk(VkSamplerMipmapMode); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); -template VkSamplerMipmapMode stormkit::gpu::to_vk< - VkSamplerMipmapMode>(stormkit::gpu::SamplerMipmapMode); + VkSamplerMipmapMode>(VkSamplerMipmapMode); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); +template VkSamplerMipmapMode stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); +template stormkit::gpu::ShaderStageFlag stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::ShaderStageFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ShaderStageFlag stormkit::gpu:: - from_vk(VkShaderStageFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); -template VkShaderStageFlagBits stormkit::gpu::to_vk< - VkShaderStageFlagBits>(stormkit::gpu::ShaderStageFlag); + VkShaderStageFlagBits>(VkShaderStageFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); +template VkShaderStageFlagBits stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); +template stormkit::gpu::StencilFaceFlag stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::StencilFaceFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::StencilFaceFlag stormkit::gpu:: - from_vk(VkStencilFaceFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); -template VkStencilFaceFlagBits stormkit::gpu::to_vk< - VkStencilFaceFlagBits>(stormkit::gpu::StencilFaceFlag); + VkStencilFaceFlagBits>(VkStencilFaceFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); +template VkStencilFaceFlagBits stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); +template stormkit::gpu::VertexInputRate stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::VertexInputRate stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::VertexInputRate stormkit::gpu:: - from_vk(VkVertexInputRate); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); -template VkVertexInputRate stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); + VkVertexInputRate>(VkVertexInputRate); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); +template VkVertexInputRate stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); diff --git a/modules/stormkit/gpu/core/vulkan/structs.mpp b/modules/stormkit/gpu/core/vulkan/structs.mpp index d27ccde16..ee2d06842 100644 --- a/modules/stormkit/gpu/core/vulkan/structs.mpp +++ b/modules/stormkit/gpu/core/vulkan/structs.mpp @@ -17,8 +17,7 @@ import :vulkan.volk; export namespace stormkit::gpu { template requires( - requires { std::declval().native_handle(); } - or requires { std::declval()->native_handle(); }) + requires { std::declval().native_handle(); } or requires { std::declval()->native_handle(); }) [[nodiscard]] auto to_vk(const T& value) noexcept -> decltype(auto); @@ -76,8 +75,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template requires( - requires { std::declval().native_handle(); } - or requires { std::declval()->native_handle(); }) + requires { std::declval().native_handle(); } or requires { std::declval()->native_handle(); }) STORMKIT_FORCE_INLINE STORMKIT_PURE inline auto to_vk(const T& value) noexcept -> decltype(auto) { @@ -179,9 +177,7 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto to_vk(const Extent& extent) noexcept -> VkExtent3D { - return VkExtent3D { .width = as(extent.width), - .height = as(extent.height), - .depth = as(extent.depth) }; + return VkExtent3D { .width = as(extent.width), .height = as(extent.height), .depth = as(extent.depth) }; } ///////////////////////////////////// diff --git a/modules/stormkit/gpu/core/vulkan/utils.mpp b/modules/stormkit/gpu/core/vulkan/utils.mpp index 926ce3048..c0e7b1980 100644 --- a/modules/stormkit/gpu/core/vulkan/utils.mpp +++ b/modules/stormkit/gpu/core/vulkan/utils.mpp @@ -51,30 +51,23 @@ export namespace stormkit::gpu { template [[nodiscard]] - auto vk_call(const Func& func, - std::span success_result, - Args&&... args) noexcept -> T; + auto vk_call(const Func& func, std::span success_result, Args&&... args) noexcept -> T; template requires(IsVulkanFuncWithResult or IsVulkanFuncWithResult) [[nodiscard]] - auto vk_call(const Func& func, - std::span success_result, - Args&&... args) noexcept -> VulkanExpected; + auto vk_call(const Func& func, std::span success_result, Args&&... args) noexcept -> VulkanExpected; template requires(IsVulkanFuncWithResult) [[nodiscard]] - auto vk_allocate(usize count, const Func& func, Args&&... args) noexcept - -> VulkanExpected>; + auto vk_allocate(usize count, const Func& func, Args&&... args) noexcept -> VulkanExpected>; template requires(IsVulkanFuncWithResult) [[nodiscard]] - auto vk_allocate(usize count, - const Func& func, - std::span possible_results, - Args&&... args) noexcept -> VulkanExpected>; + auto vk_allocate(usize count, const Func& func, std::span possible_results, Args&&... args) noexcept + -> VulkanExpected>; template [[nodiscard]] @@ -83,9 +76,8 @@ export namespace stormkit::gpu { template requires(IsVulkanFuncWithResult) [[nodiscard]] - auto vk_enumerate(const Func& func, - std::span possible_results, - Args&&... args) noexcept -> VulkanExpected>; + auto vk_enumerate(const Func& func, std::span possible_results, Args&&... args) noexcept + -> VulkanExpected>; template class VkRAIIHandle { @@ -106,8 +98,7 @@ export namespace stormkit::gpu { auto operator=(const VkRAIIHandle&) -> VkRAIIHandle& = delete; constexpr VkRAIIHandle(VkRAIIHandle&& other) noexcept - : m_value { std::exchange(other.m_value, nullptr) }, - m_deleter { std::move(other.m_deleter) } {} + : m_value { std::exchange(other.m_value, nullptr) }, m_deleter { std::move(other.m_deleter) } {} constexpr auto operator=(VkRAIIHandle&& other) noexcept -> VkRAIIHandle& { if (this == &other) [[unlikely]] @@ -201,9 +192,7 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto vk_call(const Func& func, Args&&... args) noexcept -> decltype(auto) { static constexpr auto POSSIBLE_RESULTS = std::array { VK_SUCCESS }; - return vk_call(func, - as_view(POSSIBLE_RESULTS), - std::forward(args)...); + return vk_call(func, as_view(POSSIBLE_RESULTS), std::forward(args)...); } ///////////////////////////////////// @@ -212,11 +201,8 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto vk_call(const Func& func, Args&&... args) noexcept -> decltype(auto) { static constexpr auto POSSIBLE_RESULTS = std::array { VK_SUCCESS }; - if constexpr (IsVulkanFuncWithResult - or IsVulkanFuncWithResult) - return vk_call(func, - as_view(POSSIBLE_RESULTS), - std::forward(args)...); + if constexpr (IsVulkanFuncWithResult or IsVulkanFuncWithResult) + return vk_call(func, as_view(POSSIBLE_RESULTS), std::forward(args)...); else if constexpr (not core::meta::Is) { auto out = T {}; std::invoke(func, std::forward(args)..., &out); @@ -229,15 +215,13 @@ namespace stormkit::gpu { ///////////////////////////////////// template requires(IsVulkanFuncWithResult or IsVulkanFuncWithResult) - inline auto vk_call(const Func& func, - std::span success_result, - Args&&... args) noexcept -> VulkanExpected { + inline auto vk_call(const Func& func, std::span success_result, Args&&... args) noexcept + -> VulkanExpected { using Out = VulkanExpected; auto out = Out { std::in_place }; const auto result = [&] noexcept { - if constexpr (core::meta::IsOneOf) - return std::invoke(func, std::forward(args)...); + if constexpr (core::meta::IsOneOf) return std::invoke(func, std::forward(args)...); else if constexpr (core::meta::Is) { const auto _result = std::invoke(func, std::forward(args)...); out = _result; @@ -257,8 +241,7 @@ namespace stormkit::gpu { template requires(IsVulkanFuncWithResult) STORMKIT_FORCE_INLINE - inline auto vk_allocate(usize count, const Func& func, Args&&... args) noexcept - -> VulkanExpected> { + inline auto vk_allocate(usize count, const Func& func, Args&&... args) noexcept -> VulkanExpected> { static constexpr auto POSSIBLE_RESULTS = std::array { VK_SUCCESS }; return vk_allocate(count, func, as_view(POSSIBLE_RESULTS), std::forward(args)...); } @@ -267,10 +250,8 @@ namespace stormkit::gpu { ///////////////////////////////////// template requires(IsVulkanFuncWithResult) - inline auto vk_allocate(usize count, - const Func& func, - std::span possible_results, - Args&&... args) noexcept -> VulkanExpected> { + inline auto vk_allocate(usize count, const Func& func, std::span possible_results, Args&&... args) noexcept + -> VulkanExpected> { using Out = VulkanExpected>; auto out = Out { std::in_place, count }; auto result = std::invoke(func, std::forward(args)..., stdr::data(*out)); @@ -287,9 +268,7 @@ namespace stormkit::gpu { inline auto vk_enumerate(const Func& func, Args&&... args) noexcept -> decltype(auto) { static constexpr auto POSSIBLE_RESULTS = std::array { VK_SUCCESS }; if constexpr (IsVulkanFuncWithResult) - return vk_enumerate(func, - as_view(POSSIBLE_RESULTS), - std::forward(args)...); + return vk_enumerate(func, as_view(POSSIBLE_RESULTS), std::forward(args)...); else { auto out = std::vector {}; @@ -306,9 +285,8 @@ namespace stormkit::gpu { ///////////////////////////////////// template requires(IsVulkanFuncWithResult) - inline auto vk_enumerate(const Func& func, - std::span possible_results, - Args&&... args) noexcept -> VulkanExpected> { + inline auto vk_enumerate(const Func& func, std::span possible_results, Args&&... args) noexcept + -> VulkanExpected> { using Out = VulkanExpected>; auto out = Out {}; @@ -342,9 +320,7 @@ namespace stormkit::gpu { ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto to_vk() noexcept -> decltype(auto) { - return [](const T& value) static noexcept -> decltype(auto) { - return gpu::to_vk(value); - }; + return [](const T& value) static noexcept -> decltype(auto) { return gpu::to_vk(value); }; } ///////////////////////////////////// diff --git a/modules/stormkit/gpu/execution/command_buffer.mpp b/modules/stormkit/gpu/execution/command_buffer.mpp index 68e82118e..82ef18e14 100644 --- a/modules/stormkit/gpu/execution/command_buffer.mpp +++ b/modules/stormkit/gpu/execution/command_buffer.mpp @@ -42,8 +42,7 @@ export namespace stormkit::gpu { static constexpr auto DEBUG_TYPE = DebugObjectType::QUEUE; static auto create(const Device& device, const Device::QueueEntry& entry) noexcept -> Queue; - static auto allocate(const Device& device, const Device::QueueEntry& entry) noexcept - -> Heap; + static auto allocate(const Device& device, const Device::QueueEntry& entry) noexcept -> Heap; ~Queue() noexcept; Queue(const Queue&) = delete; @@ -54,16 +53,16 @@ export namespace stormkit::gpu { auto wait_idle() const noexcept -> Expected; - auto submit(std::span submit_infos, - OptionalRef fence = std::nullopt) const noexcept -> Expected; + auto submit(std::span submit_infos, OptionalRef fence = std::nullopt) const noexcept + -> Expected; - auto submit(const SubmitInfo& submit_info, - OptionalRef fence = std::nullopt) const noexcept -> Expected; + auto submit(const SubmitInfo& submit_info, OptionalRef fence = std::nullopt) const noexcept + -> Expected; [[nodiscard]] auto present(std::span> swapchains, std::span> wait_semaphores, - std::span image_indices) const noexcept -> Expected; + std::span image_indices) const noexcept -> Expected; [[nodiscard]] auto entry() const noexcept -> const Device::QueueEntry&; @@ -101,8 +100,7 @@ export namespace stormkit::gpu { static constexpr auto DEBUG_TYPE = DebugObjectType::COMMAND_BUFFER; - using Deleter = std::function< - void(VkDevice, VkCommandPool, const VolkDeviceTable&, VkCommandBuffer)>; + using Deleter = std::function; ~CommandBuffer() noexcept; CommandBuffer(const CommandBuffer&) = delete; @@ -116,91 +114,70 @@ export namespace stormkit::gpu { std::span> wait_semaphores = {}, std::span wait_dst_stages = {}, std::span> signal_semaphores = {}, - OptionalRef fence = std::nullopt) const noexcept -> Expected; + OptionalRef fence = std::nullopt) const noexcept -> Expected; [[nodiscard]] auto state() const noexcept -> State; [[nodiscard]] auto level() const noexcept -> CommandBufferLevel; - auto begin(bool one_time_submit = false, - std::optional inheritance_info = std::nullopt) noexcept + auto begin(bool one_time_submit = false, std::optional inheritance_info = std::nullopt) noexcept -> Expected>; auto end() noexcept -> Expected>; - auto begin_debug_region(std::string_view name, - const RGBColorF& color = RGBColorDef::WHITE) noexcept + auto begin_debug_region(std::string_view name, const RGBColorF& color = RGBColorDef::WHITE) noexcept -> CommandBuffer&; - auto insert_debug_label(std::string_view name, - const RGBColorF& color = RGBColorDef::WHITE) noexcept + auto insert_debug_label(std::string_view name, const RGBColorF& color = RGBColorDef::WHITE) noexcept -> CommandBuffer&; auto end_debug_region() noexcept -> CommandBuffer&; auto begin_render_pass(const RenderPass& render_pass, const FrameBuffer& framebuffer, - std::span clear_values = std::array { ClearValue { + std::span clear_values = std::array { ClearValue { ClearColor { .color = RGBColorDef::SILVER } } }, - bool secondary_commandbuffers = false) noexcept -> CommandBuffer&; + bool secondary_commandbuffers = false) noexcept -> CommandBuffer&; auto next_sub_pass() noexcept -> CommandBuffer&; auto end_render_pass() noexcept -> CommandBuffer&; auto bind_pipeline(const Pipeline& pipeline) noexcept -> CommandBuffer&; - auto set_viewport(u32 first_viewport, std::span viewports) noexcept - -> CommandBuffer&; - auto set_scissor(u32 first_scissor, std::span scissors) noexcept - -> CommandBuffer&; + auto set_viewport(u32 first_viewport, std::span viewports) noexcept -> CommandBuffer&; + auto set_scissor(u32 first_scissor, std::span scissors) noexcept -> CommandBuffer&; auto set_line_width(float width) noexcept -> CommandBuffer&; - auto set_depth_bias(float constant_factor, float clamp, float slope_factor) noexcept - -> CommandBuffer&; + auto set_depth_bias(float constant_factor, float clamp, float slope_factor) noexcept -> CommandBuffer&; auto set_blend_constants(std::span constants) noexcept -> CommandBuffer&; auto set_depth_bounds(float min, float max) noexcept -> CommandBuffer&; auto set_stencil_compare_mask(StencilFaceFlag face, u32 mask) noexcept -> CommandBuffer&; auto set_stencil_write_mask(StencilFaceFlag face, u32 mask) noexcept -> CommandBuffer&; auto set_stencil_reference(StencilFaceFlag face, u32 reference) noexcept -> CommandBuffer&; - auto dispatch(u32 group_count_x, u32 group_count_y, u32 group_count_z) noexcept - -> CommandBuffer&; + auto dispatch(u32 group_count_x, u32 group_count_y, u32 group_count_z) noexcept -> CommandBuffer&; - auto draw(u32 vertex_count, - u32 instance_count = 1u, - u32 first_vertex = 0, - u32 first_instance = 0) noexcept -> CommandBuffer&; + auto draw(u32 vertex_count, u32 instance_count = 1u, u32 first_vertex = 0, u32 first_instance = 0) noexcept + -> CommandBuffer&; auto draw_indexed(u32 index_count, u32 instance_count = 1u, u32 first_index = 0u, i32 vertex_offset = 0, u32 first_instance = 0u) noexcept -> CommandBuffer&; - auto draw_indirect(const Buffer& buffer, usize offset, u32 draw_count, u32 stride) noexcept + auto draw_indirect(const Buffer& buffer, usize offset, u32 draw_count, u32 stride) noexcept -> CommandBuffer&; + auto draw_indexed_indirect(const Buffer& buffer, usize offset, u32 draw_count, u32 stride) noexcept -> CommandBuffer&; + + auto bind_vertex_buffers(std::span> buffers, std::span offsets) noexcept -> CommandBuffer&; - auto draw_indexed_indirect(const Buffer& buffer, - usize offset, - u32 draw_count, - u32 stride) noexcept -> CommandBuffer&; - - auto bind_vertex_buffers(std::span> buffers, - std::span offsets) noexcept -> CommandBuffer&; - auto bind_index_buffer(const Buffer& buffer, - u64 offset = 0, - bool large_indices = false) noexcept -> CommandBuffer&; + auto bind_index_buffer(const Buffer& buffer, u64 offset = 0, bool large_indices = false) noexcept -> CommandBuffer&; auto bind_descriptor_sets(const Pipeline& pipeline, const PipelineLayout& layout, std::span> descriptor_sets, - std::span dynamic_offsets = {}) noexcept - -> CommandBuffer&; + std::span dynamic_offsets = {}) noexcept -> CommandBuffer&; - auto copy_buffer(const Buffer& src, - const Buffer& dst, - usize size, - u64 src_offset = 0u, - u64 dst_offset = 0u) noexcept -> CommandBuffer&; - auto copy_buffer_to_image(const Buffer& src, - const Image& dst, - std::span - buffer_image_copies = {}) noexcept -> CommandBuffer&; - auto copy_image_to_buffer(const Image& src, - const Buffer& dst, - std::span - buffer_image_copies = {}) noexcept -> CommandBuffer&; + auto copy_buffer(const Buffer& src, const Buffer& dst, usize size, u64 src_offset = 0u, u64 dst_offset = 0u) noexcept + -> CommandBuffer&; + auto copy_buffer_to_image(const Buffer& src, + const Image& dst, + std::span buffer_image_copies = {}) noexcept -> CommandBuffer&; + auto copy_image_to_buffer(const Image& src, + const Buffer& dst, + std::span buffer_image_copies = {}) noexcept -> CommandBuffer&; auto copy_image(const Image& src, const Image& dst, ImageLayout src_layout, @@ -214,8 +191,7 @@ export namespace stormkit::gpu { ImageLayout src_layout, ImageLayout dst_layout, const ImageSubresourceLayers& src_subresource_layers = {}, - const ImageSubresourceLayers& dst_subresource_layers = {}) noexcept - -> CommandBuffer&; + const ImageSubresourceLayers& dst_subresource_layers = {}) noexcept -> CommandBuffer&; auto blit_image(const Image& src, const Image& dst, @@ -227,19 +203,16 @@ export namespace stormkit::gpu { auto transition_image_layout(const Image& image, ImageLayout src_layout, ImageLayout dst_layout, - const ImageSubresourceRange& subresource_range = {}) noexcept - -> CommandBuffer&; + const ImageSubresourceRange& subresource_range = {}) noexcept -> CommandBuffer&; - auto execute_sub_command_buffers(std::span> - commandbuffers) noexcept -> CommandBuffer&; + auto execute_sub_command_buffers(std::span> commandbuffers) noexcept -> CommandBuffer&; auto pipeline_barrier(PipelineStageFlag src_mask, PipelineStageFlag dst_mask, DependencyFlag dependency, std::span memory_barriers, std::span buffer_memory_barriers, - std::span image_memory_barriers) noexcept - -> CommandBuffer&; + std::span image_memory_barriers) noexcept -> CommandBuffer&; auto push_constants(const PipelineLayout& pipeline_layout, ShaderStageFlag stage, @@ -298,17 +271,15 @@ export namespace stormkit::gpu { CommandPool(CommandPool&&) noexcept; auto operator=(CommandPool&&) noexcept -> CommandPool&; - auto create_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) - const noexcept -> Expected; - auto create_command_buffers(usize count, - CommandBufferLevel level = CommandBufferLevel::PRIMARY) - const noexcept -> Expected>; + auto create_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected; + auto create_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected>; - auto allocate_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) - const noexcept -> Expected>; - auto allocate_command_buffers(usize count, - CommandBufferLevel level = CommandBufferLevel::PRIMARY) - const noexcept -> Expected>>; + auto allocate_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected>; + auto allocate_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected>>; [[nodiscard]] auto native_handle() const noexcept -> VkCommandPool; @@ -341,26 +312,22 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Queue::Queue(const Device& device, - const Device::QueueEntry& entry, - PrivateFuncTag) noexcept - : m_entry { entry }, m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) } { - m_vk_handle = vk_call(m_vk_device_table->vkGetDeviceQueue, - m_vk_device, - m_entry.id, - 0); + inline Queue::Queue(const Device& device, const Device::QueueEntry& entry, PrivateFuncTag) noexcept + : m_entry { entry }, m_vk_device { device.native_handle() }, m_vk_device_table { as_ref(device.device_table()) } { + m_vk_handle = vk_call(m_vk_device_table->vkGetDeviceQueue, m_vk_device, m_entry.id, 0); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Queue::~Queue() noexcept = default; + inline Queue::~Queue() noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Queue::Queue(Queue&&) noexcept = default; + inline Queue::Queue(Queue&&) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// @@ -370,16 +337,14 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Queue::create(const Device& device, const Device::QueueEntry& entry) noexcept - -> Queue { + inline auto Queue::create(const Device& device, const Device::QueueEntry& entry) noexcept -> Queue { return Queue { device, entry, PrivateFuncTag {} }; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Queue::allocate(const Device& device, const Device::QueueEntry& entry) noexcept - -> Heap { + inline auto Queue::allocate(const Device& device, const Device::QueueEntry& entry) noexcept -> Heap { return core::allocate_unsafe(device, entry, PrivateFuncTag {}); } @@ -387,16 +352,14 @@ namespace stormkit::gpu { ///////////////////////////////////// STORMKIT_FORCE_INLINE inline auto Queue::wait_idle() const noexcept -> Expected { - return vk_call(m_vk_device_table->vkQueueWaitIdle, m_vk_handle) - .transform_error(monadic::from_vk()); + return vk_call(m_vk_device_table->vkQueueWaitIdle, m_vk_handle).transform_error(monadic::from_vk()); } ///////////////////////////////////// ///////////////////////////////////// // STORMKIT_FORCE_INLINE - inline auto Queue::submit(const SubmitInfo& submit_info, - OptionalRef fence) const noexcept -> Expected { + inline auto Queue::submit(const SubmitInfo& submit_info, OptionalRef fence) const noexcept -> Expected { return submit({ &submit_info, 1 }, std::move(fence)); } @@ -424,14 +387,16 @@ namespace stormkit::gpu { VkCommandBuffer&& command_buffer, Deleter&& deleter, PrivateFuncTag) noexcept - : m_level { level }, m_vk_device { device }, m_vk_device_table { device_table }, + : m_level { level }, + m_vk_device { device }, + m_vk_device_table { device_table }, m_vk_pool { pool }, - m_vk_handle { { [vk_device = m_vk_device, - vk_pool = m_vk_pool, - vk_device_table = *m_vk_device_table, - deleter = std::move(deleter)](auto handle) noexcept { - deleter(vk_device, vk_pool, vk_device_table, handle); - } } } { + m_vk_handle { + { [vk_device = m_vk_device, + vk_pool = m_vk_pool, + vk_device_table = *m_vk_device_table, + deleter = std::move(deleter)](auto handle) noexcept { deleter(vk_device, vk_pool, vk_device_table, handle); } } + } { m_vk_handle = std::move(command_buffer); } @@ -443,10 +408,8 @@ namespace stormkit::gpu { Ref device_table, CommandBufferLevel level, VkCommandBuffer&& cmb, - Deleter&& deleter) noexcept -> CommandBuffer { - return CommandBuffer { - device, pool, device_table, level, std::move(cmb), std::move(deleter), PrivateFuncTag {} - }; + Deleter&& deleter) noexcept -> CommandBuffer { + return CommandBuffer { device, pool, device_table, level, std::move(cmb), std::move(deleter), PrivateFuncTag {} }; } ///////////////////////////////////// @@ -457,26 +420,22 @@ namespace stormkit::gpu { Ref device_table, CommandBufferLevel level, VkCommandBuffer&& cmb, - Deleter&& deleter) noexcept -> Heap { - return *allocate(device, - pool, - device_table, - level, - std::move(cmb), - std::move(deleter), - PrivateFuncTag {}) + Deleter&& deleter) noexcept -> Heap { + return *allocate(device, pool, device_table, level, std::move(cmb), std::move(deleter), PrivateFuncTag {}) .transform_error(core::monadic::assert()); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline CommandBuffer::~CommandBuffer() noexcept = default; + inline CommandBuffer::~CommandBuffer() noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline CommandBuffer::CommandBuffer(CommandBuffer&&) noexcept = default; + inline CommandBuffer::CommandBuffer(CommandBuffer&&) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// @@ -502,8 +461,7 @@ namespace stormkit::gpu { std::span> wait_semaphores, std::span wait_dst_stages, std::span> signal_semaphores, - OptionalRef fence) const noexcept - -> Expected { + OptionalRef fence) const noexcept -> Expected { auto cmbs = as_refs(*this); return queue.submit( @@ -547,9 +505,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::begin_debug_region(std::string_view name, - const RGBColorF& color) noexcept - -> CommandBuffer& { + inline auto CommandBuffer::begin_debug_region(std::string_view name, const RGBColorF& color) noexcept -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); if (not vkCmdBeginDebugUtilsLabelEXT) [[unlikely]] @@ -569,9 +525,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::insert_debug_label(std::string_view name, - const RGBColorF& color) noexcept - -> CommandBuffer& { + inline auto CommandBuffer::insert_debug_label(std::string_view name, const RGBColorF& color) noexcept -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); if (not vkCmdInsertDebugUtilsLabelEXT) [[unlikely]] @@ -627,9 +581,8 @@ namespace stormkit::gpu { inline auto CommandBuffer::bind_pipeline(const Pipeline& pipeline) noexcept -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); - const auto bind_point = (pipeline.type() == Pipeline::Type::RASTER) - ? VK_PIPELINE_BIND_POINT_GRAPHICS - : VK_PIPELINE_BIND_POINT_COMPUTE; + const auto bind_point = (pipeline.type() == Pipeline::Type::RASTER) ? VK_PIPELINE_BIND_POINT_GRAPHICS + : VK_PIPELINE_BIND_POINT_COMPUTE; vk_call(m_vk_device_table->vkCmdBindPipeline, m_vk_handle, bind_point, to_vk(pipeline)); return *this; @@ -648,24 +601,17 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::set_depth_bias(float constant_factor, - float clamp, - float slope_factor) noexcept -> CommandBuffer& { + inline auto CommandBuffer::set_depth_bias(float constant_factor, float clamp, float slope_factor) noexcept -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); - vk_call(m_vk_device_table->vkCmdSetDepthBias, - m_vk_handle, - constant_factor, - clamp, - slope_factor); + vk_call(m_vk_device_table->vkCmdSetDepthBias, m_vk_handle, constant_factor, clamp, slope_factor); return *this; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::set_blend_constants(std::span constants) noexcept - -> CommandBuffer& { + inline auto CommandBuffer::set_blend_constants(std::span constants) noexcept -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); f32 data[] = { constants[0], constants[1], constants[2], constants[3] }; @@ -687,77 +633,52 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::set_stencil_compare_mask(StencilFaceFlag face, u32 mask) noexcept - -> CommandBuffer& { + inline auto CommandBuffer::set_stencil_compare_mask(StencilFaceFlag face, u32 mask) noexcept -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); - vk_call(m_vk_device_table->vkCmdSetStencilCompareMask, - m_vk_handle, - to_vk(face), - mask); + vk_call(m_vk_device_table->vkCmdSetStencilCompareMask, m_vk_handle, to_vk(face), mask); return *this; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::set_stencil_write_mask(StencilFaceFlag face, u32 mask) noexcept - -> CommandBuffer& { + inline auto CommandBuffer::set_stencil_write_mask(StencilFaceFlag face, u32 mask) noexcept -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); - vk_call(m_vk_device_table->vkCmdSetStencilWriteMask, - m_vk_handle, - to_vk(face), - mask); + vk_call(m_vk_device_table->vkCmdSetStencilWriteMask, m_vk_handle, to_vk(face), mask); return *this; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::set_stencil_reference(StencilFaceFlag face, u32 reference) noexcept - -> CommandBuffer& { + inline auto CommandBuffer::set_stencil_reference(StencilFaceFlag face, u32 reference) noexcept -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); - vk_call(m_vk_device_table->vkCmdSetStencilReference, - m_vk_handle, - to_vk(face), - reference); + vk_call(m_vk_device_table->vkCmdSetStencilReference, m_vk_handle, to_vk(face), reference); return *this; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::dispatch(u32 group_count_x, - u32 group_count_y, - u32 group_count_z) noexcept -> CommandBuffer& { + inline auto CommandBuffer::dispatch(u32 group_count_x, u32 group_count_y, u32 group_count_z) noexcept -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); - vk_call(m_vk_device_table->vkCmdDispatch, - m_vk_handle, - group_count_x, - group_count_y, - group_count_z); + vk_call(m_vk_device_table->vkCmdDispatch, m_vk_handle, group_count_x, group_count_y, group_count_z); return *this; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::draw(u32 vertex_count, - u32 instance_count, - u32 first_vertex, - u32 first_instance) noexcept -> CommandBuffer& { + inline auto CommandBuffer::draw(u32 vertex_count, u32 instance_count, u32 first_vertex, u32 first_instance) noexcept + -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); EXPECTS(vertex_count > 0); - vk_call(m_vk_device_table->vkCmdDraw, - m_vk_handle, - vertex_count, - instance_count, - first_vertex, - first_instance); + vk_call(m_vk_device_table->vkCmdDraw, m_vk_handle, vertex_count, instance_count, first_vertex, first_instance); return *this; } @@ -785,47 +706,32 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::draw_indirect(const Buffer& buffer, - usize offset, - u32 draw_count, - u32 stride) noexcept -> CommandBuffer& { + inline auto CommandBuffer::draw_indirect(const Buffer& buffer, usize offset, u32 draw_count, u32 stride) noexcept + -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); EXPECTS(draw_count > 0); - vk_call(m_vk_device_table->vkCmdDrawIndirect, - m_vk_handle, - to_vk(buffer), - offset, - draw_count, - stride); + vk_call(m_vk_device_table->vkCmdDrawIndirect, m_vk_handle, to_vk(buffer), offset, draw_count, stride); return *this; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::draw_indexed_indirect(const Buffer& buffer, - usize offset, - u32 draw_count, - u32 stride) noexcept -> CommandBuffer& { + inline auto CommandBuffer::draw_indexed_indirect(const Buffer& buffer, usize offset, u32 draw_count, u32 stride) noexcept + -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); EXPECTS(draw_count > 0); - vk_call(m_vk_device_table->vkCmdDrawIndexedIndirect, - m_vk_handle, - to_vk(buffer), - offset, - draw_count, - stride); + vk_call(m_vk_device_table->vkCmdDrawIndexedIndirect, m_vk_handle, to_vk(buffer), offset, draw_count, stride); return *this; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::bind_index_buffer(const Buffer& buffer, - u64 offset, - bool large_indices) noexcept -> CommandBuffer& { + inline auto CommandBuffer::bind_index_buffer(const Buffer& buffer, u64 offset, bool large_indices) noexcept + -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); vk_call(m_vk_device_table->vkCmdBindIndexBuffer, @@ -849,8 +755,7 @@ namespace stormkit::gpu { inline CommandPool::CommandPool(const Device& device, PrivateFuncTag) noexcept : m_vk_device { device.native_handle() }, m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { { [vk_device_table = *m_vk_device_table, - vk_device = m_vk_device](auto handle) noexcept { + m_vk_handle { { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { vk_device_table.vkDestroyCommandPool(vk_device, handle, nullptr); } } } { } @@ -866,22 +771,22 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandPool::allocate(const Device& device) noexcept - -> Expected> { - auto pool = *core::allocate(device, PrivateFuncTag {}) - .transform_error(core::monadic::assert()); + inline auto CommandPool::allocate(const Device& device) noexcept -> Expected> { + auto pool = *core::allocate(device, PrivateFuncTag {}).transform_error(core::monadic::assert()); return pool->do_init().transform(core::monadic::consume(pool)); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline CommandPool::~CommandPool() noexcept = default; + inline CommandPool::~CommandPool() noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline CommandPool::CommandPool(CommandPool&&) noexcept = default; + inline CommandPool::CommandPool(CommandPool&&) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// @@ -891,19 +796,15 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandPool::create_command_buffer(CommandBufferLevel level) const noexcept - -> Expected { - return create_command_buffers(1, level) - .transform([](auto&& cmbs) static noexcept { return std::move(cmbs.front()); }); + inline auto CommandPool::create_command_buffer(CommandBufferLevel level) const noexcept -> Expected { + return create_command_buffers(1, level).transform([](auto&& cmbs) static noexcept { return std::move(cmbs.front()); }); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandPool::allocate_command_buffer(CommandBufferLevel level) const noexcept - -> Expected> { - return allocate_command_buffers(1, level) - .transform([](auto&& cmbs) static noexcept { return std::move(cmbs.front()); }); + inline auto CommandPool::allocate_command_buffer(CommandBufferLevel level) const noexcept -> Expected> { + return allocate_command_buffers(1, level).transform([](auto&& cmbs) static noexcept { return std::move(cmbs.front()); }); } ///////////////////////////////////// diff --git a/modules/stormkit/gpu/execution/descriptors.mpp b/modules/stormkit/gpu/execution/descriptors.mpp index 1061f3091..ebf6a8b4d 100644 --- a/modules/stormkit/gpu/execution/descriptors.mpp +++ b/modules/stormkit/gpu/execution/descriptors.mpp @@ -66,11 +66,7 @@ export { [[nodiscard]] auto native_handle() const noexcept -> VkDescriptorSet; - DescriptorSet(VkDevice, - const VolkDeviceTable&, - VkDescriptorSet&&, - Deleter&&, - PrivateFuncTag) noexcept; + DescriptorSet(VkDevice, const VolkDeviceTable&, VkDescriptorSet&&, Deleter&&, PrivateFuncTag) noexcept; private: VkDevice m_vk_device = nullptr; @@ -95,11 +91,9 @@ export { public: static constexpr auto DEBUG_TYPE = DebugObjectType::DESCRIPTOR_SET_LAYOUT; - static auto create(const Device& device, - std::vector bindings) noexcept + static auto create(const Device& device, std::vector bindings) noexcept -> Expected; - static auto allocate(const Device& device, - std::vector bindings) noexcept + static auto allocate(const Device& device, std::vector bindings) noexcept -> Expected>; ~DescriptorSetLayout() noexcept; @@ -120,9 +114,7 @@ export { [[nodiscard]] auto operator==(const DescriptorSetLayout& second) const noexcept -> bool; - DescriptorSetLayout(const Device&, - std::vector&&, - PrivateFuncTag) noexcept; + DescriptorSetLayout(const Device&, std::vector&&, PrivateFuncTag) noexcept; private: auto do_init() noexcept -> Expected; @@ -146,12 +138,10 @@ export { u32 descriptor_count; }; - static auto create(const Device& device, - std::span sizes, - u32 max_sets) noexcept -> Expected; - static auto allocate(const Device& device, - std::span sizes, - u32 max_sets) noexcept -> Expected>; + static auto create(const Device& device, std::span sizes, u32 max_sets) noexcept + -> Expected; + static auto allocate(const Device& device, std::span sizes, u32 max_sets) noexcept + -> Expected>; ~DescriptorPool() noexcept; DescriptorPool(const DescriptorPool&) = delete; @@ -160,16 +150,12 @@ export { DescriptorPool(DescriptorPool&&) noexcept; auto operator=(DescriptorPool&&) noexcept -> DescriptorPool&; - auto create_descriptor_set(const DescriptorSetLayout& layout) const noexcept - -> Expected; - auto create_descriptor_sets(usize count, - const DescriptorSetLayout& layout) const noexcept + auto create_descriptor_set(const DescriptorSetLayout& layout) const noexcept -> Expected; + auto create_descriptor_sets(usize count, const DescriptorSetLayout& layout) const noexcept -> Expected>; - auto allocate_descriptor_set(const DescriptorSetLayout& layout) const noexcept - -> Expected>; - auto allocate_descriptor_sets(usize count, - const DescriptorSetLayout& layout) const noexcept + auto allocate_descriptor_set(const DescriptorSetLayout& layout) const noexcept -> Expected>; + auto allocate_descriptor_sets(usize count, const DescriptorSetLayout& layout) const noexcept -> Expected>>; [[nodiscard]] @@ -193,23 +179,13 @@ export { template<> struct STORMKIT_API std::hash { [[nodiscard]] - auto operator()(const stormkit::gpu::DescriptorSetLayout& value) const noexcept - -> stormkit::hash64 { + auto operator()(const stormkit::gpu::DescriptorSetLayout& value) const noexcept -> stormkit::hash64 { return value.hash(); } }; - HASH_FUNC(stormkit::gpu::DescriptorSetLayoutBinding, - value.binding, - value.type, - value.stages, - value.descriptor_count) - HASH_FUNC(stormkit::gpu::BufferDescriptor, - value.type, - value.binding, - value.buffer.get(), - value.range, - value.offset) + HASH_FUNC(stormkit::gpu::DescriptorSetLayoutBinding, value.binding, value.type, value.stages, value.descriptor_count) + HASH_FUNC(stormkit::gpu::BufferDescriptor, value.type, value.binding, value.buffer.get(), value.range, value.offset) HASH_FUNC(stormkit::gpu::ImageDescriptor, value.type, value.binding, @@ -223,8 +199,7 @@ export { auto operator()(const stormkit::gpu::Descriptor& value) const noexcept -> stormkit::hash64 { auto hash = stormkit::hash64 { 0 }; - std::visit([&hash](auto& descriptor) { stormkit::hash_combine(hash, descriptor); }, - value); + std::visit([&hash](auto& descriptor) { stormkit::hash_combine(hash, descriptor); }, value); return hash; } @@ -244,8 +219,10 @@ namespace stormkit::gpu { VkDescriptorSet&& set, Deleter&& deleter, PrivateFuncTag) noexcept - : m_vk_device { device }, m_vk_device_table { as_ref(device_table) }, - m_vk_handle { std::move(set) }, m_deleter { std::move(deleter) } { + : m_vk_device { device }, + m_vk_device_table { as_ref(device_table) }, + m_vk_handle { std::move(set) }, + m_deleter { std::move(deleter) } { } ///////////////////////////////////// @@ -258,7 +235,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorSet::DescriptorSet(DescriptorSet&&) noexcept = default; + inline DescriptorSet::DescriptorSet(DescriptorSet&&) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// @@ -277,69 +255,61 @@ namespace stormkit::gpu { writes.reserve(std::size(descriptors)); auto dst = 0u; - std::ranges:: - for_each(descriptors, - core::monadic::either( - [vk_handle = m_vk_handle, - &buffers, - &writes, - &dst](const BufferDescriptor& descriptor) mutable noexcept - -> decltype(auto) { - buffers.push_back(VkDescriptorBufferInfo { - .buffer = to_vk(descriptor.buffer), - .offset = descriptor.offset, - .range = descriptor.range, - }); - const auto& buffer_descriptor = buffers.back(); - - writes.push_back(VkWriteDescriptorSet { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = vk_handle, - .dstBinding = dst++, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .pImageInfo = nullptr, - .pBufferInfo = &buffer_descriptor, - .pTexelBufferView = nullptr, - }); - }, - [vk_handle = m_vk_handle, - &images, - &writes, - &dst](const ImageDescriptor& descriptor) mutable noexcept - -> decltype(auto) { - images.push_back(VkDescriptorImageInfo { - .sampler = to_vk(descriptor.sampler), - .imageView = to_vk(descriptor.image_view), - .imageLayout = narrow(descriptor.layout), - }); - const auto& image_descriptor = images.back(); - - writes.push_back(VkWriteDescriptorSet { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = vk_handle, - .dstBinding = dst++, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .pImageInfo = &image_descriptor, - .pBufferInfo = nullptr, - .pTexelBufferView = nullptr, - }); - })); + std::ranges::for_each(descriptors, + core::monadic::either( + [vk_handle = m_vk_handle, + &buffers, + &writes, + &dst](const BufferDescriptor& descriptor) mutable noexcept -> decltype(auto) { + buffers.push_back(VkDescriptorBufferInfo { + .buffer = to_vk(descriptor.buffer), + .offset = descriptor.offset, + .range = descriptor.range, + }); + const auto& buffer_descriptor = buffers.back(); + + writes.push_back(VkWriteDescriptorSet { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = nullptr, + .dstSet = vk_handle, + .dstBinding = dst++, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .pImageInfo = nullptr, + .pBufferInfo = &buffer_descriptor, + .pTexelBufferView = nullptr, + }); + }, + [vk_handle = m_vk_handle, + &images, + &writes, + &dst](const ImageDescriptor& descriptor) mutable noexcept -> decltype(auto) { + images.push_back(VkDescriptorImageInfo { + .sampler = to_vk(descriptor.sampler), + .imageView = to_vk(descriptor.image_view), + .imageLayout = narrow(descriptor.layout), + }); + const auto& image_descriptor = images.back(); + + writes.push_back(VkWriteDescriptorSet { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = nullptr, + .dstSet = vk_handle, + .dstBinding = dst++, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .pImageInfo = &image_descriptor, + .pBufferInfo = nullptr, + .pTexelBufferView = nullptr, + }); + })); return std::tuple { std::move(buffers), std::move(images), std::move(writes) }; }(); - vk_call(m_vk_device_table->vkUpdateDescriptorSets, - m_vk_device, - stdr::size(_writes), - stdr::data(_writes), - 0, - nullptr); + vk_call(m_vk_device_table->vkUpdateDescriptorSets, m_vk_device, stdr::size(_writes), stdr::data(_writes), 0, nullptr); } ///////////////////////////////////// @@ -352,14 +322,13 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorSetLayout::DescriptorSetLayout(const Device& device, - std::vector&& - bindings, + inline DescriptorSetLayout::DescriptorSetLayout(const Device& device, + std::vector&& bindings, PrivateFuncTag) noexcept - : m_bindings { std::move(bindings) }, m_vk_device { device.native_handle() }, + : m_bindings { std::move(bindings) }, + m_vk_device { device.native_handle() }, m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { { [vk_device_table = m_vk_device_table, - vk_device = m_vk_device](VkDescriptorSetLayout handle) noexcept { + m_vk_handle { { [vk_device_table = m_vk_device_table, vk_device = m_vk_device](VkDescriptorSetLayout handle) noexcept { if (handle) vk_device_table->vkDestroyDescriptorSetLayout(vk_device, handle, nullptr); } } } { } @@ -367,9 +336,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorSetLayout::create(const Device& device, - std::vector - bindings) noexcept -> Expected { + inline auto DescriptorSetLayout::create(const Device& device, std::vector bindings) noexcept + -> Expected { auto layout = DescriptorSetLayout { device, std::move(bindings), PrivateFuncTag {} }; return layout.do_init().transform(core::monadic::consume(layout)); } @@ -377,31 +345,28 @@ namespace stormkit::gpu { ////////////////////////////////////p/ ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorSetLayout::allocate(const Device& device, - std::vector - bindings) noexcept + inline auto DescriptorSetLayout::allocate(const Device& device, std::vector bindings) noexcept -> Expected> { - auto layout = allocate_unsafe(device, - std::move(bindings), - PrivateFuncTag {}); + auto layout = allocate_unsafe(device, std::move(bindings), PrivateFuncTag {}); return layout->do_init().transform(core::monadic::consume(layout)); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorSetLayout::~DescriptorSetLayout() noexcept = default; + inline DescriptorSetLayout::~DescriptorSetLayout() noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorSetLayout::DescriptorSetLayout(DescriptorSetLayout&& other) noexcept = default; + inline DescriptorSetLayout::DescriptorSetLayout(DescriptorSetLayout&& other) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorSetLayout::operator=(DescriptorSetLayout&& other) noexcept - -> DescriptorSetLayout& = default; + inline auto DescriptorSetLayout::operator=(DescriptorSetLayout&& other) noexcept -> DescriptorSetLayout& = default; ///////////////////////////////////// ///////////////////////////////////// @@ -413,8 +378,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorSetLayout::bindings() const noexcept - -> const std::vector& { + inline auto DescriptorSetLayout::bindings() const noexcept -> const std::vector& { return m_bindings; } @@ -428,8 +392,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorSetLayout::operator==(const DescriptorSetLayout& second) const noexcept - -> bool { + inline auto DescriptorSetLayout::operator==(const DescriptorSetLayout& second) const noexcept -> bool { return m_hash == second.hash(); } @@ -438,13 +401,12 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto DescriptorSetLayout::do_init() noexcept -> Expected { const auto vk_bindings = m_bindings - | std::views::transform([](const DescriptorSetLayoutBinding& - binding) static noexcept { + | std::views::transform([](const DescriptorSetLayoutBinding& binding) static noexcept { return VkDescriptorSetLayoutBinding { - .binding = binding.binding, - .descriptorType = to_vk(binding.type), - .descriptorCount = as(binding.descriptor_count), - .stageFlags = to_vk(binding.stages), + .binding = binding.binding, + .descriptorType = to_vk(binding.type), + .descriptorCount = as(binding.descriptor_count), + .stageFlags = to_vk(binding.stages), .pImmutableSamplers = nullptr, }; }) @@ -458,10 +420,7 @@ namespace stormkit::gpu { .pBindings = std::ranges::data(vk_bindings) }; - return vk_call(m_vk_device_table->vkCreateDescriptorSetLayout, - m_vk_device, - &create_info, - nullptr) + return vk_call(m_vk_device_table->vkCreateDescriptorSetLayout, m_vk_device, &create_info, nullptr) .transform(core::monadic::set(m_vk_handle)) .transform_error(monadic::from_vk()); } @@ -472,8 +431,7 @@ namespace stormkit::gpu { inline DescriptorPool::DescriptorPool(const Device& device, PrivateFuncTag) noexcept : m_vk_device { device.native_handle() }, m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { { [vk_device = m_vk_device, - vk_device_table = m_vk_device_table](VkDescriptorPool handle) noexcept { + m_vk_handle { { [vk_device = m_vk_device, vk_device_table = m_vk_device_table](VkDescriptorPool handle) noexcept { vk_device_table->vkDestroyDescriptorPool(vk_device, handle, nullptr); } } } { } @@ -481,9 +439,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorPool::create(const Device& device, - std::span extents, - u32 max_sets) noexcept -> Expected { + inline auto DescriptorPool::create(const Device& device, std::span extents, u32 max_sets) noexcept + -> Expected { auto pool = DescriptorPool { device, PrivateFuncTag {} }; return pool.do_init(extents, max_sets).transform(core::monadic::consume(pool)); } @@ -491,9 +448,8 @@ namespace stormkit::gpu { ////////////////////////////////////p/ ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorPool::allocate(const Device& device, - std::span extents, - u32 max_sets) noexcept -> Expected> { + inline auto DescriptorPool::allocate(const Device& device, std::span extents, u32 max_sets) noexcept + -> Expected> { auto pool = allocate_unsafe(device, PrivateFuncTag {}); return pool->do_init(extents, max_sets).transform(core::monadic::consume(pool)); } @@ -501,42 +457,38 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorPool::~DescriptorPool() noexcept = default; + inline DescriptorPool::~DescriptorPool() noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorPool::DescriptorPool(DescriptorPool&& other) noexcept = default; + inline DescriptorPool::DescriptorPool(DescriptorPool&& other) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorPool::operator=(DescriptorPool&& other) noexcept - -> DescriptorPool& = default; + inline auto DescriptorPool::operator=(DescriptorPool&& other) noexcept -> DescriptorPool& = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - auto DescriptorPool::create_descriptor_set(const DescriptorSetLayout& layout) const noexcept - -> Expected { + auto DescriptorPool::create_descriptor_set(const DescriptorSetLayout& layout) const noexcept -> Expected { return create_descriptor_sets(1, layout) - .transform([](std::vector&& sets) static noexcept { - return std::move(sets.front()); - }); + .transform([](std::vector&& sets) static noexcept { return std::move(sets.front()); }); } ///////////////////////////////////// ///////////////////////////////////// - inline auto DescriptorPool::create_descriptor_sets(usize count, - const DescriptorSetLayout& layout) - const noexcept -> Expected> { + inline auto DescriptorPool::create_descriptor_sets(usize count, const DescriptorSetLayout& layout) const noexcept + -> Expected> { auto tag = DescriptorSet::PrivateFuncTag {}; return create_vk_descriptor_sets(count, layout) .transform([this, &tag](std::vector&& sets) noexcept { return std::move(sets) | stdv::as_rvalue - | stdv::transform([this, - &tag](VkDescriptorSet&& set) noexcept -> decltype(auto) { + | stdv::transform([this, &tag](VkDescriptorSet&& set) noexcept -> decltype(auto) { return DescriptorSet { m_vk_device, *m_vk_device_table, std::move(set), @@ -554,29 +506,24 @@ namespace stormkit::gpu { auto DescriptorPool::allocate_descriptor_set(const DescriptorSetLayout& layout) const noexcept -> Expected> { return allocate_descriptor_sets(1, layout) - .transform([](std::vector>&& sets) static noexcept { - return std::move(sets.front()); - }); + .transform([](std::vector>&& sets) static noexcept { return std::move(sets.front()); }); } ///////////////////////////////////// ///////////////////////////////////// - inline auto DescriptorPool::allocate_descriptor_sets(usize count, - const DescriptorSetLayout& layout) - const noexcept -> Expected>> { + inline auto DescriptorPool::allocate_descriptor_sets(usize count, const DescriptorSetLayout& layout) const noexcept + -> Expected>> { auto tag = DescriptorSet::PrivateFuncTag {}; return create_vk_descriptor_sets(count, layout) .transform([this, &tag](std::vector&& sets) noexcept { return std::move(sets) | stdv::as_rvalue - | stdv::transform([this, - &tag](VkDescriptorSet&& set) noexcept -> decltype(auto) { - return core::allocate_unsafe< - DescriptorSet>(m_vk_device, - *m_vk_device_table, - std::move(set), - DescriptorPool::delete_vk_descriptor_set, - tag); + | stdv::transform([this, &tag](VkDescriptorSet&& set) noexcept -> decltype(auto) { + return core::allocate_unsafe(m_vk_device, + *m_vk_device_table, + std::move(set), + DescriptorPool::delete_vk_descriptor_set, + tag); }) | stdr::to(); }) @@ -593,8 +540,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorPool::do_init(std::span sizes, u32 max_sets) noexcept - -> Expected { + inline auto DescriptorPool::do_init(std::span sizes, u32 max_sets) noexcept -> Expected { const auto pool_sizes = sizes | std::views::transform([](const Size& size) static noexcept { return VkDescriptorPoolSize { @@ -613,18 +559,14 @@ namespace stormkit::gpu { .pPoolSizes = std::ranges::data(pool_sizes), }; - return vk_call(m_vk_device_table->vkCreateDescriptorPool, - m_vk_device, - &create_info, - nullptr) + return vk_call(m_vk_device_table->vkCreateDescriptorPool, m_vk_device, &create_info, nullptr) .transform(core::monadic::set(m_vk_handle)) .transform_error(monadic::from_vk()); } ///////////////////////////////////// ///////////////////////////////////// - inline auto DescriptorPool::create_vk_descriptor_sets(usize count, - const DescriptorSetLayout& layout) const + inline auto DescriptorPool::create_vk_descriptor_sets(usize count, const DescriptorSetLayout& layout) const -> VulkanExpected> { const auto vk_layout = to_vk(layout); const auto allocate_info = VkDescriptorSetAllocateInfo { @@ -635,10 +577,7 @@ namespace stormkit::gpu { .pSetLayouts = &vk_layout, }; - return vk_allocate(count, - m_vk_device_table->vkAllocateDescriptorSets, - m_vk_device, - &allocate_info); + return vk_allocate(count, m_vk_device_table->vkAllocateDescriptorSets, m_vk_device, &allocate_info); } ///////////////////////////////////// diff --git a/modules/stormkit/gpu/execution/pipeline.mpp b/modules/stormkit/gpu/execution/pipeline.mpp index 83645c0a4..2873d2390 100644 --- a/modules/stormkit/gpu/execution/pipeline.mpp +++ b/modules/stormkit/gpu/execution/pipeline.mpp @@ -34,8 +34,7 @@ export namespace stormkit::gpu { static constexpr auto DEBUG_TYPE = DebugObjectType::PIPELINE_CACHE; - static auto try_load(const Device& device, std::filesystem::path cache_path) noexcept - -> LoadSaveExpected; + static auto try_load(const Device& device, std::filesystem::path cache_path) noexcept -> LoadSaveExpected; ~PipelineCache() noexcept; PipelineCache(const PipelineCache&) = delete; @@ -89,8 +88,7 @@ export namespace stormkit::gpu { public: static constexpr auto DEBUG_TYPE = DebugObjectType::PIPELINE_LAYOUT; - static auto create(const Device& device, const RasterPipelineLayout& layout) noexcept - -> Expected; + static auto create(const Device& device, const RasterPipelineLayout& layout) noexcept -> Expected; ~PipelineLayout() noexcept; PipelineLayout(const PipelineLayout&) = delete; @@ -105,9 +103,7 @@ export namespace stormkit::gpu { [[nodiscard]] auto native_handle() const noexcept -> VkPipelineLayout; - PipelineLayout(const Device& device, - const RasterPipelineLayout& layout, - PrivateFuncTag) noexcept; + PipelineLayout(const Device& device, const RasterPipelineLayout& layout, PrivateFuncTag) noexcept; private: auto do_init() noexcept -> Expected; @@ -133,8 +129,7 @@ export namespace stormkit::gpu { const RasterPipelineState& state, const PipelineLayout& layout, const RenderPass& render_pass, - OptionalRef cache = std::nullopt) noexcept - -> Expected; + OptionalRef cache = std::nullopt) noexcept -> Expected; ~Pipeline() noexcept; Pipeline(const Pipeline&) = delete; @@ -156,9 +151,7 @@ export namespace stormkit::gpu { Pipeline(const Device&, const RasterPipelineState&, PrivateFuncTag) noexcept; private: - auto do_init(const PipelineLayout&, - const RenderPass&, - OptionalRef) noexcept -> Expected; + auto do_init(const PipelineLayout&, const RenderPass&, OptionalRef) noexcept -> Expected; Type m_type; std::variant m_state; @@ -177,13 +170,11 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline PipelineCache::PipelineCache(const Device& device, - std::filesystem::path path, - PrivateFuncTag) noexcept - : m_path { std::move(path) }, m_vk_device { device.native_handle() }, + inline PipelineCache::PipelineCache(const Device& device, std::filesystem::path path, PrivateFuncTag) noexcept + : m_path { std::move(path) }, + m_vk_device { device.native_handle() }, m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { { [vk_device_table = *m_vk_device_table, - vk_device = m_vk_device](auto handle) noexcept { + m_vk_handle { { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { vk_device_table.vkDestroyPipelineCache(vk_device, handle, nullptr); } } } { } @@ -191,19 +182,18 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline PipelineCache::PipelineCache(PipelineCache&& other) noexcept = default; + inline PipelineCache::PipelineCache(PipelineCache&& other) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto PipelineCache::operator=(PipelineCache&& other) noexcept - -> PipelineCache& = default; + inline auto PipelineCache::operator=(PipelineCache&& other) noexcept -> PipelineCache& = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto PipelineCache::try_load(const Device& device, - std::filesystem::path cache_path) noexcept + inline auto PipelineCache::try_load(const Device& device, std::filesystem::path cache_path) noexcept -> LoadSaveExpected { auto cache = PipelineCache { device, std::move(cache_path), PrivateFuncTag {} }; Try(cache.do_init(device)); @@ -227,13 +217,11 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline PipelineLayout::PipelineLayout(const Device& device, - const RasterPipelineLayout& layout, - PrivateFuncTag) noexcept - : m_layout { layout }, m_vk_device { device.native_handle() }, + inline PipelineLayout::PipelineLayout(const Device& device, const RasterPipelineLayout& layout, PrivateFuncTag) noexcept + : m_layout { layout }, + m_vk_device { device.native_handle() }, m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { { [vk_device_table = *m_vk_device_table, - vk_device = m_vk_device](auto handle) noexcept { + m_vk_handle { { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { vk_device_table.vkDestroyPipelineLayout(vk_device, handle, nullptr); } } } { } @@ -241,24 +229,24 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline PipelineLayout::~PipelineLayout() noexcept = default; + inline PipelineLayout::~PipelineLayout() noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline PipelineLayout::PipelineLayout(PipelineLayout&& other) noexcept = default; + inline PipelineLayout::PipelineLayout(PipelineLayout&& other) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto PipelineLayout::operator=(PipelineLayout&& other) noexcept - -> PipelineLayout& = default; + inline auto PipelineLayout::operator=(PipelineLayout&& other) noexcept -> PipelineLayout& = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto PipelineLayout::create(const Device& device, - const RasterPipelineLayout& layout) noexcept + inline auto PipelineLayout::create(const Device& device, const RasterPipelineLayout& layout) noexcept -> Expected { auto pipeline_layout = PipelineLayout { device, layout, PrivateFuncTag {} }; Try(pipeline_layout.do_init()); @@ -283,17 +271,15 @@ namespace stormkit::gpu { | stdv::transform(monadic::to_vk()) | stdr::to(); - const auto - push_constant_ranges = m_layout.push_constant_ranges - | stdv::transform([](auto&& push_constant_range) noexcept { - return VkPushConstantRange { - .stageFlags = to_vk< - VkShaderStageFlags>(push_constant_range.stages), - .offset = push_constant_range.offset, - .size = as(push_constant_range.size), - }; - }) - | stdr::to(); + const auto push_constant_ranges = m_layout.push_constant_ranges + | stdv::transform([](auto&& push_constant_range) noexcept { + return VkPushConstantRange { + .stageFlags = to_vk(push_constant_range.stages), + .offset = push_constant_range.offset, + .size = as(push_constant_range.size), + }; + }) + | stdr::to(); const auto create_info = VkPipelineLayoutCreateInfo { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, @@ -305,10 +291,7 @@ namespace stormkit::gpu { .pPushConstantRanges = stdr::data(push_constant_ranges), }; - m_vk_handle = Try(vk_call(m_vk_device_table->vkCreatePipelineLayout, - m_vk_device, - &create_info, - nullptr) + m_vk_handle = Try(vk_call(m_vk_device_table->vkCreatePipelineLayout, m_vk_device, &create_info, nullptr) .transform_error(monadic::from_vk())); Ret({}); @@ -317,13 +300,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Pipeline::Pipeline(const Device& device, - const RasterPipelineState& state, - PrivateFuncTag) noexcept - : m_type { Type::RASTER }, m_state { state }, m_vk_device { device.native_handle() }, + inline Pipeline::Pipeline(const Device& device, const RasterPipelineState& state, PrivateFuncTag) noexcept + : m_type { Type::RASTER }, + m_state { state }, + m_vk_device { device.native_handle() }, m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { { [vk_device_table = *m_vk_device_table, - vk_device = m_vk_device](auto handle) noexcept { + m_vk_handle { { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { vk_device_table.vkDestroyPipeline(vk_device, handle, nullptr); } } } { } @@ -335,8 +317,7 @@ namespace stormkit::gpu { const RasterPipelineState& state, const PipelineLayout& layout, const RenderPass& render_pass, - OptionalRef cache) noexcept - -> Expected { + OptionalRef cache) noexcept -> Expected { auto pipeline = Pipeline { device, state, PrivateFuncTag {} }; Try(pipeline.do_init(layout, render_pass, std::move(cache))); Ret(pipeline); @@ -345,12 +326,14 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Pipeline::~Pipeline() noexcept = default; + inline Pipeline::~Pipeline() noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Pipeline::Pipeline(Pipeline&& other) noexcept = default; + inline Pipeline::Pipeline(Pipeline&& other) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// diff --git a/modules/stormkit/gpu/execution/raster_pipeline.mpp b/modules/stormkit/gpu/execution/raster_pipeline.mpp index abdcec973..d763be178 100644 --- a/modules/stormkit/gpu/execution/raster_pipeline.mpp +++ b/modules/stormkit/gpu/execution/raster_pipeline.mpp @@ -84,9 +84,9 @@ export namespace stormkit::gpu { struct RasterPipelineColorBlendState { bool logic_operation_enable = false; - LogicOperation logic_operation = LogicOperation::COPY; + LogicOperation logic_operation = LogicOperation::COPY; std::vector attachments; - std::array blend_constants = { 0.f, 0.f, 0.f, 0.f }; + std::array blend_constants = { 0.f, 0.f, 0.f, 0.f }; }; using RasterPipelineDynamicState = std::vector; diff --git a/modules/stormkit/gpu/execution/render_pass.mpp b/modules/stormkit/gpu/execution/render_pass.mpp index 2809f6ebd..91649fa55 100644 --- a/modules/stormkit/gpu/execution/render_pass.mpp +++ b/modules/stormkit/gpu/execution/render_pass.mpp @@ -31,13 +31,11 @@ export { static auto create(const Device& device, const RenderPass& render_pass, const math::Extent2& extent, - std::vector> attachments) noexcept - -> Expected; + std::vector> attachments) noexcept -> Expected; static auto allocate(const Device& device, const RenderPass& render_pass, const math::Extent2& extent, - std::vector> attachments) noexcept - -> Expected>; + std::vector> attachments) noexcept -> Expected>; ~FrameBuffer() noexcept; FrameBuffer(const FrameBuffer&) = delete; @@ -54,10 +52,7 @@ export { [[nodiscard]] auto native_handle() const noexcept -> VkFramebuffer; - FrameBuffer(const Device&, - const math::Extent2&, - std::vector>, - PrivateFuncTag) noexcept; + FrameBuffer(const Device&, const math::Extent2&, std::vector>, PrivateFuncTag) noexcept; private: auto do_init(const RenderPass&) noexcept -> Expected; @@ -116,11 +111,8 @@ export { public: static constexpr auto DEBUG_TYPE = DebugObjectType::RENDER_PASS; - static auto create(const Device& device, - const RenderPassDescription& description) noexcept - -> Expected; - static auto allocate(const Device& device, - const RenderPassDescription& description) noexcept + static auto create(const Device& device, const RenderPassDescription& description) noexcept -> Expected; + static auto allocate(const Device& device, const RenderPassDescription& description) noexcept -> Expected>; ~RenderPass() noexcept; @@ -132,8 +124,7 @@ export { auto create_frame_buffer(const Device& device, const math::Extent2& extent, - std::vector> attachments) const noexcept - -> Expected; + std::vector> attachments) const noexcept -> Expected; auto allocate_frame_buffer(const Device& device, const math::Extent2& extent, std::vector> attachments) const noexcept @@ -150,9 +141,7 @@ export { [[nodiscard]] auto native_handle() const noexcept -> VkRenderPass; - RenderPass(const Device& device, - const RenderPassDescription& description, - PrivateFuncTag) noexcept; + RenderPass(const Device& device, const RenderPassDescription& description, PrivateFuncTag) noexcept; private: auto do_init() noexcept -> Expected; @@ -169,29 +158,25 @@ export { template<> struct hash { [[nodiscard]] - constexpr auto operator()(const stormkit::gpu::AttachmentDescription&) const noexcept - -> stormkit::hash64; + constexpr auto operator()(const stormkit::gpu::AttachmentDescription&) const noexcept -> stormkit::hash64; }; template<> struct hash { [[nodiscard]] - constexpr auto operator()(const stormkit::gpu::Subpass::Ref&) const noexcept - -> stormkit::hash64; + constexpr auto operator()(const stormkit::gpu::Subpass::Ref&) const noexcept -> stormkit::hash64; }; template<> struct hash { [[nodiscard]] - constexpr auto operator()(const stormkit::gpu::Subpass&) const noexcept - -> stormkit::hash64; + constexpr auto operator()(const stormkit::gpu::Subpass&) const noexcept -> stormkit::hash64; }; template<> struct hash { [[nodiscard]] - constexpr auto operator()(const stormkit::gpu::RenderPassDescription&) const noexcept - -> stormkit::hash64; + constexpr auto operator()(const stormkit::gpu::RenderPassDescription&) const noexcept -> stormkit::hash64; }; } // namespace std } @@ -208,11 +193,11 @@ namespace stormkit::gpu { const math::Extent2& extent, std::vector> attachments, PrivateFuncTag) noexcept - : m_extent { extent }, m_attachments { std::move(attachments) }, + : m_extent { extent }, + m_attachments { std::move(attachments) }, m_vk_device { device.native_handle() }, m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { { [vk_device_table = *m_vk_device_table, - vk_device = m_vk_device](auto handle) noexcept { + m_vk_handle { { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { vk_device_table.vkDestroyFramebuffer(vk_device, handle, nullptr); } } } { } @@ -223,10 +208,8 @@ namespace stormkit::gpu { inline auto FrameBuffer::create(const Device& device, const RenderPass& render_pass, const math::Extent2& extent, - std::vector> attachments) noexcept - -> Expected { - auto - frame_buffer = FrameBuffer { device, extent, std::move(attachments), PrivateFuncTag {} }; + std::vector> attachments) noexcept -> Expected { + auto frame_buffer = FrameBuffer { device, extent, std::move(attachments), PrivateFuncTag {} }; return frame_buffer.do_init(render_pass).transform(core::monadic::consume(frame_buffer)); } @@ -236,24 +219,22 @@ namespace stormkit::gpu { inline auto FrameBuffer::allocate(const Device& device, const RenderPass& render_pass, const math::Extent2& extent, - std::vector> attachments) noexcept - -> Expected> { - auto frame_buffer = allocate_unsafe(device, - extent, - std::move(attachments), - PrivateFuncTag {}); + std::vector> attachments) noexcept -> Expected> { + auto frame_buffer = allocate_unsafe(device, extent, std::move(attachments), PrivateFuncTag {}); return frame_buffer->do_init(render_pass).transform(core::monadic::consume(frame_buffer)); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline FrameBuffer::~FrameBuffer() noexcept = default; + inline FrameBuffer::~FrameBuffer() noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline FrameBuffer::FrameBuffer(FrameBuffer&& other) noexcept = default; + inline FrameBuffer::FrameBuffer(FrameBuffer&& other) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// @@ -270,8 +251,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto FrameBuffer::attachments() const noexcept - -> const std::vector>& { + inline auto FrameBuffer::attachments() const noexcept -> const std::vector>& { return m_attachments; } @@ -302,10 +282,7 @@ namespace stormkit::gpu { .layers = 1, }; - return vk_call(m_vk_device_table->vkCreateFramebuffer, - m_vk_device, - &create_info, - nullptr) + return vk_call(m_vk_device_table->vkCreateFramebuffer, m_vk_device, &create_info, nullptr) .transform(core::monadic::set(m_vk_handle)) .transform_error(monadic::from_vk()); } @@ -313,13 +290,11 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline RenderPass::RenderPass(const Device& device, - const RenderPassDescription& description, - PrivateFuncTag) noexcept - : m_description { description }, m_vk_device { device.native_handle() }, + inline RenderPass::RenderPass(const Device& device, const RenderPassDescription& description, PrivateFuncTag) noexcept + : m_description { description }, + m_vk_device { device.native_handle() }, m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { { [vk_device_table = *m_vk_device_table, - vk_device = m_vk_device](auto handle) noexcept { + m_vk_handle { { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { vk_device_table.vkDestroyRenderPass(vk_device, handle, nullptr); } } } { } @@ -327,8 +302,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - auto RenderPass::create(const Device& device, const RenderPassDescription& description) noexcept - -> Expected { + auto RenderPass::create(const Device& device, const RenderPassDescription& description) noexcept -> Expected { auto render_pass = RenderPass { device, description, PrivateFuncTag {} }; return render_pass.do_init().transform(core::monadic::consume(render_pass)); } @@ -336,8 +310,7 @@ namespace stormkit::gpu { ////////////////////////////////////p/ ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto RenderPass::allocate(const Device& device, - const RenderPassDescription& description) noexcept + inline auto RenderPass::allocate(const Device& device, const RenderPassDescription& description) noexcept -> Expected> { auto render_pass = allocate_unsafe(device, description, PrivateFuncTag {}); return render_pass->do_init().transform(core::monadic::consume(render_pass)); @@ -346,12 +319,14 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline RenderPass::~RenderPass() noexcept = default; + inline RenderPass::~RenderPass() noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline RenderPass::RenderPass(RenderPass&& other) noexcept = default; + inline RenderPass::RenderPass(RenderPass&& other) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// @@ -363,8 +338,8 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto RenderPass::create_frame_buffer(const Device& device, const math::Extent2& extent, - std::vector> attachments) - const noexcept -> Expected { + std::vector> attachments) const noexcept + -> Expected { return FrameBuffer::create(device, *this, extent, std::move(attachments)); } @@ -373,8 +348,8 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto RenderPass::allocate_frame_buffer(const Device& device, const math::Extent2& extent, - std::vector> attachments) - const noexcept -> Expected> { + std::vector> attachments) const noexcept + -> Expected> { return FrameBuffer::allocate(device, *this, extent, std::move(attachments)); } @@ -403,8 +378,8 @@ namespace stormkit::gpu { } } // namespace stormkit::gpu -constexpr auto std::hash:: - operator()(const stormkit::gpu::AttachmentDescription& value) const noexcept -> stormkit::hash64 { +constexpr auto std::hash::operator()(const stormkit::gpu::AttachmentDescription& value) + const noexcept -> stormkit::hash64 { auto hash = stormkit::hash64 { 0 }; stormkit::hash_combine(hash, value.format, @@ -419,16 +394,15 @@ constexpr auto std::hash:: return hash; } -constexpr auto std::hash::operator()(const stormkit::gpu::Subpass::Ref& - value) const noexcept +constexpr auto std::hash::operator()(const stormkit::gpu::Subpass::Ref& value) const noexcept -> stormkit::hash64 { auto hash = stormkit::hash64 { 0 }; stormkit::hash_combine(hash, value.attachment_id, value.layout); return hash; } -constexpr auto std::hash::operator()(const stormkit::gpu::Subpass& value) - const noexcept -> stormkit::hash64 { +constexpr auto std::hash::operator()(const stormkit::gpu::Subpass& value) const noexcept + -> stormkit::hash64 { auto hash = stormkit::hash64 { 0 }; stormkit::hash_combine(hash, value.bind_point, @@ -438,8 +412,8 @@ constexpr auto std::hash::operator()(const stormkit::gpu return hash; } -constexpr auto std::hash:: - operator()(const stormkit::gpu::RenderPassDescription& value) const noexcept -> stormkit::hash64 { +constexpr auto std::hash::operator()(const stormkit::gpu::RenderPassDescription& value) + const noexcept -> stormkit::hash64 { auto hash = stormkit::hash64 { 0 }; stormkit::hash_combine(hash, value.attachments, value.subpasses); return hash; diff --git a/modules/stormkit/gpu/execution/swapchain.mpp b/modules/stormkit/gpu/execution/swapchain.mpp index 10ec92de6..46284e2cb 100644 --- a/modules/stormkit/gpu/execution/swapchain.mpp +++ b/modules/stormkit/gpu/execution/swapchain.mpp @@ -33,13 +33,11 @@ export namespace stormkit::gpu { static auto create(const Device& device, const Surface& surface, const math::Extent2& extent, - OptionalRef old_swapchain = std::nullopt) noexcept - -> Expected; + OptionalRef old_swapchain = std::nullopt) noexcept -> Expected; static auto allocate(const Device& device, const Surface& surface, const math::Extent2& extent, - OptionalRef old_swapchain = std::nullopt) noexcept - -> Expected>; + OptionalRef old_swapchain = std::nullopt) noexcept -> Expected>; ~SwapChain(); SwapChain(const SwapChain&) = delete; @@ -52,8 +50,7 @@ export namespace stormkit::gpu { auto pixel_format() const noexcept -> PixelFormat; [[nodiscard]] auto images() const noexcept -> const std::vector&; - auto acquire_next_image(std::chrono::nanoseconds wait, - const Semaphore& image_available) const noexcept + auto acquire_next_image(std::chrono::nanoseconds wait, const Semaphore& image_available) const noexcept -> Expected; [[nodiscard]] @@ -62,10 +59,7 @@ export namespace stormkit::gpu { SwapChain(const Device&, PrivateFuncTag) noexcept; private: - auto do_init(const Device&, - const Surface&, - const math::Extent2&, - VkSwapchainKHR) noexcept -> Expected; + auto do_init(const Device&, const Surface&, const math::Extent2&, VkSwapchainKHR) noexcept -> Expected; math::Extent2 m_extent; PixelFormat m_pixel_format; @@ -87,8 +81,7 @@ namespace stormkit::gpu { inline SwapChain::SwapChain(const Device& device, PrivateFuncTag) noexcept : m_vk_device { device.native_handle() }, m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { [vk_device_table = *m_vk_device_table, - vk_device = m_vk_device](auto&& handle) noexcept { + m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto&& handle) noexcept { vk_device_table.vkDestroySwapchainKHR(vk_device, handle, nullptr); } } { } @@ -96,12 +89,14 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline SwapChain::~SwapChain() = default; + inline SwapChain::~SwapChain() + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline SwapChain::SwapChain(SwapChain&&) noexcept = default; + inline SwapChain::SwapChain(SwapChain&&) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// @@ -114,14 +109,9 @@ namespace stormkit::gpu { inline auto SwapChain::create(const Device& device, const Surface& surface, const math::Extent2& extent, - OptionalRef old_swapchain) noexcept - -> Expected { + OptionalRef old_swapchain) noexcept -> Expected { auto swapchain = SwapChain { device, PrivateFuncTag {} }; - return swapchain - .do_init(device, - surface, - extent, - old_swapchain ? old_swapchain->native_handle() : nullptr) + return swapchain.do_init(device, surface, extent, old_swapchain ? old_swapchain->native_handle() : nullptr) .transform(core::monadic::consume(swapchain)); } @@ -131,14 +121,9 @@ namespace stormkit::gpu { inline auto SwapChain::allocate(const Device& device, const Surface& surface, const math::Extent2& extent, - OptionalRef old_swapchain) noexcept - -> Expected> { + OptionalRef old_swapchain) noexcept -> Expected> { auto swapchain = std::make_unique(device, PrivateFuncTag {}); - return swapchain - ->do_init(device, - surface, - extent, - old_swapchain ? old_swapchain->native_handle() : nullptr) + return swapchain->do_init(device, surface, extent, old_swapchain ? old_swapchain->native_handle() : nullptr) .transform(core::monadic::consume(swapchain)); } diff --git a/modules/stormkit/gpu/resource/buffer.mpp b/modules/stormkit/gpu/resource/buffer.mpp index 47352871c..350c16b1d 100644 --- a/modules/stormkit/gpu/resource/buffer.mpp +++ b/modules/stormkit/gpu/resource/buffer.mpp @@ -153,7 +153,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Buffer::Buffer(Buffer&& other) noexcept = default; + inline Buffer::Buffer(Buffer&& other) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// diff --git a/modules/stormkit/gpu/resource/image.mpp b/modules/stormkit/gpu/resource/image.mpp index cfc4c3848..7beb2dd3d 100644 --- a/modules/stormkit/gpu/resource/image.mpp +++ b/modules/stormkit/gpu/resource/image.mpp @@ -49,10 +49,8 @@ export namespace stormkit::gpu { static constexpr auto DEBUG_TYPE = DebugObjectType::SAMPLER; - static auto create(const Device& device, const Settings& settings) noexcept - -> Expected; - static auto allocate(const Device& device, const Settings& settings) noexcept - -> Expected>; + static auto create(const Device& device, const Settings& settings) noexcept -> Expected; + static auto allocate(const Device& device, const Settings& settings) noexcept -> Expected>; ~Sampler(); Sampler(const Sampler&) = delete; @@ -90,13 +88,11 @@ export namespace stormkit::gpu { static auto create(const Device& device, const Image& image, ImageViewType type = ImageViewType::T2D, - const ImageSubresourceRange& subresource_range = {}) noexcept - -> Expected; + const ImageSubresourceRange& subresource_range = {}) noexcept -> Expected; static auto allocate(const Device& device, const Image& image, ImageViewType type = ImageViewType::T2D, - const ImageSubresourceRange& subresource_range = {}) noexcept - -> Expected>; + const ImageSubresourceRange& subresource_range = {}) noexcept -> Expected>; ~ImageView(); ImageView(const ImageView&) = delete; @@ -113,10 +109,7 @@ export namespace stormkit::gpu { [[nodiscard]] auto native_handle() const noexcept -> VkImageView; - ImageView(const Device&, - ImageViewType, - const ImageSubresourceRange&, - PrivateFuncTag) noexcept; + ImageView(const Device&, ImageViewType, const ImageSubresourceRange&, PrivateFuncTag) noexcept; private: auto do_init(const Image&) noexcept -> Expected; @@ -141,19 +134,15 @@ export namespace stormkit::gpu { ImageType type = ImageType::T2D; ImageCreateFlag flags = ImageCreateFlag::NONE; SampleCountFlag samples = SampleCountFlag::C1; - ImageUsageFlag usages = ImageUsageFlag::SAMPLED - | ImageUsageFlag::TRANSFER_DST - | ImageUsageFlag::TRANSFER_SRC; - ImageTiling tiling = ImageTiling::OPTIMAL; - MemoryPropertyFlag property = MemoryPropertyFlag::DEVICE_LOCAL; + ImageUsageFlag usages = ImageUsageFlag::SAMPLED | ImageUsageFlag::TRANSFER_DST | ImageUsageFlag::TRANSFER_SRC; + ImageTiling tiling = ImageTiling::OPTIMAL; + MemoryPropertyFlag property = MemoryPropertyFlag::DEVICE_LOCAL; }; static constexpr auto DEBUG_TYPE = DebugObjectType::IMAGE; - static auto create(const Device& device, const CreateInfo& info) noexcept - -> Expected; - static auto allocate(const Device& device, const CreateInfo& create_info) noexcept - -> Expected>; + static auto create(const Device& device, const CreateInfo& info) noexcept -> Expected; + static auto allocate(const Device& device, const CreateInfo& create_info) noexcept -> Expected>; ~Image(); Image(const Image&) = delete; @@ -252,10 +241,7 @@ namespace stormkit::gpu { .borderColor = to_vk(m_settings.border_color), .unnormalizedCoordinates = m_settings.unnormalized_coordinates }; - return vk_call(m_vk_device_table->vkCreateSampler, - m_vk_device, - &create_info, - nullptr) + return vk_call(m_vk_device_table->vkCreateSampler, m_vk_device, &create_info, nullptr) .transform(core::monadic::set(m_vk_handle)) .transform_error(monadic::from_vk()); } @@ -264,10 +250,10 @@ namespace stormkit::gpu { ///////////////////////////////////// STORMKIT_FORCE_INLINE inline Sampler::Sampler(const Device& device, const Settings& settings, PrivateFuncTag) noexcept - : m_settings { settings }, m_vk_device { device.native_handle() }, + : m_settings { settings }, + m_vk_device { device.native_handle() }, m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { [vk_device_table = *m_vk_device_table, - vk_device = m_vk_device](auto&& handle) noexcept { + m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto&& handle) noexcept { vk_device_table.vkDestroySampler(vk_device, handle, nullptr); } } { } @@ -275,12 +261,14 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Sampler::~Sampler() = default; + inline Sampler::~Sampler() + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Sampler::Sampler(Sampler&&) noexcept = default; + inline Sampler::Sampler(Sampler&&) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// @@ -290,8 +278,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Sampler::create(const Device& device, const Settings& settings) noexcept - -> Expected { + inline auto Sampler::create(const Device& device, const Settings& settings) noexcept -> Expected { auto sampler = Sampler { device, settings, PrivateFuncTag {} }; return sampler.do_init().transform(core::monadic::consume(sampler)); } @@ -299,8 +286,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Sampler::allocate(const Device& device, const Settings& settings) noexcept - -> Expected> { + inline auto Sampler::allocate(const Device& device, const Settings& settings) noexcept -> Expected> { auto sampler = std::make_unique(device, settings, PrivateFuncTag {}); return sampler->do_init().transform(core::monadic::consume(sampler)); } @@ -346,10 +332,7 @@ namespace stormkit::gpu { .subresourceRange = vk_subresource_range, }; - return vk_call(m_vk_device_table->vkCreateImageView, - m_vk_device, - &create_info, - nullptr) + return vk_call(m_vk_device_table->vkCreateImageView, m_vk_device, &create_info, nullptr) .transform(core::monadic::set(m_vk_handle)) .transform_error(monadic::from_vk()); } @@ -361,11 +344,11 @@ namespace stormkit::gpu { ImageViewType type, const ImageSubresourceRange& subresource_range, PrivateFuncTag) noexcept - : m_type { type }, m_subresource_range { subresource_range }, + : m_type { type }, + m_subresource_range { subresource_range }, m_vk_device { device.native_handle() }, m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { [vk_device_table = *m_vk_device_table, - vk_device = m_vk_device](auto&& handle) noexcept { + m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto&& handle) noexcept { vk_device_table.vkDestroyImageView(vk_device, handle, nullptr); } } { } @@ -373,12 +356,14 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline ImageView::~ImageView() = default; + inline ImageView::~ImageView() + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline ImageView::ImageView(ImageView&&) noexcept = default; + inline ImageView::ImageView(ImageView&&) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// @@ -391,8 +376,7 @@ namespace stormkit::gpu { inline auto ImageView::create(const Device& device, const Image& image, ImageViewType type, - const ImageSubresourceRange& subresource_range) noexcept - -> Expected { + const ImageSubresourceRange& subresource_range) noexcept -> Expected { auto image_view = ImageView { device, type, subresource_range, PrivateFuncTag {} }; return image_view.do_init(image).transform(core::monadic::consume(image_view)); } @@ -403,12 +387,8 @@ namespace stormkit::gpu { inline auto ImageView::allocate(const Device& device, const Image& image, ImageViewType type, - const ImageSubresourceRange& subresource_range) noexcept - -> Expected> { - auto image_view = std::make_unique(device, - type, - subresource_range, - PrivateFuncTag {}); + const ImageSubresourceRange& subresource_range) noexcept -> Expected> { + auto image_view = std::make_unique(device, type, subresource_range, PrivateFuncTag {}); return image_view->do_init(image).transform(core::monadic::consume(image_view)); } @@ -438,14 +418,19 @@ namespace stormkit::gpu { ///////////////////////////////////// STORMKIT_FORCE_INLINE inline Image::Image(const Device& device, const CreateInfo& info, PrivateFuncTag) noexcept - : m_extent { info.extent }, m_format { info.format }, m_layers { info.layers }, - m_faces { 1 }, m_mip_levels { info.mip_levels }, m_type { info.type }, - m_flags { info.flags }, m_samples { info.samples }, m_usages { info.usages }, + : m_extent { info.extent }, + m_format { info.format }, + m_layers { info.layers }, + m_faces { 1 }, + m_mip_levels { info.mip_levels }, + m_type { info.type }, + m_flags { info.flags }, + m_samples { info.samples }, + m_usages { info.usages }, m_vk_device { device.native_handle() }, m_vk_device_table { as_ref(device.device_table()) }, m_vma_allocator { device.allocator() }, - m_vk_handle { [vk_device_table = *m_vk_device_table, - vk_device = m_vk_device](auto handle) noexcept { + m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { vk_device_table.vkDestroyImage(vk_device, handle, nullptr); } } { } @@ -453,12 +438,14 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Image::~Image() = default; + inline Image::~Image() + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Image::Image(Image&&) noexcept = default; + inline Image::Image(Image&&) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// @@ -468,8 +455,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Image::create(const Device& device, const CreateInfo& create_info) noexcept - -> Expected { + inline auto Image::create(const Device& device, const CreateInfo& create_info) noexcept -> Expected { auto image = Image { device, create_info, PrivateFuncTag {} }; return image.do_init(create_info).transform(core::monadic::consume(image)); } @@ -477,8 +463,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Image::allocate(const Device& device, const CreateInfo& create_info) noexcept - -> Expected> { + inline auto Image::allocate(const Device& device, const CreateInfo& create_info) noexcept -> Expected> { auto image = std::make_unique(device, create_info, PrivateFuncTag {}); return image->do_init(create_info).transform(core::monadic::consume(image)); } @@ -549,9 +534,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - inline auto Image::create(const Device& device, - const CreateInfo& info, - VkImage&& vk_image) noexcept -> Image { + inline auto Image::create(const Device& device, const CreateInfo& info, VkImage&& vk_image) noexcept -> Image { auto image = Image { device, info, PrivateFuncTag {} }; image.m_vma_allocation = { core::monadic::noop() }; image.m_vk_handle = { core::monadic::noop() }; diff --git a/modules/stormkit/gpu/resource/shader.mpp b/modules/stormkit/gpu/resource/shader.mpp index d87ddc6b6..ae31dc980 100644 --- a/modules/stormkit/gpu/resource/shader.mpp +++ b/modules/stormkit/gpu/resource/shader.mpp @@ -31,28 +31,21 @@ export namespace stormkit::gpu { using LoadExpected = std::expected; static constexpr auto DEBUG_TYPE = DebugObjectType::SHADER_MODULE; - static auto load_from_file(const Device& device, - const std::filesystem::path& filepath, - ShaderStageFlag type) noexcept -> LoadExpected; - static auto load_from_bytes(const Device& device, - std::span data, - ShaderStageFlag type) noexcept -> Expected; - static auto load_from_spirvid(const Device& device, - std::span data, - ShaderStageFlag type) noexcept -> Expected; + static auto load_from_file(const Device& device, const std::filesystem::path& filepath, ShaderStageFlag type) noexcept + -> LoadExpected; + static auto load_from_bytes(const Device& device, std::span data, ShaderStageFlag type) noexcept + -> Expected; + static auto load_from_spirvid(const Device& device, std::span data, ShaderStageFlag type) noexcept + -> Expected; static auto allocate_and_load_from_file(const Device& device, const std::filesystem::path& filepath, - ShaderStageFlag type) noexcept - -> LoadExpected>; - static auto allocate_and_load_from_bytes(const Device& device, - std::span data, - ShaderStageFlag type) noexcept + ShaderStageFlag type) noexcept -> LoadExpected>; + static auto allocate_and_load_from_bytes(const Device& device, std::span data, ShaderStageFlag type) noexcept -> Expected>; static auto allocate_and_load_from_spirvid(const Device& device, std::span data, - ShaderStageFlag type) noexcept - -> Expected>; + ShaderStageFlag type) noexcept -> Expected>; ~Shader(); Shader(const Shader&) = delete; @@ -117,10 +110,7 @@ namespace stormkit::gpu { .pCode = stdr::data(m_source) }; - return vk_call(m_vk_device_table->vkCreateShaderModule, - m_vk_device, - &create_info, - nullptr) + return vk_call(m_vk_device_table->vkCreateShaderModule, m_vk_device, &create_info, nullptr) .transform(core::monadic::set(m_vk_handle)) .transform_error(monadic::from_vk()); } @@ -128,14 +118,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Shader::Shader(const Device& device, - std::vector data, - ShaderStageFlag type, - PrivateFuncTag) noexcept - : m_type { type }, m_source { std::move(data) }, m_vk_device { device.native_handle() }, + inline Shader::Shader(const Device& device, std::vector data, ShaderStageFlag type, PrivateFuncTag) noexcept + : m_type { type }, + m_source { std::move(data) }, + m_vk_device { device.native_handle() }, m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { [vk_device_table = *m_vk_device_table, - vk_device = m_vk_device](auto&& handle) noexcept { + m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto&& handle) noexcept { vk_device_table.vkDestroyShaderModule(vk_device, handle, nullptr); } } { } @@ -143,12 +131,14 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Shader::~Shader() = default; + inline Shader::~Shader() + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Shader::Shader(Shader&&) noexcept = default; + inline Shader::Shader(Shader&&) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// @@ -158,34 +148,29 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::load_from_file(const Device& device, - const std::filesystem::path& filepath, - ShaderStageFlag type) noexcept -> LoadExpected { + inline auto Shader::load_from_file(const Device& device, const std::filesystem::path& filepath, ShaderStageFlag type) noexcept + -> LoadExpected { return io::File::open(filepath, io::Access::READ) .transform_error(sys_to_load_error) .and_then([](auto&& file) static noexcept -> LoadExpected> { const auto size = file.size(); - if (size % sizeof(SpirvID) != 0) - return std::unexpected { LoadError { Error::INVALID_SPIRV } }; + if (size % sizeof(SpirvID) != 0) return std::unexpected { LoadError { Error::INVALID_SPIRV } }; auto spirv = std::vector(size / sizeof(SpirvID)); - return file.read_to(as_bytes(spirv)) + return file.read_to(as_bytes_mut(spirv)) .transform(core::monadic::consume(spirv)) .transform_error(sys_to_load_error); }) .and_then([&type, &device](auto&& spirv) noexcept { auto shader = Shader { device, std::move(spirv), type, PrivateFuncTag {} }; - return shader.do_init() - .transform_error(result_to_load_error) - .transform(core::monadic::consume(shader)); + return shader.do_init().transform_error(result_to_load_error).transform(core::monadic::consume(shader)); }); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::load_from_bytes(const Device& device, - std::span data, - ShaderStageFlag type) noexcept -> Expected { + inline auto Shader::load_from_bytes(const Device& device, std::span data, ShaderStageFlag type) noexcept + -> Expected { auto shader = Shader { device, bytes_as>(data) | stdr::to(), type, @@ -196,9 +181,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::load_from_spirvid(const Device& device, - std::span data, - ShaderStageFlag type) noexcept -> Expected { + inline auto Shader::load_from_spirvid(const Device& device, std::span data, ShaderStageFlag type) noexcept + -> Expected { auto shader = Shader { device, data | stdr::to(), type, PrivateFuncTag {} }; return shader.do_init().transform(core::monadic::consume(shader)); } @@ -208,10 +192,8 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto Shader::allocate_and_load_from_file(const Device& device, const std::filesystem::path& filepath, - ShaderStageFlag type) noexcept - -> LoadExpected> { - expects(std::filesystem::is_regular_file(filepath), - std::format("{} is not a file", filepath.string())); + ShaderStageFlag type) noexcept -> LoadExpected> { + expects(std::filesystem::is_regular_file(filepath), std::format("{} is not a file", filepath.string())); return io::File::open(filepath, io::Access::READ) .transform_error(sys_to_load_error) @@ -219,18 +201,13 @@ namespace stormkit::gpu { const auto size = file.size(); auto spirv = std::vector(size / sizeof(SpirvID)); - return file.read_to(as_bytes(spirv)) + return file.read_to(as_bytes_mut(spirv)) .transform(core::monadic::consume(spirv)) .transform_error(sys_to_load_error); }) .and_then([&type, &device](auto&& spirv) noexcept { - auto shader = std::make_unique(device, - std::move(spirv), - type, - PrivateFuncTag {}); - return shader->do_init() - .transform(core::monadic::consume(shader)) - .transform_error(result_to_load_error); + auto shader = std::make_unique(device, std::move(spirv), type, PrivateFuncTag {}); + return shader->do_init().transform(core::monadic::consume(shader)).transform_error(result_to_load_error); }); } @@ -239,11 +216,9 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto Shader::allocate_and_load_from_bytes(const Device& device, std::span data, - ShaderStageFlag type) noexcept - -> Expected> { + ShaderStageFlag type) noexcept -> Expected> { auto shader = std::make_unique(device, - bytes_as>(data) - | stdr::to(), + bytes_as>(data) | stdr::to(), type, PrivateFuncTag {}); return shader->do_init().transform(core::monadic::consume(shader)); @@ -254,12 +229,8 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto Shader::allocate_and_load_from_spirvid(const Device& device, std::span data, - ShaderStageFlag type) noexcept - -> Expected> { - auto shader = std::make_unique(device, - data | stdr::to(), - type, - PrivateFuncTag {}); + ShaderStageFlag type) noexcept -> Expected> { + auto shader = std::make_unique(device, data | stdr::to(), type, PrivateFuncTag {}); return shader->do_init().transform(core::monadic::consume(shader)); } diff --git a/modules/stormkit/image.mpp b/modules/stormkit/image.mpp index 868e95005..710a861a2 100644 --- a/modules/stormkit/image.mpp +++ b/modules/stormkit/image.mpp @@ -132,15 +132,12 @@ export namespace stormkit::image { auto operator=(Image&& rhs) noexcept -> Image&; [[nodiscard]] - auto load_from_file(std::filesystem::path filepath, - Codec codec = Codec::AUTODETECT) noexcept -> std::expected; - [[nodiscard]] - auto load_from_memory(std::span data, Codec codec = Codec::AUTODETECT) noexcept + auto load_from_file(std::filesystem::path filepath, Codec codec = Codec::AUTODETECT) noexcept -> std::expected; [[nodiscard]] - auto save_to_file(std::filesystem::path filename, - Codec codec, - CodecArgs args = CodecArgs::BINARY) const noexcept + auto load_from_memory(std::span data, Codec codec = Codec::AUTODETECT) noexcept -> std::expected; + [[nodiscard]] + auto save_to_file(std::filesystem::path filename, Codec codec, CodecArgs args = CodecArgs::BINARY) const noexcept -> std::expected; [[nodiscard]] @@ -167,19 +164,13 @@ export namespace stormkit::image { auto rotate_270() const noexcept -> Image; [[nodiscard]] - auto pixel(usize id, u32 layer = 0u, u32 face = 0u, u32 level = 0u) noexcept - -> std::span; + auto pixel(usize id, u32 layer = 0u, u32 face = 0u, u32 level = 0u) noexcept -> std::span; [[nodiscard]] - auto pixel(usize id, u32 layer = 0u, u32 face = 0u, u32 level = 0u) const noexcept - -> std::span; + auto pixel(usize id, u32 layer = 0u, u32 face = 0u, u32 level = 0u) const noexcept -> std::span; [[nodiscard]] - auto pixel(math::vec3u position, u32 layer = 0u, u32 face = 0u, u32 level = 0u) noexcept - -> std::span; + auto pixel(math::vec3u position, u32 layer = 0u, u32 face = 0u, u32 level = 0u) noexcept -> std::span; [[nodiscard]] - auto pixel(math::vec3u position, - u32 layer = 0u, - u32 face = 0u, - u32 level = 0u) const noexcept -> std::span; + auto pixel(math::vec3u position, u32 layer = 0u, u32 face = 0u, u32 level = 0u) const noexcept -> std::span; [[nodiscard]] auto extent(u32 level = 0u) const noexcept -> math::Extent3; @@ -262,12 +253,10 @@ export namespace stormkit::image { export { template - struct std::formatter - : std::formatter, CharT> { + struct std::formatter: std::formatter, CharT> { template [[nodiscard]] - auto format(const stormkit::image::Image::Error& error, FormatContext& ctx) const noexcept - -> decltype(ctx.out()); + auto format(const stormkit::image::Image::Error& error, FormatContext& ctx) const noexcept -> decltype(ctx.out()); }; } @@ -278,8 +267,7 @@ export { namespace stormkit::image { ///////////////////////////////////// ///////////////////////////////////// - inline auto Image::pixel(usize index, u32 layer, u32 face, u32 level) noexcept - -> std::span { + inline auto Image::pixel(usize index, u32 layer, u32 face, u32 level) noexcept -> std::span { EXPECTS(m_data.mip_levels > level); EXPECTS(m_data.faces > face); EXPECTS(m_data.layers > layer); @@ -295,8 +283,7 @@ namespace stormkit::image { ///////////////////////////////////// ///////////////////////////////////// - inline auto Image::pixel(usize index, u32 layer, u32 face, u32 level) const noexcept - -> std::span { + inline auto Image::pixel(usize index, u32 layer, u32 face, u32 level) const noexcept -> std::span { EXPECTS(m_data.mip_levels > level); EXPECTS(m_data.faces > face); EXPECTS(m_data.layers > layer); @@ -313,26 +300,20 @@ namespace stormkit::image { ///////////////////////////////////// ///////////////////////////////////// - inline auto Image::pixel(math::vec3u position, u32 layer, u32 face, u32 level) noexcept - -> std::span { + inline auto Image::pixel(math::vec3u position, u32 layer, u32 face, u32 level) noexcept -> std::span { const auto mip_extent = extent(level); - const auto id = position.x - + (position.y * mip_extent.width) - + (mip_extent.width * mip_extent.height * position.z); + const auto id = position.x + (position.y * mip_extent.width) + (mip_extent.width * mip_extent.height * position.z); return pixel(id, layer, face, level); } ///////////////////////////////////// ///////////////////////////////////// - inline auto Image::pixel(math::vec3u position, u32 layer, u32 face, u32 level) const noexcept - -> std::span { + inline auto Image::pixel(math::vec3u position, u32 layer, u32 face, u32 level) const noexcept -> std::span { const auto mip_extent = extent(level); - const auto id = position.x - + (position.y * mip_extent.width) - + (mip_extent.width * mip_extent.height * position.z); + const auto id = position.x + (position.y * mip_extent.width) + (mip_extent.width * mip_extent.height * position.z); return pixel(id, layer, face, level); } @@ -400,11 +381,7 @@ namespace stormkit::image { const auto mip_extent = extent(level); - return mip_extent.width - * mip_extent.height - * mip_extent.depth - * m_data.channel_count - * m_data.bytes_per_channel; + return mip_extent.width * mip_extent.height * mip_extent.depth * m_data.channel_count * m_data.bytes_per_channel; } ///////////////////////////////////// @@ -455,8 +432,7 @@ namespace stormkit::image { ///////////////////////////////////// ///////////////////////////////////// - inline auto Image::data(u32 layer, u32 face, u32 level) const noexcept - -> std::span { + inline auto Image::data(u32 layer, u32 face, u32 level) const noexcept -> std::span { const auto mip_size = size(layer, face, level); auto offset = usize { 0 }; @@ -705,9 +681,8 @@ namespace stormkit::image { template template -auto std::formatter::format(const stormkit::image::Image::Error& error, - FormatContext& ctx) const noexcept -> decltype(ctx.out()) { +auto std::formatter::format(const stormkit::image::Image::Error& error, + FormatContext& ctx) const noexcept -> decltype(ctx.out()) { auto&& out = ctx.out(); return format_to(out, "{}", error.str_error); } diff --git a/modules/stormkit/log.mpp b/modules/stormkit/log.mpp index 903e3c560..14c6c0343 100644 --- a/modules/stormkit/log.mpp +++ b/modules/stormkit/log.mpp @@ -253,7 +253,8 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline ConsoleLogger::ConsoleLogger(const ConsoleLogger&) noexcept = default; + inline ConsoleLogger::ConsoleLogger(const ConsoleLogger&) noexcept + = default; //////////////////////////////////////// //////////////////////////////////////// @@ -263,7 +264,8 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline ConsoleLogger::ConsoleLogger(ConsoleLogger&&) noexcept = default; + inline ConsoleLogger::ConsoleLogger(ConsoleLogger&&) noexcept + = default; //////////////////////////////////////// //////////////////////////////////////// @@ -273,12 +275,14 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline ConsoleLogger::~ConsoleLogger() noexcept = default; + inline ConsoleLogger::~ConsoleLogger() noexcept + = default; //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline FileLogger::FileLogger(FileLogger&&) noexcept = default; + inline FileLogger::FileLogger(FileLogger&&) noexcept + = default; //////////////////////////////////////// //////////////////////////////////////// @@ -288,7 +292,8 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline FileLogger::~FileLogger() noexcept = default; + inline FileLogger::~FileLogger() noexcept + = default; //////////////////////////////////////// //////////////////////////////////////// diff --git a/modules/stormkit/luau.mpp b/modules/stormkit/luau.mpp new file mode 100644 index 000000000..844f87067 --- /dev/null +++ b/modules/stormkit/luau.mpp @@ -0,0 +1,151 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include +#include + +#include + +export module stormkit.luau; + +import std; + +import stormkit.core; + +namespace stdfs = std::filesystem; +namespace stdr = std::ranges; + +namespace lb = luabridge; + +export namespace stormkit::luau { + class STORMKIT_API Engine { + public: + Engine(const Engine&) = delete; + auto operator=(const Engine&) -> Engine& = delete; + + Engine(Engine&& other) noexcept + : m_global_state { std::exchange(other.m_global_state, nullptr) }, + m_main_thread { std::exchange(other.m_main_thread, nullptr) } {} + + auto operator=(Engine&& other) noexcept -> Engine& { + if (&other == this) [[unlikely]] + return *this; + m_global_state = std::exchange(other.m_global_state, nullptr); + m_main_thread = std::exchange(other.m_main_thread, nullptr); + + return *this; + }; + + ~Engine() noexcept { + if (m_main_thread) m_main_thread = nullptr; + + if (m_global_state) { + lua_close(m_global_state); + m_global_state = nullptr; + } + } + + auto load(const stdfs::path& file) noexcept { + expects(not stdr::empty(file)); + auto data = *io::read_text(file).transform_error(monadic::assert(std::format("Failed to load {}", file.string()))); + + auto bytecode_size = 0_usize; + auto bytecode = luau_compile(stdr::data(data), stdr::size(data), nullptr, &bytecode_size); + auto result = luau_load(m_global_state, "main", bytecode, bytecode_size, 0); + std::free(bytecode); + + if (result != 0) { + auto len = usize { 0 }; + auto msg = lua_tolstring(m_global_state, -1, &len); + + ensures(result == 0, + std::format("Lua compilation error!\n-------------------------------\n{}", + std::string_view { msg, len })); + } + + m_main_thread = lua_newthread(m_global_state); + ensures(m_main_thread); + + lua_pushvalue(m_global_state, -2); + lua_remove(m_global_state, -3); + lua_xmove(m_global_state, m_main_thread, 1); + } + + auto lua_main() noexcept -> std::expected { + expects(m_main_thread); + + auto out = std::expected {}; + + luaL_sandbox(m_global_state); + luaL_sandboxthread(m_global_state); + + auto status = lua_resume(m_main_thread, nullptr, 0); + if (status == 0) { + if (const auto n = lua_gettop(m_main_thread); n) { + luaL_checkstack(m_main_thread, LUA_MINSTACK, "too many results to print"); + lua_getglobal(m_main_thread, "print"); + lua_insert(m_main_thread, 1); + lua_pcall(m_main_thread, n, 0, 0); + } + + lua_pop(m_global_state, 1); + } else { + auto error = std::string {}; + error.reserve(150); + + luaL_traceback(m_global_state, m_global_state, nullptr, 1); + + error += lua_tostring(m_global_state, -1); + + lua_pop(m_global_state, 1); + out = std::unexpected { std::move(error) }; + } + + return out; + } + + // template + // struct Binder { + // lb::Namespace _namespace; + // lb::Namespace::Class class; + + // auto bind_function(std::string_view name, auto&& function) noexcept -> Binder { + // _namespace.addFunction(stdr::data(name), std::forward(function)); + // return Binder { _namespace }; + // } + + // auto begin_namespace(std::string_view name) noexcept -> Binder { + // return Binder { _namespace.beginNamespace(stdr::data(name)) }; + // } + + // auto end_namespace() noexcept -> Binder { return Binder { _namespace.endNamespace() }; } + + // template + // auto begin_class(std::string_view name) noexcept -> Binder { + // return Binder { _namespace, _namespace.beginClass(stdr::data(name)) }; + // } + + // auto end_class(std::string_view name) noexcept -> Binder { return Binder { class.endClass() }; } + // }; + + auto global_namespace() noexcept { return lb::getGlobalNamespace(m_global_state); } + + static auto create(const stdfs::path& file) noexcept -> Engine { + auto engine = Engine {}; + engine.load(file); + return engine; + } + + private: + Engine() noexcept { + m_global_state = luaL_newstate(); + luaL_openlibs(m_global_state); + } + + lua_State* m_global_state = nullptr; + lua_State* m_main_thread = nullptr; + }; +} // namespace stormkit::luau diff --git a/modules/stormkit/test.mpp b/modules/stormkit/test.mpp index da3f552ec..7b0163cd5 100644 --- a/modules/stormkit/test.mpp +++ b/modules/stormkit/test.mpp @@ -67,20 +67,17 @@ namespace test { namespace { constexpr auto StyleMap = frozen::make_unordered_map({ - { Status::Passed, - stormkit::ConsoleStyle { .fg = stormkit::ConsoleColor::BLACK, - .bg = stormkit::ConsoleColor::GREEN } }, + { Status::Passed, stormkit::ConsoleStyle { .fg = stormkit::ConsoleColor::BLACK, .bg = stormkit::ConsoleColor::GREEN } }, { Status::NotPassed, - stormkit::ConsoleStyle { .fg = stormkit::ConsoleColor::BLACK, - .bg = stormkit::ConsoleColor::RED } }, + stormkit::ConsoleStyle { .fg = stormkit::ConsoleColor::BLACK, .bg = stormkit::ConsoleColor::RED } }, { Status::CheckMark, stormkit::ConsoleStyle { .fg = stormkit::ConsoleColor::GREEN, - } }, + } }, { Status::CrossMark, stormkit::ConsoleStyle { .fg = stormkit::ConsoleColor::RED, - } }, + } }, }); constexpr auto passed = StyleMap.at(Status::Passed) | "Passed"sv; @@ -140,17 +137,11 @@ namespace test { return failed_tests == 0; } - TestSuite::TestSuite(std::string&& _name, - std::vector&& tests, - const std::source_location& location) noexcept { - state.test_suites.emplace_back(std::make_unique(std::move(_name), - std::move(tests), - location)); + TestSuite::TestSuite(std::string&& _name, std::vector&& tests, const std::source_location& location) noexcept { + state.test_suites.emplace_back(std::make_unique(std::move(_name), std::move(tests), location)); } - auto expects(bool cond, - std::string_view message, - const std::source_location& location) noexcept { + auto expects(bool cond, std::string_view message, const std::source_location& location) noexcept { if (not cond) [[unlikely]] { state.failed = true; if (state.verbose) { @@ -201,9 +192,7 @@ namespace test { } } else for (auto&& suite : state.test_suites) { - std::println("Running test suite {} ({} tests)", - suite->name, - std::size(suite->tests)); + std::println("Running test suite {} ({} tests)", suite->name, std::size(suite->tests)); if (not suite->runTests()) return_code = -1; } diff --git a/modules/stormkit/wsi/monitor.mpp b/modules/stormkit/wsi/monitor.mpp index 1cd06e18b..fb9ad379b 100644 --- a/modules/stormkit/wsi/monitor.mpp +++ b/modules/stormkit/wsi/monitor.mpp @@ -58,8 +58,7 @@ namespace stormkit::wsi { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_PURE - constexpr auto Monitor::operator<=>(const Monitor& other) const noexcept - -> std::strong_ordering { + constexpr auto Monitor::operator<=>(const Monitor& other) const noexcept -> std::strong_ordering { if (auto ret = flags <=> other.flags; ret != 0) return ret; #ifdef STORMKIT_COMPILER_CLANG @@ -99,15 +98,13 @@ namespace stormkit::wsi { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto format_as(const Monitor& monitor, FormatContext& ctx) noexcept - -> FormatContext::iterator { + inline auto format_as(const Monitor& monitor, FormatContext& ctx) noexcept -> FormatContext::iterator { auto&& out = ctx.out(); - return format_to( - out, - "{{ Monitor: .name = {}, .flags = {}, .extents = {}, .scale_factor = {} }}", - monitor.name, - monitor.flags, - monitor.extents, - monitor.scale_factor); + return format_to(out, + "{{ Monitor: .name = {}, .flags = {}, .extents = {}, .scale_factor = {} }}", + monitor.name, + monitor.flags, + monitor.extents, + monitor.scale_factor); } } // namespace stormkit::wsi diff --git a/modules/stormkit/wsi/window.mpp b/modules/stormkit/wsi/window.mpp index 61041452a..c0f6c254d 100644 --- a/modules/stormkit/wsi/window.mpp +++ b/modules/stormkit/wsi/window.mpp @@ -128,9 +128,7 @@ export { Window(Window&&) noexcept; auto operator=(Window&&) noexcept -> Window&; - static auto open(std::string title, - const math::Extent2& size, - WindowFlag flags) noexcept -> Window; + static auto open(std::string title, const math::Extent2& size, WindowFlag flags) noexcept -> Window; auto close() noexcept -> void; [[nodiscard]] @@ -170,8 +168,7 @@ export { [[nodiscard]] auto fullscreen() const noexcept -> bool; - auto confine_mouse(bool confined = true, u8 mouse_id = GLOBAL_MOUSE_ID) noexcept - -> void; + auto confine_mouse(bool confined = true, u8 mouse_id = GLOBAL_MOUSE_ID) noexcept -> void; auto unconfine_mouse(u8 mouse_id = GLOBAL_MOUSE_ID) noexcept -> void; auto toggle_confined_mouse(u8 mouse_id = GLOBAL_MOUSE_ID) noexcept -> void; [[nodiscard]] @@ -189,14 +186,12 @@ export { [[nodiscard]] auto is_mouse_hidden(u8 mouse_id = GLOBAL_MOUSE_ID) const noexcept -> bool; - auto set_relative_mouse(bool enabled = true, u8 mouse_id = GLOBAL_MOUSE_ID) noexcept - -> void; + auto set_relative_mouse(bool enabled = true, u8 mouse_id = GLOBAL_MOUSE_ID) noexcept -> void; auto toggle_relative_mouse(u8 mouse_id = GLOBAL_MOUSE_ID) noexcept -> void; [[nodiscard]] auto is_mouse_relative(u8 mouse_id = GLOBAL_MOUSE_ID) const noexcept -> bool; - auto set_key_repeat(bool enabled = true, u8 keyboard_id = GLOBAL_KEYBOARD_ID) noexcept - -> void; + auto set_key_repeat(bool enabled = true, u8 keyboard_id = GLOBAL_KEYBOARD_ID) noexcept -> void; auto disable_key_repeat(u8 keyboard_id = GLOBAL_KEYBOARD_ID) noexcept -> void; auto toggle_key_repeat(u8 keyboard_id = GLOBAL_KEYBOARD_ID) noexcept -> void; [[nodiscard]] @@ -208,8 +203,7 @@ export { [[nodiscard]] auto is_virtual_keyboard_visible() const noexcept -> bool; - auto set_mouse_position(const math::vec2i& position, - u8 mouse_id = GLOBAL_MOUSE_ID) noexcept -> void; + auto set_mouse_position(const math::vec2i& position, u8 mouse_id = GLOBAL_MOUSE_ID) noexcept -> void; [[nodiscard]] auto native_handle() const noexcept -> NativeHandle; @@ -257,16 +251,13 @@ namespace stormkit::wsi { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto as_string(WindowFlag flag) noexcept -> std::string_view { using Pair = std::pair; - static constexpr auto MAPPING = core::generate_substitutions_as_string_for< - WindowFlag, - 4, - WindowFlag::DEFAULT, - 67>("WindowFlag::", - { - Pair { WindowFlag::DEFAULT, "DEFAULT"sv }, - Pair { WindowFlag::BORDERLESS, "BORDERLESS"sv }, - Pair { WindowFlag::RESIZEABLE, "RESIZEABLE"sv }, - Pair { WindowFlag::EXTERNAL_CONTEXT, "EXTERNAL_CONTEXT"sv }, + static constexpr auto MAPPING = core::generate_substitutions_as_string_for( + "WindowFlag::", + { + Pair { WindowFlag::DEFAULT, "DEFAULT"sv }, + Pair { WindowFlag::BORDERLESS, "BORDERLESS"sv }, + Pair { WindowFlag::RESIZEABLE, "RESIZEABLE"sv }, + Pair { WindowFlag::EXTERNAL_CONTEXT, "EXTERNAL_CONTEXT"sv }, }); const auto it = stdr::find_if(MAPPING, [&flag](auto&& pair) { return pair.first == flag; }); diff --git a/src/core/contract.mpp b/src/core/contract.mpp index f5fbf979a..8f97cb129 100644 --- a/src/core/contract.mpp +++ b/src/core/contract.mpp @@ -21,10 +21,8 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - auto assert_base(bool cond, - AssertType type, - std::string_view message, - const std::source_location& location) noexcept -> void { + auto assert_base(bool cond, AssertType type, std::string_view message, const std::source_location& location) noexcept + -> void { if constexpr (STORMKIT_ASSERT == 1) { constexpr auto ASSERTION_PREFIX = ConsoleStyle { .fg = ConsoleColor::BRIGHT_RED, @@ -43,9 +41,7 @@ namespace stormkit { inline namespace core { ConsoleStyle { .fg = ConsoleColor::BLUE } | location.line(), ConsoleStyle { .fg = ConsoleColor::BLUE } | location.column(), ConsoleStyle { .fg = ConsoleColor::YELLOW } | location.function_name(), - ConsoleStyle { .fg = ConsoleColor::RED, - .modifiers = StyleModifier::BOLD } - | message); + ConsoleStyle { .fg = ConsoleColor::RED, .modifiers = StyleModifier::BOLD } | message); std::fflush(get_stderr()); std::terminate(); diff --git a/src/gpu/execution/pipeline_cache.cpp b/src/gpu/execution/pipeline_cache.cpp index df2133b2d..0ff471d92 100644 --- a/src/gpu/execution/pipeline_cache.cpp +++ b/src/gpu/execution/pipeline_cache.cpp @@ -80,9 +80,9 @@ namespace stormkit::gpu { const auto physical_device_infos = device.physical_device().info(); auto file = Try(io::File::open(m_path, io::Access::READ).transform_error(sys_to_load_error)); - Try(file.read_to(as_bytes(m_serialized.guard)).transform_error(sys_to_load_error)); - Try(file.read_to(as_bytes(m_serialized.infos)).transform_error(sys_to_load_error)); - Try(file.read_to(as_bytes(m_serialized.uuid.value)).transform_error(sys_to_load_error)); + Try(file.read_to(as_bytes_mut(m_serialized.guard)).transform_error(sys_to_load_error)); + Try(file.read_to(as_bytes_mut(m_serialized.infos)).transform_error(sys_to_load_error)); + Try(file.read_to(as_bytes_mut(m_serialized.uuid.value)).transform_error(sys_to_load_error)); if (m_serialized.guard.magic != MAGIC) { elog("Invalid pipeline cache magic number, have {}, expected: {}", m_serialized.guard.magic, MAGIC); diff --git a/src/image/hdr.mpp b/src/image/hdr.mpp index 0fe9415a5..dfe398aa0 100644 --- a/src/image/hdr.mpp +++ b/src/image/hdr.mpp @@ -11,16 +11,14 @@ import stormkit.image; export namespace stormkit::image::details { [[nodiscard]] - auto load_hdr(std::span data) noexcept - -> std::expected; + auto load_hdr(std::span data) noexcept -> std::expected; [[nodiscard]] auto save_hdr(const image::Image& image, const std::filesystem::path& filepath) noexcept -> std::expected; [[nodiscard]] - auto save_hdr(const image::Image& image) noexcept - -> std::expected, image::Image::Error>; + auto save_hdr(const image::Image& image) noexcept -> std::expected, image::Image::Error>; } // namespace stormkit::image::details namespace stormkit::image::details { @@ -31,24 +29,21 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto load_hdr(std::span) noexcept - -> std::expected { + auto load_hdr(std::span) noexcept -> std::expected { assert(false, "Not implemented yet !"); return {}; } ///////////////////////////////////// ///////////////////////////////////// - auto save_hdr(const image::Image&, const std::filesystem::path&) noexcept - -> std::expected { + auto save_hdr(const image::Image&, const std::filesystem::path&) noexcept -> std::expected { assert(false, "Not implemented yet !"); return {}; } ///////////////////////////////////// ///////////////////////////////////// - auto save_hdr(const image::Image&) noexcept - -> std::expected, image::Image::Error> { + auto save_hdr(const image::Image&) noexcept -> std::expected, image::Image::Error> { assert(false, "Not implemented yet !"); return {}; } diff --git a/src/image/jpg.mpp b/src/image/jpg.mpp index 7b0e2ea4f..cdda6ce84 100644 --- a/src/image/jpg.mpp +++ b/src/image/jpg.mpp @@ -27,16 +27,14 @@ namespace stdr = std::ranges; export namespace stormkit::image::details { [[nodiscard]] - auto load_jpg(std::span data) noexcept - -> std::expected; + auto load_jpg(std::span data) noexcept -> std::expected; [[nodiscard]] auto save_jpg(const image::Image& image, const std::filesystem::path& filepath) noexcept -> std::expected; [[nodiscard]] - auto save_jpg(const image::Image& image) noexcept - -> std::expected, image::Image::Error>; + auto save_jpg(const image::Image& image) noexcept -> std::expected, image::Image::Error>; } // namespace stormkit::image::details namespace stormkit::image::details { @@ -71,11 +69,10 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto load_jpg(std::span data) noexcept - -> std::expected { + auto load_jpg(std::span data) noexcept -> std::expected { auto image_memory = std::vector {}; - volatile auto format = Format {}; // NOTE volatile for error: variable ‘format’ might be - // clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered] + volatile auto format = Format {}; // NOTE volatile for error: variable ‘format’ might be + // clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered] auto extent = math::Extent3 {}; auto info = jpeg_decompress_struct {}; auto error_mgr = jpeg_error_mgr {}; @@ -88,13 +85,10 @@ namespace stormkit::image::details { jpeg_create_decompress(&info); if (setjmp(error_data.setjmp_buffer)) { - return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, - .str_error = error_data.msg }); + return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, .str_error = error_data.msg }); } - jpeg_mem_src(&info, - reinterpret_cast(stdr::data(data)), - as(stdr::size(data))); + jpeg_mem_src(&info, reinterpret_cast(stdr::data(data)), as(stdr::size(data))); jpeg_read_header(&info, TRUE); jpeg_start_decompress(&info); @@ -105,20 +99,13 @@ namespace stormkit::image::details { if (info.output_components == 2) format = Format::RG8_UNORM; if (info.output_components == 3) format = Format::RGB8_UNORM; - image_memory.resize(as(extent.width - * extent.height - * extent.depth - * as(info.out_color_components))); + image_memory.resize(as(extent.width * extent.height * extent.depth * as(info.out_color_components))); auto row_ptr = std::array { nullptr }; while (info.output_scanline < info.output_height) { - const auto index = as(extent.width - * as(info.output_components) - * info.output_scanline); + const auto index = as(extent.width * as(info.output_components) * info.output_scanline); row_ptr[0] = stdr::data(image_memory) + index; - jpeg_read_scanlines(&info, - reinterpret_cast(stdr::data(row_ptr)), - as(stdr::size(row_ptr))); + jpeg_read_scanlines(&info, reinterpret_cast(stdr::data(row_ptr)), as(stdr::size(row_ptr))); } jpeg_finish_decompress(&info); @@ -126,8 +113,7 @@ namespace stormkit::image::details { if (setjmp(error_data.setjmp_buffer)) { jpeg_destroy_decompress(&info); - return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, - .str_error = error_data.msg }); + return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, .str_error = error_data.msg }); } auto image_data = image::Image::ImageData {}; @@ -165,9 +151,7 @@ namespace stormkit::image::details { if (i >= 1u) _filename += to_native_encoding(std::format("_mip{}", i)); auto file = io::File::open(_filename, io::Access::WRITE); - if (not file) - return std::unexpected(Error { .reason = Reason::FAILED_TO_SAVE, - .str_error = error_data.msg }); + if (not file) return std::unexpected(Error { .reason = Reason::FAILED_TO_SAVE, .str_error = error_data.msg }); auto data = image_rgb.data(0, 0, 0); const auto& extent = image_rgb.extent(0); @@ -208,8 +192,7 @@ namespace stormkit::image::details { if (setjmp(error_data.setjmp_buffer)) { jpeg_destroy_compress(&info); - return std::unexpected(Error { .reason = Reason::FAILED_TO_SAVE, - .str_error = error_data.msg }); + return std::unexpected(Error { .reason = Reason::FAILED_TO_SAVE, .str_error = error_data.msg }); } return {}; @@ -217,8 +200,7 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto save_jpg(const image::Image& image) noexcept - -> std::expected, image::Image::Error> { + auto save_jpg(const image::Image& image) noexcept -> std::expected, image::Image::Error> { using uchar_ptr = unsigned char*; auto output_ptr = uchar_ptr { nullptr }; @@ -265,8 +247,7 @@ namespace stormkit::image::details { if (setjmp(error_data.setjmp_buffer)) { jpeg_destroy_compress(&info); - return std::unexpected(Error { .reason = Reason::FAILED_TO_SAVE, - .str_error = error_data.msg }); + return std::unexpected(Error { .reason = Reason::FAILED_TO_SAVE, .str_error = error_data.msg }); } auto output = std::vector {}; diff --git a/src/image/ktx.mpp b/src/image/ktx.mpp index 2537bcd49..c65f01633 100644 --- a/src/image/ktx.mpp +++ b/src/image/ktx.mpp @@ -14,16 +14,14 @@ import stormkit.image; export namespace stormkit::image::details { [[nodiscard]] - auto load_ktx(std::span data) noexcept - -> std::expected; + auto load_ktx(std::span data) noexcept -> std::expected; [[nodiscard]] auto save_ktx(const image::Image& image, const std::filesystem::path& filepath) noexcept -> std::expected; [[nodiscard]] - auto save_ktx(const image::Image& image) noexcept - -> std::expected, image::Image::Error>; + auto save_ktx(const image::Image& image) noexcept -> std::expected, image::Image::Error>; } // namespace stormkit::image::details namespace stormkit::image::details { @@ -102,8 +100,7 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto load_ktx([[maybe_unused]] std::span data) noexcept - -> std::expected { + auto load_ktx([[maybe_unused]] std::span data) noexcept -> std::expected { /*auto image = gli::load_ktx(reinterpret_cast(std::data(data)), * std::size(data));*/ /**/ @@ -140,16 +137,14 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto save_ktx(const image::Image&, const std::filesystem::path&) noexcept - -> std::expected { + auto save_ktx(const image::Image&, const std::filesystem::path&) noexcept -> std::expected { assert(false, "Not implemented yet !"); return {}; } ///////////////////////////////////// ///////////////////////////////////// - auto save_ktx(const image::Image&) noexcept - -> std::expected, image::Image::Error> { + auto save_ktx(const image::Image&) noexcept -> std::expected, image::Image::Error> { assert(false, "Not implemented yet !"); return {}; } diff --git a/src/image/ppm.mpp b/src/image/ppm.mpp index e884429b1..a0284c21b 100644 --- a/src/image/ppm.mpp +++ b/src/image/ppm.mpp @@ -15,13 +15,10 @@ import stormkit.image; export namespace stormkit::image::details { [[nodiscard]] - auto load_ppm(std::span data) noexcept - -> std::expected; + auto load_ppm(std::span data) noexcept -> std::expected; [[nodiscard]] - auto save_ppm(const image::Image& image, - image::Image::CodecArgs args, - const std::filesystem::path& filepath) noexcept + auto save_ppm(const image::Image& image, image::Image::CodecArgs args, const std::filesystem::path& filepath) noexcept -> std::expected; [[nodiscard]] @@ -40,17 +37,14 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto load_ppm(std::span) noexcept - -> std::expected { + auto load_ppm(std::span) noexcept -> std::expected { assert(false, "Not implemented yet !"); return {}; } ///////////////////////////////////// ///////////////////////////////////// - auto save_ppm(const image::Image& image, - image::Image::CodecArgs args, - const std::filesystem::path& filepath) noexcept + auto save_ppm(const image::Image& image, image::Image::CodecArgs args, const std::filesystem::path& filepath) noexcept -> std::expected { return save_ppm(image, args) .and_then([&filepath](auto&& val) noexcept { @@ -76,10 +70,7 @@ namespace stormkit::image::details { for (auto [i, j] : multi_range(extent.height, extent.width)) { const auto pixel = output_image.pixel(i * output_image.extent().width + j); - result += std::format("{} {} {}\n"sv, - as(pixel[0]), - as(pixel[1]), - as(pixel[2])); + result += std::format("{} {} {}\n"sv, as(pixel[0]), as(pixel[1]), as(pixel[2])); if (j == extent.width) result += '\n'; } diff --git a/src/image/tga.mpp b/src/image/tga.mpp index 6c94dbc33..279156350 100644 --- a/src/image/tga.mpp +++ b/src/image/tga.mpp @@ -16,16 +16,14 @@ import stormkit.image; export namespace stormkit::image::details { [[nodiscard]] - auto load_tga(std::span data) noexcept - -> std::expected; + auto load_tga(std::span data) noexcept -> std::expected; [[nodiscard]] auto save_tga(const image::Image& image, const std::filesystem::path& filepath) noexcept -> std::expected; [[nodiscard]] - auto save_tga(const image::Image& image) noexcept - -> std::expected, image::Image::Error>; + auto save_tga(const image::Image& image) noexcept -> std::expected, image::Image::Error>; } // namespace stormkit::image::details namespace stormkit::image::details { @@ -36,24 +34,21 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto load_tga(std::span) noexcept - -> std::expected { + auto load_tga(std::span) noexcept -> std::expected { assert(false, "Not implemented yet !"); return {}; } ///////////////////////////////////// ///////////////////////////////////// - auto save_tga(const image::Image&, const std::filesystem::path&) noexcept - -> std::expected { + auto save_tga(const image::Image&, const std::filesystem::path&) noexcept -> std::expected { assert(false, "Not implemented yet !"); return {}; } ///////////////////////////////////// ///////////////////////////////////// - auto save_tga(const image::Image&) noexcept - -> std::expected, image::Image::Error> { + auto save_tga(const image::Image&) noexcept -> std::expected, image::Image::Error> { assert(false, "Not implemented yet !"); return {}; } diff --git a/src/wsi/common/window_base.mpp b/src/wsi/common/window_base.mpp index 3e19a3f44..66bca81e4 100644 --- a/src/wsi/common/window_base.mpp +++ b/src/wsi/common/window_base.mpp @@ -91,8 +91,7 @@ export namespace stormkit::wsi::common { auto mouse_state(this T& self, u8 id) noexcept -> core::meta::ForwardConst&; template - auto keyboard_state(this T& self, u8 id) noexcept - -> core::meta::ForwardConst&; + auto keyboard_state(this T& self, u8 id) noexcept -> core::meta::ForwardConst&; protected: struct { @@ -216,8 +215,7 @@ namespace stormkit::wsi::common { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto WindowBase::set_monitor_changed_event(MonitorChangedEventFunc&& func) noexcept - -> void { + inline auto WindowBase::set_monitor_changed_event(MonitorChangedEventFunc&& func) noexcept -> void { monitor_changed_event = std::move(func); } @@ -259,16 +257,14 @@ namespace stormkit::wsi::common { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto WindowBase::set_mouse_button_down_event(MouseButtonDownEventFunc&& func) noexcept - -> void { + inline auto WindowBase::set_mouse_button_down_event(MouseButtonDownEventFunc&& func) noexcept -> void { mouse_button_down_event = std::move(func); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto WindowBase::set_mouse_button_up_event(MouseButtonUpEventFunc&& func) noexcept - -> void { + inline auto WindowBase::set_mouse_button_up_event(MouseButtonUpEventFunc&& func) noexcept -> void { mouse_button_up_event = std::move(func); } @@ -297,8 +293,7 @@ namespace stormkit::wsi::common { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto WindowBase::mouse_state(this T& self, u8 id) noexcept - -> core::meta::ForwardConst& { + inline auto WindowBase::mouse_state(this T& self, u8 id) noexcept -> core::meta::ForwardConst& { expects(id < stdr::size(self.m_mouse_states)); return self.m_mouse_states[id]; } @@ -307,8 +302,7 @@ namespace stormkit::wsi::common { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto WindowBase::keyboard_state(this T& self, u8 id) noexcept - -> core::meta::ForwardConst& { + inline auto WindowBase::keyboard_state(this T& self, u8 id) noexcept -> core::meta::ForwardConst& { expects(id < stdr::size(self.m_keyboard_states)); return self.m_keyboard_states[id]; } diff --git a/src/wsi/linux/common/xkb.mpp b/src/wsi/linux/common/xkb.mpp index 8f80259a6..8eb19e52a 100644 --- a/src/wsi/linux/common/xkb.mpp +++ b/src/wsi/linux/common/xkb.mpp @@ -20,18 +20,9 @@ import stormkit.wsi; export namespace stormkit::wsi::linux::common { namespace xkb { - using Keymap = RAIICapsule; - using State - = RAIICapsule; - using Context = RAIICapsule; + using Keymap = RAIICapsule; + using State = RAIICapsule; + using Context = RAIICapsule; struct Mods { xkb_mod_index_t shift; diff --git a/src/wsi/linux/wayland/context.mpp b/src/wsi/linux/wayland/context.mpp index 4923ee580..5981d99f5 100644 --- a/src/wsi/linux/wayland/context.mpp +++ b/src/wsi/linux/wayland/context.mpp @@ -35,23 +35,22 @@ export namespace stormkit::wsi::linux::wayland { }; struct Globals { - bool initialized = false; - wl::Display display = wl::Display::empty(); - wl::Registry registry = wl::Registry::empty(); - wl::Compositor compositor = wl::Compositor::empty(); - std::vector outputs; - wl::XDGWmBase xdg_wm_base = wl::XDGWmBase::empty(); - wl::Shm shm = wl::Shm::empty(); - wl::XDGDecorationManager decoration_manager = wl::XDGDecorationManager::empty(); - wl::Seat seat = wl::Seat::empty(); - wl::SinglePixelBufferManager - single_pixel_buffer_manager = wl::SinglePixelBufferManager::empty(); - wl::Viewporter viewporter = wl::Viewporter::empty(); - wl::CursorShapeManager cursor_shape_manager = wl::CursorShapeManager::empty(); - wl::CursorShapeDevice cursor_shape_device = wl::CursorShapeDevice::empty(); - wl::PointerWarp pointer_warp = wl::PointerWarp::empty(); - wl::PointerConstraints pointer_constraints = wl::PointerConstraints::empty(); - wl::ContentTypeManager content_type_manager = wl::ContentTypeManager::empty(); + bool initialized = false; + wl::Display display = wl::Display::empty(); + wl::Registry registry = wl::Registry::empty(); + wl::Compositor compositor = wl::Compositor::empty(); + std::vector outputs; + wl::XDGWmBase xdg_wm_base = wl::XDGWmBase::empty(); + wl::Shm shm = wl::Shm::empty(); + wl::XDGDecorationManager decoration_manager = wl::XDGDecorationManager::empty(); + wl::Seat seat = wl::Seat::empty(); + wl::SinglePixelBufferManager single_pixel_buffer_manager = wl::SinglePixelBufferManager::empty(); + wl::Viewporter viewporter = wl::Viewporter::empty(); + wl::CursorShapeManager cursor_shape_manager = wl::CursorShapeManager::empty(); + wl::CursorShapeDevice cursor_shape_device = wl::CursorShapeDevice::empty(); + wl::PointerWarp pointer_warp = wl::PointerWarp::empty(); + wl::PointerConstraints pointer_constraints = wl::PointerConstraints::empty(); + wl::ContentTypeManager content_type_manager = wl::ContentTypeManager::empty(); wl::CursorTheme cursor_theme = wl::CursorTheme::empty(); wl::CursorTheme cursor_theme_high_dpi = wl::CursorTheme::empty(); @@ -60,8 +59,7 @@ export namespace stormkit::wsi::linux::wayland { std::vector> pointers; std::vector> touchs; - wl::RelativePointerManager - relative_pointer_manager = wl::RelativePointerManager::empty(); + wl::RelativePointerManager relative_pointer_manager = wl::RelativePointerManager::empty(); std::vector monitors; diff --git a/src/wsi/linux/wayland/monitor.mpp b/src/wsi/linux/wayland/monitor.mpp index b08fe072f..6c154a07b 100644 --- a/src/wsi/linux/wayland/monitor.mpp +++ b/src/wsi/linux/wayland/monitor.mpp @@ -22,9 +22,7 @@ namespace stormkit::wsi::linux::wayland { if (update or stdr::empty(monitors)) { auto& globals = wl::get_globals(); monitors = globals.monitors - | stdv::transform([](const wl::WaylandMonitor& pair) static noexcept { - return pair.monitor; - }) + | stdv::transform([](const wl::WaylandMonitor& pair) static noexcept { return pair.monitor; }) | stdr::to(); } diff --git a/src/wsi/linux/wayland/wayland.mpp b/src/wsi/linux/wayland/wayland.mpp index 07e6c194b..9b851888a 100644 --- a/src/wsi/linux/wayland/wayland.mpp +++ b/src/wsi/linux/wayland/wayland.mpp @@ -26,140 +26,91 @@ import stormkit.core; import stormkit.wsi; export namespace stormkit::wsi::linux::wayland::wl { - using Display = stormkit::RAIICapsule; - using Registry = stormkit::RAIICapsule; - using Compositor = stormkit::RAIICapsule; - using Output = stormkit:: - RAIICapsule; - using XDGWmBase = stormkit:: - RAIICapsule; + using Display = stormkit::RAIICapsule; + using Registry = stormkit:: + RAIICapsule; + using Compositor = stormkit:: + RAIICapsule; + using Output = stormkit::RAIICapsule; + using XDGWmBase = stormkit::RAIICapsule; using XDGDecorationManager = stormkit::RAIICapsule; - using Buffer = stormkit:: - RAIICapsule; - using Keyboard = stormkit::RAIICapsule; - using Pointer = stormkit:: - RAIICapsule; - using Touch = stormkit:: - RAIICapsule; - using Shm = stormkit:: - RAIICapsule; - using Seat = stormkit:: - RAIICapsule; - using SinglePixelBufferManager = stormkit::RAIICapsule< - wp_single_pixel_buffer_manager_v1*, - monadic::noop(), - wp_single_pixel_buffer_manager_v1_destroy, - struct SinglePixelBufferManagerTag, - nullptr>; - using Viewporter = stormkit::RAIICapsule; + using Buffer = stormkit::RAIICapsule; + using Keyboard = stormkit::RAIICapsule; + using Pointer = stormkit::RAIICapsule; + using Touch = stormkit::RAIICapsule; + using Shm = stormkit::RAIICapsule; + using Seat = stormkit::RAIICapsule; + using SinglePixelBufferManager = stormkit::RAIICapsule; + using Viewporter = stormkit:: + RAIICapsule; using ContentTypeManager = stormkit::RAIICapsule; - using ShmPool = stormkit::RAIICapsule; - using CursorTheme = stormkit::RAIICapsule; - using CursorShapeManager = stormkit::RAIICapsule; - using CursorShapeDevice = stormkit::RAIICapsule; - using PointerConstraints = stormkit::RAIICapsule; - using PointerWarp = stormkit::RAIICapsule; + using ShmPool = stormkit::RAIICapsule; + using CursorTheme = stormkit:: + RAIICapsule; + using CursorShapeManager = stormkit::RAIICapsule; + using CursorShapeDevice = stormkit::RAIICapsule; + using PointerConstraints = stormkit::RAIICapsule; + using PointerWarp = stormkit:: + RAIICapsule; using RelativePointerManager = stormkit::RAIICapsule; - using Surface = stormkit::RAIICapsule; + using XDGSurface = stormkit:: + RAIICapsule; + using XDGTopLevel = stormkit:: + RAIICapsule; + using XDGTopLevelDecoration = stormkit::RAIICapsule; - using XDGSurface = stormkit::RAIICapsule; - using XDGTopLevel = stormkit::RAIICapsule; - using XDGTopLevelDecoration = stormkit::RAIICapsule< - zxdg_toplevel_decoration_v1*, - zxdg_decoration_manager_v1_get_toplevel_decoration, - zxdg_toplevel_decoration_v1_destroy, - struct XDGTopLevelDecorationTag, - nullptr>; - using LockedPointer = stormkit::RAIICapsule; - using ConfinedPointer = stormkit::RAIICapsule; - using RelativePointer = stormkit::RAIICapsule< - zwp_relative_pointer_v1*, - zwp_relative_pointer_manager_v1_get_relative_pointer, - zwp_relative_pointer_v1_destroy, - struct RelativePointerTag, - nullptr>; - using Viewport = stormkit::RAIICapsule; + using RelativePointer = stormkit::RAIICapsule; + using Viewport = stormkit:: + RAIICapsule; using ContentType = stormkit::RAIICapsule Window&; - auto open(std::string title, const math::Extent2& size, WindowFlag flags) noexcept - -> void; + auto open(std::string title, const math::Extent2& size, WindowFlag flags) noexcept -> void; auto close() noexcept -> void; auto handle_events() noexcept -> void; @@ -88,10 +87,7 @@ export { auto handle_xdg_surface_configure(u32) noexcept -> void; auto handle_xdg_surface_close() noexcept -> void; - auto handle_xdg_top_level_configure(u32, - u32, - std::span) noexcept - -> void; + auto handle_xdg_top_level_configure(u32, u32, std::span) noexcept -> void; auto handle_surface_enter(wl_surface*, wl_output*) noexcept -> void; auto handle_keyboard_key(Key, char, bool) noexcept -> void; @@ -120,13 +116,12 @@ export { Handles m_handles; - wl::Surface m_surface = wl::Surface::empty(); - wl::XDGSurface m_xdg_surface = wl::XDGSurface::empty(); - wl::XDGTopLevel m_xdg_top_level = wl::XDGTopLevel::empty(); - wl::XDGTopLevelDecoration - m_xdg_top_level_decoration = wl::XDGTopLevelDecoration::empty(); - wl::ContentType m_content_type = wl::ContentType::empty(); - wl::Viewport m_viewport = wl::Viewport::empty(); + wl::Surface m_surface = wl::Surface::empty(); + wl::XDGSurface m_xdg_surface = wl::XDGSurface::empty(); + wl::XDGTopLevel m_xdg_top_level = wl::XDGTopLevel::empty(); + wl::XDGTopLevelDecoration m_xdg_top_level_decoration = wl::XDGTopLevelDecoration::empty(); + wl::ContentType m_content_type = wl::ContentType::empty(); + wl::Viewport m_viewport = wl::Viewport::empty(); DeferInit m_shm_buffer; wl::ShmPool m_shm_pool = wl::ShmPool::empty(); diff --git a/src/wsi/linux/window.mpp b/src/wsi/linux/window.mpp index 73344d438..efaa291fc 100644 --- a/src/wsi/linux/window.mpp +++ b/src/wsi/linux/window.mpp @@ -35,8 +35,7 @@ export namespace stormkit::wsi::linux { Window(Window&&) noexcept; auto operator=(Window&&) noexcept -> Window&; - auto open(std::string title, const math::Extent2& size, WindowFlag flags) noexcept - -> void; + auto open(std::string title, const math::Extent2& size, WindowFlag flags) noexcept -> void; auto close() noexcept -> void; [[nodiscard]] @@ -127,12 +126,14 @@ namespace stormkit::wsi::linux { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Window::~Window() noexcept = default; + inline Window::~Window() noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Window::Window(Window&&) noexcept = default; + inline Window::Window(Window&&) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// @@ -142,14 +143,10 @@ namespace stormkit::wsi::linux { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Window::open(std::string title, - const math::Extent2& extent, - WindowFlag flags) noexcept -> void { + inline auto Window::open(std::string title, const math::Extent2& extent, WindowFlag flags) noexcept -> void { switch (m_wm) { case WM::X11: as(m_impl).open(std::move(title), extent, flags); break; - case WM::WAYLAND: - as(m_impl).open(std::move(title), extent, flags); - break; + case WM::WAYLAND: as(m_impl).open(std::move(title), extent, flags); break; default: std::unreachable(); } @@ -407,9 +404,7 @@ namespace stormkit::wsi::linux { inline auto Window::set_relative_mouse(bool enabled, u8 mouse_id) noexcept -> void { switch (m_wm) { case WM::X11: as(m_impl).set_relative_mouse(enabled, mouse_id); break; - case WM::WAYLAND: - as(m_impl).set_relative_mouse(enabled, mouse_id); - break; + case WM::WAYLAND: as(m_impl).set_relative_mouse(enabled, mouse_id); break; default: std::unreachable(); } @@ -435,8 +430,7 @@ namespace stormkit::wsi::linux { inline auto Window::set_key_repeat(bool enabled, u8 keyboard_id) noexcept -> void { switch (m_wm) { case WM::X11: return as(m_impl).set_key_repeat(enabled, keyboard_id); - case WM::WAYLAND: - return as(m_impl).set_key_repeat(enabled, keyboard_id); + case WM::WAYLAND: return as(m_impl).set_key_repeat(enabled, keyboard_id); default: break; } @@ -487,13 +481,10 @@ namespace stormkit::wsi::linux { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Window::set_mouse_position(const math::vec2i& position, u8 mouse_id) noexcept - -> void { + inline auto Window::set_mouse_position(const math::vec2i& position, u8 mouse_id) noexcept -> void { switch (m_wm) { case WM::X11: as(m_impl).set_mouse_position(position, mouse_id); break; - case WM::WAYLAND: - as(m_impl).set_mouse_position(position, mouse_id); - break; + case WM::WAYLAND: as(m_impl).set_mouse_position(position, mouse_id); break; default: std::unreachable(); } @@ -529,9 +520,7 @@ namespace stormkit::wsi::linux { inline auto Window::set_monitor_changed_event(MonitorChangedEventFunc&& func) noexcept -> void { switch (m_wm) { case WM::X11: as(m_impl).monitor_changed_event = std::move(func); break; - case WM::WAYLAND: - as(m_impl).monitor_changed_event = std::move(func); - break; + case WM::WAYLAND: as(m_impl).monitor_changed_event = std::move(func); break; default: std::unreachable(); } } @@ -594,13 +583,10 @@ namespace stormkit::wsi::linux { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Window::set_mouse_button_down_event(MouseButtonDownEventFunc&& func) noexcept - -> void { + inline auto Window::set_mouse_button_down_event(MouseButtonDownEventFunc&& func) noexcept -> void { switch (m_wm) { case WM::X11: as(m_impl).mouse_button_down_event = std::move(func); break; - case WM::WAYLAND: - as(m_impl).mouse_button_down_event = std::move(func); - break; + case WM::WAYLAND: as(m_impl).mouse_button_down_event = std::move(func); break; default: std::unreachable(); } } @@ -611,9 +597,7 @@ namespace stormkit::wsi::linux { inline auto Window::set_mouse_button_up_event(MouseButtonUpEventFunc&& func) noexcept -> void { switch (m_wm) { case WM::X11: as(m_impl).mouse_button_up_event = std::move(func); break; - case WM::WAYLAND: - as(m_impl).mouse_button_up_event = std::move(func); - break; + case WM::WAYLAND: as(m_impl).mouse_button_up_event = std::move(func); break; default: std::unreachable(); } } @@ -624,9 +608,7 @@ namespace stormkit::wsi::linux { inline auto Window::set_mouse_moved_event(MouseMovedEventFunc&& func) noexcept -> void { switch (m_wm) { case WM::X11: as(m_impl).mouse_moved_event = std::move(func); break; - case WM::WAYLAND: - as(m_impl).mouse_moved_event = std::move(func); - break; + case WM::WAYLAND: as(m_impl).mouse_moved_event = std::move(func); break; default: std::unreachable(); } } diff --git a/src/wsi/linux/x11/context.mpp b/src/wsi/linux/x11/context.mpp index f5a346bfe..43250beca 100644 --- a/src/wsi/linux/x11/context.mpp +++ b/src/wsi/linux/x11/context.mpp @@ -31,14 +31,12 @@ export namespace stormkit::wsi::linux::x11::xcb { auto init() noexcept -> bool; auto get_globals() noexcept -> Globals&; - auto get_atom(std::string_view name, bool only_if_exists) noexcept - -> std::expected; + auto get_atom(std::string_view name, bool only_if_exists) noexcept -> std::expected; auto get_atom_name(xcb_atom_t atom) -> std::expected; auto get_error(Ref error) -> std::string; - auto get_xi_device_info(xcb_input_device_id_t device_id) - -> std::expected, Error>; + auto get_xi_device_info(xcb_input_device_id_t device_id) -> std::expected, Error>; // template // auto get_xft_value(std::string_view name) -> std::optional; diff --git a/src/wsi/linux/x11/monitor.mpp b/src/wsi/linux/x11/monitor.mpp index a737e02a1..788fd333d 100644 --- a/src/wsi/linux/x11/monitor.mpp +++ b/src/wsi/linux/x11/monitor.mpp @@ -35,22 +35,16 @@ namespace stormkit::wsi::linux::x11 { xcb_randr_get_output_info_reply, std::free, struct OutputTag>; - using CRTC = RAIICapsule; + using CRTC = RAIICapsule; const auto root = xcb_setup_roots_iterator(xcb_get_setup(globals.connection)).data; auto xcb_monitors = Monitors::create(globals.connection, - xcb_randr_get_monitors(globals.connection, - root->root, - 0), + xcb_randr_get_monitors(globals.connection, root->root, 0), nullptr); auto xcb_monitor_iter = xcb_randr_get_monitors_monitors_iterator(xcb_monitors); - for (auto i = 0; xcb_monitor_iter.rem; - xcb_randr_monitor_info_next(&xcb_monitor_iter), ++i) { + for (auto i = 0; xcb_monitor_iter.rem; xcb_randr_monitor_info_next(&xcb_monitor_iter), ++i) { auto monitor_info = xcb_monitor_iter.data; xcb_randr_select_input(globals.connection, root->root, true); @@ -69,8 +63,7 @@ namespace stormkit::wsi::linux::x11 { for (auto j : range(len)) { auto output_cookie = xcb_randr_get_output_info(globals.connection, outputs[j], - xcb_monitors.handle() - ->timestamp); + xcb_monitors.handle()->timestamp); auto output = Output::create(globals.connection, output_cookie, nullptr); if (!output) continue; @@ -84,14 +77,12 @@ namespace stormkit::wsi::linux::x11 { if (crtc == nullptr) {} - monitor.extents.emplace_back(math::Extent2 { as(crtc.handle()->width), - as(crtc.handle()->height) }); + monitor.extents.emplace_back(math::Extent2 { as(crtc.handle()->width), as(crtc.handle()->height) }); } if (stdr::empty(monitor.extents)) - monitor.extents - .emplace_back(math::Extent2 { as(xcb_monitor_iter.data->width), - as(xcb_monitor_iter.data->height) }); + monitor.extents.emplace_back(math::Extent2 { as(xcb_monitor_iter.data->width), + as(xcb_monitor_iter.data->height) }); } } return monitors; diff --git a/src/wsi/linux/x11/utils.mpp b/src/wsi/linux/x11/utils.mpp index a8a52215e..73613b2e9 100644 --- a/src/wsi/linux/x11/utils.mpp +++ b/src/wsi/linux/x11/utils.mpp @@ -53,8 +53,7 @@ namespace stormkit::wsi::linux::x11 { inline auto screen_of_display(xcb_connection_t* c, int screen) noexcept -> xcb_screen_t* { auto iter = xcb_screen_iterator_t {}; - for (iter = xcb_setup_roots_iterator(xcb_get_setup(c)); iter.rem; --screen, - xcb_screen_next(&iter)) + for (iter = xcb_setup_roots_iterator(xcb_get_setup(c)); iter.rem; --screen, xcb_screen_next(&iter)) if (screen == 0) return iter.data; return iter.data; @@ -63,8 +62,7 @@ namespace stormkit::wsi::linux::x11 { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto default_root_window(xcb_connection_t* connection, int32_t screen_id) noexcept - -> xcb_window_t { + inline auto default_root_window(xcb_connection_t* connection, int32_t screen_id) noexcept -> xcb_window_t { auto screen = screen_of_display(connection, screen_id); return screen->root; diff --git a/src/wsi/linux/x11/window.mpp b/src/wsi/linux/x11/window.mpp index 4212bb41f..4d2b5ea91 100644 --- a/src/wsi/linux/x11/window.mpp +++ b/src/wsi/linux/x11/window.mpp @@ -44,31 +44,14 @@ export namespace stormkit::wsi::linux::x11 { Destructor(globals.connection, val); }; - using Window = RAIICapsule, - struct WindowTag, - XCB_WINDOW_NONE>; - using ColorMap = RAIICapsule, - struct ColorMapTag, - XCB_NONE>; - using GraphicsContext = RAIICapsule, - struct GraphicsContextTag, - XCB_NONE>; - using Image = RAIICapsule; - using Pixmap = RAIICapsule, - struct PixmapTag, - XCB_NONE>; + using Window + = RAIICapsule, struct WindowTag, XCB_WINDOW_NONE>; + using ColorMap + = RAIICapsule, struct ColorMapTag, XCB_NONE>; + using GraphicsContext + = RAIICapsule, struct GraphicsContextTag, XCB_NONE>; + using Image = RAIICapsule; + using Pixmap = RAIICapsule, struct PixmapTag, XCB_NONE>; } // namespace xcb class Window: public stormkit::wsi::common::WindowBase { @@ -89,8 +72,7 @@ export namespace stormkit::wsi::linux::x11 { Window(Window&&) noexcept; auto operator=(Window&&) noexcept -> Window&; - auto open(std::string title, const math::Extent2& size, WindowFlag flags) noexcept - -> void; + auto open(std::string title, const math::Extent2& size, WindowFlag flags) noexcept -> void; auto close() noexcept -> void; auto handle_events() noexcept -> void; @@ -172,7 +154,8 @@ namespace stormkit::wsi::linux::x11 { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Window::Window(Window&&) noexcept = default; + inline Window::Window(Window&&) noexcept + = default; ///////////////////////////////////// ///////////////////////////////////// diff --git a/src/wsi/linux/x11/xcb.mpp b/src/wsi/linux/x11/xcb.mpp index cabe661b4..3bb31b2ae 100644 --- a/src/wsi/linux/x11/xcb.mpp +++ b/src/wsi/linux/x11/xcb.mpp @@ -26,49 +26,30 @@ export namespace stormkit::wsi::linux::x11 { }; namespace xcb { - using Connection = RAIICapsule; + using Connection = RAIICapsule; using ErrorContext = RAIICapsule< xcb_errors_context_t*, monadic::init_by(), xcb_errors_context_free, struct ErrorContextTag, nullptr>; - using GenericError = RAIICapsule; - using InternAtomReply = RAIICapsule; - using AtomNameReply = RAIICapsule; + using GenericError = RAIICapsule; + using InternAtomReply + = RAIICapsule; + using AtomNameReply + = RAIICapsule; using InputXIQueryDeviceReply = RAIICapsule; - using KeySymbols = RAIICapsule; + using KeySymbols + = RAIICapsule; - constexpr auto atom_error(std::string_view msg, std::string_view atom_name) - -> decltype(auto); + constexpr auto atom_error(std::string_view msg, std::string_view atom_name) -> decltype(auto); } // namespace xcb } // namespace stormkit::wsi::linux::x11 diff --git a/tests/core/containers/tree.cpp b/tests/core/containers/tree.cpp index 8dfd67eaa..c7654ea48 100644 --- a/tests/core/containers/tree.cpp +++ b/tests/core/containers/tree.cpp @@ -13,13 +13,12 @@ using namespace stormkit::core; using namespace std::literals; namespace { - auto _ = test::TestSuite { "Core.Containers", - { { "Tree.Node.name", [] { - static constexpr auto name = "TestNodeName"sv; + auto _ = test::TestSuite { "Core.Containers", { { "Tree.Node.name", [] { + static constexpr auto name = "TestNodeName"sv; - auto node = TreeNode {}; - EXPECTS(node.name() == ""s); - node.set_name(std::string { name }); - EXPECTS(node.name() == name); - } } } }; + auto node = TreeNode {}; + EXPECTS(node.name() == ""s); + node.set_name(std::string { name }); + EXPECTS(node.name() == name); + } } } }; } // namespace diff --git a/tests/core/typesafe/safecasts.integer.cpp b/tests/core/typesafe/safecasts.integer.cpp index 144d7167b..6091d63e1 100644 --- a/tests/core/typesafe/safecasts.integer.cpp +++ b/tests/core/typesafe/safecasts.integer.cpp @@ -33,54 +33,74 @@ namespace bar { namespace { [[maybe_unused]] - const auto i8_1 = i8 { 1 }; + const auto i8_1 + = i8 { 1 }; [[maybe_unused]] - const auto i8_2 = i8 { 2 }; + const auto i8_2 + = i8 { 2 }; [[maybe_unused]] - const auto u8_1 = u8 { 1 }; + const auto u8_1 + = u8 { 1 }; [[maybe_unused]] - const auto u8_2 = u8 { 2 }; + const auto u8_2 + = u8 { 2 }; [[maybe_unused]] - const auto i16_1 = i16 { 1 }; + const auto i16_1 + = i16 { 1 }; [[maybe_unused]] - const auto i16_2 = i16 { 2 }; + const auto i16_2 + = i16 { 2 }; [[maybe_unused]] - const auto u16_1 = u16 { 1 }; + const auto u16_1 + = u16 { 1 }; [[maybe_unused]] - const auto u16_2 = u16 { 2 }; + const auto u16_2 + = u16 { 2 }; [[maybe_unused]] - const auto i32_1 = i32 { 1 }; + const auto i32_1 + = i32 { 1 }; [[maybe_unused]] - const auto i32_2 = i32 { 2 }; + const auto i32_2 + = i32 { 2 }; [[maybe_unused]] - const auto u32_1 = u32 { 1 }; + const auto u32_1 + = u32 { 1 }; [[maybe_unused]] - const auto u32_2 = u32 { 2 }; + const auto u32_2 + = u32 { 2 }; [[maybe_unused]] - const auto i64_1 = i64 { 1 }; + const auto i64_1 + = i64 { 1 }; [[maybe_unused]] - const auto i64_2 = i64 { 2 }; + const auto i64_2 + = i64 { 2 }; [[maybe_unused]] - const auto u64_1 = u64 { 1 }; + const auto u64_1 + = u64 { 1 }; [[maybe_unused]] - const auto u64_2 = u64 { 2 }; + const auto u64_2 + = u64 { 2 }; [[maybe_unused]] - const auto i128_1 = i128 { 1 }; + const auto i128_1 + = i128 { 1 }; [[maybe_unused]] - const auto i128_2 = i128 { 2 }; + const auto i128_2 + = i128 { 2 }; [[maybe_unused]] - const auto u128_1 = u128 { 1 }; + const auto u128_1 + = u128 { 1 }; [[maybe_unused]] - const auto u128_2 = u128 { 2 }; + const auto u128_2 + = u128 { 2 }; auto _ = test::TestSuite { "Core.typesafe.safecasts", From d04711a6af43545ef93c2678eb5640a7f3b16079 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sat, 24 Jan 2026 01:21:22 +0100 Subject: [PATCH 004/194] (core) fix compilation on gcc --- modules/stormkit/core/console/style.mpp | 4 +-- .../stormkit/core/containers/shmbuffer.mpp | 26 +++++++++---------- modules/stormkit/core/functional/monadic.mpp | 7 ++--- modules/stormkit/core/math/combinatoric.mpp | 6 ++--- modules/stormkit/core/meta/concepts.mpp | 13 +++++++++- modules/stormkit/core/parallelism/locked.mpp | 2 +- .../stormkit/core/parallelism/threadpool.mpp | 2 +- modules/stormkit/core/string/format.mpp | 2 +- modules/stormkit/core/typesafe/ref.mpp | 2 +- modules/stormkit/core/utils/color.mpp | 4 +-- modules/stormkit/core/utils/filesystem.mpp | 6 ++--- modules/stormkit/core/utils/random.mpp | 13 ++++------ 12 files changed, 46 insertions(+), 41 deletions(-) diff --git a/modules/stormkit/core/console/style.mpp b/modules/stormkit/core/console/style.mpp index 04e9dfb4a..82e1c8b99 100644 --- a/modules/stormkit/core/console/style.mpp +++ b/modules/stormkit/core/console/style.mpp @@ -98,7 +98,7 @@ export { using namespace std::literals; namespace stormkit { inline namespace core { - namespace { namespace ecma48 { + namespace ecma48 { constexpr auto FOREGROUND = frozen::make_unordered_map({ { ConsoleColor::BLACK, "\x1B[30m" }, { ConsoleColor::RED, "\x1B[31m" }, @@ -143,7 +143,7 @@ namespace stormkit { inline namespace core { constexpr auto ITALIC = "\x1B[3m"sv; constexpr auto UNDERLINE = "\x1B[4m"sv; constexpr auto INVERSE = "\x1B[7m"sv; - }} // namespace ::ecma48 + } // namespace ecma48 ///////////////////////////////////// ///////////////////////////////////// diff --git a/modules/stormkit/core/containers/shmbuffer.mpp b/modules/stormkit/core/containers/shmbuffer.mpp index 07a8fec42..1a8418131 100644 --- a/modules/stormkit/core/containers/shmbuffer.mpp +++ b/modules/stormkit/core/containers/shmbuffer.mpp @@ -85,14 +85,14 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - auto SHMBuffer::create(usize size, std::string name) noexcept -> std::expected { + inline auto SHMBuffer::create(usize size, std::string name) noexcept -> std::expected { return create_with_access(size, std::move(name), Access::READ | Access::WRITE); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - auto SHMBuffer::create_with_access(usize size, std::string name, Access access) noexcept + inline auto SHMBuffer::create_with_access(usize size, std::string name, Access access) noexcept -> std::expected { auto buffer = SHMBuffer { size, std::move(name), access, PrivateFuncTag {} }; return buffer.allocate_buffer().transform(core::monadic::consume(buffer)); @@ -136,7 +136,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - auto SHMBuffer::begin(this Self& self) noexcept -> decltype(auto) { + inline auto SHMBuffer::begin(this Self& self) noexcept -> decltype(auto) { EXPECTS(self.m_handle); return stdr::begin(std::forward(self).m_data); } @@ -144,7 +144,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_PURE STORMKIT_FORCE_INLINE - auto SHMBuffer::cbegin() const noexcept -> decltype(auto) { + inline auto SHMBuffer::cbegin() const noexcept -> decltype(auto) { EXPECTS(m_handle); return stdr::cbegin(m_data); } @@ -153,7 +153,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - auto SHMBuffer::end(this Self& self) noexcept -> decltype(auto) { + inline auto SHMBuffer::end(this Self& self) noexcept -> decltype(auto) { EXPECTS(self.m_handle); return stdr::end(std::forward(self).m_data); } @@ -161,7 +161,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_PURE STORMKIT_FORCE_INLINE - auto SHMBuffer::cend() const noexcept -> decltype(auto) { + inline auto SHMBuffer::cend() const noexcept -> decltype(auto) { EXPECTS(m_handle); return stdr::cend(m_data); } @@ -170,7 +170,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - auto SHMBuffer::operator[](this Self& self, usize index) noexcept -> meta::ForwardConst& { + inline auto SHMBuffer::operator[](this Self& self, usize index) noexcept -> meta::ForwardConst& { EXPECTS(self.m_handle); EXPECTS(index < self.m_size); return std::forward(self).m_data[index]; @@ -180,7 +180,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - auto SHMBuffer::at(this Self& self, usize index) noexcept -> meta::ForwardConst& { + inline auto SHMBuffer::at(this Self& self, usize index) noexcept -> meta::ForwardConst& { EXPECTS(self.m_handle); EXPECTS(index < self.m_size); return std::forward(self).m_data.at(index); @@ -189,7 +189,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_PURE STORMKIT_FORCE_INLINE - auto SHMBuffer::size() const noexcept -> usize { + inline auto SHMBuffer::size() const noexcept -> usize { return m_size; } @@ -197,7 +197,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - auto SHMBuffer::data(this Self& self) noexcept -> meta::ForwardConst* { + inline auto SHMBuffer::data(this Self& self) noexcept -> meta::ForwardConst* { EXPECTS(self.m_handle); return stdr::data(std::forward(self).m_data); } @@ -206,21 +206,21 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - auto SHMBuffer::native_handle(this Self& self) noexcept -> meta::ForwardConst* { + inline auto SHMBuffer::native_handle(this Self& self) noexcept -> meta::ForwardConst* { return std::forward(self).m_handle; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_PURE STORMKIT_FORCE_INLINE - auto SHMBuffer::name() const noexcept -> const std::string& { + inline auto SHMBuffer::name() const noexcept -> const std::string& { return m_name; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_PURE STORMKIT_FORCE_INLINE - auto SHMBuffer::access() const noexcept -> Access { + inline auto SHMBuffer::access() const noexcept -> Access { return m_access; } }} // namespace stormkit::core diff --git a/modules/stormkit/core/functional/monadic.mpp b/modules/stormkit/core/functional/monadic.mpp index 6c51e6552..a0c406e02 100644 --- a/modules/stormkit/core/functional/monadic.mpp +++ b/modules/stormkit/core/functional/monadic.mpp @@ -147,11 +147,12 @@ namespace stormkit { inline namespace core { namespace monadic { ///////////////////////////////////// ///////////////////////////////////// - template [[nodiscard]] STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto consume(T&& value) noexcept -> decltype(auto) { - return [value = std::move(value)](auto&&...) mutable noexcept -> meta::CanonicalType { return std::move(value); }; + constexpr auto consume(auto&& value) noexcept -> decltype(auto) { + return [value = std::move(value)](auto&&...) mutable noexcept -> meta::CanonicalType { + return std::move(value); + }; } ///////////////////////////////////// diff --git a/modules/stormkit/core/math/combinatoric.mpp b/modules/stormkit/core/math/combinatoric.mpp index a9f3a41ac..205cb2269 100644 --- a/modules/stormkit/core/math/combinatoric.mpp +++ b/modules/stormkit/core/math/combinatoric.mpp @@ -24,10 +24,8 @@ export namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////////////////////////////////// namespace stormkit { inline namespace core { namespace math { - namespace { - constexpr auto FTABLE = std::array { 1, 1, 2, 6, 24, 120, 720, - 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800 }; - } + constexpr auto FTABLE = std::array { 1, 1, 2, 6, 24, 120, 720, + 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800 }; ///////////////////////////////////// ///////////////////////////////////// diff --git a/modules/stormkit/core/meta/concepts.mpp b/modules/stormkit/core/meta/concepts.mpp index eb6e81e70..68c0a5fa4 100644 --- a/modules/stormkit/core/meta/concepts.mpp +++ b/modules/stormkit/core/meta/concepts.mpp @@ -282,7 +282,18 @@ export namespace stormkit { inline namespace core { namespace meta { concept IsCharType = IsOneOf; template - concept IsColorComponent = Is or Is; + concept IsColorComponent = IsOneOf; template concept IsConst = std::is_const_v; diff --git a/modules/stormkit/core/parallelism/locked.mpp b/modules/stormkit/core/parallelism/locked.mpp index 97ff4bf6d..6169e3861 100644 --- a/modules/stormkit/core/parallelism/locked.mpp +++ b/modules/stormkit/core/parallelism/locked.mpp @@ -95,7 +95,7 @@ export namespace stormkit { inline namespace core { template class Lock, LockAccessMode Mode> class Access { public: - using ValueType = std::conditional_t; + using AccessValueType = std::conditional_t; using RefContainerType = std::conditional_t, Ref>; using ReferenceType = ValueType&; using PointerType = ValueType*; diff --git a/modules/stormkit/core/parallelism/threadpool.mpp b/modules/stormkit/core/parallelism/threadpool.mpp index e50a78682..3062ea07b 100644 --- a/modules/stormkit/core/parallelism/threadpool.mpp +++ b/modules/stormkit/core/parallelism/threadpool.mpp @@ -21,7 +21,7 @@ export namespace stormkit { inline namespace core { class STORMKIT_API ThreadPool { public: static constexpr struct NoFutureType { - } NoFuture; + } NoFuture = {}; template using Callback = std::function; diff --git a/modules/stormkit/core/string/format.mpp b/modules/stormkit/core/string/format.mpp index 12c2d8389..c25809b16 100644 --- a/modules/stormkit/core/string/format.mpp +++ b/modules/stormkit/core/string/format.mpp @@ -34,7 +34,7 @@ export { }; } // namespace meta - inline constexpr struct { + inline constexpr struct FormatFN { template static constexpr auto operator()(const T& value, FormatContext& ctx) noexcept -> FormatContext::iterator { return format_as(value, ctx); diff --git a/modules/stormkit/core/typesafe/ref.mpp b/modules/stormkit/core/typesafe/ref.mpp index 8427c0758..38b49245e 100644 --- a/modules/stormkit/core/typesafe/ref.mpp +++ b/modules/stormkit/core/typesafe/ref.mpp @@ -29,7 +29,7 @@ export { using ptr = T*; template - class [[nodiscard, gsl::Pointer]] + class [[nodiscard]] Ref { public: using ElementType = T; diff --git a/modules/stormkit/core/utils/color.mpp b/modules/stormkit/core/utils/color.mpp index 3494f2a2b..81602d70b 100644 --- a/modules/stormkit/core/utils/color.mpp +++ b/modules/stormkit/core/utils/color.mpp @@ -4,12 +4,10 @@ module; +#include #include - #include -#include - export module stormkit.core:utils.color; import std; diff --git a/modules/stormkit/core/utils/filesystem.mpp b/modules/stormkit/core/utils/filesystem.mpp index 444f5410f..8e48069d1 100644 --- a/modules/stormkit/core/utils/filesystem.mpp +++ b/modules/stormkit/core/utils/filesystem.mpp @@ -385,7 +385,7 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// //////////////////////////////////////// - template + template STORMKIT_FORCE_INLINE inline auto read_text_to(const stdfs::path& path, std::span> out) noexcept -> Expected { return TextFile::open(path, Access::READ).and_then([&out](auto&& file) mutable noexcept { @@ -396,7 +396,7 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// //////////////////////////////////////// - template + template STORMKIT_FORCE_INLINE inline auto read_text(const stdfs::path& path) noexcept -> Expected>> { auto out = std::vector> {}; @@ -436,7 +436,7 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// //////////////////////////////////////// - template + template STORMKIT_FORCE_INLINE inline auto write_text(const stdfs::path& path, std::span> data) noexcept -> Expected { diff --git a/modules/stormkit/core/utils/random.mpp b/modules/stormkit/core/utils/random.mpp index 367949115..846ea432e 100644 --- a/modules/stormkit/core/utils/random.mpp +++ b/modules/stormkit/core/utils/random.mpp @@ -31,21 +31,18 @@ export namespace stormkit { inline namespace core { //////////////////////////////////////////////////////////////////// namespace stormkit { inline namespace core { - namespace { - std::default_random_engine generator {}; - } - ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - auto random_generator() noexcept -> std::default_random_engine& { + inline auto random_generator() noexcept -> std::default_random_engine& { + static auto generator = std::default_random_engine {}; return generator; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - auto seed(u32 seed) noexcept -> void { + inline auto seed(u32 seed) noexcept -> void { random_generator().seed(seed); } @@ -53,7 +50,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - auto rand(T min, T max) noexcept -> T { + inline auto rand(T min, T max) noexcept -> T { std::uniform_real_distribution dis(min, max); return dis(random_generator()); } @@ -62,7 +59,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - auto rand(T min, T max) noexcept -> T { + inline auto rand(T min, T max) noexcept -> T { std::uniform_int_distribution dis(min, max); return dis(random_generator()); } From fe38a6bc6eccf615a049621a971e320d40ece552 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sat, 24 Jan 2026 01:22:00 +0100 Subject: [PATCH 005/194] (luau) add more lua bindings --- examples/wsi/luau/luau/events.luau | 22 ++-- examples/wsi/luau/src/main.cpp | 74 +---------- modules/stormkit/luau.mpp | 24 ++-- modules/stormkit/luau/core.mpp | 38 ++++++ modules/stormkit/luau/entities.mpp | 0 modules/stormkit/luau/gpu.mpp | 0 modules/stormkit/luau/image.mpp | 0 modules/stormkit/luau/log.mpp | 0 modules/stormkit/luau/wsi.mpp | 196 +++++++++++++++++++++++++++++ xmake.lua | 2 +- xmake/targets.xmake.lua | 10 +- 11 files changed, 272 insertions(+), 94 deletions(-) create mode 100644 modules/stormkit/luau/core.mpp create mode 100644 modules/stormkit/luau/entities.mpp create mode 100644 modules/stormkit/luau/gpu.mpp create mode 100644 modules/stormkit/luau/image.mpp create mode 100644 modules/stormkit/luau/log.mpp create mode 100644 modules/stormkit/luau/wsi.mpp diff --git a/examples/wsi/luau/luau/events.luau b/examples/wsi/luau/luau/events.luau index 795ee2ce4..21c10d371 100644 --- a/examples/wsi/luau/luau/events.luau +++ b/examples/wsi/luau/luau/events.luau @@ -1,13 +1,17 @@ -print(wsi.EventType) +local function main() + local window = wsi.open_window("test", 800, 600, wsi.WindowFlag.RESIZEABLE) -local window = wsi.open_window("test", 800, 600, wsi.WindowFlag.RESIZEABLE) -print("wm: " .. window:wm()) + window:on_closed(function() + print("Close event!") + return true + end) --- window:on(wsi.EventType.CLOSED, function() --- print("Close event!") --- end) + window:event_loop(function() + print("AAAAAAAAAA") + window:clear() + print("BBBBBBBBB") + end) +end --- window:event_loop(function() --- window.clear() --- end) +main() diff --git a/examples/wsi/luau/src/main.cpp b/examples/wsi/luau/src/main.cpp index 9c1dee595..b167a8853 100644 --- a/examples/wsi/luau/src/main.cpp +++ b/examples/wsi/luau/src/main.cpp @@ -2,6 +2,8 @@ // This file is subject to the license terms in the LICENSE file // found in the top-level of this distribution +#include + import std; import stormkit.core; @@ -22,14 +24,6 @@ LOGGER("Luau-Events"); using namespace stormkit; -auto open_window(std::string name, u32 width, u32 height, wsi::WindowFlag flags) noexcept { - return wsi::Window::open(std::move(name), { width, height }, flags); -} - -auto closed() { - return wsi::EventType::CLOSED; -} - //////////////////////////////////////// //////////////////////////////////////// auto main(std::span args) -> int { @@ -37,70 +31,6 @@ auto main(std::span args) -> int { auto logger = log::Logger::create_logger_instance(); auto engine = luau::Engine::create(LUAU_DIR "/events.luau"); - - engine.global_namespace() - .beginNamespace("wsi") - .beginNamespace("WindowFlag") - .addProperty( - "DEFAULT", - +[] static noexcept { return wsi::WindowFlag::DEFAULT; }) - .addProperty( - "BORDERLESS", - +[] static noexcept { return wsi::WindowFlag::BORDERLESS; }) - .addProperty( - "RESIZEABLE", - +[] static noexcept { return wsi::WindowFlag::RESIZEABLE; }) - .addProperty( - "EXTERNAL_CONTEXT", - +[] static noexcept { return wsi::WindowFlag::EXTERNAL_CONTEXT; }) - .endNamespace() - .beginNamespace("EventType") - .addProperty( - "NONE", - +[] static noexcept { return wsi::EventType::NONE; }) - .addProperty( - "CLOSED", - +[] static noexcept { return wsi::EventType::CLOSED; }) - .addProperty( - "MONITOR_CHANGED", - +[] static noexcept { return wsi::EventType::MONITOR_CHANGED; }) - .addProperty( - "RESIZED", - +[] static noexcept { return wsi::EventType::RESIZED; }) - .addProperty( - "RESTORED", - +[] static noexcept { return wsi::EventType::RESTORED; }) - .addProperty( - "MINIMIZED", - +[] static noexcept { return wsi::EventType::MINIMIZED; }) - .addProperty( - "KEY_DOWN", - +[] static noexcept { return wsi::EventType::KEY_DOWN; }) - .addProperty( - "KEY_UP", - +[] static noexcept { return wsi::EventType::KEY_UP; }) - .addProperty( - "MOUSE_BUTTON_DOWN", - +[] static noexcept { return wsi::EventType::MOUSE_BUTTON_DOWN; }) - .addProperty( - "MOUSE_BUTTON_UP", - +[] static noexcept { return wsi::EventType::MOUSE_BUTTON_UP; }) - .addProperty( - "MOUSE_MOVED", - +[] static noexcept { return wsi::EventType::MOUSE_MOVED; }) - .addProperty( - "ACTIVATE", - +[] static noexcept { return wsi::EventType::ACTIVATE; }) - .addProperty( - "DEACTIVATE", - +[] static noexcept { return wsi::EventType::DEACTIVATE; }) - .endNamespace() - .beginClass("window") - .addFunction("wm", &wsi::Window::wm) - .endClass() - .addFunction("open_window", open_window) - .endNamespace(); - engine.lua_main().transform_error(monadic::assert("lua runtime error!\n-------------------------------\n")); return 0; diff --git a/modules/stormkit/luau.mpp b/modules/stormkit/luau.mpp index 844f87067..ea5e74247 100644 --- a/modules/stormkit/luau.mpp +++ b/modules/stormkit/luau.mpp @@ -15,6 +15,12 @@ import std; import stormkit.core; +import :core; + +// #ifdef STORMKIT_WSI +import :wsi; +// #endif + namespace stdfs = std::filesystem; namespace stdr = std::ranges; @@ -66,6 +72,11 @@ export namespace stormkit::luau { std::string_view { msg, len })); } + core::init_lua(global_namespace()); + // #ifdef STORMKIT_WSI + wsi::init_lua(global_namespace()); + // #endif + m_main_thread = lua_newthread(m_global_state); ensures(m_main_thread); @@ -93,15 +104,12 @@ export namespace stormkit::luau { lua_pop(m_global_state, 1); } else { - auto error = std::string {}; - error.reserve(150); - - luaL_traceback(m_global_state, m_global_state, nullptr, 1); - - error += lua_tostring(m_global_state, -1); + auto l = 0; + luaL_traceback(m_global_state, m_main_thread, nullptr, l); + const auto str = lua_tostring(m_main_thread, -1); + out = std::unexpected { std::string { str } }; lua_pop(m_global_state, 1); - out = std::unexpected { std::move(error) }; } return out; @@ -131,7 +139,7 @@ export namespace stormkit::luau { // auto end_class(std::string_view name) noexcept -> Binder { return Binder { class.endClass() }; } // }; - auto global_namespace() noexcept { return lb::getGlobalNamespace(m_global_state); } + auto global_namespace() noexcept -> lb::Namespace { return lb::getGlobalNamespace(m_global_state); } static auto create(const stdfs::path& file) noexcept -> Engine { auto engine = Engine {}; diff --git a/modules/stormkit/luau/core.mpp b/modules/stormkit/luau/core.mpp new file mode 100644 index 000000000..ea481899e --- /dev/null +++ b/modules/stormkit/luau/core.mpp @@ -0,0 +1,38 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.luau:core; + +import std; + +import stormkit.core; + +namespace lb = luabridge; + +export namespace stormkit::luau::core { + inline auto init_lua(lb::Namespace global_namespace) noexcept -> void; +} // namespace stormkit::luau::core + +namespace stormkit::luau::core { + //////////////////////////////////////// + //////////////////////////////////////// + inline auto bind_color(lb::Namespace& global_namespace) noexcept -> lb::Namespace { + return global_namespace.beginNamespace("core") + .beginClass("RGBColorF") + .endClass() + .beginClass("RGBColorU") + .endClass() + .endNamespace(); + } + + //////////////////////////////////////// + //////////////////////////////////////// + inline auto init_lua(lb::Namespace global_namespace) noexcept -> void { + global_namespace = bind_color(global_namespace); + } +} // namespace stormkit::luau::core diff --git a/modules/stormkit/luau/entities.mpp b/modules/stormkit/luau/entities.mpp new file mode 100644 index 000000000..e69de29bb diff --git a/modules/stormkit/luau/gpu.mpp b/modules/stormkit/luau/gpu.mpp new file mode 100644 index 000000000..e69de29bb diff --git a/modules/stormkit/luau/image.mpp b/modules/stormkit/luau/image.mpp new file mode 100644 index 000000000..e69de29bb diff --git a/modules/stormkit/luau/log.mpp b/modules/stormkit/luau/log.mpp new file mode 100644 index 000000000..e69de29bb diff --git a/modules/stormkit/luau/wsi.mpp b/modules/stormkit/luau/wsi.mpp new file mode 100644 index 000000000..dcea7f8fc --- /dev/null +++ b/modules/stormkit/luau/wsi.mpp @@ -0,0 +1,196 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.luau:wsi; + +import std; + +import stormkit.core; +import stormkit.wsi; + +namespace lb = luabridge; + +export namespace stormkit::luau::wsi { + inline auto init_lua(lb::Namespace global_namespace) noexcept -> void; +} // namespace stormkit::luau::wsi + +namespace stormkit::luau::wsi { + using stormkit::wsi::EventType; + using stormkit::wsi::Window; + using stormkit::wsi::WindowFlag; + using stormkit::wsi::WM; + + //////////////////////////////////////// + //////////////////////////////////////// + auto open_window(std::string name, u32 width, u32 height, wsi::WindowFlag flags) noexcept -> decltype(auto) { + return wsi::Window::open(std::move(name), { width, height }, flags); + } + + //////////////////////////////////////// + //////////////////////////////////////// + inline auto bind_core(lb::Namespace& global_namespace) noexcept -> lb::Namespace { + return global_namespace.beginNamespace("wsi") + .beginNamespace("WM") + .addProperty( + "WIN32", + +[] static noexcept { return wsi::WM::WIN32; }) + .addProperty( + "WAYLAND", + +[] static noexcept { return wsi::WM::WAYLAND; }) + .addProperty( + "X11", + +[] static noexcept { return wsi::WM::X11; }) + .addProperty( + "ANDROID", + +[] static noexcept { return wsi::WM::ANDROID; }) + .addProperty( + "MACOS", + +[] static noexcept { return wsi::WM::MACOS; }) + .addProperty( + "IOS", + +[] static noexcept { return wsi::WM::IOS; }) + .addProperty( + "TVOS", + +[] static noexcept { return wsi::WM::TVOS; }) + .addProperty( + "SWITCH", + +[] static noexcept { return wsi::WM::SWITCH; }) + .endNamespace() + .endNamespace(); + } + + //////////////////////////////////////// + //////////////////////////////////////// + inline auto bind_window(lb::Namespace& global_namespace) noexcept -> lb::Namespace { + return global_namespace.beginNamespace("wsi") + .beginNamespace("WindowFlag") + .addProperty( + "DEFAULT", + +[] static noexcept { return wsi::WindowFlag::DEFAULT; }) + .addProperty( + "BORDERLESS", + +[] static noexcept { return wsi::WindowFlag::BORDERLESS; }) + .addProperty( + "RESIZEABLE", + +[] static noexcept { return wsi::WindowFlag::RESIZEABLE; }) + .addProperty( + "EXTERNAL_CONTEXT", + +[] static noexcept { return wsi::WindowFlag::EXTERNAL_CONTEXT; }) + .endNamespace() + .beginNamespace("EventType") + .addProperty( + "NONE", + +[] static noexcept { return wsi::EventType::NONE; }) + .addProperty( + "CLOSED", + +[] static noexcept { return wsi::EventType::CLOSED; }) + .addProperty( + "MONITOR_CHANGED", + +[] static noexcept { return wsi::EventType::MONITOR_CHANGED; }) + .addProperty( + "RESIZED", + +[] static noexcept { return wsi::EventType::RESIZED; }) + .addProperty( + "RESTORED", + +[] static noexcept { return wsi::EventType::RESTORED; }) + .addProperty( + "MINIMIZED", + +[] static noexcept { return wsi::EventType::MINIMIZED; }) + .addProperty( + "KEY_DOWN", + +[] static noexcept { return wsi::EventType::KEY_DOWN; }) + .addProperty( + "KEY_UP", + +[] static noexcept { return wsi::EventType::KEY_UP; }) + .addProperty( + "MOUSE_BUTTON_DOWN", + +[] static noexcept { return wsi::EventType::MOUSE_BUTTON_DOWN; }) + .addProperty( + "MOUSE_BUTTON_UP", + +[] static noexcept { return wsi::EventType::MOUSE_BUTTON_UP; }) + .addProperty( + "MOUSE_MOVED", + +[] static noexcept { return wsi::EventType::MOUSE_MOVED; }) + .addProperty( + "ACTIVATE", + +[] static noexcept { return wsi::EventType::ACTIVATE; }) + .addProperty( + "DEACTIVATE", + +[] static noexcept { return wsi::EventType::DEACTIVATE; }) + .endNamespace() + .beginClass("window") + .addFunction("wm", &wsi::Window::wm) + .addFunction("clear", [](Window* window) static noexcept { window->clear(); }) + .addFunction( + "event_loop", + +[](Window* window, lb::LuaRef func) static noexcept { + window->event_loop([func = std::move(func)] noexcept { + const auto result = func(); + ensures(result.wasOk(), result.errorMessage()); + }); + }) + .addFunction( + "on_closed", + +[](Window* window, lb::LuaRef func) static noexcept { + expects(func.isCallable()); + + window->on([func = std::move(func)] noexcept { + const auto result = func(); + ensures(result.wasOk(), result.errorMessage()); + const auto return_value = result[0]; + ensures(return_value.isValid()); + ensures(return_value.isBool(), "on_closed closure must return a boolean value"); + return return_value.cast().value(); + }); + }) + .endClass() + .addFunction("open_window", &open_window) + .endNamespace(); + } + + //////////////////////////////////////// + //////////////////////////////////////// + inline auto init_lua(lb::Namespace global_namespace) noexcept -> void { + global_namespace = bind_core(global_namespace); + global_namespace = bind_window(global_namespace); + } +} // namespace stormkit::luau::wsi + +using namespace stormkit; + +template<> +struct lb::Stack: lb::Enum {}; + +template<> +struct lb::Stack + : lb::Enum {}; + +template<> +struct lb::Stack + : lb::Enum {}; diff --git a/xmake.lua b/xmake.lua index 900a807b3..7673c4368 100644 --- a/xmake.lua +++ b/xmake.lua @@ -21,7 +21,7 @@ includes("xmake/rules/*.lua") includes("xmake/options.xmake.lua") if get_config("devmode") then - set_policy("build.c++.modules.non_cascading_changes", true) + -- set_policy("build.c++.modules.non_cascading_changes", true) set_policy("build.c++.modules.hide_dependencies", true) end diff --git a/xmake/targets.xmake.lua b/xmake/targets.xmake.lua index 4c61d9aa7..34eaed96d 100644 --- a/xmake/targets.xmake.lua +++ b/xmake/targets.xmake.lua @@ -59,13 +59,14 @@ modules = { }, luau = get_config("luau") and { modulename = "luau", - public_deps = { "core" }, + public_deps = { "core", "wsi" }, public_packages = { "luau", "luabridge3" }, public_defines = { 'LUA_API=extern __attribute__((visibility("default")))' }, } or nil, wsi = { modulename = "wsi", public_deps = { "core" }, + public_defines = get_config("luau") and { "STORMKIT_WSI_LUA" } or {}, deps = { "log" }, packages = is_plat("linux") and { "libxcb", @@ -137,14 +138,15 @@ modules = { "vulkan-headers", "vulkan-memory-allocator", }, - public_deps = { "core", "log", "wsi", "image" }, + public_deps = { "core", "wsi", "image" }, + deps = { "log" }, packages = is_plat("linux") and { "libxcb", "wayland", } or nil, - public_defines = { + public_defines = table.join({ "STORMKIT_GPU_VULKAN", - }, + }, get_config("luau") and { "STORMKIT_WSI_LUA" } or {}), custom = function() add_cxflags("clang::-Wno-missing-declarations") end, }, } From fc6b9fd955b4a8c3415967fb14141ea2df0fada1 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 25 Jan 2026 22:00:42 +0100 Subject: [PATCH 006/194] (gpu) fix some warnings --- examples/gpu/imgui/src/main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/gpu/imgui/src/main.cpp b/examples/gpu/imgui/src/main.cpp index e53a8b10e..7e5f520c9 100644 --- a/examples/gpu/imgui/src/main.cpp +++ b/examples/gpu/imgui/src/main.cpp @@ -157,10 +157,10 @@ class Application: public base::Application { .QueueFamily = 0, .Queue = m_raster_queue->native_handle(), .DescriptorPool = m_descriptor_pool->native_handle(), + .DescriptorPoolSize = 0, .MinImageCount = BUFFERING_COUNT, .ImageCount = BUFFERING_COUNT, .PipelineCache = nullptr, - .DescriptorPoolSize = 0, .PipelineInfoMain = { .RenderPass = m_render_pass->native_handle(), .Subpass = 0, @@ -174,6 +174,8 @@ class Application: public base::Application { if (result != VK_SUCCESS) elog("{}", gpu::from_vk(result)); }, .MinAllocationSize = 1024 * 1024, + .CustomShaderVertCreateInfo = {}, + .CustomShaderFragCreateInfo = {}, }; ImGui_ImplVulkan_LoadFunctions(VK_API_VERSION_1_1, gpu::imgui_vk_loader, &*m_device); ImGui_ImplVulkan_Init(&init_info); From d5142ce19b60dba20b52c4c25c9defc697568dff Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 25 Jan 2026 22:01:13 +0100 Subject: [PATCH 007/194] (luau) add luau defines and improve xmake related code --- xmake.lua | 2 ++ xmake/options.xmake.lua | 2 +- xmake/targets.xmake.lua | 22 +++++++++++----------- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/xmake.lua b/xmake.lua index 7673c4368..78fe5c484 100644 --- a/xmake.lua +++ b/xmake.lua @@ -167,6 +167,8 @@ namespace("stormkit", function() end end + if not get_config("luau") then remove_files(path.join(src_path, name, "lua.mpp")) end + add_includedirs("$(projectdir)/include", { public = true }) if module.defines then add_defines(module.defines) end diff --git a/xmake/options.xmake.lua b/xmake/options.xmake.lua index 6ce81fe0f..ec610b00e 100644 --- a/xmake/options.xmake.lua +++ b/xmake/options.xmake.lua @@ -51,7 +51,7 @@ option("entities", { default = true, category = "root menu/modules" }) option("image", { default = true, category = "root menu/modules", deps = { "log" } }) option("wsi", { default = true, category = "root menu/modules", deps = { "log" } }) option("gpu", { default = true, category = "root menu/modules", deps = { "log", "image", "wsi" } }) -option("luau", { default = false, category = "root menu/modules" }) +option("luau", { default = true, category = "root menu/modules", deps = { "log", "entities", "image", "wsi", "gpu" } }) option("compile_commands", { default = false, category = "root menu/support" }) option("vsxmake", { default = false, category = "root menu/support" }) diff --git a/xmake/targets.xmake.lua b/xmake/targets.xmake.lua index 34eaed96d..9599bb116 100644 --- a/xmake/targets.xmake.lua +++ b/xmake/targets.xmake.lua @@ -35,17 +35,17 @@ modules = { }, log = { modulename = "log", - public_deps = { "core" }, + public_deps = table.join("core", get_config("luau") and "luau" or {}), has_headers = true, }, entities = { modulename = "entities", - public_deps = { "core" }, + public_deps = table.join("core", get_config("luau") and "luau" or {}), }, image = { - packages = { "libktx", "libpng", "libjpeg-turbo" }, modulename = "image", - public_deps = { "core" }, + packages = { "libktx", "libpng", "libjpeg-turbo" }, + public_deps = table.join("core", get_config("luau") and "luau" or {}), }, main = { modulename = "main", @@ -59,14 +59,14 @@ modules = { }, luau = get_config("luau") and { modulename = "luau", - public_deps = { "core", "wsi" }, + has_headers = true, + public_deps = { "core" }, public_packages = { "luau", "luabridge3" }, - public_defines = { 'LUA_API=extern __attribute__((visibility("default")))' }, + public_defines = { "STORMKIT_LUA_BINDING", 'LUA_API=extern __attribute__((visibility("default")))' }, } or nil, wsi = { modulename = "wsi", - public_deps = { "core" }, - public_defines = get_config("luau") and { "STORMKIT_WSI_LUA" } or {}, + public_deps = table.join("core", get_config("luau") and "luau" or {}), deps = { "log" }, packages = is_plat("linux") and { "libxcb", @@ -138,15 +138,15 @@ modules = { "vulkan-headers", "vulkan-memory-allocator", }, - public_deps = { "core", "wsi", "image" }, + public_deps = table.join("core", "wsi", "image", get_config("luau") and "luau" or {}), deps = { "log" }, packages = is_plat("linux") and { "libxcb", "wayland", } or nil, - public_defines = table.join({ + public_defines = { "STORMKIT_GPU_VULKAN", - }, get_config("luau") and { "STORMKIT_WSI_LUA" } or {}), + }, custom = function() add_cxflags("clang::-Wno-missing-declarations") end, }, } From 67cda39242c8c925688ec66a4eed4b4e19bb817a Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 25 Jan 2026 22:01:55 +0100 Subject: [PATCH 008/194] (gpu) add convertions of ExtentX to Vk vector types --- modules/stormkit/gpu/core/structs.mpp | 11 +++++-- modules/stormkit/gpu/core/vulkan/structs.mpp | 30 +++++++++++++------- src/gpu/execution/command_buffer.cpp | 8 +++--- 3 files changed, 33 insertions(+), 16 deletions(-) diff --git a/modules/stormkit/gpu/core/structs.mpp b/modules/stormkit/gpu/core/structs.mpp index 369168951..2495938d5 100644 --- a/modules/stormkit/gpu/core/structs.mpp +++ b/modules/stormkit/gpu/core/structs.mpp @@ -262,8 +262,15 @@ export { ImageSubresourceLayers src; ImageSubresourceLayers dst; - std::array src_offset; - std::array dst_offset; + struct { + math::vec3i position; + math::Extent3 extent; + } src_offset; + + struct { + math::vec3i position; + math::Extent3 extent; + } dst_offset; }; struct PushConstantRange { diff --git a/modules/stormkit/gpu/core/vulkan/structs.mpp b/modules/stormkit/gpu/core/vulkan/structs.mpp index ee2d06842..d7cd70386 100644 --- a/modules/stormkit/gpu/core/vulkan/structs.mpp +++ b/modules/stormkit/gpu/core/vulkan/structs.mpp @@ -21,6 +21,8 @@ export namespace stormkit::gpu { [[nodiscard]] auto to_vk(const T& value) noexcept -> decltype(auto); + struct ToVec; + template [[nodiscard]] constexpr auto to_vk(const math::vec2i& vector) noexcept -> Out; @@ -52,13 +54,13 @@ export namespace stormkit::gpu { [[nodiscard]] constexpr auto from_vk(const VkViewport& viewport) noexcept -> Viewport; - template + template [[nodiscard]] - constexpr auto to_vk(const Extent& extent) noexcept -> VkExtent2D; + constexpr auto to_vk(const Extent& extent) noexcept -> Out; - template + template [[nodiscard]] - constexpr auto to_vk(const Extent& extent) noexcept -> VkExtent3D; + constexpr auto to_vk(const Extent& extent) noexcept -> Out; template> [[nodiscard]] @@ -164,20 +166,28 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto to_vk(const Extent& extent) noexcept -> VkExtent2D { - return VkExtent2D { .width = as(extent.width), .height = as(extent.height) }; + constexpr auto to_vk(const Extent& extent) noexcept -> Out { + if constexpr (stormkit::meta::Is) + return VkExtent2D { .width = as(extent.width), .height = as(extent.height) }; + else + return Out { .x = extent.width, .y = extent.height }; } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto to_vk(const Extent& extent) noexcept -> VkExtent3D { - return VkExtent3D { .width = as(extent.width), .height = as(extent.height), .depth = as(extent.depth) }; + constexpr auto to_vk(const Extent& extent) noexcept -> Out { + if constexpr (stormkit::meta::Is) + return VkExtent3D { .width = as(extent.width), + .height = as(extent.height), + .depth = as(extent.depth) }; + else + return Out { .x = extent.width, .y = extent.height, .z = extent.depth }; } ///////////////////////////////////// diff --git a/src/gpu/execution/command_buffer.cpp b/src/gpu/execution/command_buffer.cpp index 42e2f227f..0384d2bbf 100644 --- a/src/gpu/execution/command_buffer.cpp +++ b/src/gpu/execution/command_buffer.cpp @@ -442,11 +442,11 @@ namespace stormkit::gpu { return VkImageBlit { .srcSubresource = vk_src_subresource_layers, - .srcOffsets = { to_vk(region.src_offset[0]), - to_vk(region.src_offset[1]) }, + .srcOffsets = { to_vk(region.src_offset.position), + to_vk(region.src_offset.extent) }, .dstSubresource = vk_dst_subresource_layers, - .dstOffsets = { to_vk(region.dst_offset[0]), - to_vk(region.dst_offset[1]) }, + .dstOffsets = { to_vk(region.dst_offset.position), + to_vk(region.dst_offset.extent) }, }; }) | stdr::to(); From aa9cc4bd60fa208ec3d98c69c215c1c7bc5b0f65 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 25 Jan 2026 22:02:12 +0100 Subject: [PATCH 009/194] (luau) refactor lua architecture --- modules/stormkit/entities.mpp | 4 ++ modules/stormkit/entities/lua.mpp | 26 ++++++++++++ modules/stormkit/gpu.mpp | 5 ++- modules/stormkit/gpu/lua.mpp | 26 ++++++++++++ modules/stormkit/image.mpp | 4 ++ modules/stormkit/image/lua.mpp | 26 ++++++++++++ modules/stormkit/log/lua.mpp | 26 ++++++++++++ modules/stormkit/luau.mpp | 7 ---- modules/stormkit/luau/core.mpp | 17 ++++++-- modules/stormkit/luau/entities.mpp | 0 modules/stormkit/luau/gpu.mpp | 0 modules/stormkit/luau/image.mpp | 0 modules/stormkit/luau/log.mpp | 0 modules/stormkit/wsi.mpp | 4 ++ .../stormkit/{luau/wsi.mpp => wsi/lua.mpp} | 41 +++++++++++++++---- 15 files changed, 167 insertions(+), 19 deletions(-) create mode 100644 modules/stormkit/entities/lua.mpp create mode 100644 modules/stormkit/gpu/lua.mpp create mode 100644 modules/stormkit/image/lua.mpp create mode 100644 modules/stormkit/log/lua.mpp delete mode 100644 modules/stormkit/luau/entities.mpp delete mode 100644 modules/stormkit/luau/gpu.mpp delete mode 100644 modules/stormkit/luau/image.mpp delete mode 100644 modules/stormkit/luau/log.mpp rename modules/stormkit/{luau/wsi.mpp => wsi/lua.mpp} (82%) diff --git a/modules/stormkit/entities.mpp b/modules/stormkit/entities.mpp index e34427357..4bf27e6dc 100644 --- a/modules/stormkit/entities.mpp +++ b/modules/stormkit/entities.mpp @@ -16,6 +16,10 @@ import std; import stormkit.core; +#ifdef STORMKIT_LUA_BINDING +export import :lua; +#endif + namespace stdr = std::ranges; namespace stdv = std::views; diff --git a/modules/stormkit/entities/lua.mpp b/modules/stormkit/entities/lua.mpp new file mode 100644 index 000000000..b38aa03a0 --- /dev/null +++ b/modules/stormkit/entities/lua.mpp @@ -0,0 +1,26 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.entities:lua; + +import std; + +import stormkit.core; + +namespace lb = luabridge; + +export namespace stormkit::entities::lua { + inline auto init_lua(lb::Namespace global_namespace) noexcept -> void; +} + +namespace stormkit::entities::lua { + //////////////////////////////////////// + //////////////////////////////////////// + inline auto init_lua(lb::Namespace) noexcept -> void { + } +} // namespace stormkit::entities::lua diff --git a/modules/stormkit/gpu.mpp b/modules/stormkit/gpu.mpp index dd5fa1cc5..b3ccf97c7 100644 --- a/modules/stormkit/gpu.mpp +++ b/modules/stormkit/gpu.mpp @@ -8,4 +8,7 @@ export module stormkit.gpu; export import stormkit.gpu.core; export import stormkit.gpu.execution; export import stormkit.gpu.resource; -export; + +#ifdef STORMKIT_LUA_BINDING +export import :lua; +#endif diff --git a/modules/stormkit/gpu/lua.mpp b/modules/stormkit/gpu/lua.mpp new file mode 100644 index 000000000..a4384c047 --- /dev/null +++ b/modules/stormkit/gpu/lua.mpp @@ -0,0 +1,26 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.gpu:lua; + +import std; + +import stormkit.core; + +namespace lb = luabridge; + +export namespace stormkit::gpu::lua { + inline auto init_lua(lb::Namespace global_namespace) noexcept -> void; +} + +namespace stormkit::gpu::lua { + //////////////////////////////////////// + //////////////////////////////////////// + inline auto init_lua(lb::Namespace) noexcept -> void { + } +} // namespace stormkit::gpu::lua diff --git a/modules/stormkit/image.mpp b/modules/stormkit/image.mpp index 710a861a2..950279c5a 100644 --- a/modules/stormkit/image.mpp +++ b/modules/stormkit/image.mpp @@ -14,6 +14,10 @@ import std; import stormkit.core; +#ifdef STORMKIT_LUA_BINDING +export import :lua; +#endif + export namespace stormkit::image { class STORMKIT_API Image { public: diff --git a/modules/stormkit/image/lua.mpp b/modules/stormkit/image/lua.mpp new file mode 100644 index 000000000..6e7293e56 --- /dev/null +++ b/modules/stormkit/image/lua.mpp @@ -0,0 +1,26 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.image:lua; + +import std; + +import stormkit.core; + +namespace lb = luabridge; + +export namespace stormkit::image::lua { + inline auto init_lua(lb::Namespace global_namespace) noexcept -> void; +} + +namespace stormkit::image::lua { + //////////////////////////////////////// + //////////////////////////////////////// + inline auto init_lua(lb::Namespace) noexcept -> void { + } +} // namespace stormkit::image::lua diff --git a/modules/stormkit/log/lua.mpp b/modules/stormkit/log/lua.mpp new file mode 100644 index 000000000..ad09fda84 --- /dev/null +++ b/modules/stormkit/log/lua.mpp @@ -0,0 +1,26 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.log:lua; + +import std; + +import stormkit.core; + +namespace lb = luabridge; + +export namespace stormkit::log::lua { + inline auto init_lua(lb::Namespace global_namespace) noexcept -> void; +} + +namespace stormkit::log::lua { + //////////////////////////////////////// + //////////////////////////////////////// + inline auto init_lua(lb::Namespace) noexcept -> void { + } +} // namespace stormkit::log::lua diff --git a/modules/stormkit/luau.mpp b/modules/stormkit/luau.mpp index ea5e74247..a99aa1b30 100644 --- a/modules/stormkit/luau.mpp +++ b/modules/stormkit/luau.mpp @@ -17,10 +17,6 @@ import stormkit.core; import :core; -// #ifdef STORMKIT_WSI -import :wsi; -// #endif - namespace stdfs = std::filesystem; namespace stdr = std::ranges; @@ -73,9 +69,6 @@ export namespace stormkit::luau { } core::init_lua(global_namespace()); - // #ifdef STORMKIT_WSI - wsi::init_lua(global_namespace()); - // #endif m_main_thread = lua_newthread(m_global_state); ensures(m_main_thread); diff --git a/modules/stormkit/luau/core.mpp b/modules/stormkit/luau/core.mpp index ea481899e..171c8c1fc 100644 --- a/modules/stormkit/luau/core.mpp +++ b/modules/stormkit/luau/core.mpp @@ -22,10 +22,20 @@ namespace stormkit::luau::core { //////////////////////////////////////// //////////////////////////////////////// inline auto bind_color(lb::Namespace& global_namespace) noexcept -> lb::Namespace { - return global_namespace.beginNamespace("core") - .beginClass("RGBColorF") + return global_namespace.beginClass("fcolor").endClass().beginClass("ucolor").endClass(); + } + + //////////////////////////////////////// + //////////////////////////////////////// + inline auto bind_extent(lb::Namespace& global_namespace) noexcept -> lb::Namespace { + return global_namespace.beginNamespace("math") + .beginClass>("uextent2") + .endClass() + .beginClass>("uextent3") + .endClass() + .beginClass>("fextent2") .endClass() - .beginClass("RGBColorU") + .beginClass>("fextent3") .endClass() .endNamespace(); } @@ -34,5 +44,6 @@ namespace stormkit::luau::core { //////////////////////////////////////// inline auto init_lua(lb::Namespace global_namespace) noexcept -> void { global_namespace = bind_color(global_namespace); + global_namespace = bind_extent(global_namespace); } } // namespace stormkit::luau::core diff --git a/modules/stormkit/luau/entities.mpp b/modules/stormkit/luau/entities.mpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/modules/stormkit/luau/gpu.mpp b/modules/stormkit/luau/gpu.mpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/modules/stormkit/luau/image.mpp b/modules/stormkit/luau/image.mpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/modules/stormkit/luau/log.mpp b/modules/stormkit/luau/log.mpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/modules/stormkit/wsi.mpp b/modules/stormkit/wsi.mpp index 259a58ee6..5f52b05f9 100644 --- a/modules/stormkit/wsi.mpp +++ b/modules/stormkit/wsi.mpp @@ -10,3 +10,7 @@ export import :window; // export import :event_handler; export import :keyboard; export import :mouse; + +#ifdef STORMKIT_LUA_BINDING +export import :lua; +#endif diff --git a/modules/stormkit/luau/wsi.mpp b/modules/stormkit/wsi/lua.mpp similarity index 82% rename from modules/stormkit/luau/wsi.mpp rename to modules/stormkit/wsi/lua.mpp index dcea7f8fc..20f439319 100644 --- a/modules/stormkit/luau/wsi.mpp +++ b/modules/stormkit/wsi/lua.mpp @@ -4,22 +4,28 @@ module; +#include + #include -export module stormkit.luau:wsi; +export module stormkit.wsi:lua; import std; import stormkit.core; -import stormkit.wsi; +import :core; +import :mouse; +import :keyboard; +import :monitor; +import :window; namespace lb = luabridge; -export namespace stormkit::luau::wsi { +export namespace stormkit::wsi::lua { inline auto init_lua(lb::Namespace global_namespace) noexcept -> void; -} // namespace stormkit::luau::wsi +} // namespace stormkit::wsi::lua -namespace stormkit::luau::wsi { +namespace stormkit::wsi::lua { using stormkit::wsi::EventType; using stormkit::wsi::Window; using stormkit::wsi::WindowFlag; @@ -35,7 +41,7 @@ namespace stormkit::luau::wsi { //////////////////////////////////////// inline auto bind_core(lb::Namespace& global_namespace) noexcept -> lb::Namespace { return global_namespace.beginNamespace("wsi") - .beginNamespace("WM") + .beginNamespace("wm") .addProperty( "WIN32", +[] static noexcept { return wsi::WM::WIN32; }) @@ -64,11 +70,24 @@ namespace stormkit::luau::wsi { .endNamespace(); } + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline constexpr auto make_lua_closure() noexcept { + return [](Window* window, lb::LuaRef func) static noexcept { + window->on([func = std::move(func)](Args&&... args) noexcept { + const auto result = func(std::forward(args)...); + ensures(result.wasOk(), result.errorMessage()); + }); + }; + } + //////////////////////////////////////// //////////////////////////////////////// inline auto bind_window(lb::Namespace& global_namespace) noexcept -> lb::Namespace { return global_namespace.beginNamespace("wsi") - .beginNamespace("WindowFlag") + .beginNamespace("window_flag") .addProperty( "DEFAULT", +[] static noexcept { return wsi::WindowFlag::DEFAULT; }) @@ -125,6 +144,7 @@ namespace stormkit::luau::wsi { .endNamespace() .beginClass("window") .addFunction("wm", &wsi::Window::wm) + .addFunction("extent", &wsi::Window::extent) .addFunction("clear", [](Window* window) static noexcept { window->clear(); }) .addFunction( "event_loop", @@ -148,6 +168,11 @@ namespace stormkit::luau::wsi { return return_value.cast().value(); }); }) + .addFunction("on_resized", +(make_lua_closure&>())) + .addFunction("on_restored", +(make_lua_closure())) + .addFunction("on_minimized", +(make_lua_closure())) + .addFunction("on_activate", +(make_lua_closure())) + .addFunction("on_deactivate", +(make_lua_closure())) .endClass() .addFunction("open_window", &open_window) .endNamespace(); @@ -159,7 +184,7 @@ namespace stormkit::luau::wsi { global_namespace = bind_core(global_namespace); global_namespace = bind_window(global_namespace); } -} // namespace stormkit::luau::wsi +} // namespace stormkit::wsi::lua using namespace stormkit; From 5c2402cdbc073e1e28af7e8bebddf72bef0ff87b Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 25 Jan 2026 22:02:42 +0100 Subject: [PATCH 010/194] (luau) disable warnings in lua files --- examples/wsi/luau/luau/events.luau | 109 ++++++++++++++++++++++++++++- examples/wsi/luau/src/main.cpp | 1 + include/stormkit/luau/lua.hpp | 7 ++ 3 files changed, 114 insertions(+), 3 deletions(-) diff --git a/examples/wsi/luau/luau/events.luau b/examples/wsi/luau/luau/events.luau index 21c10d371..48768b587 100644 --- a/examples/wsi/luau/luau/events.luau +++ b/examples/wsi/luau/luau/events.luau @@ -1,5 +1,5 @@ local function main() - local window = wsi.open_window("test", 800, 600, wsi.WindowFlag.RESIZEABLE) + local window = wsi.open_window("test", 800, 600, wsi.window_flag.RESIZEABLE) window:on_closed(function() @@ -7,10 +7,113 @@ local function main() return true end) + local vec = vector.create(0, 1, 0) + + window:on_resized(function(extent) + print("Resize event: %s", extent) + return true + end) + + window:on_monitor_changed(function(monitor) + print("Monitor changed event: %s", monitor) + return true + end) + + window:on_mouse_moved(function(_, position) + print("Mouse move event: %s", position) + return true + end) + + window:on_mouse_button_down(function(_, button, position) + print("Mouse button down event: %s %s", button, position) + return true + end) + + window:on_mouse_button_up(function(_, button, position) + print("Mouse button up event: %s %s", button, position) + return true + end) + + window:on_restored(function() + print("Restored event!") + return true + end) + + window:on_minimized(function() + print("Minimzed event!") + return true + end) + + window:on_activate(function() + print("Activate event!") + return true + end) + + window:on_deactivate(function() + print("Deactivate event!") + return true + end) + + window:on_key_down(function(_, key, c) + local closures = { + [wsi.Key.ESCAPE] = function() + window:close() + print("Closing window") + end, + [wsi.Key.W] = function() + window:close() + print("Closing window") + end, + [wsi.Key.T] = function() + window:close() + print("Closing window") + end, + [wsi.Key.H] = function() + window:close() + print("Closing window") + end, + [wsi.Key.F11] = function() + window:close() + print("Closing window") + end, + [wsi.Key.F1] = function() + window:close() + print("Closing window") + end, + [wsi.Key.F2] = function() + window:close() + print("Closing window") + end, + [wsi.Key.F3] = function() + window:close() + print("Closing window") + end, + [wsi.Key.F4] = function() + window:close() + print("Closing window") + end, + [wsi.Key.F5] = function() + window:close() + print("Closing window") + end, + } + + for k, closure in pairs(closures) do + if k == key then + closure() + break + end + end + + print("Key down --\n code: %s\n value: '%s'\n)", key, c); + end) + + window:on_key_up(function(_, key, c) + print("Key up --\n code: %s\n value: '%s'\n)", key, c); + end) + window:event_loop(function() - print("AAAAAAAAAA") window:clear() - print("BBBBBBBBB") end) end diff --git a/examples/wsi/luau/src/main.cpp b/examples/wsi/luau/src/main.cpp index b167a8853..7f41481c1 100644 --- a/examples/wsi/luau/src/main.cpp +++ b/examples/wsi/luau/src/main.cpp @@ -31,6 +31,7 @@ auto main(std::span args) -> int { auto logger = log::Logger::create_logger_instance(); auto engine = luau::Engine::create(LUAU_DIR "/events.luau"); + wsi::lua::init_lua(engine.global_namespace()); engine.lua_main().transform_error(monadic::assert("lua runtime error!\n-------------------------------\n")); return 0; diff --git a/include/stormkit/luau/lua.hpp b/include/stormkit/luau/lua.hpp index a8f3b2aee..c7293d24c 100644 --- a/include/stormkit/luau/lua.hpp +++ b/include/stormkit/luau/lua.hpp @@ -1,6 +1,10 @@ #ifndef STORMKIT_LUA_HPP #define STORMKIT_LUA_HPP +#include + +STORMKIT_PUSH_WARNINGS + extern "C" { #include @@ -8,7 +12,10 @@ extern "C" { #include } +#pragma clang diagnostic ignored "-Wdeprecated-declarations" #include #undef assert +STORMKIT_POP_WARNINGS + #endif From a939e3491b5a65106f5acd8efcb69a1066f392be Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 25 Jan 2026 22:19:23 +0100 Subject: [PATCH 011/194] (xmake) add missing luau dependencies --- xmake/targets.xmake.lua | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/xmake/targets.xmake.lua b/xmake/targets.xmake.lua index 9599bb116..6690102f3 100644 --- a/xmake/targets.xmake.lua +++ b/xmake/targets.xmake.lua @@ -36,16 +36,19 @@ modules = { log = { modulename = "log", public_deps = table.join("core", get_config("luau") and "luau" or {}), + public_packages = get_config("luau") and { "luau", "luabridge3" } or {}, has_headers = true, }, entities = { modulename = "entities", public_deps = table.join("core", get_config("luau") and "luau" or {}), + public_packages = get_config("luau") and { "luau", "luabridge3" } or {}, }, image = { modulename = "image", packages = { "libktx", "libpng", "libjpeg-turbo" }, public_deps = table.join("core", get_config("luau") and "luau" or {}), + public_packages = get_config("luau") and { "luau", "luabridge3" } or {}, }, main = { modulename = "main", @@ -68,6 +71,7 @@ modules = { modulename = "wsi", public_deps = table.join("core", get_config("luau") and "luau" or {}), deps = { "log" }, + public_packages = get_config("luau") and { "luau", "luabridge3" } or {}, packages = is_plat("linux") and { "libxcb", "xcb-util-keysyms", @@ -132,12 +136,12 @@ modules = { gpu = { modulename = "gpu", has_headers = true, - public_packages = { + public_packages = table.join({ "frozen", "volk", "vulkan-headers", "vulkan-memory-allocator", - }, + }, get_config("luau") and { "luau", "luabridge3" } or {}), public_deps = table.join("core", "wsi", "image", get_config("luau") and "luau" or {}), deps = { "log" }, packages = is_plat("linux") and { From fa2cc71fa79b9c3359249f218dd15470c297670a Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 25 Jan 2026 22:27:25 +0100 Subject: [PATCH 012/194] (core) add missings inline to constexpr constants --- modules/stormkit/core/console/style.mpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/stormkit/core/console/style.mpp b/modules/stormkit/core/console/style.mpp index 82e1c8b99..0c670775b 100644 --- a/modules/stormkit/core/console/style.mpp +++ b/modules/stormkit/core/console/style.mpp @@ -99,7 +99,7 @@ using namespace std::literals; namespace stormkit { inline namespace core { namespace ecma48 { - constexpr auto FOREGROUND = frozen::make_unordered_map({ + inline constexpr auto FOREGROUND = frozen::make_unordered_map({ { ConsoleColor::BLACK, "\x1B[30m" }, { ConsoleColor::RED, "\x1B[31m" }, { ConsoleColor::GREEN, "\x1B[32m" }, @@ -118,7 +118,7 @@ namespace stormkit { inline namespace core { { ConsoleColor::BRIGHT_WHITE, "\x1B[97m" }, }); - constexpr auto BACKGROUND = frozen::make_unordered_map({ + inline constexpr auto BACKGROUND = frozen::make_unordered_map({ { ConsoleColor::BLACK, "\x1B[40m" }, { ConsoleColor::RED, "\x1B[41m" }, { ConsoleColor::GREEN, "\x1B[42m" }, @@ -137,12 +137,12 @@ namespace stormkit { inline namespace core { { ConsoleColor::BRIGHT_WHITE, "\x1B[107m" }, }); - constexpr auto RESET = "\x1B[0m"sv; - constexpr auto BOLD = "\x1B[1m"sv; - constexpr auto FAINT = "\x1B[2m"sv; - constexpr auto ITALIC = "\x1B[3m"sv; - constexpr auto UNDERLINE = "\x1B[4m"sv; - constexpr auto INVERSE = "\x1B[7m"sv; + inline constexpr auto RESET = "\x1B[0m"sv; + inline constexpr auto BOLD = "\x1B[1m"sv; + inline constexpr auto FAINT = "\x1B[2m"sv; + inline constexpr auto ITALIC = "\x1B[3m"sv; + inline constexpr auto UNDERLINE = "\x1B[4m"sv; + inline constexpr auto INVERSE = "\x1B[7m"sv; } // namespace ecma48 ///////////////////////////////////// From 847c7370438516736d7442d51d76fc4b58b428f4 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 25 Jan 2026 22:44:45 +0100 Subject: [PATCH 013/194] (log, wsi) fix lua partition not exported --- modules/stormkit/log.mpp | 4 ++++ modules/stormkit/wsi/lua.mpp | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/stormkit/log.mpp b/modules/stormkit/log.mpp index 14c6c0343..cfee13822 100644 --- a/modules/stormkit/log.mpp +++ b/modules/stormkit/log.mpp @@ -15,6 +15,10 @@ import frozen; import stormkit.core; +#ifdef STORMKIT_LUA_BINDING +export import :lua; +#endif + export { namespace stormkit::log { struct Module; diff --git a/modules/stormkit/wsi/lua.mpp b/modules/stormkit/wsi/lua.mpp index 20f439319..67e8b981f 100644 --- a/modules/stormkit/wsi/lua.mpp +++ b/modules/stormkit/wsi/lua.mpp @@ -33,7 +33,7 @@ namespace stormkit::wsi::lua { //////////////////////////////////////// //////////////////////////////////////// - auto open_window(std::string name, u32 width, u32 height, wsi::WindowFlag flags) noexcept -> decltype(auto) { + inline auto open_window(std::string name, u32 width, u32 height, wsi::WindowFlag flags) noexcept -> decltype(auto) { return wsi::Window::open(std::move(name), { width, height }, flags); } From 27a7a6c8c92e4f113026da148bd236c719a13117 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 25 Jan 2026 22:48:57 +0100 Subject: [PATCH 014/194] (core) fix missing bytes_as implementation --- modules/stormkit/core/typesafe/byte.mpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stormkit/core/typesafe/byte.mpp b/modules/stormkit/core/typesafe/byte.mpp index adb7e3026..782c1dce4 100644 --- a/modules/stormkit/core/typesafe/byte.mpp +++ b/modules/stormkit/core/typesafe/byte.mpp @@ -192,7 +192,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto bytes_mut_as(std::span bytes) noexcept -> const T& { + constexpr auto bytes_as(std::span bytes) noexcept -> const T& { if constexpr (EXTENT != std::dynamic_extent) EXPECTS(EXTENT == sizeof(T)); EXPECTS(stdr::size(bytes) == sizeof(T)); return *std::bit_cast(stdr::data(bytes)); From 71385882c89246b78d659fe7dc006a60e5debb20 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 26 Jan 2026 20:43:53 +0100 Subject: [PATCH 015/194] (all) fix compilation on latest llvm --- examples/gpu/common/app.mpp | 2 +- examples/gpu/imgui/src/main.cpp | 52 +++--- examples/gpu/textured_cube/src/main.cpp | 88 ++++----- examples/gpu/textured_cube/xmake.lua | 9 +- examples/gpu/triangle/src/main.cpp | 66 +++---- examples/gpu/triangle/xmake.lua | 6 +- examples/wsi/luau/src/main.cpp | 2 +- modules/stormkit/core/coroutines.mpp | 216 +++++++++-------------- modules/stormkit/core/typesafe/byte.mpp | 36 ++++ modules/stormkit/gpu/resource/buffer.mpp | 44 ++--- modules/stormkit/gpu/resource/shader.mpp | 6 +- src/core/contract.mpp | 3 + src/wsi/linux/x11/window.cpp | 130 +++++++------- 13 files changed, 323 insertions(+), 337 deletions(-) diff --git a/examples/gpu/common/app.mpp b/examples/gpu/common/app.mpp index da562a8c7..9ef9e3245 100644 --- a/examples/gpu/common/app.mpp +++ b/examples/gpu/common/app.mpp @@ -60,7 +60,7 @@ export namespace base { *gpu::initialize_backend().transform_error(monadic::assert("Failed to initialize gpu backend")); // create gpu instance and attach surface to window - m_instance = gpu::Instance::create(std::string { example_name }) + m_instance = gpu::Instance::create(std::string { example_name }, true) .transform_error(monadic::assert("Failed to initialize gpu instance")) .value(); diff --git a/examples/gpu/imgui/src/main.cpp b/examples/gpu/imgui/src/main.cpp index 7e5f520c9..1f2ee4f62 100644 --- a/examples/gpu/imgui/src/main.cpp +++ b/examples/gpu/imgui/src/main.cpp @@ -70,18 +70,18 @@ class Application: public base::Application { out.reserve(BUFFERING_COUNT); for (auto _ : range(BUFFERING_COUNT)) { out.push_back({ - .in_flight = gpu::Fence::create_signaled(m_device) - .transform_error(monadic::assert("Failed to create swapchain image " - "in flight fence")) - .value(), + .in_flight = gpu::Fence::create_signaled(m_device) + .transform_error(monadic::assert("Failed to create swapchain image " + "in flight fence")) + .value(), .image_available = gpu::Semaphore::create(m_device) .transform_error(monadic::assert("Failed to create " "present wait semaphore")) .value(), - .render_cmb = m_command_pool->create_command_buffer() - .transform_error(monadic::assert("Failed to create transition " - "command buffers")) - .value(), + .render_cmb = m_command_pool->create_command_buffer() + .transform_error(monadic::assert("Failed to create transition " + "command buffers")) + .value(), }); } }); @@ -91,15 +91,15 @@ class Application: public base::Application { const auto image_count = stdr::size(images); auto transition_cmbs = m_command_pool->create_command_buffers(image_count) - .transform_error(monadic::assert("Failed to create transition command buffers")) - .value(); + .transform_error(monadic::assert("Failed to create transition command buffers")) + .value(); m_image_resources.reserve(stdr::size(images)); auto image_index = 0u; for (const auto& swap_image : images) { - auto view = gpu::ImageView::create(m_device, swap_image) - .transform_error(core::monadic::assert("Failed to create swapchain image view")) - .value(); + auto view = gpu::ImageView::create(m_device, swap_image) + .transform_error(core::monadic::assert("Failed to create swapchain image view")) + .value(); auto framebuffer = m_render_pass->create_frame_buffer(m_device, window_extent, to_refs(view)) .transform_error(core::monadic::assert(std::format("Failed to create framebuffer for image {}", image_index))) @@ -116,15 +116,15 @@ class Application: public base::Application { }); auto& transition_cmb = transition_cmbs[image_index]; - *transition_cmb.begin(true) - .transform_error(monadic::assert("Failed to begin texture transition command buffer")) - .value() - ->begin_debug_region(std::format("transition image {}", image_index)) - .transition_image_layout(swap_image, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::PRESENT_SRC) - .end_debug_region() - .end() - .transform_error(monadic::assert("Failed to begin texture transition command " - "buffer")); + auto _ = *transition_cmb.begin(true) + .transform_error(monadic::assert("Failed to begin texture transition command buffer")) + .value() + ->begin_debug_region(std::format("transition image {}", image_index)) + .transition_image_layout(swap_image, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::PRESENT_SRC) + .end_debug_region() + .end() + .transform_error(monadic::assert("Failed to begin texture transition command " + "buffer")); ++image_index; } @@ -139,7 +139,7 @@ class Application: public base::Application { .value(); // wait for transition to be done - fence.wait().transform_error(monadic::assert()); + auto _ = fence.wait().transform_error(monadic::assert()); } auto init_imgui() -> void { @@ -274,9 +274,9 @@ class Application: public base::Application { if (++m_current_frame >= BUFFERING_COUNT) m_current_frame = 0; }; - m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)) - .transform(update_current_frame) - .transform_error(monadic::assert("Failed to present swapchain image")); + *m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)) + .transform(update_current_frame) + .transform_error(monadic::assert("Failed to present swapchain image")); } auto deinit() { diff --git a/examples/gpu/textured_cube/src/main.cpp b/examples/gpu/textured_cube/src/main.cpp index 7aa6c4573..b84a8420f 100644 --- a/examples/gpu/textured_cube/src/main.cpp +++ b/examples/gpu/textured_cube/src/main.cpp @@ -16,11 +16,11 @@ import gpu_app; LOGGER("stormkit.examples.gpu.textured_cube"); #ifndef SHADER_DIR - #define SHADER_DIR "../share/shaders" + #define SHADER_DIR "." #endif #ifndef TEXTURE_DIR - #define TEXTURE_DIR "../share/textures" + #define TEXTURE_DIR "." #endif namespace stdc = std::chrono; @@ -138,12 +138,18 @@ class Application: public base::Application { .value(); // load shaders - m_vertex_shader = gpu::Shader::load_from_file(m_device, SHADER_DIR "/textured_cube.spv", gpu::ShaderStageFlag::VERTEX) - .transform_error(monadic::assert("Failed to load vertex shader")) + m_vertex_shader = gpu::Shader::load_from_file(m_device, + SHADER_DIR "/shaders/textured_cube.spv", + gpu::ShaderStageFlag::VERTEX) + .transform_error(monadic::assert(std::format("Failed to load vertex shader {}", + SHADER_DIR "/shaders/textured_cube.spv"))) .value(); - m_fragment_shader = gpu::Shader::load_from_file(m_device, SHADER_DIR "/textured_cube.spv", gpu::ShaderStageFlag::FRAGMENT) - .transform_error(monadic::assert("Failed to load fragment shader")) + m_fragment_shader = gpu::Shader::load_from_file(m_device, + SHADER_DIR "/shaders/textured_cube.spv", + gpu::ShaderStageFlag::FRAGMENT) + .transform_error(monadic::assert(std::format("Failed to load fragment shader {}", + SHADER_DIR "/shaders/textured_cube.spv"))) .value(); m_descriptor_set_layout = gpu::DescriptorSetLayout::create(m_device, @@ -162,8 +168,8 @@ class Application: public base::Application { const auto depth_format = [this] { const auto formats_properties = m_physical_device->formats_properties(); const auto candidates = std::array { gpu::PixelFormat::DEPTH32F, - gpu::PixelFormat::DEPTH32F_STENCIL8U, - gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U }; + gpu::PixelFormat::DEPTH32F_STENCIL8U, + gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U }; for (const auto format : candidates) { const auto properties = stdr::find_if(formats_properties, [format](const auto& pair) { @@ -244,7 +250,9 @@ class Application: public base::Application { // load texture auto image = image::Image {}; - image.load_from_file(TEXTURE_DIR "/cube.png").transform_error(monadic::assert()).value(); + image.load_from_file(TEXTURE_DIR "/textures/cube.png") + .transform_error(monadic::assert(std::format("Failed to load texture file {}", TEXTURE_DIR "/textures/cube.png"))) + .value(); m_texture = gpu::Image::create(m_device, { .extent = image.extent(), @@ -299,7 +307,7 @@ class Application: public base::Application { .transform_error(monadic::assert("Failed to submit texture upload command buffer")) .value(); - *cpy_fence.wait().transform_error(monadic::assert()); + auto _ = cpy_fence.wait().transform_error(monadic::assert()); } m_texture_view = gpu::ImageView::create(m_device, m_texture) @@ -314,30 +322,30 @@ class Application: public base::Application { for (auto _ : range(BUFFERING_COUNT)) { m_submission_resources.push_back({ - .in_flight = gpu::Fence::create_signaled(m_device) - .transform_error(core::monadic::assert("Failed to create swapchain image " - "in flight fence")) - .value(), + .in_flight = gpu::Fence::create_signaled(m_device) + .transform_error(core::monadic::assert("Failed to create swapchain image " + "in flight fence")) + .value(), .image_available = gpu::Semaphore::create(m_device) .transform_error(core::monadic::assert("Failed to create present " "wait semaphore")) .value(), - .render_cmb = m_command_pool->create_command_buffer() - .transform_error(monadic::assert("Failed to create " - "transition command " - "buffers")) - .value(), - .viewer_buffer = gpu::Buffer::create(m_device, - { - .usages = gpu::BufferUsageFlag::UNIFORM, - .size = sizeof(ViewerData), - }, - true) - .transform_error(monadic::assert("Failed to allocate gpu viewer buffer")) - .value(), - .descriptor_set = m_descriptor_pool->create_descriptor_set(m_descriptor_set_layout) - .transform_error(monadic::assert("Failed to create descriptor set")) - .value(), + .render_cmb = m_command_pool->create_command_buffer() + .transform_error(monadic::assert("Failed to create " + "transition command " + "buffers")) + .value(), + .viewer_buffer = gpu::Buffer::create(m_device, + { + .usages = gpu::BufferUsageFlag::UNIFORM, + .size = sizeof(ViewerData), + }, + true) + .transform_error(monadic::assert("Failed to allocate gpu viewer buffer")) + .value(), + .descriptor_set = m_descriptor_pool->create_descriptor_set(m_descriptor_set_layout) + .transform_error(monadic::assert("Failed to create descriptor set")) + .value(), }); auto& res = m_submission_resources.back(); const auto sets = std::array { @@ -361,8 +369,8 @@ class Application: public base::Application { const auto image_count = stdr::size(images); auto transition_cmbs = m_command_pool->create_command_buffers(image_count) - .transform_error(monadic::assert("Failed to create transition command buffers")) - .value(); + .transform_error(monadic::assert("Failed to create transition command buffers")) + .value(); m_image_resources = std::vector {}; m_image_resources.reserve(stdr::size(images)); @@ -473,11 +481,11 @@ class Application: public base::Application { .value() ->submit(m_raster_queue, {}, {}, {}, as_ref(cpy_fence)); - cpy_fence.wait().transform_error(monadic::assert()); + auto _ = cpy_fence.wait().transform_error(monadic::assert()); } // wait for transition to be done - fence.wait().transform_error(monadic::assert()); + auto _ = fence.wait().transform_error(monadic::assert()); } auto run_example() { @@ -485,9 +493,9 @@ class Application: public base::Application { const auto window_extent = m_window->extent(); const auto window_extent_f32 = window_extent.to(); auto viewer_data = ViewerData { - .proj = math::perspective(math::radians(45.f), window_extent_f32.width / window_extent_f32.height, 0.1f, 100.f), - .view = math::look_at(math::vec3f { 0.f, 3.f, 5.f }, { 0.f, 0.f, 0.f }, { 0.f, 1.f, 0.f }), - .model = math::mat4f::identity(), + .proj = math::perspective(math::radians(45.f), window_extent_f32.width / window_extent_f32.height, 0.1f, 100.f), + .view = math::look_at(math::vec3f { 0.f, 3.f, 5.f }, { 0.f, 0.f, 0.f }, { 0.f, 1.f, 0.f }), + .model = math::mat4f::identity(), }; LOG_MODULE.flush(); @@ -560,9 +568,9 @@ class Application: public base::Application { if (++m_current_frame >= BUFFERING_COUNT) m_current_frame = 0; }; - m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)) - .transform(update_current_frame) - .transform_error(monadic::assert("Failed to present swapchain image")); + auto _ = m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)) + .transform(update_current_frame) + .transform_error(monadic::assert("Failed to present swapchain image")); m_raster_queue->wait_idle(); m_device->wait_idle(); diff --git a/examples/gpu/textured_cube/xmake.lua b/examples/gpu/textured_cube/xmake.lua index fc1db3a6d..93277400f 100644 --- a/examples/gpu/textured_cube/xmake.lua +++ b/examples/gpu/textured_cube/xmake.lua @@ -25,14 +25,7 @@ target("textured_cube", function() add_includedirs("$(builddir)/shaders") - if get_config("devmode") then - add_defines('SHADER_DIR="$(builddir)/shaders"') - add_defines('TEXTURE_DIR="$(builddir)/textures"') - set_rundir("$(projectdir)") - end - - -- add_cxflags("--embed-dir=$(builddir)/shaders", {tools = {"clang", "clangxx", "clang-cl", "gcc", "gxx"}}) - after_build(function(target) os.cp("examples/gpu/textured_cube/textures/", "$(builddir)") end) + if get_config("devmode") then set_rundir("$(builddir)") end set_group("examples/stormkit-gpu") end) diff --git a/examples/gpu/triangle/src/main.cpp b/examples/gpu/triangle/src/main.cpp index 6870849a5..a4745f073 100644 --- a/examples/gpu/triangle/src/main.cpp +++ b/examples/gpu/triangle/src/main.cpp @@ -13,7 +13,7 @@ import gpu_app; LOGGER("stormkit.examples.gpu.triangle"); #ifndef SHADER_DIR - #define SHADER_DIR "../share/shaders" + #define SHADER_DIR "." #endif namespace stdr = std::ranges; @@ -41,12 +41,16 @@ class Application: public base::Application { public: auto init_example() { // load shaders - m_vertex_shader = gpu::Shader::load_from_file(m_device, SHADER_DIR "/triangle.spv", gpu::ShaderStageFlag::VERTEX) - .transform_error(monadic::assert("Failed to load vertex shader")) + m_vertex_shader = gpu::Shader::load_from_file(m_device, SHADER_DIR "/shaders/triangle.spv", gpu::ShaderStageFlag::VERTEX) + .transform_error(monadic::assert(std::format("Failed to load vertex shader {}", + SHADER_DIR "/shaders/triangle.spv"))) .value(); - m_fragment_shader = gpu::Shader::load_from_file(m_device, SHADER_DIR "/triangle.spv", gpu::ShaderStageFlag::FRAGMENT) - .transform_error(monadic::assert("Failed to load fragment shader")) + m_fragment_shader = gpu::Shader::load_from_file(m_device, + SHADER_DIR "/shaders/triangle.spv", + gpu::ShaderStageFlag::FRAGMENT) + .transform_error(monadic::assert(std::format("Failed to load fragment shader {}", + SHADER_DIR "/shaders/triangle.spv"))) .value(); m_pipeline_layout = gpu::PipelineLayout::create(m_device, {}) @@ -97,18 +101,18 @@ class Application: public base::Application { out.reserve(BUFFERING_COUNT); for (auto _ : range(BUFFERING_COUNT)) { out.push_back({ - .in_flight = gpu::Fence::create_signaled(m_device) - .transform_error(monadic::assert("Failed to create swapchain image " - "in flight fence")) - .value(), + .in_flight = gpu::Fence::create_signaled(m_device) + .transform_error(monadic::assert("Failed to create swapchain image " + "in flight fence")) + .value(), .image_available = gpu::Semaphore::create(m_device) .transform_error(monadic::assert("Failed to create " "present wait semaphore")) .value(), - .render_cmb = m_command_pool->create_command_buffer() - .transform_error(monadic::assert("Failed to create transition " - "command buffers")) - .value(), + .render_cmb = m_command_pool->create_command_buffer() + .transform_error(monadic::assert("Failed to create transition " + "command buffers")) + .value(), }); } }); @@ -118,15 +122,15 @@ class Application: public base::Application { const auto image_count = stdr::size(images); auto transition_cmbs = m_command_pool->create_command_buffers(image_count) - .transform_error(monadic::assert("Failed to create transition command buffers")) - .value(); + .transform_error(monadic::assert("Failed to create transition command buffers")) + .value(); m_image_resources.reserve(stdr::size(images)); auto image_index = 0u; for (const auto& swap_image : images) { - auto view = gpu::ImageView::create(m_device, swap_image) - .transform_error(core::monadic::assert("Failed to create swapchain image view")) - .value(); + auto view = gpu::ImageView::create(m_device, swap_image) + .transform_error(core::monadic::assert("Failed to create swapchain image view")) + .value(); auto framebuffer = m_render_pass->create_frame_buffer(m_device, window_extent, to_refs(view)) .transform_error(core::monadic::assert(std::format("Failed to create framebuffer for image {}", image_index))) @@ -143,15 +147,15 @@ class Application: public base::Application { }); auto& transition_cmb = transition_cmbs[image_index]; - *transition_cmb.begin(true) - .transform_error(monadic::assert("Failed to begin texture transition command buffer")) - .value() - ->begin_debug_region(std::format("transition image {}", image_index)) - .transition_image_layout(swap_image, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::PRESENT_SRC) - .end_debug_region() - .end() - .transform_error(monadic::assert("Failed to begin texture transition command " - "buffer")); + auto _ = *transition_cmb.begin(true) + .transform_error(monadic::assert("Failed to begin texture transition command buffer")) + .value() + ->begin_debug_region(std::format("transition image {}", image_index)) + .transition_image_layout(swap_image, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::PRESENT_SRC) + .end_debug_region() + .end() + .transform_error(monadic::assert("Failed to begin texture transition command " + "buffer")); ++image_index; } @@ -167,7 +171,7 @@ class Application: public base::Application { .value(); // wait for transition to be done - fence.wait().transform_error(monadic::assert()); + auto _ = fence.wait().transform_error(monadic::assert()); } auto run_example() { @@ -223,9 +227,9 @@ class Application: public base::Application { if (++m_current_frame >= BUFFERING_COUNT) m_current_frame = 0; }; - m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)) - .transform(update_current_frame) - .transform_error(monadic::assert("Failed to present swapchain image")); + auto _ = m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)) + .transform(update_current_frame) + .transform_error(monadic::assert("Failed to present swapchain image")); } constexpr auto example_name() const noexcept -> std::string_view { return "Triangle"; } diff --git a/examples/gpu/triangle/xmake.lua b/examples/gpu/triangle/xmake.lua index ac0e95fac..2e058eb9f 100644 --- a/examples/gpu/triangle/xmake.lua +++ b/examples/gpu/triangle/xmake.lua @@ -13,7 +13,6 @@ elseif is_plat("linux") then toolchain = "gcc" end add_requires("nzsl", { configs = { fs_watcher = false, kind = "binary", toolchains = toolchain, runtimes = runtimes } }) - target("triangle", function() set_kind("binary") set_languages("cxxlatest", "clatest") @@ -40,10 +39,7 @@ target("triangle", function() add_includedirs("$(builddir)/shaders") - if get_config("devmode") then - add_defines('SHADER_DIR="$(builddir)/shaders"') - set_rundir("$(projectdir)") - end + if get_config("devmode") then set_rundir("$(builddir)") end add_embeddirs("$(builddir)/shaders") diff --git a/examples/wsi/luau/src/main.cpp b/examples/wsi/luau/src/main.cpp index 7f41481c1..c01334c14 100644 --- a/examples/wsi/luau/src/main.cpp +++ b/examples/wsi/luau/src/main.cpp @@ -32,7 +32,7 @@ auto main(std::span args) -> int { auto engine = luau::Engine::create(LUAU_DIR "/events.luau"); wsi::lua::init_lua(engine.global_namespace()); - engine.lua_main().transform_error(monadic::assert("lua runtime error!\n-------------------------------\n")); + auto _ = engine.lua_main().transform_error(monadic::assert("lua runtime error!\n-------------------------------\n")); return 0; } diff --git a/modules/stormkit/core/coroutines.mpp b/modules/stormkit/core/coroutines.mpp index 00ff16359..9c02bdffe 100644 --- a/modules/stormkit/core/coroutines.mpp +++ b/modules/stormkit/core/coroutines.mpp @@ -9,23 +9,13 @@ export module stormkit.core:coroutines; export import std; -#if not defined(__cpp_lib_generator) or (defined(__cpp_lib_generator) and (__cpp_lib_generator < 202207L)) +#if not defined(__cpp_lib_generator) or __cpp_lib_generator < 202207L export namespace std { struct use_allocator_arg {}; - template, typename _Allocator = use_allocator_arg> + template, typename _Alloc = use_allocator_arg> class generator; - namespace ranges { - template - inline constexpr bool enable_view> = true; - - template - struct elements_of; - } // namespace ranges -} // namespace std - -namespace std { template class __manual_lifetime { public: @@ -34,11 +24,11 @@ namespace std { ~__manual_lifetime() {} template - _T& construct(_Args&&... __args) noexcept(std::is_nothrow_constructible_v<_T, _Args...>) { - return *::new (static_cast(std::addressof(__value_))) _T((_Args&&)__args...); + _T& construct(_Args&&... __args) noexcept(is_nothrow_constructible_v<_T, _Args...>) { + return *::new (static_cast(addressof(__value_))) _T((_Args&&)__args...); } - void destruct() noexcept(std::is_nothrow_destructible_v<_T>) { __value_.~_T(); } + void destruct() noexcept(is_nothrow_destructible_v<_T>) { __value_.~_T(); } _T& get() & noexcept { return __value_; } @@ -50,7 +40,7 @@ namespace std { private: union { - std::remove_const_t<_T> __value_; + remove_const_t<_T> __value_; }; }; @@ -62,7 +52,7 @@ namespace std { ~__manual_lifetime() {} _T& construct(_T& __value) noexcept { - __value_ = std::addressof(__value); + __value_ = addressof(__value); return __value; } @@ -82,7 +72,7 @@ namespace std { ~__manual_lifetime() {} _T&& construct(_T&& __value) noexcept { - __value_ = std::addressof(__value); + __value_ = addressof(__value); return static_cast<_T&&>(__value); } @@ -94,42 +84,9 @@ namespace std { _T* __value_; }; - namespace ranges { - template - struct elements_of { - explicit constexpr elements_of(_Rng&& __rng) noexcept - requires std::is_default_constructible_v<_Allocator> - : __range(static_cast<_Rng&&>(__rng)) {} - - constexpr elements_of(_Rng&& __rng, _Allocator&& __alloc) noexcept - : __range((_Rng&&)__rng), __alloc((_Allocator&&)__alloc) {} - - constexpr elements_of(elements_of&&) noexcept = default; - - constexpr elements_of(const elements_of&) = delete; - constexpr elements_of& operator=(const elements_of&) = delete; - constexpr elements_of& operator=(elements_of&&) = delete; - - constexpr _Rng&& get() noexcept { return static_cast<_Rng&&>(__range); } - - constexpr _Allocator get_allocator() const noexcept { return __alloc; } - - private: - STORMKIT_NO_UNIQUE_ADDRESS - _Allocator __alloc; // \expos - _Rng&& __range; // \expos - }; - - template - elements_of(_Rng&&) -> elements_of<_Rng>; - - template - elements_of(_Rng&&, Allocator&&) -> elements_of<_Rng, Allocator>; - } // namespace ranges - template - static constexpr bool __allocator_needs_to_be_stored = !std::allocator_traits<_Alloc>::is_always_equal::value - || !std::is_default_constructible_v<_Alloc>; + inline constexpr bool __allocator_needs_to_be_stored = !allocator_traits<_Alloc>::is_always_equal::value + || !is_default_constructible_v<_Alloc>; // Round s up to next multiple of a. constexpr size_t __aligned_allocation_size(size_t s, size_t a) { @@ -138,41 +95,41 @@ namespace std { template class __promise_base_alloc { - static constexpr std::size_t __offset_of_allocator(std::size_t __frameSize) noexcept { + static constexpr size_t __offset_of_allocator(size_t __frameSize) noexcept { return __aligned_allocation_size(__frameSize, alignof(_Alloc)); } - static constexpr std::size_t __padded_frame_size(std::size_t __frameSize) noexcept { + static constexpr size_t __padded_frame_size(size_t __frameSize) noexcept { return __offset_of_allocator(__frameSize) + sizeof(_Alloc); } - static _Alloc& __get_allocator(void* __frame, std::size_t __frameSize) noexcept { + static _Alloc& __get_allocator(void* __frame, size_t __frameSize) noexcept { return *reinterpret_cast<_Alloc*>(static_cast(__frame) + __offset_of_allocator(__frameSize)); } public: template - static void* operator new(std::size_t __frameSize, std::allocator_arg_t, _Alloc __alloc, _Args&...) { + static void* operator new(size_t __frameSize, allocator_arg_t, _Alloc __alloc, _Args&...) { void* __frame = __alloc.allocate(__padded_frame_size(__frameSize)); // Store allocator at end of the coroutine frame. // Assuming the allocator's move constructor is non-throwing (a requirement for // allocators) - ::new (static_cast(std::addressof(__get_allocator(__frame, __frameSize)))) _Alloc(std::move(__alloc)); + ::new (static_cast(addressof(__get_allocator(__frame, __frameSize)))) _Alloc(move(__alloc)); return __frame; } template - static void* operator new(std::size_t __frameSize, _This&, std::allocator_arg_t, _Alloc __alloc, _Args&...) { - return __promise_base_alloc::operator new(__frameSize, std::allocator_arg, std::move(__alloc)); + static void* operator new(size_t __frameSize, _This&, allocator_arg_t, _Alloc __alloc, _Args&...) { + return __promise_base_alloc::operator new(__frameSize, allocator_arg, move(__alloc)); } - static void operator delete(void* __ptr, std::size_t __frameSize) noexcept { + static void operator delete(void* __ptr, size_t __frameSize) noexcept { _Alloc& __alloc = __get_allocator(__ptr, __frameSize); - _Alloc __localAlloc(std::move(__alloc)); + _Alloc __localAlloc(move(__alloc)); __alloc.~Alloc(); - __localAlloc.deallocate(static_cast(__ptr), __padded_frame_size(__frameSize)); + __localAlloc.deallocate(static_cast(__ptr), __padded_frame_size(__frameSize)); } }; @@ -180,14 +137,14 @@ namespace std { requires(!__allocator_needs_to_be_stored<_Alloc>) class __promise_base_alloc<_Alloc> { public: - static void* operator new(std::size_t __size) { + static void* operator new(size_t __size) { _Alloc __alloc; return __alloc.allocate(__size); } - static void operator delete(void* __ptr, std::size_t __size) noexcept { + static void operator delete(void* __ptr, size_t __size) noexcept { _Alloc __alloc; - __alloc.deallocate(static_cast(__ptr), __size); + __alloc.deallocate(static_cast(__ptr), __size); } }; @@ -197,16 +154,16 @@ namespace std { friend class generator; __generator_promise_base* __root_; - std::coroutine_handle<> __parentOrLeaf_; + coroutine_handle<> __parentOrLeaf_; // Note: Using manual_lifetime here to avoid extra calls to exception_ptr // constructor/destructor in cases where it is not needed (i.e. where this // generator coroutine is not used as a nested coroutine). // This member is lazily constructed by the __yield_sequence_awaiter::await_suspend() // method if this generator is used as a nested generator. - __manual_lifetime __exception_; - __manual_lifetime<_Ref> __value_; + __manual_lifetime __exception_; + __manual_lifetime<_Ref> __value_; - explicit __generator_promise_base(std::coroutine_handle<> thisCoro) noexcept : __root_(this), __parentOrLeaf_(thisCoro) {} + explicit __generator_promise_base(coroutine_handle<> thisCoro) noexcept : __root_(this), __parentOrLeaf_(thisCoro) {} ~__generator_promise_base() { if (__root_ != this) { @@ -217,13 +174,13 @@ namespace std { } } - std::suspend_always initial_suspend() noexcept { return {}; } + suspend_always initial_suspend() noexcept { return {}; } void return_void() noexcept {} void unhandled_exception() { if (__root_ != this) { - __exception_.get() = std::current_exception(); + __exception_.get() = current_exception(); } else { throw; } @@ -234,7 +191,7 @@ namespace std { bool await_ready() noexcept { return false; } template - std::coroutine_handle<> await_suspend(std::coroutine_handle<_Promise> __h) noexcept { + coroutine_handle<> await_suspend(coroutine_handle<_Promise> __h) noexcept { _Promise& __promise = __h.promise(); __generator_promise_base& __root = *__promise.__root_; if (&__root != &__promise) { @@ -242,7 +199,7 @@ namespace std { __root.__parentOrLeaf_ = __parent; return __parent; } - return std::noop_coroutine(); + return noop_coroutine(); } void await_resume() noexcept {} @@ -250,14 +207,14 @@ namespace std { __final_awaiter final_suspend() noexcept { return {}; } - std::suspend_always yield_value(_Ref&& __x) noexcept(std::is_nothrow_move_constructible_v<_Ref>) { + suspend_always yield_value(_Ref&& __x) noexcept(is_nothrow_move_constructible_v<_Ref>) { __root_->__value_.construct((_Ref&&)__x); return {}; } template - requires(!std::is_reference_v<_Ref>) && std::is_convertible_v<_T, _Ref> - std::suspend_always yield_value(_T&& __x) noexcept(std::is_nothrow_constructible_v<_Ref, _T>) { + requires(!is_reference_v<_Ref>) && is_convertible_v<_T, _Ref> + suspend_always yield_value(_T&& __x) noexcept(is_nothrow_constructible_v<_Ref, _T>) { __root_->__value_.construct((_T&&)__x); return {}; } @@ -276,7 +233,7 @@ namespace std { // set the parent, root and exceptions pointer and // resume the nested template - std::coroutine_handle<> await_suspend(std::coroutine_handle<_Promise> __h) noexcept { + coroutine_handle<> await_suspend(coroutine_handle<_Promise> __h) noexcept { __generator_promise_base& __current = __h.promise(); __generator_promise_base& __nested = *__gen_.__get_promise(); __generator_promise_base& __root = *__current.__root_; @@ -296,26 +253,26 @@ namespace std { void await_resume() { __generator_promise_base& __nestedPromise = *__gen_.__get_promise(); - if (__nestedPromise.__exception_.get()) { std::rethrow_exception(std::move(__nestedPromise.__exception_.get())); } + if (__nestedPromise.__exception_.get()) { rethrow_exception(move(__nestedPromise.__exception_.get())); } } }; template - __yield_sequence_awaiter> yield_value(std::ranges::elements_of< + __yield_sequence_awaiter> yield_value(ranges::elements_of< generator<_Ref, _OValue, _OAlloc>> __g) noexcept { - return std::move(__g).get(); + return move(__g).get(); } - template - __yield_sequence_awaiter, _Allocator>> yield_value(std::ranges::elements_of< - _Rng, - _Allocator>&& __x) { + template + __yield_sequence_awaiter, _Allocator>> yield_value(ranges::elements_of<_Rng, + _Allocator>&& + __x) { return [](allocator_arg_t, [[maybe_unused]] _Allocator alloc, - auto&& __rng) -> generator<_Ref, std::remove_cvref_t<_Ref>, _Allocator> { + auto&& __rng) -> generator<_Ref, remove_cvref_t<_Ref>, _Allocator> { for (auto&& e : __rng) co_yield static_cast(e); - }(std::allocator_arg, __x.get_allocator(), std::forward<_Rng>(__x.get())); + }(allocator_arg, __x.get_allocator(), forward<_Rng>(__x.get())); } void resume() { __parentOrLeaf_.resume(); } @@ -332,37 +289,37 @@ namespace std { : public __generator_promise_base<_Ref>, public __promise_base_alloc<_ByteAllocator> { __generator_promise() noexcept - : __generator_promise_base<_Ref>(std::coroutine_handle<__generator_promise>::from_promise(*this)) {} + : __generator_promise_base<_Ref>(coroutine_handle<__generator_promise>::from_promise(*this)) {} generator<_Ref, _Value, _Alloc> get_return_object() noexcept { - return generator<_Ref, _Value, _Alloc> { std::coroutine_handle<__generator_promise>::from_promise(*this) }; + return generator<_Ref, _Value, _Alloc> { coroutine_handle<__generator_promise>::from_promise(*this) }; } using __generator_promise_base<_Ref>::yield_value; - template + template typename __generator_promise_base<_Ref>::template __yield_sequence_awaiter> - yield_value(std::ranges::elements_of<_Rng>&& __x) { + yield_value(ranges::elements_of<_Rng>&& __x) { static_assert(!_ExplicitAllocator, "This coroutine has an explicit allocator specified with " - "std::allocator_arg so an allocator needs to be passed " - "explicitely to std::elements_of"); + "allocator_arg so an allocator needs to be passed " + "explicitely to elements_of"); return [](auto&& __rng) -> generator<_Ref, _Value, _Alloc> { for (auto&& e : __rng) co_yield static_cast(e); - }(std::forward<_Rng>(__x.get())); + }(forward<_Rng>(__x.get())); } }; template - using __byte_allocator_t = typename std::allocator_traits>::template rebind_alloc; + using __byte_allocator_t = typename allocator_traits>::template rebind_alloc; // Type-erased allocator with default allocator behaviour. template struct coroutine_traits, _Args...> { - using promise_type = __generator_promise, std::allocator>; + using promise_type = __generator_promise, allocator>; }; - // Type-erased allocator with std::allocator_arg parameter + // Type-erased allocator with allocator_arg parameter template struct coroutine_traits, allocator_arg_t, _Alloc, _Args...> { private: @@ -372,7 +329,7 @@ namespace std { using promise_type = __generator_promise, __byte_allocator, true /*explicit Allocator*/>; }; - // Type-erased allocator with std::allocator_arg parameter (non-static member functions) + // Type-erased allocator with allocator_arg parameter (non-static member functions) template struct coroutine_traits, _This, allocator_arg_t, _Alloc, _Args...> { private: @@ -401,13 +358,13 @@ namespace std { friend promise_type; private: - using __coroutine_handle = std::coroutine_handle; + using __coroutine_handle = coroutine_handle; public: generator() noexcept = default; generator(generator&& __other) noexcept - : __coro_(std::exchange(__other.__coro_, {})), __started_(std::exchange(__other.__started_, false)) {} + : __coro_(exchange(__other.__coro_, {})), __started_(exchange(__other.__started_, false)) {} ~generator() noexcept { if (__coro_) { @@ -422,24 +379,24 @@ namespace std { } void swap(generator& __other) noexcept { - std::swap(__coro_, __other.__coro_); - std::swap(__started_, __other.__started_); + swap(__coro_, __other.__coro_); + swap(__started_, __other.__started_); } struct sentinel {}; class iterator { public: - using iterator_category = std::input_iterator_tag; - using difference_type = std::ptrdiff_t; + using iterator_category = input_iterator_tag; + using difference_type = ptrdiff_t; using value_type = _Value; using reference = _Ref; - using pointer = std::add_pointer_t<_Ref>; + using pointer = add_pointer_t<_Ref>; iterator() noexcept = default; iterator(const iterator&) = delete; - iterator(iterator&& __other) noexcept : __coro_(std::exchange(__other.__coro_, {})) {} + iterator(iterator&& __other) noexcept : __coro_(exchange(__other.__coro_, {})) {} iterator& operator=(iterator&& __other) { std::swap(__coro_, __other.__coro_); @@ -482,9 +439,9 @@ namespace std { explicit generator(__coroutine_handle __coro) noexcept : __coro_(__coro) {} public: // to get around access restrictions for __yield_sequence_awaitable - std::coroutine_handle<> __get_coro() noexcept { return __coro_; } + coroutine_handle<> __get_coro() noexcept { return __coro_; } - promise_type* __get_promise() noexcept { return std::addressof(__coro_.promise()); } + promise_type* __get_promise() noexcept { return addressof(__coro_.promise()); } private: __coroutine_handle __coro_; @@ -500,9 +457,9 @@ namespace std { generator() noexcept : __promise_(nullptr), __coro_(), __started_(false) {} generator(generator&& __other) noexcept - : __promise_(std::exchange(__other.__promise_, nullptr)), - __coro_(std::exchange(__other.__coro_, {})), - __started_(std::exchange(__other.__started_, false)) {} + : __promise_(exchange(__other.__promise_, nullptr)), + __coro_(exchange(__other.__coro_, {})), + __started_(exchange(__other.__started_, false)) {} ~generator() noexcept { if (__coro_) { @@ -517,30 +474,30 @@ namespace std { } void swap(generator& __other) noexcept { - std::swap(__promise_, __other.__promise_); - std::swap(__coro_, __other.__coro_); - std::swap(__started_, __other.__started_); + swap(__promise_, __other.__promise_); + swap(__coro_, __other.__coro_); + swap(__started_, __other.__started_); } struct sentinel {}; class iterator { public: - using iterator_category = std::input_iterator_tag; - using difference_type = std::ptrdiff_t; + using iterator_category = input_iterator_tag; + using difference_type = ptrdiff_t; using value_type = _Value; using reference = _Ref; - using pointer = std::add_pointer_t<_Ref>; + using pointer = add_pointer_t<_Ref>; iterator() noexcept = default; iterator(const iterator&) = delete; iterator(iterator&& __other) noexcept - : __promise_(std::exchange(__other.__promise_, nullptr)), __coro_(std::exchange(__other.__coro_, {})) {} + : __promise_(exchange(__other.__promise_, nullptr)), __coro_(exchange(__other.__coro_, {})) {} iterator& operator=(iterator&& __other) { - __promise_ = std::exchange(__other.__promise_, nullptr); - __coro_ = std::exchange(__other.__coro_, {}); + __promise_ = exchange(__other.__promise_, nullptr); + __coro_ = exchange(__other.__coro_, {}); return *this; } @@ -561,11 +518,11 @@ namespace std { private: friend generator; - explicit iterator(__promise_base* __promise, std::coroutine_handle<> __coro) noexcept + explicit iterator(__promise_base* __promise, coroutine_handle<> __coro) noexcept : __promise_(__promise), __coro_(__coro) {} - __promise_base* __promise_; - std::coroutine_handle<> __coro_; + __promise_base* __promise_; + coroutine_handle<> __coro_; }; iterator begin() { @@ -583,19 +540,18 @@ namespace std { friend struct __generator_promise; template - explicit generator(std::coroutine_handle<_Promise> __coro) noexcept - : __promise_(std::addressof(__coro.promise())), __coro_(__coro) {} + explicit generator(coroutine_handle<_Promise> __coro) noexcept + : __promise_(addressof(__coro.promise())), __coro_(__coro) {} public: // to get around access restrictions for __yield_sequence_awaitable - std::coroutine_handle<> __get_coro() noexcept { return __coro_; } + coroutine_handle<> __get_coro() noexcept { return __coro_; } __promise_base* __get_promise() noexcept { return __promise_; } private: - __promise_base* __promise_; - std::coroutine_handle<> __coro_; - bool __started_ = false; + __promise_base* __promise_; + coroutine_handle<> __coro_; + bool __started_ = false; }; - } // namespace std #endif diff --git a/modules/stormkit/core/typesafe/byte.mpp b/modules/stormkit/core/typesafe/byte.mpp index 782c1dce4..e76480fe1 100644 --- a/modules/stormkit/core/typesafe/byte.mpp +++ b/modules/stormkit/core/typesafe/byte.mpp @@ -56,6 +56,13 @@ export namespace stormkit { inline namespace core { [[nodiscard]] constexpr auto as_bytes(const T* const ptr, usize size = 1) noexcept -> std::span; + template + [[nodiscard]] + constexpr auto as_bytes(const Range& range) noexcept -> std::span; + + [[nodiscard]] + constexpr auto as_bytes(std::string_view string) noexcept -> std::span; + template [[nodiscard]] constexpr auto as_bytes(const T& value) noexcept -> std::span; @@ -66,6 +73,10 @@ export namespace stormkit { inline namespace core { constexpr auto as_bytes_mut(std::span container) noexcept -> std::span()>; + template + [[nodiscard]] + constexpr auto as_bytes_mut(Range& range) noexcept -> std::span; + template [[nodiscard]] constexpr auto as_bytes_mut(T* const ptr, usize size = 1) noexcept -> std::span; @@ -125,6 +136,8 @@ namespace stormkit { inline namespace core { stdr::fill(bytes, byte { 0 }); } + ///////////////////////////////////// + ///////////////////////////////////// template STORMKIT_FORCE_INLINE constexpr auto zeroed() noexcept -> T { @@ -156,6 +169,21 @@ namespace stormkit { inline namespace core { return std::as_bytes(std::span { ptr, size }); } + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto as_bytes(const Range& range) noexcept -> std::span { + return as_bytes(std::span { range }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto as_bytes(std::string_view value) noexcept -> std::span { + return std::as_bytes(std::span { stdr::data(value), stdr::size(value) }); + } + ///////////////////////////////////// ///////////////////////////////////// template @@ -172,6 +200,14 @@ namespace stormkit { inline namespace core { return std::as_writable_bytes(container); } + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto as_bytes_mut(Range& range) noexcept -> std::span { + return as_bytes_mut(std::span { range }); + } + ///////////////////////////////////// ///////////////////////////////////// template diff --git a/modules/stormkit/gpu/resource/buffer.mpp b/modules/stormkit/gpu/resource/buffer.mpp index 350c16b1d..18cc04fc5 100644 --- a/modules/stormkit/gpu/resource/buffer.mpp +++ b/modules/stormkit/gpu/resource/buffer.mpp @@ -51,18 +51,19 @@ export namespace stormkit::gpu { [[nodiscard]] auto memory_property() const noexcept -> MemoryPropertyFlag; - auto map(ioffset offset) noexcept -> Expected; - auto map(ioffset offset, usize size) noexcept -> Expected; + auto map(ioffset offset) noexcept -> Expected; + auto map(ioffset offset, usize size) noexcept -> Expected>; template auto map_as(ioffset offset) noexcept -> Expected>; template [[nodiscard]] - auto data(this Self& self) noexcept -> core::meta::ForwardConst*; + auto data(this Self& self) noexcept -> core::meta::ForwardConst*; template [[nodiscard]] - auto data(this Self& self, usize size) noexcept -> core::meta::If, ByteView, MutableByteView>; + auto data(this Self& self, usize size) noexcept + -> core::meta::If, std::span, std::span>; template [[nodiscard]] @@ -74,9 +75,10 @@ export namespace stormkit::gpu { [[nodiscard]] auto is_persistently_mapped() const noexcept -> bool; - auto upload(std::span data, ioffset offset = 0) noexcept -> Expected; + auto upload(std::span data, ioffset offset = 0) noexcept -> Expected; - template T> + template + requires(not stormkit::meta::IsSpecializationWithNTTPOf) auto upload(const T& data, ioffset offset = 0) noexcept -> Expected; [[nodiscard]] @@ -97,7 +99,7 @@ export namespace stormkit::gpu { MemoryPropertyFlag m_memory_property = {}; bool m_is_persistently_mapped = false; - Byte* m_mapped_pointer = nullptr; + byte* m_mapped_pointer = nullptr; VkDevice m_vk_device; Ref m_vk_device_table; @@ -153,8 +155,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Buffer::Buffer(Buffer&& other) noexcept - = default; + inline Buffer::Buffer(Buffer&& other) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// @@ -198,13 +199,13 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Buffer::map(ioffset offset) noexcept -> Expected { + inline auto Buffer::map(ioffset offset) noexcept -> Expected { EXPECTS(m_vma_allocation and m_vk_handle); EXPECTS(offset < as(m_size)); return vk_call(vmaMapMemory, m_vma_allocator, m_vma_allocation) .transform([this, &offset](auto&& ptr) noexcept { - m_mapped_pointer = std::bit_cast(ptr); + m_mapped_pointer = std::bit_cast(ptr); m_mapped_pointer += offset; return m_mapped_pointer; }) @@ -214,7 +215,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Buffer::map(ioffset offset, usize size) noexcept -> Expected { + inline auto Buffer::map(ioffset offset, usize size) noexcept -> Expected> { EXPECTS(m_vma_allocation and m_vk_handle); return map(offset).transform([&size](auto&& ptr) noexcept { return as_bytes_mut(ptr, size); }); } @@ -235,11 +236,11 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Buffer::data(this Self& self) noexcept -> core::meta::ForwardConst* { + inline auto Buffer::data(this Self& self) noexcept -> core::meta::ForwardConst* { EXPECTS(self.m_vma_allocation and self.m_vk_handle); EXPECTS(self.m_mapped_pointer); - using Out = core::meta::ForwardConst*; + using Out = core::meta::ForwardConst*; return std::bit_cast(self.m_mapped_pointer); } @@ -248,11 +249,11 @@ namespace stormkit::gpu { template STORMKIT_FORCE_INLINE inline auto Buffer::data(this Self& self, usize size) noexcept - -> core::meta::If, ByteView, MutableByteView> { + -> core::meta::If, std::span, std::span> { EXPECTS(self.m_vma_allocation and self.m_vk_handle); EXPECTS(self.m_mapped_pointer); - using Out = core::meta::If, ByteView, MutableByteView>; + using Out = core::meta::If, std::span, std::span>; return Out { std::bit_cast(self.m_mapped_pointer), size }; } @@ -295,23 +296,24 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Buffer::upload(std::span data, ioffset offset) noexcept -> Expected { + inline auto Buffer::upload(std::span data, ioffset offset) noexcept -> Expected { EXPECTS(stdr::size(data) <= m_size); if (m_is_persistently_mapped) { - std::ranges::copy(data, m_mapped_pointer); + stdr::copy(data, m_mapped_pointer); return {}; } - return map(offset, std::ranges::size(data)).transform([this, &data](auto&& out) noexcept { - std::ranges::copy(data, std::ranges::begin(out)); + return map(offset, stdr::size(data)).transform([this, &data](auto&& out) noexcept -> void { + stdr::copy(data, stdr::begin(out)); unmap(); }); } ///////////////////////////////////// ///////////////////////////////////// - template T> + template + requires(not stormkit::meta::IsSpecializationWithNTTPOf) STORMKIT_FORCE_INLINE inline auto Buffer::upload(const T& data, ioffset offset) noexcept -> Expected { const auto bytes = as_bytes(data); diff --git a/modules/stormkit/gpu/resource/shader.mpp b/modules/stormkit/gpu/resource/shader.mpp index ae31dc980..71827d0f3 100644 --- a/modules/stormkit/gpu/resource/shader.mpp +++ b/modules/stormkit/gpu/resource/shader.mpp @@ -131,14 +131,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Shader::~Shader() - = default; + inline Shader::~Shader() = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Shader::Shader(Shader&&) noexcept - = default; + inline Shader::Shader(Shader&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// diff --git a/src/core/contract.mpp b/src/core/contract.mpp index 8f97cb129..c9b05c851 100644 --- a/src/core/contract.mpp +++ b/src/core/contract.mpp @@ -43,6 +43,9 @@ namespace stormkit { inline namespace core { ConsoleStyle { .fg = ConsoleColor::YELLOW } | location.function_name(), ConsoleStyle { .fg = ConsoleColor::RED, .modifiers = StyleModifier::BOLD } | message); std::fflush(get_stderr()); +#if defined(__cpp_lib_debugging) and __cpp_lib_debugging >= 202311L + if (std::is_debugger_present) { std::breakpoint(); } +#endif std::terminate(); } diff --git a/src/wsi/linux/x11/window.cpp b/src/wsi/linux/x11/window.cpp index 44ad009f5..41ecf7370 100644 --- a/src/wsi/linux/x11/window.cpp +++ b/src/wsi/linux/x11/window.cpp @@ -45,8 +45,7 @@ namespace stdv = std::views; namespace stormkit::wsi::linux::x11 { namespace { [[maybe_unused]] - constexpr auto WM_CLASS - = std::string_view("WM_CLASS"); + constexpr auto WM_CLASS = std::string_view("WM_CLASS"); constexpr auto WM_HINTS_STR = std::string_view("_MOTIF_WM_HINTS"); constexpr auto WM_PROTOCOLS = std::string_view("WM_PROTOCOLS"); constexpr auto WM_DELETE_WINDOW = std::string_view("WM_DELETE_WINDOW"); @@ -62,29 +61,25 @@ namespace stormkit::wsi::linux::x11 { constexpr auto MWM_DECOR_TITLE = 1 << 3; constexpr auto MWM_DECOR_MENU = 1 << 4; [[maybe_unused]] - constexpr auto MWM_DECOR_MINIMIZE - = 1 << 5; + constexpr auto MWM_DECOR_MINIMIZE = 1 << 5; [[maybe_unused]] - constexpr auto MWM_DECOR_MAXIMIZE - = 1 << 6; + constexpr auto MWM_DECOR_MAXIMIZE = 1 << 6; constexpr auto MWM_FUNC_RESIZE = 1 << 1; constexpr auto MWM_FUNC_MOVE = 1 << 2; [[maybe_unused]] - constexpr auto MWM_FUNC_MINIMIZE - = 1 << 3; + constexpr auto MWM_FUNC_MINIMIZE = 1 << 3; constexpr auto MWM_FUNC_MAXIMIZE = 1 << 4; constexpr auto MWM_FUNC_CLOSE = 1 << 5; constexpr auto _NET_WM_STATE_REMOVE = 0; // remove/unset property constexpr auto _NET_WM_STATE_ADD = 1; // add/set property [[maybe_unused]] - constexpr auto _NET_WM_STATE_TOGGLE - = 2; // toggle property + constexpr auto _NET_WM_STATE_TOGGLE = 2; // toggle property constexpr auto MOUSE_RAW_EVENTS = u32 { XCB_INPUT_XI_EVENT_MASK_RAW_BUTTON_PRESS - | XCB_INPUT_XI_EVENT_MASK_RAW_BUTTON_RELEASE - | XCB_INPUT_XI_EVENT_MASK_RAW_MOTION }; + | XCB_INPUT_XI_EVENT_MASK_RAW_BUTTON_RELEASE + | XCB_INPUT_XI_EVENT_MASK_RAW_MOTION }; constexpr auto KEYBOARD_RAW_EVENTS = u32 { XCB_INPUT_XI_EVENT_MASK_RAW_KEY_PRESS | XCB_INPUT_XI_EVENT_MASK_RAW_KEY_RELEASE }; constexpr auto KEYBOARD_EVENTS = u32 { XCB_INPUT_XI_EVENT_MASK_KEY_PRESS | XCB_INPUT_XI_EVENT_MASK_KEY_RELEASE }; @@ -304,18 +299,18 @@ namespace stormkit::wsi::linux::x11 { xcb_icccm_set_wm_normal_hints(connection, m_window, &size_hints); } - xcb::get_atom(WM_CLASS, false) - .transform([this, &connection](auto&& atom) noexcept { - constexpr auto CLASS_NAME = "StormKit.Window\0StormKit.Window"; - xcb_change_property(connection, XCB_PROP_MODE_REPLACE, m_window, atom, atom, 8, 32, CLASS_NAME); - }) - .transform_error(xcb::atom_error(WM_HINTS_STR)); + auto _ = xcb::get_atom(WM_CLASS, false) + .transform([this, &connection](auto&& atom) noexcept { + constexpr auto CLASS_NAME = "StormKit.Window\0StormKit.Window"; + xcb_change_property(connection, XCB_PROP_MODE_REPLACE, m_window, atom, atom, 8, 32, CLASS_NAME); + }) + .transform_error(xcb::atom_error(WM_HINTS_STR)); - xcb::get_atom(WM_HINTS_STR, false) - .transform([this, &window_hints, &connection](auto&& atom) noexcept { - xcb_change_property(connection, XCB_PROP_MODE_REPLACE, m_window, atom, atom, 32, 5, &window_hints); - }) - .transform_error(xcb::atom_error(WM_HINTS_STR)); + auto _ = xcb::get_atom(WM_HINTS_STR, false) + .transform([this, &window_hints, &connection](auto&& atom) noexcept { + xcb_change_property(connection, XCB_PROP_MODE_REPLACE, m_window, atom, atom, 32, 5, &window_hints); + }) + .transform_error(xcb::atom_error(WM_HINTS_STR)); m_handles.connection = connection; m_handles.window = m_window; @@ -337,13 +332,13 @@ namespace stormkit::wsi::linux::x11 { 1, &(*close_atom)); - xcb::get_atom(WM_STATE_STR, false) - .transform([this, &connection](auto&& atom) noexcept { - xcb_change_property(connection, XCB_PROP_MODE_REPLACE, m_window, atom, XCB_ATOM_ATOM, 32, 0, nullptr); - }) - .transform_error(xcb::atom_error(WM_STATE_STR)); + auto _ = xcb::get_atom(WM_STATE_STR, false) + .transform([this, &connection](auto&& atom) noexcept { + xcb_change_property(connection, XCB_PROP_MODE_REPLACE, m_window, atom, XCB_ATOM_ATOM, 32, 0, nullptr); + }) + .transform_error(xcb::atom_error(WM_STATE_STR)); - xcb::get_atom(WM_STATE_HIDDEN_STR, false).transform_error(xcb::atom_error(WM_STATE_HIDDEN_STR)); + auto _ = xcb::get_atom(WM_STATE_HIDDEN_STR, false).transform_error(xcb::atom_error(WM_STATE_HIDDEN_STR)); xcb_map_window(connection, m_window); @@ -483,34 +478,34 @@ namespace stormkit::wsi::linux::x11 { ///////////////////////////////////// ///////////////////////////////////// auto Window::set_fullscreen(bool enabled) noexcept -> void { - xcb::get_atom(WM_STATE_FULLSCREEN_STR, false) - .transform_error(xcb::atom_error(WM_STATE_FULLSCREEN_STR)) - .and_then([](auto&& fullscreen_atom) static noexcept { - return xcb::get_atom(WM_STATE_STR, false).transform(monadic::as_tuple(std::move(fullscreen_atom))); - }) - .transform_error(xcb::atom_error(WM_STATE_STR)) - .transform(monadic::unpack_tuple_to([this, enabled](auto&& fullscreen_atom, auto&& state_atom) { - auto& globals = xcb::get_globals(); - auto ev = xcb_client_message_event_t {}; - ev.response_type = XCB_CLIENT_MESSAGE; - ev.type = state_atom; - ev.format = 32; - ev.window = m_window; - ev.data.data32[0] = enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; - ev.data.data32[1] = fullscreen_atom; - ev.data.data32[2] = XCB_ATOM_NONE; - ev.data.data32[3] = 0; - ev.data.data32[4] = 0; - - xcb_send_event(globals.connection, - 1, - m_window, - XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY, - std::bit_cast(&ev)); - - xcb_flush(globals.connection); - m_state.fullscreen = enabled; - })); + auto _ = xcb::get_atom(WM_STATE_FULLSCREEN_STR, false) + .transform_error(xcb::atom_error(WM_STATE_FULLSCREEN_STR)) + .and_then([](auto&& fullscreen_atom) static noexcept { + return xcb::get_atom(WM_STATE_STR, false).transform(monadic::as_tuple(std::move(fullscreen_atom))); + }) + .transform_error(xcb::atom_error(WM_STATE_STR)) + .transform(monadic::unpack_tuple_to([this, enabled](auto&& fullscreen_atom, auto&& state_atom) { + auto& globals = xcb::get_globals(); + auto ev = xcb_client_message_event_t {}; + ev.response_type = XCB_CLIENT_MESSAGE; + ev.type = state_atom; + ev.format = 32; + ev.window = m_window; + ev.data.data32[0] = enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE; + ev.data.data32[1] = fullscreen_atom; + ev.data.data32[2] = XCB_ATOM_NONE; + ev.data.data32[3] = 0; + ev.data.data32[4] = 0; + + xcb_send_event(globals.connection, + 1, + m_window, + XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY, + std::bit_cast(&ev)); + + xcb_flush(globals.connection); + m_state.fullscreen = enabled; + })); } ///////////////////////////////////// @@ -698,11 +693,11 @@ namespace stormkit::wsi::linux::x11 { case XCB_CLIENT_MESSAGE: { auto client_message_event = std::bit_cast(xevent); - xcb::get_atom(WM_DELETE_WINDOW, false) - .transform([this, &client_message_event](auto&& atom) noexcept { - if (client_message_event->data.data32[0] == atom) closed_event(); - }) - .transform_error(xcb::atom_error(WM_DELETE_WINDOW)); + auto _ = xcb::get_atom(WM_DELETE_WINDOW, false) + .transform([this, &client_message_event](auto&& atom) noexcept { + if (client_message_event->data.data32[0] == atom) closed_event(); + }) + .transform_error(xcb::atom_error(WM_DELETE_WINDOW)); } break; case XCB_MAPPING_NOTIFY: { auto mapping_notify_event = std::bit_cast(xevent); @@ -717,14 +712,9 @@ namespace stormkit::wsi::linux::x11 { auto property_notify_event = std::bit_cast(xevent); auto _ = xcb::get_atom(WM_STATE_STR, false).transform([this, property_notify_event](auto wm_state_atom) { if (wm_state_atom == property_notify_event->atom) { - auto& globals = xcb::get_globals(); - const auto cookie = xcb_get_property(globals.connection, - false, - m_window, - wm_state_atom, - XCB_ATOM_ATOM, - 0, - 32); + auto& globals = xcb::get_globals(); + const auto + cookie = xcb_get_property(globals.connection, false, m_window, wm_state_atom, XCB_ATOM_ATOM, 0, 32); auto error = xcb::GenericError::empty(); auto reply = xcb_get_property_reply(globals.connection, cookie, &error.handle()); From 79e99b3665a9270cd338fb8973d604d555141737 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 26 Jan 2026 20:46:31 +0100 Subject: [PATCH 016/194] (all) fix some warnings --- modules/stormkit/core/coroutines.mpp | 2 +- src/wsi/linux/wayland/window.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/stormkit/core/coroutines.mpp b/modules/stormkit/core/coroutines.mpp index 9c02bdffe..cfdf6b380 100644 --- a/modules/stormkit/core/coroutines.mpp +++ b/modules/stormkit/core/coroutines.mpp @@ -253,7 +253,7 @@ export namespace std { void await_resume() { __generator_promise_base& __nestedPromise = *__gen_.__get_promise(); - if (__nestedPromise.__exception_.get()) { rethrow_exception(move(__nestedPromise.__exception_.get())); } + if (__nestedPromise.__exception_.get()) { rethrow_exception(std::move(__nestedPromise.__exception_.get())); } } }; diff --git a/src/wsi/linux/wayland/window.cpp b/src/wsi/linux/wayland/window.cpp index 46c2b851e..3db828e74 100644 --- a/src/wsi/linux/wayland/window.cpp +++ b/src/wsi/linux/wayland/window.cpp @@ -611,9 +611,9 @@ namespace stormkit::wsi::linux::wayland { old_shm_pool = std::move(m_shm_pool); old_pixel_buffer = std::move(m_pixel_buffer); - SHMBuffer::create(size, std::format("StormKit::{}::PixelBuffer", m_title)) - .transform(bind_front(&DeferInit::construct, &m_shm_buffer)) - .transform_error(monadic::assert()); + auto _ = SHMBuffer::create(size, std::format("StormKit::{}::PixelBuffer", m_title)) + .transform(bind_front(&DeferInit::construct, &m_shm_buffer)) + .transform_error(monadic::assert()); m_shm_pool = wl::ShmPool::create(globals.shm, narrow(std::bit_cast(m_shm_buffer->native_handle())), From 2228c8b15adf8bd67437639cfb29074d50d4002e Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 27 Jan 2026 18:30:43 +0100 Subject: [PATCH 017/194] (core) improve Tree --- modules/stormkit/core/containers/tree.mpp | 158 ++++++++++----------- modules/stormkit/core/utils/filesystem.mpp | 5 +- 2 files changed, 76 insertions(+), 87 deletions(-) diff --git a/modules/stormkit/core/containers/tree.mpp b/modules/stormkit/core/containers/tree.mpp index f7981b82e..cf1031610 100644 --- a/modules/stormkit/core/containers/tree.mpp +++ b/modules/stormkit/core/containers/tree.mpp @@ -15,9 +15,15 @@ export module stormkit.core:containers.tree; import std; import :typesafe.integer; +import :typesafe.byte; import :typesafe.safecasts; import :utils.handle; import :utils.contract; +import :utils.function_ref; +import :utils.filesystem; + +namespace stdr = std::ranges; +namespace stdfs = std::filesystem; export namespace stormkit { inline namespace core { class STORMKIT_API TreeNode { @@ -58,7 +64,7 @@ export namespace stormkit { inline namespace core { template class Tree { public: - static constexpr auto DEFAULT_PREALLOCATED_TREE_SIZE = usize { 1000 }; + static constexpr auto DEFAULT_PREALLOCATED_TREE_SIZE = usize { 10 }; using TreeNodeType = TreeNodeClass; using TreeNodeIndexType = typename TreeNodeType::IndexType; @@ -73,12 +79,12 @@ export namespace stormkit { inline namespace core { Tree(Tree&&); auto operator=(Tree&&) -> Tree&; - auto getFreeNode() -> TreeNodeIndexType; + auto get_free_node() -> TreeNodeIndexType; auto insert(TreeNodeType&& node, TreeNodeIndexType parent_index, TreeNodeIndexType previous_sibling) -> TreeNodeIndexType; auto remove(TreeNodeIndexType index) -> void; - auto markDirty(TreeNodeIndexType index, TreeNodeDirtyBitType bits) -> void; + auto mark_dirty(TreeNodeIndexType index, TreeNodeDirtyBitType bits) -> void; auto operator[](TreeNodeIndexType index) noexcept -> TreeNodeType&; auto operator[](TreeNodeIndexType index) const noexcept -> const TreeNodeType&; @@ -100,16 +106,16 @@ export namespace stormkit { inline namespace core { [[nodiscard]] auto cend() const noexcept; - auto clearDirties() noexcept -> void; + auto clear_dirties() noexcept -> void; [[nodiscard]] auto dirties() const noexcept -> std::span; - auto genDotFile(std::filesystem::path filepath, std::function colorize_node) const - -> void; + auto gen_dot_file(stdfs::path filepath, FunctionRef colorize_node) const noexcept + -> io::Expected; - auto genDotFile(std::filesystem::path filepath, - core::u32 highlight, - std::function colorize_node) const -> void; + auto gen_dot_file(stdfs::path filepath, + core::u32 highlight, + FunctionRef colorize_node) const noexcept -> io::Expected; private: TreeNodeIndexType m_first_free_index = 0; @@ -199,7 +205,7 @@ namespace stormkit { inline namespace core { Tree::Tree() { m_tree.resize(DEFAULT_PREALLOCATED_TREE_SIZE); - for (auto i : range(std::size(m_tree) - 1u)) m_tree[i].set_next_sibling(i + 1u); + for (auto i : range(stdr::size(m_tree) - 1u)) m_tree[i].set_next_sibling(i + 1u); } //////////////////////////////////////// @@ -230,13 +236,13 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - auto Tree::getFreeNode() -> TreeNodeIndexType { + auto Tree::get_free_node() -> TreeNodeIndexType { if (m_tree[m_first_free_index].next_sibling() == TreeNode::INVALID_INDEX) { - const auto size = as(std::size(m_tree)); - const auto first_new = as(size); + const auto size = as(stdr::size(m_tree)); + const auto first_new = as(stdr::size(m_tree)); m_tree.resize(as(size * 1.5f)); - const auto new_size = std::size(m_tree); + const auto new_size = stdr::size(m_tree); // generate a new chain of free objects, with the last one pointing to // ~0 @@ -255,7 +261,7 @@ namespace stormkit { inline namespace core { template auto Tree::insert(TreeNodeType&& node, TreeNodeIndexType parent_index, TreeNodeIndexType previous_sibling) -> TreeNodeIndexType { - const auto index = getFreeNode(); + const auto index = get_free_node(); auto& _node = m_tree[index]; _node = std::forward(node); @@ -336,7 +342,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - auto Tree::markDirty(TreeNodeIndexType index, TreeNodeDirtyBitType bits) -> void { + auto Tree::mark_dirty(TreeNodeIndexType index, TreeNodeDirtyBitType bits) -> void { auto& node = m_tree[index]; if (not node.dirty_bits()) { m_dirties.emplace_back(index); @@ -351,7 +357,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template auto Tree::operator[](TreeNodeIndexType index) noexcept -> TreeNodeType& { - EXPECTS(index < std::size(m_tree)); + EXPECTS(index < stdr::size(m_tree)); return m_tree[index]; } @@ -360,7 +366,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template auto Tree::operator[](TreeNodeIndexType index) const noexcept -> const TreeNodeType& { - EXPECTS(index < std::size(m_tree)); + EXPECTS(index < stdr::size(m_tree)); return m_tree[index]; } @@ -369,7 +375,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template auto Tree::size() const noexcept -> usize { - return std::size(m_tree); + return stdr::size(m_tree); } //////////////////////////////////////// @@ -417,7 +423,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - auto Tree::clearDirties() noexcept -> void { + auto Tree::clear_dirties() noexcept -> void { if (std::empty(m_dirties)) return; for (auto i : m_dirties) { m_tree[i].set_dirty_bits(0); } @@ -435,33 +441,28 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - auto Tree::genDotFile(std::filesystem::path filepath, - std::function colorize_node) const -> void { - auto stream = std::fstream(filepath, std::ios::out); - - stream - << "digraph G { \n" - << " rankdir = LR\n" - << " bgcolor = black\n\n" - << " node [shape=box, fontname=\"helvetica\", fontsize=12];\n\n"; + auto Tree::gen_dot_file(stdfs::path filepath, + FunctionRef colorize_node) const noexcept + -> io::Expected { + using namespace stormkit::literals; + auto out = std::string {}; + out.reserve(1_kb); + + out += "digraph G { \n" + " rankdir = LR\n" + " bgcolor = black\n\n" + " node [shape=box, fontname=\"helvetica\", fontsize=12];\n\n"; for (auto i : range(m_first_free_index)) { const auto name = operator[](i).name(); const auto dirty = bool(operator[](i).dirty_bits()); - stream - << " \"node" - << i - << "\" [label=\"id: " - << i - << " type: " - << name - << " dirty: " - << std::boolalpha - << dirty - << "\", style=filled,color=\"" - << colorize_node(name) - << "\"];\n"; + out += std::format(" \"node{}\" [label=\"id: {} type: {} dirty: {} \", style=filled,color=\"{}\"];\n", + i, + i, + name, + dirty, + colorize_node(name)); } for (auto i : range(m_first_free_index)) { @@ -469,60 +470,49 @@ namespace stormkit { inline namespace core { for (auto current = operator[](i).first_child(); current != TreeNodeClass::INVALID_INDEX; current = operator[](current).next_sibling()) { - stream << " \"node" << i << "\" -> \"node" << current << "\" [color=seagreen] ;\n"; + out += std::format(" \"node{}\" -> \"node{}\" [color=seagreen] ;\n", i, current); } } - stream << "}" << std::flush; + out += "}"; - stream.close(); + return io::write_text(filepath, out); } //////////////////////////////////////// //////////////////////////////////////// template - auto Tree::genDotFile(std::filesystem::path filepath, - core::u32 highlight, - std::function colorize_node) const -> void { - std::fstream stream(filepath.string(), std::ios::out); - - stream - << "digraph G { \n" - << " rankdir = LR\n" - << " bgcolor = black\n\n" - << " node [shape=box, fontname=\"helvetica\", fontsize=12];\n\n"; + auto Tree::gen_dot_file(stdfs::path filepath, + core::u32 highlight, + FunctionRef colorize_node) const noexcept + -> io::Expected { + using namespace stormkit::literals; + auto out = std::string {}; + out.reserve(1_kb); + + out += "digraph G { \n" + " rankdir = LR\n" + " bgcolor = black\n\n" + " node [shape=box, fontname=\"helvetica\", fontsize=12];\n\n"; for (auto i : range(m_first_free_index)) { const auto name = operator[](i).name(); const auto dirty = bool(operator[](i).dirty_bits()); if (i != highlight) - stream - << " \"node" - << i - << "\" [label=\"id: " - << i - << " type: " - << name - << " dirty: " - << std::boolalpha - << dirty - << "\", style=filled,color=\"" - << colorize_node(name) - << "\"];\n"; + out += std::format(" \"node{}\" [label=\"id: {} type: {} dirty: {} \", style=filled,color=\"{}\"];\n", + i, + i, + name, + dirty, + colorize_node(name)); else - stream - << " \"node" - << i - << "\" [shape=polygon,sides=5,peripheries=3, label=\"id: " - << i - << " type: " - << name - << " dirty: " - << std::boolalpha - << dirty - << "\", style=filled,color=\"" - << colorize_node(name) - << "\"];\n"; + out += std::format(" \"node{}\" [shape = polygon,sides=5,peripheries=3, label=\"id: {} type: {} dirty: {} \", " + "style=filled,color=\"{}\"];\n", + i, + i, + name, + dirty, + colorize_node(name)); } for (auto i : range(m_first_free_index)) { @@ -530,12 +520,12 @@ namespace stormkit { inline namespace core { for (auto current = operator[](i).first_child(); current != TreeNodeClass::INVALID_INDEX; current = operator[](current).next_sibling()) { - stream << " \"node" << i << "\" -> \"nodeNode" << current << "\" [color=seagreen] ;\n"; + out += std::format(" \"node{}\" -> \"node{}\" [color=seagreen] ;\n", i, current); } } - stream << "}" << std::flush; + out += "}"; - stream.close(); + return io::write_text(filepath, out); } }} // namespace stormkit::core diff --git a/modules/stormkit/core/utils/filesystem.mpp b/modules/stormkit/core/utils/filesystem.mpp index 8e48069d1..3160ca1b4 100644 --- a/modules/stormkit/core/utils/filesystem.mpp +++ b/modules/stormkit/core/utils/filesystem.mpp @@ -33,7 +33,7 @@ import :utils.contract; import :typesafe; import :functional; import :meta; -import :containers; +// import :containers; namespace stdfs = std::filesystem; @@ -177,8 +177,7 @@ namespace stormkit { inline namespace core { namespace io { const auto // err = _sopen_s(&ret, stdr::data(p), posix_access | text_mode, _SH_DENYNO, // win32_access); - err - = _sopen_s(&ret, stdr::data(p), posix_access | text_mode, _SH_SECURE, win32_access); + err = _sopen_s(&ret, stdr::data(p), posix_access | text_mode, _SH_SECURE, win32_access); if (err != 0) return std::unexpected { SystemError::from_errno() }; #else const auto ret = ::open(stdr::data(p), posix_access); From 4c1d43e7731845b04cf08631b7734c07bc91c8dc Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 28 Jan 2026 19:14:03 +0100 Subject: [PATCH 018/194] (core) fix stacktrace and sanitizers --- src/core/stacktrace.cpp | 26 +++++++++++++------------- xmake/rules/stormkit_flags.xmake.lua | 23 +++++++++++++++++++++-- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/core/stacktrace.cpp b/src/core/stacktrace.cpp index b2e5dde4d..abc336e76 100644 --- a/src/core/stacktrace.cpp +++ b/src/core/stacktrace.cpp @@ -31,13 +31,13 @@ namespace stormkit { inline namespace core { out = replace(out, "basic_string_view>", "string_view"); out = replace(out, "basic_string_view >", "string_view"); out = replace(out, - "basic_string, " + "basic_string, " "std::allocator>", - "string"); + "string"); out = replace(out, - "basic_string, " + "basic_string, " "std::allocator >", - "string"); + "string"); return out; } @@ -63,14 +63,14 @@ namespace stormkit { inline namespace core { continue; } #ifdef STORMKIT_COMPILER_MSSTL - const auto frame_str = std::to_string(frame); - auto splitted = split(frame_str, "+"); - const auto address = from_string(splitted[1].substr(2), 16) - .transform_error([stderr, &splitted](auto&& err) noexcept { + const auto frame_str = std::to_string(frame); + auto splitted = split(frame_str, "+"); + const auto address = from_string(splitted[1].substr(2), 16) + .transform_error([stderr, &splitted](auto&& err) noexcept { std::println(stderr, "Failed to parse {}, reason: {}", splitted[0], err); return 0; - }) - .value(); + }) + .value(); splitted = split(splitted[0], "!"); const auto formatted_symbol = prettify((stdr::size(splitted) >= 2) ? "\n in " + (YELLOW_TEXT_STYLE | splitted[1]).render() @@ -83,11 +83,11 @@ namespace stormkit { inline namespace core { const auto frame_str = std::to_string(frame); const auto splitted = split(frame_str, ": "); const auto address = from_string(splitted[0].substr(2), 16) - .transform_error([stderr, &splitted](auto&& err) noexcept { + .transform_error([stderr, &splitted](auto&& err) noexcept { std::println(stderr, "Failed to parse {}, reason: {}", splitted[0], err); return 0; - }) - .value(); + }) + .value(); const auto formatted_symbol = prettify((stdr::size(splitted) > 2) ? "\n in " + (YELLOW_TEXT_STYLE | splitted[1]).render() diff --git a/xmake/rules/stormkit_flags.xmake.lua b/xmake/rules/stormkit_flags.xmake.lua index 8e2dedb20..bc59183cf 100644 --- a/xmake/rules/stormkit_flags.xmake.lua +++ b/xmake/rules/stormkit_flags.xmake.lua @@ -1,6 +1,12 @@ rule("stormkit.flags", function() on_load("linux", "mingw", "macosx", "ios", "android", function(target) - if get_config("lto") then target:set("policy", "build.optimization.lto", true) end + if get_config("lto") then + target:set("policy", "build.optimization.lto", true) + if get_config("toolchain") == "llvm" or get_config("toolchain") == "clang" then + target:add("ldflags", "-flto=thin", { force = true }) + target:add("shflags", "-flto=thin", { force = true }) + end + end if get_config("mold") and not is_subhost("windows") then local arg = "-fuse-ld=mold" if type(get_config("mold")) == "string" then arg = "-fuse-ld=" .. get_config("mold") end @@ -9,10 +15,23 @@ rule("stormkit.flags", function() end target:set("utf-8", true) - if get_config("sanitizers") and is_mode("release", "releasedbg") and target:is_binary() then + if get_config("sanitizers") and is_mode("debug", "release", "releasedbg") and target:is_binary() then target:set("policy", "build.sanitizer.address", true) target:set("policy", "build.sanitizer.undefined", true) end + if + get_config("toolchain") == "llvm" + or get_config("toolchain") == "clang" + or get_config("toolchain") == "gcc" + then + target:add("syslinks", "dl") + + if is_mode("debug") then + target:add("cxflags", "-no-pie") + target:add("ldflags", "-fno-pie") + target:add("shflags", "-fno-pie") + end + end end) on_load("windows", function(target) import("core.tool.compiler") From 5699615e32fd51ac38523e8cc457d7f68a4c534b Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 28 Jan 2026 19:14:13 +0100 Subject: [PATCH 019/194] (core) implement DAG --- modules/stormkit/core/containers.mpp | 1 + modules/stormkit/core/containers/dag.mpp | 565 +++++++++++++++++++++++ tests/core/containers/dag.cpp | 135 ++++++ 3 files changed, 701 insertions(+) create mode 100644 modules/stormkit/core/containers/dag.mpp create mode 100644 tests/core/containers/dag.cpp diff --git a/modules/stormkit/core/containers.mpp b/modules/stormkit/core/containers.mpp index fbfbf8e45..bffa4cdf7 100644 --- a/modules/stormkit/core/containers.mpp +++ b/modules/stormkit/core/containers.mpp @@ -7,6 +7,7 @@ export module stormkit.core:containers; export import :containers.multi_buffer; export import :containers.ringbuffer; export import :containers.tree; +export import :containers.dag; export import :containers.utils; export import :containers.raii_capsule; export import :containers.shmbuffer; diff --git a/modules/stormkit/core/containers/dag.mpp b/modules/stormkit/core/containers/dag.mpp new file mode 100644 index 000000000..5383abbdc --- /dev/null +++ b/modules/stormkit/core/containers/dag.mpp @@ -0,0 +1,565 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +#include + +export module stormkit.core:containers.dag; + +import std; + +import :typesafe.integer; +import :typesafe.byte; +import :typesafe.safecasts; +import :utils.handle; +import :utils.contract; +import :utils.function_ref; +import :utils.filesystem; +import :string.format; + +namespace stdr = std::ranges; +namespace stdfs = std::filesystem; + +export namespace stormkit { inline namespace core { + namespace dag { + inline constexpr struct { + } DIRECTED = {}; + + using VertexID = u32; + + struct Edge { + VertexID from; + VertexID to; + }; + + template + struct Vertex { + dag::VertexID id; + VertexValue value; + }; + } // namespace dag + + template + class DAG { + public: + using Vertex = dag::Vertex; + + struct Directed {}; + + constexpr explicit DAG(std::optional = std::nullopt, + std::optional reserve = std::nullopt) noexcept; + constexpr ~DAG() noexcept; + + constexpr DAG(DAG&&) noexcept; + constexpr DAG(const DAG&) noexcept = delete; + + constexpr auto operator=(DAG&&) noexcept -> DAG&; + constexpr auto operator=(const DAG&) noexcept -> DAG& = delete; + + constexpr auto directed() const noexcept -> bool; + + constexpr auto clear() noexcept -> void; + constexpr auto empty() const noexcept -> bool; + + constexpr auto add_vertex(const VertexValue& vertex) noexcept -> dag::VertexID + requires(meta::IsCopyConstructible); + constexpr auto add_vertex(VertexValue&& vertex) noexcept -> dag::VertexID + requires(meta::IsMoveConstructible); + template + constexpr auto emplace_vertex(Args&&... vertex) noexcept -> dag::VertexID + requires(meta::IsConstructible); + constexpr auto get_vertex_value(this auto&& self, dag::VertexID id) noexcept -> decltype(auto); + constexpr auto has_vertex(const VertexValue& vertex) const noexcept -> bool + requires(meta::HasEqualityOperator); + constexpr auto has_vertex(dag::VertexID vertex) const noexcept -> bool; + constexpr auto remove_vertex(const VertexValue& vertex) noexcept -> void + requires(meta::HasEqualityOperator); + constexpr auto remove_vertex(dag::VertexID id) noexcept -> void; + + constexpr auto add_edge(dag::VertexID from, dag::VertexID to) noexcept -> void; + constexpr auto has_edge(dag::VertexID from, dag::VertexID to) const noexcept -> bool; + constexpr auto remove_edge(dag::VertexID from, dag::VertexID to) noexcept -> void; + constexpr auto adjacent_edges(dag::VertexID vertex) const noexcept -> const std::vector&; + + constexpr auto vertices() const noexcept -> const std::vector&; + constexpr auto vertices_count() const noexcept -> usize; + + constexpr auto edges() const noexcept -> const std::vector&; + constexpr auto edges_count() const noexcept -> usize; + + constexpr auto topological_sort() const noexcept -> std::expected, std::vector>; + constexpr auto find_cycle() const noexcept -> std::optional>; + + constexpr auto dump() const noexcept -> std::string; + + private: + bool m_directed; + dag::VertexID m_next_id = 0; + + std::vector m_vertices; + std::vector m_edges; + HashMap> m_adjacent_edges; + }; + + namespace dag { + template + auto format_as(const Edge& edge, FormatContext&) noexcept -> FormatContext::iterator; + + template + auto format_as(const dag::Vertex& vertex, FormatContext&) noexcept -> FormatContext::iterator; + + [[nodiscard]] + constexpr auto to_string(const Edge& edge) noexcept -> std::string; + + template + [[nodiscard]] + constexpr auto to_string(const dag::Vertex& vertex) noexcept -> std::string; + } // namespace dag +}} // namespace stormkit::core + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit { inline namespace core { + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr DAG::DAG(std::optional directed, std::optional reserve) noexcept + : m_directed { directed } { + if (reserve) m_vertices.reserve(*reserve); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr DAG::~DAG() noexcept = default; + + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr DAG::DAG(DAG&&) noexcept = default; + + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr auto DAG::operator=(DAG&&) noexcept -> DAG& = default; + + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr auto DAG::directed() const noexcept -> bool { + return m_directed; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr auto DAG::clear() noexcept -> void { + m_adjacent_edges.clear(); + m_edges.clear(); + m_vertices.clear(); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto DAG::empty() const noexcept -> bool { + return stdr::empty(m_vertices); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr auto DAG::add_vertex(const VertexValue& vertex) noexcept -> dag::VertexID + requires(meta::IsCopyConstructible) + { + if constexpr (meta::HasEqualityOperator) { + if (not has_vertex(vertex)) { + const auto id = m_next_id++; + m_vertices.emplace_back(id, vertex); + m_adjacent_edges[id] = {}; + return id; + } + + return stdr::find_if(m_vertices, [&vertex](const auto& other) noexcept { return vertex == other.value; })->id; + } else { + const auto id = m_next_id++; + m_vertices.emplace_back(id, vertex); + m_adjacent_edges[id] = {}; + return id; + } + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr auto DAG::add_vertex(VertexValue&& vertex) noexcept -> dag::VertexID + requires(meta::IsMoveConstructible) + { + if constexpr (meta::HasEqualityOperator) { + if (not has_vertex(vertex)) { + const auto id = m_next_id++; + m_vertices.emplace_back(id, std::move(vertex)); + m_adjacent_edges[id] = {}; + return id; + } + + return stdr::find_if(m_vertices, [&vertex](const auto& other) noexcept { return vertex == other.value; })->id; + } else { + const auto id = m_next_id++; + m_vertices.emplace_back(id, std::move(vertex)); + m_adjacent_edges[id] = {}; + return id; + } + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + template + constexpr auto DAG::emplace_vertex(Args&&... args) noexcept -> dag::VertexID + requires(meta::IsConstructible) + { + return add_vertex(VertexValue { std::forward(args)... }); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr auto DAG::get_vertex_value(this auto&& self, dag::VertexID id) noexcept -> decltype(auto) { + expects(self.has_vertex(id), std::format("Unknown DAG vertex id: {}!", id)); + + return std::forward_like(*stdr::find_if(self.m_vertices, [id](const auto& other) noexcept { + return other.id == id; + })); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto DAG::has_vertex(const VertexValue& vertex) const noexcept -> bool + requires(meta::HasEqualityOperator) + { + return stdr::any_of(m_vertices, [&vertex](const auto& other) noexcept { return vertex == other.value; }); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto DAG::has_vertex(dag::VertexID id) const noexcept -> bool { + return m_adjacent_edges.find(id) != stdr::cend(m_adjacent_edges); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr auto DAG::remove_vertex(const VertexValue& vertex) noexcept -> void + requires(meta::HasEqualityOperator) + { + if constexpr (std::formattable) expects(has_vertex(vertex), "Unknown DAG vertex value: {}!", vertex); + else + expects(has_vertex(vertex), "Unknown DAG vertex value!"); + + auto it = stdr::find_if(m_vertices, [&value = vertex](const auto& vertex) noexcept { return vertex.value == value; }); + auto&& [remove_begin, remove_end] = stdr::remove_if(m_edges, [&it](auto&& edge) noexcept { + return edge.from == it->id or edge.to == it->id; + }); + + const auto id = it->id; + m_adjacent_edges.erase(it->id); + m_edges.erase(remove_begin, remove_end); + m_vertices.erase(it); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr auto DAG::remove_vertex(dag::VertexID id) noexcept -> void { + expects(has_vertex(id), std::format("Unknown DAG vertex id: {}!", id)); + + auto it = stdr::find_if(m_vertices, [id](const auto& vertex) noexcept { return vertex.id == id; }); + + auto touching = std::vector {}; + for (auto&& edge : m_edges) + if (edge.from == id or edge.to == id) touching.emplace_back(edge); + + for (auto&& [from, to] : touching) remove_edge(from, to); + + m_adjacent_edges.erase(id); + m_vertices.erase(it); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr auto DAG::add_edge(dag::VertexID from, dag::VertexID to) noexcept -> void { + expects(has_vertex(from), std::format("Unknown DAG vertex from: {}", from)); + expects(has_vertex(to), std::format("Unknown DAG vertex to: {}", to)); + if (has_edge(from, to)) return; + + const auto& edge = m_edges.emplace_back(from, to); + + if (m_directed) { + m_adjacent_edges[from].emplace_back(edge); + } else { + m_adjacent_edges[from].emplace_back(edge); + m_adjacent_edges[to].emplace_back(edge); + } + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr auto DAG::has_edge(dag::VertexID from, dag::VertexID to) const noexcept -> bool { + if (not has_vertex(from) or not has_vertex(to)) return false; + + return stdr::any_of(m_edges, [from, to](auto&& edge) noexcept { return edge.from == from and edge.to == to; }) + and (m_directed ? true : stdr::any_of(m_edges, [from, to](auto&& edge) noexcept { + return edge.from == to and edge.to == from; + })); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr auto DAG::remove_edge(dag::VertexID from, dag::VertexID to) noexcept -> void { + expects(has_vertex(from), std::format("Unknown DAG vertex from: {}", from)); + expects(has_vertex(to), std::format("Unknown DAG vertex to: {}", to)); + if (not has_edge(from, to)) return; + + { + const auto it = stdr::find_if(m_edges, [from, to](auto&& edge) noexcept { + return edge.from == from and edge.to == to; + }); + m_edges.erase(it); + } + if (not m_directed) { + const auto it = stdr::find_if(m_edges, [from, to](auto&& edge) noexcept { + return edge.from == to and edge.to == from; + }); + m_edges.erase(it); + } + + for (auto&& [_, edges] : m_adjacent_edges) { + { + const auto it = stdr::find_if(edges, [from, to](auto&& edge) noexcept { + return edge.from == from and edge.to == to; + }); + if (it != stdr::cend(edges)) edges.erase(it); + } + if (not m_directed) { + const auto it = stdr::find_if(edges, [from, to](auto&& edge) noexcept { + return edge.from == to and edge.to == from; + }); + if (it != stdr::cend(edges)) edges.erase(it); + } + } + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr auto DAG::adjacent_edges(dag::VertexID id) const noexcept -> const std::vector& { + expects(has_vertex(id), std::format("Unknown DAG vertex id: {}!", id)); + + return m_adjacent_edges.at(id); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto DAG::vertices() const noexcept -> const std::vector& { + return m_vertices; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto DAG::vertices_count() const noexcept -> usize { + return stdr::size(m_vertices); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto DAG::edges() const noexcept -> const std::vector& { + return m_edges; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto DAG::edges_count() const noexcept -> usize { + return stdr::size(m_edges); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr auto DAG::topological_sort() const noexcept + -> std::expected, std::vector> { + expects(m_directed, "Can't do topological sort on a non-directed graph"); + + if (auto result = find_cycle(); result.has_value()) return std::unexpected { std::move(*result) }; + + struct Degree { + dag::VertexID id; + u32 d = 0; + }; + + auto in_degree = std::vector {}; + in_degree.reserve(stdr::size(m_vertices)); + for (const auto& [id, _] : m_vertices) { in_degree.emplace_back(id, 0); } + + for (const auto& [id, _] : m_vertices) { + const auto& edges = adjacent_edges(id); + + if (not stdr::empty(edges)) { + for (auto&& [from, to] : edges) { + if (from != id) continue; + auto&& [_, d] = *stdr::find_if(in_degree, [to](auto&& other) noexcept { return other.id == to; }); + d += 1; + } + } + } + + auto queue = std::queue {}; + + for (const auto& [id, _] : m_vertices) { + auto&& [_, d] = *stdr::find_if(in_degree, [id](auto&& other) noexcept { return other.id == id; }); + if (d == 0) queue.push(id); + } + + auto ordered_vertices = std::vector {}; + ordered_vertices.reserve(stdr::size(m_vertices)); + while (not stdr::empty(queue)) { + auto id = queue.front(); + queue.pop(); + + ordered_vertices.emplace_back(id); + + const auto& edges = adjacent_edges(id); + if (not stdr::empty(edges)) { + for (auto&& [from, to] : edges) { + if (from == id) { + auto&& [_, d] = *stdr::find_if(in_degree, [to](auto&& other) noexcept { return other.id == to; }); + if (d > 0) d -= 1; + if (d == 0) queue.push(to); + } + } + } + } + + return ordered_vertices; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr auto DAG::find_cycle() const noexcept -> std::optional> { + auto out = std::optional> { std::nullopt }; + + auto visited = std::vector {}; + visited.reserve(stdr::size(m_vertices)); + auto stack = std::vector {}; + + auto dfs = [&visited, &stack, &out, this](auto&& dfs, auto&& id) mutable noexcept -> bool { + visited.emplace_back(id); + + const auto& edges = adjacent_edges(id); + if (stdr::empty(edges)) return false; + + stack.emplace_back(id); + + for (const auto& [from, to] : edges) { + const auto w = (from == id) ? to : from; + if (not stdr::contains(visited, w)) { + if (dfs(dfs, w)) { + return true; + } else if (auto it = stdr::find(stack, w); it != stdr::cend(stack)) { + auto cycle = std::vector(it, stdr::end(stack)); + cycle.emplace_back(w); + out = std::move(cycle); + return true; + } + } else if (auto it = stdr::find(stack, w); it != stdr::cend(stack)) { + auto cycle = std::vector(it, stdr::end(stack)); + cycle.emplace_back(w); + out = std::move(cycle); + return true; + } + } + + auto [begin, end] = stdr::remove(stack, id); + stack.erase(begin, end); + return false; + }; + + for (auto&& [id, _] : m_vertices) { + if (stdr::contains(visited, id)) continue; + + if (dfs(dfs, id)) break; + } + + return out; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr auto DAG::dump() const noexcept -> std::string { + return {}; + } + + namespace dag { + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto format_as(const Edge& edge, FormatContext& ctx) noexcept -> FormatContext::iterator { + auto&& out = ctx.out(); + return std::format_to(out, "[dag_edge from: {}, to: {}]", edge.from, edge.to); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto format_as(const dag::Vertex& vertex, FormatContext& ctx) noexcept -> FormatContext::iterator { + auto&& out = ctx.out(); + if constexpr (std::formattable) + return std::format_to(out, "[dag_vertex id: {}, value: {}]", vertex.id, vertex.value); + else + return std::format_to(out, "[dag_vertex id: {}, value: ]", vertex.id); + } + + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + constexpr auto to_string(const dag::Edge& edge) noexcept -> std::string { + return std::format("{}", edge); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE STORMKIT_PURE + constexpr auto to_string(const dag::Vertex& vertex) noexcept -> std::string { + return std::format("{}", vertex); + } + } // namespace dag +}} // namespace stormkit::core diff --git a/tests/core/containers/dag.cpp b/tests/core/containers/dag.cpp new file mode 100644 index 000000000..694ef0d66 --- /dev/null +++ b/tests/core/containers/dag.cpp @@ -0,0 +1,135 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +import std; + +import stormkit.core; +import stormkit.test; + +#include + +using namespace stormkit::core; +using namespace std::literals; + +namespace stdr = std::ranges; + +namespace { + auto _ = test::TestSuite { + "core.containers.dag", + { + { "topological_sort", + [] { + using Edge = std::pair; + constexpr auto edges = into_array(Edge { 0, 5 }, + Edge { 0, 2 }, + Edge { 0, 1 }, + Edge { 3, 6 }, + Edge { 3, 5 }, + Edge { 3, 4 }, + Edge { 5, 4 }, + Edge { 6, 4 }, + Edge { 6, 0 }, + Edge { 3, 2 }, + Edge { 1, 4 }); + + auto dag = DAG { dag::DIRECTED }; + for (auto i : range(7)) dag.add_vertex(i); + + for (auto&& [from, to] : edges) dag.add_edge(from, to); + + auto result = dag.topological_sort(); + if (not result) { + for (auto id : result.error()) std::println(" {} ->", id); + } + EXPECTS((result.has_value())); + + auto ordered = std::move(*result); + + auto orders = HashMap {}; + { + auto i = 0; + for (auto id : ordered) orders.emplace(id, i++); + } + + for (auto&& [from, to] : edges) EXPECTS(orders[from] < orders[to]); + } }, + { "remove_edge_and_vertex", + [] { + auto dag = DAG { dag::DIRECTED }; + dag.emplace_vertex("a"); + dag.emplace_vertex("b"); + dag.emplace_vertex("c"); + dag.emplace_vertex("d"); + + dag.add_edge(0, 1); + dag.add_edge(1, 2); + dag.add_edge(2, 3); + dag.add_edge(0, 3); + + EXPECTS(dag.has_edge(0, 1)); + + dag.remove_edge(0, 1); + + EXPECTS(not dag.has_edge(0, 1)); + EXPECTS(dag.has_edge(0, 3)); + + dag.remove_vertex(2); + + EXPECTS(not dag.has_edge(1, 2)); + EXPECTS(not dag.has_edge(2, 3)); + + EXPECTS(stdr::size(dag.vertices()) == 3); + + { + auto result = dag.topological_sort(); + if (not result) { + for (auto id : result.error()) std::println(" {} ->", id); + } + EXPECTS(result.has_value()); + EXPECTS(stdr::size(*result) == 3); + } + + dag.add_edge(1, 0); + dag.add_edge(3, 1); + { + auto result = dag.topological_sort(); + EXPECTS((not result.has_value())); + } + } }, + { "find_cycle", + [] { + auto dag = DAG { dag::DIRECTED }; + dag.add_vertex(0); + dag.add_vertex(1); + dag.add_vertex(4); + dag.add_vertex(5); + dag.add_vertex(6); + dag.add_vertex(9); + + dag.add_edge(5, 1); + dag.add_edge(1, 4); + dag.add_edge(4, 0); + dag.add_edge(0, 1); + dag.add_edge(2, 3); + + { + auto result = dag.find_cycle(); + EXPECTS(result.has_value()); + + auto&& cycle = std::move(*result); + EXPECTS(stdr::size(cycle) == 4); + EXPECTS(dag.get_vertex_value(cycle[0]).value == 0); + EXPECTS(dag.get_vertex_value(cycle[1]).value == 1); + EXPECTS(dag.get_vertex_value(cycle[2]).value == 6); + EXPECTS(dag.get_vertex_value(cycle[3]).value == 0); + } + + { + auto result = dag.topological_sort(); + EXPECTS(not result.has_value()); + } + } }, + } + }; +} // namespace From 5cdad211daa99cd61d4643c36c0b6a0fec89c74d Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 28 Jan 2026 20:06:33 +0100 Subject: [PATCH 020/194] (core) implement dump() on dag class --- modules/stormkit/core/containers/dag.mpp | 25 ++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/modules/stormkit/core/containers/dag.mpp b/modules/stormkit/core/containers/dag.mpp index 5383abbdc..f196cf910 100644 --- a/modules/stormkit/core/containers/dag.mpp +++ b/modules/stormkit/core/containers/dag.mpp @@ -48,7 +48,8 @@ export namespace stormkit { inline namespace core { template class DAG { public: - using Vertex = dag::Vertex; + using Vertex = dag::Vertex; + using ColorizeFunc = FunctionRef; struct Directed {}; @@ -96,7 +97,7 @@ export namespace stormkit { inline namespace core { constexpr auto topological_sort() const noexcept -> std::expected, std::vector>; constexpr auto find_cycle() const noexcept -> std::optional>; - constexpr auto dump() const noexcept -> std::string; + constexpr auto dump(ColorizeFunc colorize = [](const auto&) { return "white"; }) const noexcept -> std::string; private: bool m_directed; @@ -521,8 +522,24 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - constexpr auto DAG::dump() const noexcept -> std::string { - return {}; + constexpr auto DAG::dump(ColorizeFunc colorize) const noexcept -> std::string { + auto out = std::string { "digraph G { \n" + " rankdir = LR\n" + " bgcolor = black\n\n" + " node [shape=box, fontname=\"helvetica\", fontsize=12];\n\n" }; + + for (const auto& [id, value] : m_vertices) + out += std::format(" \"node{}\" [label=\"id: {} value: {} \", style=filled,color=\"{}\"];\n", + id, + id, + value, + colorize(value)); + + for (const auto& [from, to] : m_edges) out += std::format(" \"node{}\" -> \"node{}\" [color=seagreen];\n", from, to); + + out += "}"; + + return out; } namespace dag { From 309d115e5d53f08fa2548519136f61a500a1489d Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 28 Jan 2026 20:40:28 +0100 Subject: [PATCH 021/194] (core) fix error not moved in Try macro --- include/stormkit/core/try_expected.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/stormkit/core/try_expected.hpp b/include/stormkit/core/try_expected.hpp index f1ab7250d..cd0da9ef5 100644 --- a/include/stormkit/core/try_expected.hpp +++ b/include/stormkit/core/try_expected.hpp @@ -6,12 +6,12 @@ #define STORMKIT_TRY_EXPECTED_HPP #if (defined(__clang__) or defined(__GNUC__)) - #define Try(m) \ - ({ \ - auto res = (m); \ - if (!res.has_value()) [[unlikely]] \ - return std::unexpected { res.error() }; \ - std::move(res).value(); \ + #define Try(m) \ + ({ \ + auto res = (m); \ + if (not res.has_value()) [[unlikely]] \ + return std::unexpected { std::move(res).error() }; \ + std::move(res).value(); \ }) #define Ret(x) return x #define RetErr(x) return std::unexpected { x }; From 23165f85705cccadb33bc10f3606ec243769c7c0 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 29 Jan 2026 23:58:04 +0100 Subject: [PATCH 022/194] (core, gpu) improve and use Try expected macro --- examples/gpu/triangle/src/main.cpp | 183 ++++++++------------ include/stormkit/core/try_expected.hpp | 34 +++- modules/stormkit/core/utils/filesystem.mpp | 39 ++--- modules/stormkit/gpu/core/sync.mpp | 12 +- modules/stormkit/gpu/execution/pipeline.mpp | 25 ++- src/gpu/execution/pipeline_cache.cpp | 18 +- 6 files changed, 142 insertions(+), 169 deletions(-) diff --git a/examples/gpu/triangle/src/main.cpp b/examples/gpu/triangle/src/main.cpp index a4745f073..cfae721e1 100644 --- a/examples/gpu/triangle/src/main.cpp +++ b/examples/gpu/triangle/src/main.cpp @@ -2,11 +2,14 @@ // This file is subject to the license terms in the LICENSE file // found in the top-level of this distribution +#include + import std; import stormkit; import gpu_app; +#include #include #include @@ -41,29 +44,25 @@ class Application: public base::Application { public: auto init_example() { // load shaders - m_vertex_shader = gpu::Shader::load_from_file(m_device, SHADER_DIR "/shaders/triangle.spv", gpu::ShaderStageFlag::VERTEX) - .transform_error(monadic::assert(std::format("Failed to load vertex shader {}", - SHADER_DIR "/shaders/triangle.spv"))) - .value(); - - m_fragment_shader = gpu::Shader::load_from_file(m_device, - SHADER_DIR "/shaders/triangle.spv", - gpu::ShaderStageFlag::FRAGMENT) - .transform_error(monadic::assert(std::format("Failed to load fragment shader {}", - SHADER_DIR "/shaders/triangle.spv"))) - .value(); - - m_pipeline_layout = gpu::PipelineLayout::create(m_device, {}) - .transform_error(monadic::assert("Failed to create pipeline layout")) - .value(); + m_vertex_shader = TryAssert(gpu::Shader::load_from_file(m_device, + SHADER_DIR "/shaders/triangle.spv", + gpu::ShaderStageFlag::VERTEX), + std::format("Failed to load vertex shader {}", SHADER_DIR "/shaders/triangle.spv")); + + m_fragment_shader = TryAssert(gpu::Shader::load_from_file(m_device, + SHADER_DIR "/shaders/triangle.spv", + gpu::ShaderStageFlag::FRAGMENT), + std::format("Failed to load fragment shader {}", SHADER_DIR "/shaders/triangle.spv")); + + m_pipeline_layout = TryAssert(gpu::PipelineLayout::create(m_device, {}), "Failed to create pipeline layout"); // initialize render pass - m_render_pass = gpu::RenderPass::create(m_device, - { .attachments = { { .format = m_swapchain->pixel_format() } }, - .subpasses = { { .bind_point = gpu::PipelineBindPoint::GRAPHICS, - .color_attachment_refs = { { .attachment_id = 0u } } } } }) - .transform_error(monadic::assert("Failed to create render pass")) - .value(); + m_render_pass = TryAssert(gpu::RenderPass:: + create(m_device, + { .attachments = { { .format = m_swapchain->pixel_format() } }, + .subpasses = { { .bind_point = gpu::PipelineBindPoint::GRAPHICS, + .color_attachment_refs = { { .attachment_id = 0u } } } } }), + "Failed to create render pass"); const auto window_extent = m_window->extent(); @@ -92,27 +91,23 @@ class Application: public base::Application { .shader_state = to_refs(m_vertex_shader, m_fragment_shader), }; - m_pipeline = gpu::Pipeline::create(m_device, state, m_pipeline_layout, m_render_pass) - .transform_error(monadic::assert("Failed to create raster pipeline")) - .value(); + m_pipeline = TryAssert(gpu::Pipeline::create(m_device, state, m_pipeline_layout, m_render_pass), + "Failed to create raster pipeline"); // create present engine resources m_submission_resources = init_by>([&](auto& out) noexcept { out.reserve(BUFFERING_COUNT); for (auto _ : range(BUFFERING_COUNT)) { out.push_back({ - .in_flight = gpu::Fence::create_signaled(m_device) - .transform_error(monadic::assert("Failed to create swapchain image " - "in flight fence")) - .value(), - .image_available = gpu::Semaphore::create(m_device) - .transform_error(monadic::assert("Failed to create " - "present wait semaphore")) - .value(), - .render_cmb = m_command_pool->create_command_buffer() - .transform_error(monadic::assert("Failed to create transition " - "command buffers")) - .value(), + .in_flight = TryAssert(gpu::Fence::create_signaled(m_device), + "Failed to create swapchain image " + "in flight fence"), + .image_available = TryAssert(gpu::Semaphore::create(m_device), + "Failed to create " + "present wait semaphore"), + .render_cmb = TryAssert(m_command_pool->create_command_buffer(), + "Failed to create transition " + "command buffers"), }); } }); @@ -121,57 +116,47 @@ class Application: public base::Application { const auto& images = m_swapchain->images(); const auto image_count = stdr::size(images); - auto transition_cmbs = m_command_pool->create_command_buffers(image_count) - .transform_error(monadic::assert("Failed to create transition command buffers")) - .value(); + auto transition_cmbs = TryAssert(m_command_pool->create_command_buffers(image_count), + "Failed to create transition command buffers"); m_image_resources.reserve(stdr::size(images)); auto image_index = 0u; for (const auto& swap_image : images) { - auto view = gpu::ImageView::create(m_device, swap_image) - .transform_error(core::monadic::assert("Failed to create swapchain image view")) - .value(); - auto framebuffer = m_render_pass->create_frame_buffer(m_device, window_extent, to_refs(view)) - .transform_error(core::monadic::assert(std::format("Failed to create framebuffer for image {}", - image_index))) - .value(); - - m_image_resources.push_back({ - .image = as_ref(swap_image), - .view = std::move(view), - .framebuffer = std::move(framebuffer), - .render_finished = gpu::Semaphore::create(m_device) - .transform_error(core::monadic::assert("Failed to create render " - "signal semaphore")) - .value(), - }); + auto view = TryAssert(gpu::ImageView::create(m_device, swap_image), "Failed to create swapchain image view"); + auto framebuffer = TryAssert(m_render_pass->create_frame_buffer(m_device, window_extent, to_refs(view)), + std::format("Failed to create framebuffer for image {}", image_index)); + + m_image_resources + .push_back({ .image = as_ref(swap_image), + .view = std::move(view), + .framebuffer = std::move(framebuffer), + .render_finished = TryAssert(gpu::Semaphore::create(m_device), + "Failed to create render " + "signal semaphore") }); auto& transition_cmb = transition_cmbs[image_index]; - auto _ = *transition_cmb.begin(true) - .transform_error(monadic::assert("Failed to begin texture transition command buffer")) - .value() - ->begin_debug_region(std::format("transition image {}", image_index)) - .transition_image_layout(swap_image, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::PRESENT_SRC) - .end_debug_region() - .end() - .transform_error(monadic::assert("Failed to begin texture transition command " - "buffer")); + TryAssertDiscard(transition_cmb.begin(true), "Failed to begin texture transition command buffer"); + + transition_cmb.begin_debug_region(std::format("transition image {}", image_index)) + .transition_image_layout(swap_image, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::PRESENT_SRC) + .end_debug_region(); + + TryAssertDiscard(transition_cmb.end(), + "Failed to begin texture transition command " + "buffer"); ++image_index; } - const auto fence = gpu::Fence::create(m_device) - .transform_error(monadic::assert("Failed to create transition fence")) - .value(); + const auto fence = TryAssert(gpu::Fence::create(m_device), "Failed to create transition fence"); const auto cmbs = to_refs(transition_cmbs); - m_raster_queue->submit({ .command_buffers = cmbs }, as_ref(fence)) - .transform_error(monadic::assert("Failed to submit texture transition command buffers")) - .value(); + TryAssert(m_raster_queue->submit({ .command_buffers = cmbs }, as_ref(fence)), + "Failed to submit texture transition command buffers"); // wait for transition to be done - auto _ = fence.wait().transform_error(monadic::assert()); + TryAssert(fence.wait(), ""); } auto run_example() { @@ -183,18 +168,11 @@ class Application: public base::Application { const auto& wait = submission_resource.image_available; auto& in_flight = submission_resource.in_flight; - const auto acquire_next_image = bind_front(&gpu::SwapChain::acquire_next_image, &*m_swapchain, 100ms, std::cref(wait)); - const auto extract_index = [](auto&& _result) static noexcept { - auto&& [result, _image_index] = _result; - return _image_index; - }; + TryAssert(in_flight.wait(), "Failed to wait in_flight fence"); + in_flight.reset(); - const auto image_index = in_flight.wait() - .transform([&in_flight](auto&&) mutable noexcept { in_flight.reset(); }) - .and_then(acquire_next_image) - .transform(extract_index) - .transform_error(monadic::assert("Failed to acquire next swapchain image")) - .value(); + const auto&& [_, image_index] = TryAssert(m_swapchain->acquire_next_image(100ms, wait), + "Failed to acquire next swapchain image"); const auto& swapchain_image_resource = m_image_resources[image_index]; const auto& framebuffer = swapchain_image_resource.framebuffer; @@ -204,32 +182,25 @@ class Application: public base::Application { // render in it auto& render_cmb = submission_resource.render_cmb; - *render_cmb.reset() - .transform_error(monadic::assert("Failed to reset render command buffer")) - .value() - ->begin() - .transform_error(monadic::assert("Failed to begin render command buffer")) - .value() - ->begin_debug_region("Render triangle") - .begin_render_pass(m_render_pass, framebuffer) - .bind_pipeline(m_pipeline) - .draw(3) - .end_render_pass() - .end_debug_region() - .end() - .transform_error(monadic::assert("Failed to end render command buffer")) - .value() - ->submit(m_raster_queue, as_refs(wait), PIPELINE_FLAGS, as_refs(signal), as_ref(in_flight)) - .transform_error(monadic::assert("Failed to submit render command buffer")); + TryAssertDiscard(render_cmb.reset(), "Failed to reset render command buffer"); + TryAssertDiscard(render_cmb.begin(), "Failed to begin render command buffer"); + + render_cmb.begin_debug_region("Render triangle") + .begin_render_pass(m_render_pass, framebuffer) + .bind_pipeline(m_pipeline) + .draw(3) + .end_render_pass() + .end_debug_region(); + + TryAssertDiscard(render_cmb.end(), "Failed to end render command buffer"); + TryAssertDiscard(render_cmb.submit(m_raster_queue, as_refs(wait), PIPELINE_FLAGS, as_refs(signal), as_ref(in_flight)), + "Failed to submit render command buffer"); // present it - auto update_current_frame = [this](auto&&) mutable noexcept { - if (++m_current_frame >= BUFFERING_COUNT) m_current_frame = 0; - }; + TryAssert(m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)), + "Failed to present swapchain image"); - auto _ = m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)) - .transform(update_current_frame) - .transform_error(monadic::assert("Failed to present swapchain image")); + if (++m_current_frame >= BUFFERING_COUNT) m_current_frame = 0; } constexpr auto example_name() const noexcept -> std::string_view { return "Triangle"; } diff --git a/include/stormkit/core/try_expected.hpp b/include/stormkit/core/try_expected.hpp index cd0da9ef5..7d82b0159 100644 --- a/include/stormkit/core/try_expected.hpp +++ b/include/stormkit/core/try_expected.hpp @@ -13,12 +13,34 @@ return std::unexpected { std::move(res).error() }; \ std::move(res).value(); \ }) - #define Ret(x) return x - #define RetErr(x) return std::unexpected { x }; + #define TryOr(m, t) \ + ({ \ + auto res = (m); \ + if (not res.has_value()) [[unlikely]] \ + t(std::move(res).error()); \ + std::move(res).value(); \ + }) + #define TryDiscard(m) \ + ({ \ + auto res = (m).transform(stormkit::core::monadic::discard()); \ + if (not res.has_value()) [[unlikely]] \ + return std::unexpected { std::move(res).error() }; \ + }) + #define TryOrDiscard(m, t) \ + ({ \ + auto res = (m).transform(stormkit::core::monadic::discard()); \ + if (not res.has_value()) [[unlikely]] \ + t(std::move(res).error()); \ + }) + + #define Return return #else - #define Try(x) co_await x - #define Ret(x) co_return x - #define RetErr(x) co_return std::unexpected { x }; + #define Try(m) co_await m + #define TryOr(m, t) co_await t(co_await m) + #define TryDiscard(m) co_await m.transform(stormkit::core::monadic::discard()) + #define TryOrDiscard(m, t) co_await m.transform(stormkit::core::monadic::discard()) + #define Return co_return #endif - +#define TryAssert(m, msg) TryOr(m, stormkit::core::monadic::assert(msg)) +#define TryAssertDiscard(m, msg) TryOrDiscard(m, stormkit::core::monadic::assert(msg)) #endif diff --git a/modules/stormkit/core/utils/filesystem.mpp b/modules/stormkit/core/utils/filesystem.mpp index 3160ca1b4..d3a004abe 100644 --- a/modules/stormkit/core/utils/filesystem.mpp +++ b/modules/stormkit/core/utils/filesystem.mpp @@ -9,6 +9,8 @@ module; #include #include +#include + #ifdef STORMKIT_OS_WINDOWS #include #include @@ -387,10 +389,8 @@ namespace stormkit { inline namespace core { namespace io { template STORMKIT_FORCE_INLINE inline auto read_text_to(const stdfs::path& path, std::span> out) noexcept -> Expected { - return TextFile::open(path, Access::READ).and_then([&out](auto&& file) mutable noexcept { - EXPECTS(file.size() >= stdr::size(out)); - return file.read_to(out); - }); + auto file = Try((TextFile::open(path, Access::READ))); + Return Try(file.read_to(std::span> { out })); } //////////////////////////////////////// @@ -399,24 +399,16 @@ namespace stormkit { inline namespace core { namespace io { STORMKIT_FORCE_INLINE inline auto read_text(const stdfs::path& path) noexcept -> Expected>> { auto out = std::vector> {}; - return TextFile::open(path, Access::READ) - .and_then([&out](auto&& file) mutable noexcept { - out.resize(file.size()); - static_assert(core::meta::Is, decltype(out)>); - return file.read_to(std::span> { out }); - }) - .transform(monadic::discard()) - .transform(monadic::consume(out)); + TryDiscard(read_text_to(path, out)); + return out; } //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE inline auto read_to(const stdfs::path& path, std::span out) noexcept -> Expected { - return File::open(path, Access::READ).and_then([&out](auto&& file) mutable noexcept { - EXPECTS(file.size() >= stdr::size(out)); - return file.read_to(out); - }); + auto file = Try((File::open(path, Access::READ))); + Return Try(file.read_to(std::span { out })); } //////////////////////////////////////// @@ -424,13 +416,8 @@ namespace stormkit { inline namespace core { namespace io { STORMKIT_FORCE_INLINE inline auto read(const stdfs::path& path) noexcept -> Expected> { auto out = std::vector {}; - return File::open(path, Access::READ) - .and_then([&out](auto&& file) mutable noexcept { - out.resize(file.size()); - return file.read_to(out); - }) - .transform(monadic::discard()) - .transform(monadic::consume(out)); + TryDiscard(read_to(path, out)); + return out; } //////////////////////////////////////// @@ -439,13 +426,15 @@ namespace stormkit { inline namespace core { namespace io { STORMKIT_FORCE_INLINE inline auto write_text(const stdfs::path& path, std::span> data) noexcept -> Expected { - return TextFile::open(path, Access::WRITE).and_then(bind_back(&File::write, data)); + auto file = Try((TextFile::open(path, Access::WRITE))); + Return Try(file.write(data)); } //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE inline auto write(const stdfs::path& path, std::span data) noexcept -> Expected { - return File::open(path, Access::WRITE).and_then(std::bind_back(&File::write, data)); + auto file = Try((File::open(path, Access::WRITE))); + Return Try(file.write(data)); } }}} // namespace stormkit::core::io diff --git a/modules/stormkit/gpu/core/sync.mpp b/modules/stormkit/gpu/core/sync.mpp index 540c49d16..ba8e488e1 100644 --- a/modules/stormkit/gpu/core/sync.mpp +++ b/modules/stormkit/gpu/core/sync.mpp @@ -150,14 +150,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Fence::~Fence() - = default; + inline Fence::~Fence() = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Fence::Fence(Fence&&) noexcept - = default; + inline Fence::Fence(Fence&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// @@ -254,14 +252,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Semaphore::~Semaphore() - = default; + inline Semaphore::~Semaphore() = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Semaphore::Semaphore(Semaphore&&) noexcept - = default; + inline Semaphore::Semaphore(Semaphore&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// diff --git a/modules/stormkit/gpu/execution/pipeline.mpp b/modules/stormkit/gpu/execution/pipeline.mpp index 2873d2390..d36959362 100644 --- a/modules/stormkit/gpu/execution/pipeline.mpp +++ b/modules/stormkit/gpu/execution/pipeline.mpp @@ -182,8 +182,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline PipelineCache::PipelineCache(PipelineCache&& other) noexcept - = default; + inline PipelineCache::PipelineCache(PipelineCache&& other) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// @@ -197,7 +196,7 @@ namespace stormkit::gpu { -> LoadSaveExpected { auto cache = PipelineCache { device, std::move(cache_path), PrivateFuncTag {} }; Try(cache.do_init(device)); - Ret(cache); + Return cache; } ///////////////////////////////////// @@ -211,7 +210,7 @@ namespace stormkit::gpu { ///////////////////////////////////// STORMKIT_FORCE_INLINE inline auto PipelineCache::do_init(const Device& device) noexcept -> LoadSaveExpected { - Ret(read_pipeline_cache(device)); + Return read_pipeline_cache(device); } ///////////////////////////////////// @@ -229,14 +228,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline PipelineLayout::~PipelineLayout() noexcept - = default; + inline PipelineLayout::~PipelineLayout() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline PipelineLayout::PipelineLayout(PipelineLayout&& other) noexcept - = default; + inline PipelineLayout::PipelineLayout(PipelineLayout&& other) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// @@ -250,7 +247,7 @@ namespace stormkit::gpu { -> Expected { auto pipeline_layout = PipelineLayout { device, layout, PrivateFuncTag {} }; Try(pipeline_layout.do_init()); - Ret(pipeline_layout); + Return pipeline_layout; } ///////////////////////////////////// @@ -294,7 +291,7 @@ namespace stormkit::gpu { m_vk_handle = Try(vk_call(m_vk_device_table->vkCreatePipelineLayout, m_vk_device, &create_info, nullptr) .transform_error(monadic::from_vk())); - Ret({}); + Return {}; } ///////////////////////////////////// @@ -320,20 +317,18 @@ namespace stormkit::gpu { OptionalRef cache) noexcept -> Expected { auto pipeline = Pipeline { device, state, PrivateFuncTag {} }; Try(pipeline.do_init(layout, render_pass, std::move(cache))); - Ret(pipeline); + Return pipeline; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Pipeline::~Pipeline() noexcept - = default; + inline Pipeline::~Pipeline() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Pipeline::Pipeline(Pipeline&& other) noexcept - = default; + inline Pipeline::Pipeline(Pipeline&& other) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// diff --git a/src/gpu/execution/pipeline_cache.cpp b/src/gpu/execution/pipeline_cache.cpp index 0ff471d92..6e509004f 100644 --- a/src/gpu/execution/pipeline_cache.cpp +++ b/src/gpu/execution/pipeline_cache.cpp @@ -69,13 +69,13 @@ namespace stormkit::gpu { .transform_error(monadic::from_vk()) .transform_error(result_to_load_error)); - Ret({}); + Return {}; } ///////////////////////////////////// ///////////////////////////////////// auto PipelineCache::read_pipeline_cache(const Device& device) noexcept -> LoadSaveExpected { - if (not std::filesystem::exists(m_path)) Ret(create_new_pipeline_cache(device)); + if (not std::filesystem::exists(m_path)) Return create_new_pipeline_cache(device); const auto physical_device_infos = device.physical_device().info(); @@ -87,13 +87,13 @@ namespace stormkit::gpu { if (m_serialized.guard.magic != MAGIC) { elog("Invalid pipeline cache magic number, have {}, expected: {}", m_serialized.guard.magic, MAGIC); - Ret(create_new_pipeline_cache(device)); + Return create_new_pipeline_cache(device); } if (m_serialized.infos.version != VERSION) { elog("Mismatch pipeline cache version, have {}, expected: {}", m_serialized.infos.version, VERSION); - Ret(create_new_pipeline_cache(device)); + Return create_new_pipeline_cache(device); } if (m_serialized.infos.vendor_id != physical_device_infos.vendor_id) { @@ -101,7 +101,7 @@ namespace stormkit::gpu { m_serialized.infos.vendor_id, physical_device_infos.vendor_id); - Ret(create_new_pipeline_cache(device)); + Return create_new_pipeline_cache(device); } if (m_serialized.infos.device_id != physical_device_infos.device_id) { @@ -109,11 +109,11 @@ namespace stormkit::gpu { m_serialized.infos.device_id, physical_device_infos.device_id); - Ret(create_new_pipeline_cache(device)); + Return create_new_pipeline_cache(device); } if (not stdr::equal(m_serialized.uuid.value, physical_device_infos.pipeline_cache_uuid)) { - Ret(create_new_pipeline_cache(device)); + Return create_new_pipeline_cache(device); } auto data = std::vector {}; @@ -133,7 +133,7 @@ namespace stormkit::gpu { .transform_error(monadic::from_vk()) .transform_error(result_to_load_error)); - Ret({}); + Return {}; } ///////////////////////////////////// @@ -153,6 +153,6 @@ namespace stormkit::gpu { Try(file.write(as_bytes(m_serialized.uuid.value)).transform_error(sys_to_load_error)); Try(file.write(as_bytes(data)).transform_error(sys_to_load_error)); - Ret({}); + Return {}; } } // namespace stormkit::gpu From 8f6f60d4cd94034ca490853c044849622b61ff21 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 29 Jan 2026 23:58:58 +0100 Subject: [PATCH 023/194] (core) add reverse method and improve dump (and add tests) for dag class --- modules/stormkit/core/containers/dag.mpp | 73 ++++++++++++++++++++---- tests/core/containers/dag.cpp | 54 ++++++++++++++++++ 2 files changed, 115 insertions(+), 12 deletions(-) diff --git a/modules/stormkit/core/containers/dag.mpp b/modules/stormkit/core/containers/dag.mpp index f196cf910..6a5899916 100644 --- a/modules/stormkit/core/containers/dag.mpp +++ b/modules/stormkit/core/containers/dag.mpp @@ -48,8 +48,19 @@ export namespace stormkit { inline namespace core { template class DAG { public: - using Vertex = dag::Vertex; - using ColorizeFunc = FunctionRef; + using Vertex = dag::Vertex; + using ColorizeClosure = FunctionRef; + using FormatValueClosure = FunctionRef; + + struct Closures { + std::optional colorize = std::nullopt; + std::optional format_value = []() static noexcept -> std::optional { + if constexpr (std::formattable) + return [](const auto& value) static noexcept { return std::format("{}", value); }; + else + return std::nullopt; + }(); + }; struct Directed {}; @@ -97,7 +108,10 @@ export namespace stormkit { inline namespace core { constexpr auto topological_sort() const noexcept -> std::expected, std::vector>; constexpr auto find_cycle() const noexcept -> std::optional>; - constexpr auto dump(ColorizeFunc colorize = [](const auto&) { return "white"; }) const noexcept -> std::string; + constexpr auto reverse() const noexcept -> DAG>; + constexpr auto reverse_clone() const noexcept -> DAG; + + constexpr auto dump(Closures closures = {}) const noexcept -> std::string; private: bool m_directed; @@ -522,18 +536,53 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - constexpr auto DAG::dump(ColorizeFunc colorize) const noexcept -> std::string { - auto out = std::string { "digraph G { \n" + constexpr auto DAG::reverse() const noexcept -> DAG> { + auto out = DAG>(dag::DIRECTED, stdr::size(m_vertices)); + + for (auto&& [_, vertice] : m_vertices) out.add_vertex(as_ref(vertice)); + + for (auto&& [from, to] : m_edges) out.add_edge(to, from); + + return out; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr auto DAG::reverse_clone() const noexcept -> DAG { + auto out = DAG>(dag::DIRECTED, stdr::size(m_vertices)); + + for (auto&& [_, vertice] : m_vertices) out.add_vertex(vertice); + + for (auto&& [from, to] : m_edges) out.add_edge(to, from); + + return out; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr auto DAG::dump(Closures closures) const noexcept -> std::string { + auto out = std::string { "digraph G {\n" " rankdir = LR\n" - " bgcolor = black\n\n" + " bgcolor = black\n" " node [shape=box, fontname=\"helvetica\", fontsize=12];\n\n" }; - for (const auto& [id, value] : m_vertices) - out += std::format(" \"node{}\" [label=\"id: {} value: {} \", style=filled,color=\"{}\"];\n", - id, - id, - value, - colorize(value)); + if (closures.format_value) + for (const auto& [id, value] : m_vertices) { + out += std::format(" \"node{}\" [label=\"id: {} value: {}\", style=filled,color=\"{}\"];\n", + id, + id, + closures.format_value.value()(value), + closures.colorize ? closures.colorize.value()(value) : "white"); + } + else + for (const auto& [id, value] : m_vertices) { + out += std::format(" \"node{}\" [label=\"id: {}\", style=filled,color=\"{}\"];\n", + id, + id, + closures.colorize ? closures.colorize.value()(value) : "white"); + } for (const auto& [from, to] : m_edges) out += std::format(" \"node{}\" -> \"node{}\" [color=seagreen];\n", from, to); diff --git a/tests/core/containers/dag.cpp b/tests/core/containers/dag.cpp index 694ef0d66..496e92728 100644 --- a/tests/core/containers/dag.cpp +++ b/tests/core/containers/dag.cpp @@ -130,6 +130,60 @@ namespace { EXPECTS(not result.has_value()); } } }, + { "reverse", + [] { + auto dag = DAG { dag::DIRECTED }; + dag.emplace_vertex("a"); + dag.emplace_vertex("b"); + dag.emplace_vertex("c"); + dag.emplace_vertex("d"); + + dag.add_edge(0, 1); + dag.add_edge(1, 2); + dag.add_edge(2, 3); + dag.add_edge(0, 3); + + auto reversed = dag.reverse(); + + const auto& edges = dag.edges(); + const auto& redges = reversed.edges(); + + for (auto i : range(4u)) { + const auto [from, to] = edges[i]; + const auto [rfrom, rto] = redges[i]; + EXPECTS(from == rto and rfrom == to); + } + } }, + { "dump", + [] { + auto dag = DAG { dag::DIRECTED }; + dag.emplace_vertex("a"); + dag.emplace_vertex("b"); + dag.emplace_vertex("c"); + dag.emplace_vertex("d"); + + dag.add_edge(0, 1); + dag.add_edge(1, 2); + dag.add_edge(2, 3); + dag.add_edge(0, 3); + + const auto required_result = "digraph G {\n" + " rankdir = LR\n" + " bgcolor = black\n" + " node [shape=box, fontname=\"helvetica\", fontsize=12];\n\n" + " \"node0\" [label=\"id: 0 value: a\", style=filled,color=\"white\"];\n" + " \"node1\" [label=\"id: 1 value: b\", style=filled,color=\"white\"];\n" + " \"node2\" [label=\"id: 2 value: c\", style=filled,color=\"white\"];\n" + " \"node3\" [label=\"id: 3 value: d\", style=filled,color=\"white\"];\n" + " \"node0\" -> \"node1\" [color=seagreen];\n" + " \"node1\" -> \"node2\" [color=seagreen];\n" + " \"node2\" -> \"node3\" [color=seagreen];\n" + " \"node0\" -> \"node3\" [color=seagreen];\n" + "}"sv; + + const auto out = dag.dump(); + EXPECTS(out == required_result); + } }, } }; } // namespace From d9d9b5f0316d9159e8a02ab209a8120c65d41c09 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 29 Jan 2026 23:59:09 +0100 Subject: [PATCH 024/194] (gpu) enable api dump validation layer --- src/gpu/core/instance.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/gpu/core/instance.cpp b/src/gpu/core/instance.cpp index ec0d1bf5e..de7d420d4 100644 --- a/src/gpu/core/instance.cpp +++ b/src/gpu/core/instance.cpp @@ -27,7 +27,7 @@ namespace stormkit::gpu { namespace { constexpr auto VALIDATION_LAYERS = std::array { "VK_LAYER_KHRONOS_validation", - // "VK_LAYER_LUNARG_api_dump", + "VK_LAYER_LUNARG_api_dump", "VK_LAYER_LUNARG_monitor", }; constexpr auto OPTIONAL_VALIDATION_LAYERS = std::array { @@ -35,11 +35,10 @@ namespace stormkit::gpu { }; [[maybe_unused]] - constexpr auto VALIDATION_FEATURES - = std::array { - VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT, - VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT, - }; + constexpr auto VALIDATION_FEATURES = std::array { + VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT, + VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT, + }; constexpr auto STORMKIT_VK_VERSION = vk_make_version(STORMKIT_MAJOR_VERSION, STORMKIT_MINOR_VERSION, From 524eedd8a424e8900eb3a435e832078b8aa0c1c1 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 29 Jan 2026 23:59:16 +0100 Subject: [PATCH 025/194] (core) fix ref class --- modules/stormkit/core/typesafe/ref.mpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/modules/stormkit/core/typesafe/ref.mpp b/modules/stormkit/core/typesafe/ref.mpp index 38b49245e..7be835ad3 100644 --- a/modules/stormkit/core/typesafe/ref.mpp +++ b/modules/stormkit/core/typesafe/ref.mpp @@ -29,8 +29,7 @@ export { using ptr = T*; template - class [[nodiscard]] - Ref { + class Ref { public: using ElementType = T; using ReferenceType = ElementType&; @@ -332,8 +331,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr Ref::~Ref() noexcept - = default; + constexpr Ref::~Ref() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// @@ -486,7 +484,7 @@ namespace stormkit { inline namespace core { template STORMKIT_FORCE_INLINE constexpr auto Ref::operator==(const Ref& other) const noexcept -> bool { - return m_value == other.value(); + return m_value == other.m_value; } ///////////////////////////////////// From de81be2057d587d12593ab814f5a175a121e1ab1 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 29 Jan 2026 23:59:27 +0100 Subject: [PATCH 026/194] (core) improve hash support --- modules/stormkit/core/hash/base.mpp | 99 +++++++++++++++++++------ modules/stormkit/core/meta/concepts.mpp | 2 +- 2 files changed, 76 insertions(+), 25 deletions(-) diff --git a/modules/stormkit/core/hash/base.mpp b/modules/stormkit/core/hash/base.mpp index ea676d52f..bea9833d4 100644 --- a/modules/stormkit/core/hash/base.mpp +++ b/modules/stormkit/core/hash/base.mpp @@ -2,6 +2,10 @@ // This file is subject to the license terms in the LICENSE file // found in the top-level of this distribution +module; + +#include + export module stormkit.core:hash.base; import std; @@ -12,18 +16,38 @@ export namespace stormkit { inline namespace core { using hash32 = std::uint32_t; using hash64 = std::uint64_t; - template - concept HashValue = meta::IsOneOf; + namespace meta { + template + concept HashValue = meta::IsOneOf; + } + + template + constexpr auto hasher(const T& value) noexcept -> Ret = delete; + + namespace meta { + template + concept HasHasher = requires(T&& value) { + { hasher(std::forward(value)) } -> meta::HashValue; + }; + } // namespace meta - template - constexpr auto hash_combine(auto&& value) -> OutputType; + template + constexpr auto hash(T&& value) noexcept -> Ret; - template - constexpr auto hash_combine(HashValue auto& hash, T&& range) noexcept; + template + requires(sizeof(T) <= sizeof(Ret)) + constexpr auto hasher(T value) noexcept -> Ret; - template + template + requires(sizeof(T) <= sizeof(Ret)) + constexpr auto hasher(T value) noexcept -> Ret; + + template + constexpr auto hash_combine(Ret& hash, T&& range) noexcept -> void; + + template requires(sizeof...(Args) > 1) - constexpr auto hash_combine(HashValue auto& hash, Args&&... args) noexcept; + constexpr auto hash_combine(Ret& hash, Args&&... args) noexcept -> void; }} // namespace stormkit::core //////////////////////////////////////////////////////////////////// @@ -31,33 +55,60 @@ export namespace stormkit { inline namespace core { //////////////////////////////////////////////////////////////////// namespace stormkit { inline namespace core { - template - constexpr auto hash_combine(auto&& value) -> OutputType { - auto hash = OutputType { 0u }; - hash_combine(hash, std::forward(value)); - - return hash; - } + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE STORMKIT_PURE + constexpr auto hash(T&& value) noexcept -> Ret { + static_assert(meta::HasHasher or meta::HasStdHashSpecialization, "No hasher or std::hash specialization!"); - template - constexpr auto hash_combine(HashValue auto& hash, T&& value) noexcept { - if constexpr (std::ranges::range) - for (auto&& elem : value) hash_combine(hash, elem); + if constexpr (meta::HasHasher) return hasher(std::forward(value)); else { const auto hasher = std::hash> {}; - hash ^= hasher(std::forward(value)) + 0x9e3779b9 + (hash << 6) + (hash >> 2); + return static_cast(hasher(std::forward(value))); } } - template + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(sizeof(T) <= sizeof(Ret)) + STORMKIT_FORCE_INLINE STORMKIT_PURE + constexpr auto hasher(T value) noexcept -> Ret { + return static_cast(value); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(sizeof(T) <= sizeof(Ret)) + STORMKIT_FORCE_INLINE STORMKIT_PURE + constexpr auto hasher(T value) noexcept -> Ret { + return static_cast(value); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto hash_combine(Ret& out, T&& value) noexcept -> void { + if constexpr (std::ranges::range) + for (auto&& elem : value) hash_combine(out, elem); + else { out ^= hash(std::forward(value)) + 0x9e3779b9 + (out << 6) + (out >> 2); } + } + + ///////////////////////////////////// + ///////////////////////////////////// + template requires(sizeof...(Args) > 1) - constexpr auto hash_combine(HashValue auto& hash, Args&&... args) noexcept { + STORMKIT_FORCE_INLINE + constexpr auto hash_combine(Ret& out, Args&&... args) noexcept -> void { #if defined(__cpp_expansion_statements) and __cpp_expansion_statements >= 202500L template for (constexpr auto elem : { std::forward(args)... }) - hash_combine(hash, std::forward(elem)); + hash_combine(out, std::forward(elem)); #else - (hash_combine(hash, std::forward(args)), ...); + (hash_combine(out, std::forward(args)), ...); #endif } }} // namespace stormkit::core diff --git a/modules/stormkit/core/meta/concepts.mpp b/modules/stormkit/core/meta/concepts.mpp index 68c0a5fa4..3ac2ee44c 100644 --- a/modules/stormkit/core/meta/concepts.mpp +++ b/modules/stormkit/core/meta/concepts.mpp @@ -66,7 +66,7 @@ export namespace stormkit { inline namespace core { namespace meta { concept IsConvertibleTo = std::convertible_to; template - concept IsHashable = requires(std::remove_cvref_t& a) { std::hash> {}(a); }; + concept HasStdHashSpecialization = requires(T&& a) { std::hash> {}(std::forward(a)); }; template concept IsCanonical = IsStrict, std::remove_cvref_t>; From aab4817276770b494ce2976eb2b2d2bc22a95835 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 30 Jan 2026 22:01:48 +0100 Subject: [PATCH 027/194] (core) fix math::rect::extent() --- modules/stormkit/core/math/geometry.mpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stormkit/core/math/geometry.mpp b/modules/stormkit/core/math/geometry.mpp index 737f00310..9327625d3 100644 --- a/modules/stormkit/core/math/geometry.mpp +++ b/modules/stormkit/core/math/geometry.mpp @@ -89,7 +89,7 @@ namespace stormkit { inline namespace core { namespace math { template STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto rect::extent() const noexcept -> Extent2 { - return { width, height }; + return { width.value, height.value }; } //////////////////////////////////////// From ecc8a29836f3f9bfcfd5c6ea5521660a1cb5b80e Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 30 Jan 2026 22:02:01 +0100 Subject: [PATCH 028/194] (core) fix io read operations --- modules/stormkit/core/utils/filesystem.mpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/modules/stormkit/core/utils/filesystem.mpp b/modules/stormkit/core/utils/filesystem.mpp index d3a004abe..868fa4466 100644 --- a/modules/stormkit/core/utils/filesystem.mpp +++ b/modules/stormkit/core/utils/filesystem.mpp @@ -398,9 +398,11 @@ namespace stormkit { inline namespace core { namespace io { template STORMKIT_FORCE_INLINE inline auto read_text(const stdfs::path& path) noexcept -> Expected>> { - auto out = std::vector> {}; - TryDiscard(read_text_to(path, out)); - return out; + auto file = Try((TextFile::open(path, Access::READ))); + auto out = std::vector> {}; + out.resize(file.size()); + TryDiscard(file.read_to(std::span> { out })); + Return out; } //////////////////////////////////////// @@ -415,9 +417,11 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// STORMKIT_FORCE_INLINE inline auto read(const stdfs::path& path) noexcept -> Expected> { - auto out = std::vector {}; - TryDiscard(read_to(path, out)); - return out; + auto file = Try((File::open(path, Access::READ))); + auto out = std::vector {}; + out.resize(file.size()); + TryDiscard(file.read_to(std::span { out })); + Return out; } //////////////////////////////////////// From 26b83a85a287419c4ae3d1c81bf787b776daec2a Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 30 Jan 2026 22:02:24 +0100 Subject: [PATCH 029/194] (core) add missing <=> operations with std::nullopt for ref --- modules/stormkit/core/typesafe/ref.mpp | 62 ++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/modules/stormkit/core/typesafe/ref.mpp b/modules/stormkit/core/typesafe/ref.mpp index 7be835ad3..1a63a4776 100644 --- a/modules/stormkit/core/typesafe/ref.mpp +++ b/modules/stormkit/core/typesafe/ref.mpp @@ -478,6 +478,68 @@ namespace stormkit { inline namespace core { return std::compare_three_way {}(m_value, static_cast::pointer>(nullptr)); } + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto Ref::operator==(std::nullopt_t) const noexcept -> bool + requires(Optional == true) + { + return !m_value; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto Ref::operator<(std::nullopt_t) const noexcept -> bool + requires(Optional == true) + { + return std::less::pointer> {}(m_value, std::nullopt); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto Ref::operator<=(std::nullopt_t) const noexcept -> bool + requires(Optional == true) + { + return !(std::nullopt < *this); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto Ref::operator>(std::nullopt_t) const noexcept -> bool + requires(Optional == true) + { + return std::nullopt < *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto Ref::operator>=(std::nullopt_t) const noexcept -> bool + requires(Optional == true) + { + return !(*this < std::nullopt); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto Ref::operator<=>(std::nullopt_t) const noexcept + -> std::compare_three_way_result_t::PointerType, typename Ref::PointerType> + requires(std::three_way_comparable::PointerType, typename Ref::PointerType> + and Optional == true) + { + return std::compare_three_way {}(m_value, static_cast::pointer>(std::nullopt)); + } + ///////////////////////////////////// ///////////////////////////////////// template From c6a331527285cd48ea5df7f76aef424afd3a92f1 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 30 Jan 2026 22:02:37 +0100 Subject: [PATCH 030/194] (terra) update to latest stormkit api --- tools/terra/src/main.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/tools/terra/src/main.cpp b/tools/terra/src/main.cpp index f400b0665..5e1eb116b 100644 --- a/tools/terra/src/main.cpp +++ b/tools/terra/src/main.cpp @@ -4,6 +4,8 @@ import stormkit.core; #include +#include + namespace stdr = std::ranges; namespace stdfs = std::filesystem; @@ -21,9 +23,7 @@ auto main(const std::span args) noexcept -> int { std::println(get_stderr(), "Template file {} doesn't exists", template_path.c_str()); return -1; } else if (not stdfs::is_regular_file(template_path)) { - std::println(get_stderr(), - "Template file {} path is not a regular file", - template_path.c_str()); + std::println(get_stderr(), "Template file {} path is not a regular file", template_path.c_str()); return -1; } @@ -32,12 +32,8 @@ auto main(const std::span args) noexcept -> int { return stdfs::path { args[2] }; }(); - const auto - template_data = io::readfile(io::text_file_tag, template_path) - .transform_error(monadic:: - assert(std::format("Failed to read file {}, reason: ", - template_path.c_str()))) - .value(); + const auto template_data = TryAssert(io::read_text(template_path), + std::format("Failed to read file {}, reason: ", template_path.c_str())); auto out = std::string {}; out.reserve(stdr::size(template_data)); @@ -75,8 +71,7 @@ outfile = io.open("{}", "w") buff.clear(); last_char_was_bracket = false; } else { - if (c == '{' and i + 1 < stdr::size(template_data) and template_data[i + 1] == '%') - last_char_was_bracket = true; + if (c == '{' and i + 1 < stdr::size(template_data) and template_data[i + 1] == '%') last_char_was_bracket = true; else buff.emplace_back(c); } @@ -92,7 +87,7 @@ outfile = io.open("{}", "w") out += "\\x" + str_char; } - out += "\")"; + out += "\")\n"; out += "outfile:close()"; std::println("{}", out); From e4224d41a3a5d93fdb7d3c9036dcf2bfa31f77e4 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 30 Jan 2026 22:45:04 +0100 Subject: [PATCH 031/194] (gpu) implement dynamic rendering --- examples/gpu/triangle/src/main.cpp | 44 +- modules/stormkit/gpu/core/vulkan/enums.mpp | 5375 ++++++++--------- modules/stormkit/gpu/core/vulkan/mapping.json | 680 ++- modules/stormkit/gpu/core/vulkan/structs.mpp | 12 + .../stormkit/gpu/execution/command_buffer.mpp | 58 +- modules/stormkit/gpu/execution/pipeline.mpp | 28 +- .../gpu/execution/raster_pipeline.mpp | 7 + src/gpu/core/device.cpp | 64 +- src/gpu/core/instance.cpp | 4 +- src/gpu/execution/command_buffer.cpp | 118 +- src/gpu/execution/pipeline.cpp | 42 +- xmake/rules/stormkit_flags.xmake.lua | 6 - 12 files changed, 3309 insertions(+), 3129 deletions(-) diff --git a/examples/gpu/triangle/src/main.cpp b/examples/gpu/triangle/src/main.cpp index cfae721e1..01176d0bb 100644 --- a/examples/gpu/triangle/src/main.cpp +++ b/examples/gpu/triangle/src/main.cpp @@ -34,7 +34,6 @@ struct SubmissionResource { struct SwapchainImageResource { Ref image; gpu::ImageView view; - gpu::FrameBuffer framebuffer; gpu::Semaphore render_finished; }; @@ -56,14 +55,6 @@ class Application: public base::Application { m_pipeline_layout = TryAssert(gpu::PipelineLayout::create(m_device, {}), "Failed to create pipeline layout"); - // initialize render pass - m_render_pass = TryAssert(gpu::RenderPass:: - create(m_device, - { .attachments = { { .format = m_swapchain->pixel_format() } }, - .subpasses = { { .bind_point = gpu::PipelineBindPoint::GRAPHICS, - .color_attachment_refs = { { .attachment_id = 0u } } } } }), - "Failed to create render pass"); - const auto window_extent = m_window->extent(); // initialize render pipeline @@ -91,7 +82,11 @@ class Application: public base::Application { .shader_state = to_refs(m_vertex_shader, m_fragment_shader), }; - m_pipeline = TryAssert(gpu::Pipeline::create(m_device, state, m_pipeline_layout, m_render_pass), + const auto rendering_info = gpu::RasterPipelineRenderingInfo { + .color_attachment_formats = { m_swapchain->pixel_format() } + }; + + m_pipeline = TryAssert(gpu::Pipeline::create(m_device, state, m_pipeline_layout, rendering_info), "Failed to create raster pipeline"); // create present engine resources @@ -122,14 +117,11 @@ class Application: public base::Application { auto image_index = 0u; for (const auto& swap_image : images) { - auto view = TryAssert(gpu::ImageView::create(m_device, swap_image), "Failed to create swapchain image view"); - auto framebuffer = TryAssert(m_render_pass->create_frame_buffer(m_device, window_extent, to_refs(view)), - std::format("Failed to create framebuffer for image {}", image_index)); + auto view = TryAssert(gpu::ImageView::create(m_device, swap_image), "Failed to create swapchain image view"); m_image_resources .push_back({ .image = as_ref(swap_image), .view = std::move(view), - .framebuffer = std::move(framebuffer), .render_finished = TryAssert(gpu::Semaphore::create(m_device), "Failed to create render " "signal semaphore") }); @@ -175,7 +167,6 @@ class Application: public base::Application { "Failed to acquire next swapchain image"); const auto& swapchain_image_resource = m_image_resources[image_index]; - const auto& framebuffer = swapchain_image_resource.framebuffer; const auto& signal = swapchain_image_resource.render_finished; static constexpr auto PIPELINE_FLAGS = std::array { gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT }; @@ -185,12 +176,27 @@ class Application: public base::Application { TryAssertDiscard(render_cmb.reset(), "Failed to reset render command buffer"); TryAssertDiscard(render_cmb.begin(), "Failed to begin render command buffer"); - render_cmb.begin_debug_region("Render triangle") - .begin_render_pass(m_render_pass, framebuffer) + const auto window_extent = m_window->extent().to(); + const auto rendering_info = gpu::RenderingInfo { + .render_area = { .x = 0, .y = 0, .width = window_extent.width, .height = window_extent.height }, + .color_attachments = { { .image_view = as_ref(swapchain_image_resource.view), + .layout = gpu::ImageLayout::ATTACHMENT_OPTIMAL, + .clear_value = gpu::ClearColor { .color = RGBColorDef::SILVER } } } + }; + + render_cmb + .transition_image_layout(swapchain_image_resource.image, + gpu::ImageLayout::PRESENT_SRC, + gpu::ImageLayout::ATTACHMENT_OPTIMAL) + .begin_debug_region("Render triangle") + .begin_rendering(rendering_info) .bind_pipeline(m_pipeline) .draw(3) - .end_render_pass() - .end_debug_region(); + .end_rendering() + .end_debug_region() + .transition_image_layout(swapchain_image_resource.image, + gpu::ImageLayout::ATTACHMENT_OPTIMAL, + gpu::ImageLayout::PRESENT_SRC); TryAssertDiscard(render_cmb.end(), "Failed to end render command buffer"); TryAssertDiscard(render_cmb.submit(m_raster_queue, as_refs(wait), PIPELINE_FLAGS, as_refs(signal), as_ref(in_flight)), diff --git a/modules/stormkit/gpu/core/vulkan/enums.mpp b/modules/stormkit/gpu/core/vulkan/enums.mpp index fdc31b94c..00a2c2043 100644 --- a/modules/stormkit/gpu/core/vulkan/enums.mpp +++ b/modules/stormkit/gpu/core/vulkan/enums.mpp @@ -4,8 +4,8 @@ module; -#include #include +#include #include @@ -16,10 +16,11 @@ import stormkit.core; import :vulkan.volk; + export { namespace stormkit::gpu { namespace details { - template + template inline constexpr auto IS_VULKAN_ENUMERATION = false; } @@ -29,711 +30,768 @@ export { } inline constexpr auto QUEUE_FAMILY_IGNORED = std::numeric_limits::max(); - + enum class AccessFlag : u32 { - COLOR_ATTACHMENT_READ = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, - COLOR_ATTACHMENT_WRITE = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - DEPTH_STENCIL_ATTACHMENT_READ = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, - DEPTH_STENCIL_ATTACHMENT_WRITE = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - HOST_READ = VK_ACCESS_HOST_READ_BIT, - HOST_WRITE = VK_ACCESS_HOST_WRITE_BIT, - INDIRECT_COMMAND_READ = VK_ACCESS_INDIRECT_COMMAND_READ_BIT, - INPUT_ATTACHMENT_READ = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, - MEMORY_READ = VK_ACCESS_MEMORY_READ_BIT, - MEMORY_WRITE = VK_ACCESS_MEMORY_WRITE_BIT, - NONE = 0, - SHADER_READ = VK_ACCESS_SHADER_READ_BIT, - SHADER_WRITE = VK_ACCESS_SHADER_WRITE_BIT, - TRANSFER_READ = VK_ACCESS_TRANSFER_READ_BIT, - TRANSFER_WRITE = VK_ACCESS_TRANSFER_WRITE_BIT, - UNIFORM_READ = VK_ACCESS_UNIFORM_READ_BIT, - VERTEX_ATTRIBUTE_READ = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, - }; - - template<> + COLOR_ATTACHMENT_READ = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, + COLOR_ATTACHMENT_WRITE = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + DEPTH_STENCIL_ATTACHMENT_READ = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, + DEPTH_STENCIL_ATTACHMENT_WRITE = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + HOST_READ = VK_ACCESS_HOST_READ_BIT, + HOST_WRITE = VK_ACCESS_HOST_WRITE_BIT, + INDIRECT_COMMAND_READ = VK_ACCESS_INDIRECT_COMMAND_READ_BIT, + INPUT_ATTACHMENT_READ = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, + MEMORY_READ = VK_ACCESS_MEMORY_READ_BIT, + MEMORY_WRITE = VK_ACCESS_MEMORY_WRITE_BIT, + NONE = 0, + SHADER_READ = VK_ACCESS_SHADER_READ_BIT, + SHADER_WRITE = VK_ACCESS_SHADER_WRITE_BIT, + TRANSFER_READ = VK_ACCESS_TRANSFER_READ_BIT, + TRANSFER_WRITE = VK_ACCESS_TRANSFER_WRITE_BIT, + UNIFORM_READ = VK_ACCESS_UNIFORM_READ_BIT, + VERTEX_ATTRIBUTE_READ = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class AttachmentLoadOperation : u8 { - CLEAR = VK_ATTACHMENT_LOAD_OP_CLEAR, - DONT_CARE = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - LOAD = VK_ATTACHMENT_LOAD_OP_LOAD, + CLEAR = VK_ATTACHMENT_LOAD_OP_CLEAR, + DONT_CARE = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + LOAD = VK_ATTACHMENT_LOAD_OP_LOAD, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class AttachmentStoreOperation : u8 { - DONT_CARE = VK_ATTACHMENT_STORE_OP_DONT_CARE, - STORE = VK_ATTACHMENT_STORE_OP_STORE, + DONT_CARE = VK_ATTACHMENT_STORE_OP_DONT_CARE, + STORE = VK_ATTACHMENT_STORE_OP_STORE, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class BlendFactor : u8 { - CONSTANT_ALPHA = VK_BLEND_FACTOR_CONSTANT_ALPHA, - CONSTANT_COLOR = VK_BLEND_FACTOR_CONSTANT_COLOR, - DST_ALPHA = VK_BLEND_FACTOR_DST_ALPHA, - DST_COLOR = VK_BLEND_FACTOR_DST_COLOR, - ONE = VK_BLEND_FACTOR_ONE, - ONE_MINUS_CONSTANT_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA, - ONE_MINUS_CONSTANT_COLOR = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, - ONE_MINUS_DST_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, - ONE_MINUS_DST_COLOR = VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, - ONE_MINUS_SRC1_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, - ONE_MINUS_SRC1_COLOR = VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, - ONE_MINUS_SRC_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, - ONE_MINUS_SRC_COLOR = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, - SRC1_ALPHA = VK_BLEND_FACTOR_SRC1_ALPHA, - SRC1_COLOR = VK_BLEND_FACTOR_SRC1_COLOR, - SRC_ALPHA = VK_BLEND_FACTOR_SRC_ALPHA, - SRC_ALPHA_SATURATE = VK_BLEND_FACTOR_SRC_ALPHA_SATURATE, - SRC_COLOR = VK_BLEND_FACTOR_SRC_COLOR, - ZERO = VK_BLEND_FACTOR_ZERO, - }; - - template<> + CONSTANT_ALPHA = VK_BLEND_FACTOR_CONSTANT_ALPHA, + CONSTANT_COLOR = VK_BLEND_FACTOR_CONSTANT_COLOR, + DST_ALPHA = VK_BLEND_FACTOR_DST_ALPHA, + DST_COLOR = VK_BLEND_FACTOR_DST_COLOR, + ONE = VK_BLEND_FACTOR_ONE, + ONE_MINUS_CONSTANT_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA, + ONE_MINUS_CONSTANT_COLOR = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, + ONE_MINUS_DST_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, + ONE_MINUS_DST_COLOR = VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, + ONE_MINUS_SRC1_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, + ONE_MINUS_SRC1_COLOR = VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, + ONE_MINUS_SRC_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + ONE_MINUS_SRC_COLOR = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, + SRC1_ALPHA = VK_BLEND_FACTOR_SRC1_ALPHA, + SRC1_COLOR = VK_BLEND_FACTOR_SRC1_COLOR, + SRC_ALPHA = VK_BLEND_FACTOR_SRC_ALPHA, + SRC_ALPHA_SATURATE = VK_BLEND_FACTOR_SRC_ALPHA_SATURATE, + SRC_COLOR = VK_BLEND_FACTOR_SRC_COLOR, + ZERO = VK_BLEND_FACTOR_ZERO, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class BlendOperation : u8 { - ADD = VK_BLEND_OP_ADD, - MAX = VK_BLEND_OP_MAX, - MIN = VK_BLEND_OP_MIN, - REVERSE_SUBTRACT = VK_BLEND_OP_REVERSE_SUBTRACT, - SUBTRACT = VK_BLEND_OP_SUBTRACT, + ADD = VK_BLEND_OP_ADD, + MAX = VK_BLEND_OP_MAX, + MIN = VK_BLEND_OP_MIN, + REVERSE_SUBTRACT = VK_BLEND_OP_REVERSE_SUBTRACT, + SUBTRACT = VK_BLEND_OP_SUBTRACT, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class BorderColor : u8 { - FLOAT_OPAQUE_BLACK = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK, - FLOAT_OPAQUE_WHITE = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE, - FLOAT_TRANSPARENT_BLACK = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, - INT_OPAQUE_BLACK = VK_BORDER_COLOR_INT_OPAQUE_BLACK, - INT_OPAQUE_WHITE = VK_BORDER_COLOR_INT_OPAQUE_WHITE, - INT_TRANSPARENT_BLACK = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK, + FLOAT_OPAQUE_BLACK = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK, + FLOAT_OPAQUE_WHITE = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE, + FLOAT_TRANSPARENT_BLACK = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, + INT_OPAQUE_BLACK = VK_BORDER_COLOR_INT_OPAQUE_BLACK, + INT_OPAQUE_WHITE = VK_BORDER_COLOR_INT_OPAQUE_WHITE, + INT_TRANSPARENT_BLACK = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class BufferUsageFlag : u16 { - INDEX = VK_BUFFER_USAGE_INDEX_BUFFER_BIT, - INDIRECT = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, - STORAGE = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, - STORAGE_TEXEL = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, - TRANSFER_DST = VK_BUFFER_USAGE_TRANSFER_DST_BIT, - TRANSFER_SRC = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - UNIFORM = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, - UNIFORM_TEXEL = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, - VERTEX = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, - }; - - template<> + INDEX = VK_BUFFER_USAGE_INDEX_BUFFER_BIT, + INDIRECT = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, + STORAGE = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, + STORAGE_TEXEL = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, + TRANSFER_DST = VK_BUFFER_USAGE_TRANSFER_DST_BIT, + TRANSFER_SRC = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + UNIFORM = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + UNIFORM_TEXEL = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, + VERTEX = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ColorComponentFlag : u8 { - A = VK_COLOR_COMPONENT_A_BIT, - B = VK_COLOR_COMPONENT_B_BIT, - G = VK_COLOR_COMPONENT_G_BIT, - NONE = 0, - R = VK_COLOR_COMPONENT_R_BIT, - RG = R | G, - RGB = RG | B, - RGBA = RGB | A, - }; - - template<> + A = VK_COLOR_COMPONENT_A_BIT, + B = VK_COLOR_COMPONENT_B_BIT, + G = VK_COLOR_COMPONENT_G_BIT, + NONE = 0, + R = VK_COLOR_COMPONENT_R_BIT, + RG = R | G, + RGB = RG | B, + RGBA = RGB | A, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ColorSpace : u32 { - ADOBERGB_LINEAR = VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT, - ADOBERGB_NONLINEAR = VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT, - BT2020_LINEAR = VK_COLOR_SPACE_BT2020_LINEAR_EXT, - BT709_LINEAR = VK_COLOR_SPACE_BT709_LINEAR_EXT, - BT709_NONLINEAR = VK_COLOR_SPACE_BT709_NONLINEAR_EXT, - DCI_P3_NONLINEAR = VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT, - DISPLAY_NATIVE_AMD = VK_COLOR_SPACE_DISPLAY_NATIVE_AMD, - DISPLAY_P3_LINEAR = VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT, - DISPLAY_P3_NONLINEAR = VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT, - DOLBYVISION = VK_COLOR_SPACE_DOLBYVISION_EXT, - EXTENDED_SRGB_LINEAR = VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT, - EXTENDED_SRGB_NONLINEAR = VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT, - HDR10_HLG = VK_COLOR_SPACE_HDR10_HLG_EXT, - HDR10_ST2084 = VK_COLOR_SPACE_HDR10_ST2084_EXT, - PASS_THROUGH = VK_COLOR_SPACE_PASS_THROUGH_EXT, - SRGB_NONLINEAR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, - }; - - template<> + ADOBERGB_LINEAR = VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT, + ADOBERGB_NONLINEAR = VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT, + BT2020_LINEAR = VK_COLOR_SPACE_BT2020_LINEAR_EXT, + BT709_LINEAR = VK_COLOR_SPACE_BT709_LINEAR_EXT, + BT709_NONLINEAR = VK_COLOR_SPACE_BT709_NONLINEAR_EXT, + DCI_P3_NONLINEAR = VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT, + DISPLAY_NATIVE_AMD = VK_COLOR_SPACE_DISPLAY_NATIVE_AMD, + DISPLAY_P3_LINEAR = VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT, + DISPLAY_P3_NONLINEAR = VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT, + DOLBYVISION = VK_COLOR_SPACE_DOLBYVISION_EXT, + EXTENDED_SRGB_LINEAR = VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT, + EXTENDED_SRGB_NONLINEAR = VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT, + HDR10_HLG = VK_COLOR_SPACE_HDR10_HLG_EXT, + HDR10_ST2084 = VK_COLOR_SPACE_HDR10_ST2084_EXT, + PASS_THROUGH = VK_COLOR_SPACE_PASS_THROUGH_EXT, + SRGB_NONLINEAR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class CommandBufferLevel : u8 { - PRIMARY = VK_COMMAND_BUFFER_LEVEL_PRIMARY, - SECONDARY = VK_COMMAND_BUFFER_LEVEL_SECONDARY, + PRIMARY = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + SECONDARY = VK_COMMAND_BUFFER_LEVEL_SECONDARY, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class CompareOperation : u8 { - ALWAYS = VK_COMPARE_OP_ALWAYS, - EQUAL = VK_COMPARE_OP_EQUAL, - GREATER = VK_COMPARE_OP_GREATER, - GREATER_OR_EQUAL = VK_COMPARE_OP_GREATER_OR_EQUAL, - LESS = VK_COMPARE_OP_LESS, - LESS_OR_EQUAL = VK_COMPARE_OP_LESS_OR_EQUAL, - NEVER = VK_COMPARE_OP_NEVER, - NOT_EQUAL = VK_COMPARE_OP_NOT_EQUAL, - }; - - template<> + ALWAYS = VK_COMPARE_OP_ALWAYS, + EQUAL = VK_COMPARE_OP_EQUAL, + GREATER = VK_COMPARE_OP_GREATER, + GREATER_OR_EQUAL = VK_COMPARE_OP_GREATER_OR_EQUAL, + LESS = VK_COMPARE_OP_LESS, + LESS_OR_EQUAL = VK_COMPARE_OP_LESS_OR_EQUAL, + NEVER = VK_COMPARE_OP_NEVER, + NOT_EQUAL = VK_COMPARE_OP_NOT_EQUAL, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class CullModeFlag : u8 { - BACK = VK_CULL_MODE_BACK_BIT, - FRONT = VK_CULL_MODE_FRONT_BIT, - FRONT_BACK = FRONT | BACK, - NONE = 0, + BACK = VK_CULL_MODE_BACK_BIT, + FRONT = VK_CULL_MODE_FRONT_BIT, + FRONT_BACK = FRONT | BACK, + NONE = 0, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class DebugObjectType : u32 { - BUFFER = VK_OBJECT_TYPE_BUFFER, - BUFFER_VIEW = VK_OBJECT_TYPE_BUFFER_VIEW, - COMMAND_BUFFER = VK_OBJECT_TYPE_COMMAND_BUFFER, - COMMAND_POOL = VK_OBJECT_TYPE_COMMAND_POOL, - DEBUG_REPORT_CALLBACK = VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT, - DESCRIPTOR_POOL = VK_OBJECT_TYPE_DESCRIPTOR_POOL, - DESCRIPTOR_SET = VK_OBJECT_TYPE_DESCRIPTOR_SET, - DESCRIPTOR_SET_LAYOUT = VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, - DEVICE = VK_OBJECT_TYPE_DEVICE, - DEVICE_MEMORY = VK_OBJECT_TYPE_DEVICE_MEMORY, - DISPLAY = VK_OBJECT_TYPE_DISPLAY_KHR, - EVENT = VK_OBJECT_TYPE_EVENT, - FENCE = VK_OBJECT_TYPE_FENCE, - FRAMEBUFFER = VK_OBJECT_TYPE_FRAMEBUFFER, - IMAGE = VK_OBJECT_TYPE_IMAGE, - IMAGE_VIEW = VK_OBJECT_TYPE_IMAGE_VIEW, - INSTANCE = VK_OBJECT_TYPE_INSTANCE, - PHYSICAL_DEVICE = VK_OBJECT_TYPE_PHYSICAL_DEVICE, - PIPELINE = VK_OBJECT_TYPE_PIPELINE, - PIPELINE_CACHE = VK_OBJECT_TYPE_PIPELINE_CACHE, - PIPELINE_LAYOUT = VK_OBJECT_TYPE_PIPELINE_LAYOUT, - QUERY_POOL = VK_OBJECT_TYPE_QUERY_POOL, - QUEUE = VK_OBJECT_TYPE_QUEUE, - RENDER_PASS = VK_OBJECT_TYPE_RENDER_PASS, - SAMPLER = VK_OBJECT_TYPE_SAMPLER, - SEMAPHORE = VK_OBJECT_TYPE_SEMAPHORE, - SHADER_MODULE = VK_OBJECT_TYPE_SHADER_MODULE, - SURFACE = VK_OBJECT_TYPE_SURFACE_KHR, - SWAPCHAIN = VK_OBJECT_TYPE_SWAPCHAIN_KHR, - UNKNOWN = VK_OBJECT_TYPE_UNKNOWN, - }; - - template<> + BUFFER = VK_OBJECT_TYPE_BUFFER, + BUFFER_VIEW = VK_OBJECT_TYPE_BUFFER_VIEW, + COMMAND_BUFFER = VK_OBJECT_TYPE_COMMAND_BUFFER, + COMMAND_POOL = VK_OBJECT_TYPE_COMMAND_POOL, + DEBUG_REPORT_CALLBACK = VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT, + DESCRIPTOR_POOL = VK_OBJECT_TYPE_DESCRIPTOR_POOL, + DESCRIPTOR_SET = VK_OBJECT_TYPE_DESCRIPTOR_SET, + DESCRIPTOR_SET_LAYOUT = VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, + DEVICE = VK_OBJECT_TYPE_DEVICE, + DEVICE_MEMORY = VK_OBJECT_TYPE_DEVICE_MEMORY, + DISPLAY = VK_OBJECT_TYPE_DISPLAY_KHR, + EVENT = VK_OBJECT_TYPE_EVENT, + FENCE = VK_OBJECT_TYPE_FENCE, + FRAMEBUFFER = VK_OBJECT_TYPE_FRAMEBUFFER, + IMAGE = VK_OBJECT_TYPE_IMAGE, + IMAGE_VIEW = VK_OBJECT_TYPE_IMAGE_VIEW, + INSTANCE = VK_OBJECT_TYPE_INSTANCE, + PHYSICAL_DEVICE = VK_OBJECT_TYPE_PHYSICAL_DEVICE, + PIPELINE = VK_OBJECT_TYPE_PIPELINE, + PIPELINE_CACHE = VK_OBJECT_TYPE_PIPELINE_CACHE, + PIPELINE_LAYOUT = VK_OBJECT_TYPE_PIPELINE_LAYOUT, + QUERY_POOL = VK_OBJECT_TYPE_QUERY_POOL, + QUEUE = VK_OBJECT_TYPE_QUEUE, + RENDER_PASS = VK_OBJECT_TYPE_RENDER_PASS, + SAMPLER = VK_OBJECT_TYPE_SAMPLER, + SEMAPHORE = VK_OBJECT_TYPE_SEMAPHORE, + SHADER_MODULE = VK_OBJECT_TYPE_SHADER_MODULE, + SURFACE = VK_OBJECT_TYPE_SURFACE_KHR, + SWAPCHAIN = VK_OBJECT_TYPE_SWAPCHAIN_KHR, + UNKNOWN = VK_OBJECT_TYPE_UNKNOWN, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class DependencyFlag : u8 { - BY_REGION = VK_DEPENDENCY_BY_REGION_BIT, - DEVICE_GROUP = VK_DEPENDENCY_DEVICE_GROUP_BIT, - NONE = 0, - VIEW_LOCAL = VK_DEPENDENCY_VIEW_LOCAL_BIT, + BY_REGION = VK_DEPENDENCY_BY_REGION_BIT, + DEVICE_GROUP = VK_DEPENDENCY_DEVICE_GROUP_BIT, + NONE = 0, + VIEW_LOCAL = VK_DEPENDENCY_VIEW_LOCAL_BIT, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class DescriptorType : u8 { - COMBINED_IMAGE_SAMPLER = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - INPUT_ATTACHMENT = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, - SAMPLED_IMAGE = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - SAMPLER = VK_DESCRIPTOR_TYPE_SAMPLER, - STORAGE_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - STORAGE_BUFFER_DYNAMIC = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, - STORAGE_IMAGE = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - STORAGE_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, - UNIFORM_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - UNIFORM_BUFFER_DYNAMIC = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, - UNIFORM_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, - }; - - template<> + COMBINED_IMAGE_SAMPLER = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + INPUT_ATTACHMENT = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, + SAMPLED_IMAGE = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + SAMPLER = VK_DESCRIPTOR_TYPE_SAMPLER, + STORAGE_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + STORAGE_BUFFER_DYNAMIC = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, + STORAGE_IMAGE = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + STORAGE_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, + UNIFORM_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + UNIFORM_BUFFER_DYNAMIC = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, + UNIFORM_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class DynamicState : u8 { - BLEND_CONSTANTS = VK_DYNAMIC_STATE_BLEND_CONSTANTS, - DEPTH_BIAS = VK_DYNAMIC_STATE_DEPTH_BIAS, - DEPTH_BOUNDS = VK_DYNAMIC_STATE_DEPTH_BOUNDS, - LINE_WIDTH = VK_DYNAMIC_STATE_LINE_WIDTH, - SCISSOR = VK_DYNAMIC_STATE_SCISSOR, - STENCIL_COMPARE_MASK = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, - STENCIL_REFERENCE = VK_DYNAMIC_STATE_STENCIL_REFERENCE, - STENCIL_WRITE_MASK = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, - VIEWPORT = VK_DYNAMIC_STATE_VIEWPORT, - }; - - template<> + BLEND_CONSTANTS = VK_DYNAMIC_STATE_BLEND_CONSTANTS, + DEPTH_BIAS = VK_DYNAMIC_STATE_DEPTH_BIAS, + DEPTH_BOUNDS = VK_DYNAMIC_STATE_DEPTH_BOUNDS, + LINE_WIDTH = VK_DYNAMIC_STATE_LINE_WIDTH, + SCISSOR = VK_DYNAMIC_STATE_SCISSOR, + STENCIL_COMPARE_MASK = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, + STENCIL_REFERENCE = VK_DYNAMIC_STATE_STENCIL_REFERENCE, + STENCIL_WRITE_MASK = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, + VIEWPORT = VK_DYNAMIC_STATE_VIEWPORT, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class Filter : u32 { - CUBIC_IMG = VK_FILTER_CUBIC_IMG, - LINEAR = VK_FILTER_LINEAR, - NEAREST = VK_FILTER_NEAREST, + CUBIC_IMG = VK_FILTER_CUBIC_IMG, + LINEAR = VK_FILTER_LINEAR, + NEAREST = VK_FILTER_NEAREST, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class FormatFeatureFlag : u32 { - BLIT_DST = VK_FORMAT_FEATURE_BLIT_DST_BIT, - BLIT_SRC = VK_FORMAT_FEATURE_BLIT_SRC_BIT, - COLOR_ATTACHMENT = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, - COLOR_ATTACHMENT_BLEND = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT, - COSITED_CHROMA_SAMPLES = VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT, - DEPTH_STENCIL_ATTACHMENT = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, - DISJOINT = VK_FORMAT_FEATURE_DISJOINT_BIT, - MIDPOINT_CHROMA_SAMPLES = VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT, - SAMPLED_IMAGE = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, - SAMPLED_IMAGE_FILTER_LINEAR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT, - SAMPLED_IMAGE_FILTER_MINMAX = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT, - SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT - = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT, - SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE - = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT, - SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT, - SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER - = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT, - STORAGE_IMAGE = VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT, - STORAGE_IMAGE_ATOMIC = VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT, - STORAGE_TEXEL_BUFFER = VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT, - STORAGE_TEXEL_BUFFER_ATOMIC = VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT, - TRANSFER_DST = VK_FORMAT_FEATURE_TRANSFER_DST_BIT, - TRANSFER_SRC = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT, - UNIFORM_TEXEL_BUFFER = VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT, - VERTEX_BUFFER = VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT, - }; - - template<> + BLIT_DST = VK_FORMAT_FEATURE_BLIT_DST_BIT, + BLIT_SRC = VK_FORMAT_FEATURE_BLIT_SRC_BIT, + COLOR_ATTACHMENT = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, + COLOR_ATTACHMENT_BLEND = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT, + COSITED_CHROMA_SAMPLES = VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT, + DEPTH_STENCIL_ATTACHMENT = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, + DISJOINT = VK_FORMAT_FEATURE_DISJOINT_BIT, + MIDPOINT_CHROMA_SAMPLES = VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT, + SAMPLED_IMAGE = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, + SAMPLED_IMAGE_FILTER_LINEAR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT, + SAMPLED_IMAGE_FILTER_MINMAX = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT, + SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT, + SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT, + SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT, + SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT, + STORAGE_IMAGE = VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT, + STORAGE_IMAGE_ATOMIC = VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT, + STORAGE_TEXEL_BUFFER = VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT, + STORAGE_TEXEL_BUFFER_ATOMIC = VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT, + TRANSFER_DST = VK_FORMAT_FEATURE_TRANSFER_DST_BIT, + TRANSFER_SRC = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT, + UNIFORM_TEXEL_BUFFER = VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT, + VERTEX_BUFFER = VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class FrontFace : u8 { - CLOCKWISE = VK_FRONT_FACE_CLOCKWISE, - COUNTER_CLOCKWISE = VK_FRONT_FACE_COUNTER_CLOCKWISE, + CLOCKWISE = VK_FRONT_FACE_CLOCKWISE, + COUNTER_CLOCKWISE = VK_FRONT_FACE_COUNTER_CLOCKWISE, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class GeometryFlag : u8 { - NO_DUPLICATE_ANY_HIT_INVOCATION = VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR, - OPAQUE = VK_GEOMETRY_OPAQUE_BIT_KHR, + NO_DUPLICATE_ANY_HIT_INVOCATION = VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR, + OPAQUE = VK_GEOMETRY_OPAQUE_BIT_KHR, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class GeometryType : u8 { - AABBS = VK_GEOMETRY_TYPE_AABBS_KHR, - INSTANCES = VK_GEOMETRY_TYPE_INSTANCES_KHR, - TRIANGLES = VK_GEOMETRY_TYPE_TRIANGLES_KHR, + AABBS = VK_GEOMETRY_TYPE_AABBS_KHR, + INSTANCES = VK_GEOMETRY_TYPE_INSTANCES_KHR, + TRIANGLES = VK_GEOMETRY_TYPE_TRIANGLES_KHR, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageAspectFlag : u8 { - COLOR = VK_IMAGE_ASPECT_COLOR_BIT, - DEPTH = VK_IMAGE_ASPECT_DEPTH_BIT, - NONE = VK_IMAGE_ASPECT_NONE_KHR, - STENCIL = VK_IMAGE_ASPECT_STENCIL_BIT, + COLOR = VK_IMAGE_ASPECT_COLOR_BIT, + DEPTH = VK_IMAGE_ASPECT_DEPTH_BIT, + NONE = VK_IMAGE_ASPECT_NONE_KHR, + STENCIL = VK_IMAGE_ASPECT_STENCIL_BIT, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageCreateFlag : u16 { - ALIAS = VK_IMAGE_CREATE_ALIAS_BIT, - ARRAY_2D_COMPATIBLE = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, - BLOCK_TEXEL_VIEW_COMPATIBLE = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, - CUBE_COMPATIBLE = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, - DISJOINT = VK_IMAGE_CREATE_DISJOINT_BIT, - EXTENDED_USAGE = VK_IMAGE_CREATE_EXTENDED_USAGE_BIT, - MUTABLE_FORMAT = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, - NONE = 0, - PROTECTED = VK_IMAGE_CREATE_PROTECTED_BIT, - SPARSE_ALIASED = VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, - SPARSE_BINDING = VK_IMAGE_CREATE_SPARSE_BINDING_BIT, - SPARSE_RESIDENCY = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, - SPLIT_INSTANCE_BIND_REGIONS = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT, - }; - - template<> + ALIAS = VK_IMAGE_CREATE_ALIAS_BIT, + ARRAY_2D_COMPATIBLE = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, + BLOCK_TEXEL_VIEW_COMPATIBLE = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, + CUBE_COMPATIBLE = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, + DISJOINT = VK_IMAGE_CREATE_DISJOINT_BIT, + EXTENDED_USAGE = VK_IMAGE_CREATE_EXTENDED_USAGE_BIT, + MUTABLE_FORMAT = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, + NONE = 0, + PROTECTED = VK_IMAGE_CREATE_PROTECTED_BIT, + SPARSE_ALIASED = VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, + SPARSE_BINDING = VK_IMAGE_CREATE_SPARSE_BINDING_BIT, + SPARSE_RESIDENCY = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, + SPLIT_INSTANCE_BIND_REGIONS = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageLayout : u32 { - COLOR_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, - DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, - DEPTH_STENCIL_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - DEPTH_STENCIL_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, - GENERAL = VK_IMAGE_LAYOUT_GENERAL, - PREINITIALIZED = VK_IMAGE_LAYOUT_PREINITIALIZED, - PRESENT_SRC = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - SHADER_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - SHARED_PRESENT = VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, - TRANSFER_DST_OPTIMAL = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - TRANSFER_SRC_OPTIMAL = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - UNDEFINED = VK_IMAGE_LAYOUT_UNDEFINED, - }; - - template<> + ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, + COLOR_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, + DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, + DEPTH_STENCIL_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + DEPTH_STENCIL_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, + GENERAL = VK_IMAGE_LAYOUT_GENERAL, + PREINITIALIZED = VK_IMAGE_LAYOUT_PREINITIALIZED, + PRESENT_SRC = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + SHADER_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + SHARED_PRESENT = VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, + TRANSFER_DST_OPTIMAL = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + TRANSFER_SRC_OPTIMAL = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + UNDEFINED = VK_IMAGE_LAYOUT_UNDEFINED, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageTiling : u8 { - LINEAR = VK_IMAGE_TILING_LINEAR, - OPTIMAL = VK_IMAGE_TILING_OPTIMAL, + LINEAR = VK_IMAGE_TILING_LINEAR, + OPTIMAL = VK_IMAGE_TILING_OPTIMAL, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageType : u8 { - T1D = VK_IMAGE_TYPE_1D, - T2D = VK_IMAGE_TYPE_2D, - T3D = VK_IMAGE_TYPE_3D, + T1D = VK_IMAGE_TYPE_1D, + T2D = VK_IMAGE_TYPE_2D, + T3D = VK_IMAGE_TYPE_3D, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageUsageFlag : u16 { - COLOR_ATTACHMENT = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, - DEPTH_STENCIL_ATTACHMENT = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, - INPUT_ATTACHMENT = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, - SAMPLED = VK_IMAGE_USAGE_SAMPLED_BIT, - STORAGE = VK_IMAGE_USAGE_STORAGE_BIT, - TRANSFER_DST = VK_IMAGE_USAGE_TRANSFER_DST_BIT, - TRANSFER_SRC = VK_IMAGE_USAGE_TRANSFER_SRC_BIT, - TRANSIENT_ATTACHMENT = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, - }; - - template<> + COLOR_ATTACHMENT = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + DEPTH_STENCIL_ATTACHMENT = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + INPUT_ATTACHMENT = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, + SAMPLED = VK_IMAGE_USAGE_SAMPLED_BIT, + STORAGE = VK_IMAGE_USAGE_STORAGE_BIT, + TRANSFER_DST = VK_IMAGE_USAGE_TRANSFER_DST_BIT, + TRANSFER_SRC = VK_IMAGE_USAGE_TRANSFER_SRC_BIT, + TRANSIENT_ATTACHMENT = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageViewType : u8 { - CUBE = VK_IMAGE_VIEW_TYPE_CUBE, - CUBE_ARRAY = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, - T1D = VK_IMAGE_VIEW_TYPE_1D, - T1D_ARRAY = VK_IMAGE_VIEW_TYPE_1D_ARRAY, - T2D = VK_IMAGE_VIEW_TYPE_2D, - T2D_ARRAY = VK_IMAGE_VIEW_TYPE_2D_ARRAY, - T3D = VK_IMAGE_VIEW_TYPE_3D, + CUBE = VK_IMAGE_VIEW_TYPE_CUBE, + CUBE_ARRAY = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, + T1D = VK_IMAGE_VIEW_TYPE_1D, + T1D_ARRAY = VK_IMAGE_VIEW_TYPE_1D_ARRAY, + T2D = VK_IMAGE_VIEW_TYPE_2D, + T2D_ARRAY = VK_IMAGE_VIEW_TYPE_2D_ARRAY, + T3D = VK_IMAGE_VIEW_TYPE_3D, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class LogicOperation : u8 { - AND = VK_LOGIC_OP_AND, - AND_INVERTED = VK_LOGIC_OP_AND_INVERTED, - AND_REVERSE = VK_LOGIC_OP_AND_REVERSE, - CLEAR = VK_LOGIC_OP_CLEAR, - COPY = VK_LOGIC_OP_COPY, - COPY_INVERTED = VK_LOGIC_OP_COPY_INVERTED, - EQUIVALENT = VK_LOGIC_OP_EQUIVALENT, - INVERT = VK_LOGIC_OP_INVERT, - NAND = VK_LOGIC_OP_NAND, - NO_OP = VK_LOGIC_OP_NO_OP, - NOR = VK_LOGIC_OP_NOR, - OR = VK_LOGIC_OP_OR, - OR_INVERTED = VK_LOGIC_OP_OR_INVERTED, - OR_REVERSE = VK_LOGIC_OP_OR_REVERSE, - SET = VK_LOGIC_OP_SET, - XOR = VK_LOGIC_OP_XOR, - }; - - template<> + AND = VK_LOGIC_OP_AND, + AND_INVERTED = VK_LOGIC_OP_AND_INVERTED, + AND_REVERSE = VK_LOGIC_OP_AND_REVERSE, + CLEAR = VK_LOGIC_OP_CLEAR, + COPY = VK_LOGIC_OP_COPY, + COPY_INVERTED = VK_LOGIC_OP_COPY_INVERTED, + EQUIVALENT = VK_LOGIC_OP_EQUIVALENT, + INVERT = VK_LOGIC_OP_INVERT, + NAND = VK_LOGIC_OP_NAND, + NO_OP = VK_LOGIC_OP_NO_OP, + NOR = VK_LOGIC_OP_NOR, + OR = VK_LOGIC_OP_OR, + OR_INVERTED = VK_LOGIC_OP_OR_INVERTED, + OR_REVERSE = VK_LOGIC_OP_OR_REVERSE, + SET = VK_LOGIC_OP_SET, + XOR = VK_LOGIC_OP_XOR, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class MemoryPropertyFlag : u8 { - DEVICE_LOCAL = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - HOST_CACHED = VK_MEMORY_PROPERTY_HOST_CACHED_BIT, - HOST_COHERENT = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - HOST_VISIBLE = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + DEVICE_LOCAL = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + HOST_CACHED = VK_MEMORY_PROPERTY_HOST_CACHED_BIT, + HOST_COHERENT = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + HOST_VISIBLE = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PhysicalDeviceType : u8 { - CPU = VK_PHYSICAL_DEVICE_TYPE_CPU, - DISCRETE_GPU = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, - INTEGRATED_GPU = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, - OTHER = VK_PHYSICAL_DEVICE_TYPE_OTHER, - VIRTUAL_GPU = VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, + CPU = VK_PHYSICAL_DEVICE_TYPE_CPU, + DISCRETE_GPU = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, + INTEGRATED_GPU = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, + OTHER = VK_PHYSICAL_DEVICE_TYPE_OTHER, + VIRTUAL_GPU = VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PipelineBindPoint : u8 { - COMPUTE = VK_PIPELINE_BIND_POINT_COMPUTE, - GRAPHICS = VK_PIPELINE_BIND_POINT_GRAPHICS, + COMPUTE = VK_PIPELINE_BIND_POINT_COMPUTE, + GRAPHICS = VK_PIPELINE_BIND_POINT_GRAPHICS, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PipelineStageFlag : u32 { - ALL_COMMANDS = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - ALL_GRAPHICS = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, - BOTTOM_OF_PIPE = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - COLOR_ATTACHMENT_OUTPUT = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - COMPUTE_SHADER = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - DRAW_INDIRECT = VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, - EARLY_FRAGMENT_TESTS = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, - FRAGMENT_SHADER = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - GEOMETRY_SHADER = VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, - HOST = VK_PIPELINE_STAGE_HOST_BIT, - LATE_FRAGMENT_TESTS = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - TESSELLATION_CONTROL_SHADER = VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, - TESSELLATION_EVALUATION_SHADER = VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, - TOP_OF_PIPE = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - TRANSFER = VK_PIPELINE_STAGE_TRANSFER_BIT, - VERTEX_INPUT = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, - VERTEX_SHADER = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, - }; - - template<> + ALL_COMMANDS = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + ALL_GRAPHICS = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, + BOTTOM_OF_PIPE = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + COLOR_ATTACHMENT_OUTPUT = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + COMPUTE_SHADER = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + DRAW_INDIRECT = VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, + EARLY_FRAGMENT_TESTS = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, + FRAGMENT_SHADER = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + GEOMETRY_SHADER = VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, + HOST = VK_PIPELINE_STAGE_HOST_BIT, + LATE_FRAGMENT_TESTS = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + TESSELLATION_CONTROL_SHADER = VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, + TESSELLATION_EVALUATION_SHADER = VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, + TOP_OF_PIPE = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + TRANSFER = VK_PIPELINE_STAGE_TRANSFER_BIT, + VERTEX_INPUT = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, + VERTEX_SHADER = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PixelFormat : u32 { - A1_RGB5_UNORM_PACK16 = VK_FORMAT_A1R5G5B5_UNORM_PACK16, - A2_RGB10I_PACK32 = VK_FORMAT_A2R10G10B10_SINT_PACK32, - A2_RGB10_SNORM_PACK32 = VK_FORMAT_A2R10G10B10_SNORM_PACK32, - A2_RGB10_UNORM_PACK32 = VK_FORMAT_A2R10G10B10_UNORM_PACK32, - A2_RGB10U_PACK32 = VK_FORMAT_A2R10G10B10_UINT_PACK32, - B10_GR11UF_PACK32 = VK_FORMAT_B10G11R11_UFLOAT_PACK32, - BGR8_UNORM = VK_FORMAT_B8G8R8_UNORM, - BGRA8_UNORM = VK_FORMAT_B8G8R8A8_UNORM, - DEPTH16_UNORM = VK_FORMAT_D16_UNORM, - DEPTH16_UNORM_STENCIL8U = VK_FORMAT_D16_UNORM_S8_UINT, - DEPTH24_UNORM_PACK32 = VK_FORMAT_X8_D24_UNORM_PACK32, - DEPTH24_UNORM_STENCIL8U = VK_FORMAT_D24_UNORM_S8_UINT, - DEPTH32F = VK_FORMAT_D32_SFLOAT, - DEPTH32F_STENCIL8U = VK_FORMAT_D32_SFLOAT_S8_UINT, - R16F = VK_FORMAT_R16_SFLOAT, - R16I = VK_FORMAT_R16_SINT, - R16_SNORM = VK_FORMAT_R16_SNORM, - R16U = VK_FORMAT_R16_UINT, - R16_UNORM = VK_FORMAT_R16_UNORM, - R32F = VK_FORMAT_R32_SFLOAT, - R32I = VK_FORMAT_R32_SINT, - R32U = VK_FORMAT_R32_UINT, - R5_G6_B5_UNORM_PACK16 = VK_FORMAT_R5G6B5_UNORM_PACK16, - R8I = VK_FORMAT_R8_SINT, - R8_SNORM = VK_FORMAT_R8_SNORM, - R8U = VK_FORMAT_R8_UINT, - R8_UNORM = VK_FORMAT_R8_UNORM, - RG16F = VK_FORMAT_R16G16_SFLOAT, - RG16I = VK_FORMAT_R16G16_SINT, - RG16_SNORM = VK_FORMAT_R16G16_SNORM, - RG16U = VK_FORMAT_R16G16_UINT, - RG16_UNORM = VK_FORMAT_R16G16_UNORM, - RG32F = VK_FORMAT_R32G32_SFLOAT, - RG32I = VK_FORMAT_R32G32_SINT, - RG32U = VK_FORMAT_R32G32_UINT, - RG8I = VK_FORMAT_R8G8_SINT, - RG8_SNORM = VK_FORMAT_R8G8_SNORM, - RG8U = VK_FORMAT_R8G8_UINT, - RG8_UNORM = VK_FORMAT_R8G8_UNORM, - RGB16F = VK_FORMAT_R16G16B16_SFLOAT, - RGB16I = VK_FORMAT_R16G16B16_SINT, - RGB16_SNORM = VK_FORMAT_R16G16B16_SNORM, - RGB16U = VK_FORMAT_R16G16B16_UINT, - RGB16_UNORM = VK_FORMAT_R16G16B16_UNORM, - RGB32F = VK_FORMAT_R32G32B32_SFLOAT, - RGB32I = VK_FORMAT_R32G32B32_SINT, - RGB32U = VK_FORMAT_R32G32B32_UINT, - RGB8I = VK_FORMAT_R8G8B8_SINT, - RGB8_SNORM = VK_FORMAT_R8G8B8_SNORM, - RGB8U = VK_FORMAT_R8G8B8_UINT, - RGB8_UNORM = VK_FORMAT_R8G8B8_UNORM, - RGBA16F = VK_FORMAT_R16G16B16A16_SFLOAT, - RGBA16I = VK_FORMAT_R16G16B16A16_SINT, - RGBA16_SNORM = VK_FORMAT_R16G16B16A16_SNORM, - RGBA16U = VK_FORMAT_R16G16B16A16_UINT, - RGBA16_UNORM = VK_FORMAT_R16G16B16A16_UNORM, - RGBA32F = VK_FORMAT_R32G32B32A32_SFLOAT, - RGBA32I = VK_FORMAT_R32G32B32A32_SINT, - RGBA32U = VK_FORMAT_R32G32B32A32_UINT, - RGBA4_UNORM_PACK16 = VK_FORMAT_R4G4B4A4_UNORM_PACK16, - RGBA8I = VK_FORMAT_R8G8B8A8_SINT, - RGBA8_SNORM = VK_FORMAT_R8G8B8A8_SNORM, - RGBA8U = VK_FORMAT_R8G8B8A8_UINT, - RGBA8_UNORM = VK_FORMAT_R8G8B8A8_UNORM, - SBGR8 = VK_FORMAT_B8G8R8_SRGB, - SBGRA8 = VK_FORMAT_B8G8R8A8_SRGB, - SR8 = VK_FORMAT_R8_SRGB, - SRG8 = VK_FORMAT_R8G8_SRGB, - SRGB8 = VK_FORMAT_R8G8B8_SRGB, - SRGBA8 = VK_FORMAT_R8G8B8A8_SRGB, - UNDEFINED = VK_FORMAT_UNDEFINED, - }; - - template<> + A1_RGB5_UNORM_PACK16 = VK_FORMAT_A1R5G5B5_UNORM_PACK16, + A2_RGB10I_PACK32 = VK_FORMAT_A2R10G10B10_SINT_PACK32, + A2_RGB10_SNORM_PACK32 = VK_FORMAT_A2R10G10B10_SNORM_PACK32, + A2_RGB10_UNORM_PACK32 = VK_FORMAT_A2R10G10B10_UNORM_PACK32, + A2_RGB10U_PACK32 = VK_FORMAT_A2R10G10B10_UINT_PACK32, + B10_GR11UF_PACK32 = VK_FORMAT_B10G11R11_UFLOAT_PACK32, + BGR8_UNORM = VK_FORMAT_B8G8R8_UNORM, + BGRA8_UNORM = VK_FORMAT_B8G8R8A8_UNORM, + DEPTH16_UNORM = VK_FORMAT_D16_UNORM, + DEPTH16_UNORM_STENCIL8U = VK_FORMAT_D16_UNORM_S8_UINT, + DEPTH24_UNORM_PACK32 = VK_FORMAT_X8_D24_UNORM_PACK32, + DEPTH24_UNORM_STENCIL8U = VK_FORMAT_D24_UNORM_S8_UINT, + DEPTH32F = VK_FORMAT_D32_SFLOAT, + DEPTH32F_STENCIL8U = VK_FORMAT_D32_SFLOAT_S8_UINT, + R16F = VK_FORMAT_R16_SFLOAT, + R16I = VK_FORMAT_R16_SINT, + R16_SNORM = VK_FORMAT_R16_SNORM, + R16U = VK_FORMAT_R16_UINT, + R16_UNORM = VK_FORMAT_R16_UNORM, + R32F = VK_FORMAT_R32_SFLOAT, + R32I = VK_FORMAT_R32_SINT, + R32U = VK_FORMAT_R32_UINT, + R5_G6_B5_UNORM_PACK16 = VK_FORMAT_R5G6B5_UNORM_PACK16, + R8I = VK_FORMAT_R8_SINT, + R8_SNORM = VK_FORMAT_R8_SNORM, + R8U = VK_FORMAT_R8_UINT, + R8_UNORM = VK_FORMAT_R8_UNORM, + RG16F = VK_FORMAT_R16G16_SFLOAT, + RG16I = VK_FORMAT_R16G16_SINT, + RG16_SNORM = VK_FORMAT_R16G16_SNORM, + RG16U = VK_FORMAT_R16G16_UINT, + RG16_UNORM = VK_FORMAT_R16G16_UNORM, + RG32F = VK_FORMAT_R32G32_SFLOAT, + RG32I = VK_FORMAT_R32G32_SINT, + RG32U = VK_FORMAT_R32G32_UINT, + RG8I = VK_FORMAT_R8G8_SINT, + RG8_SNORM = VK_FORMAT_R8G8_SNORM, + RG8U = VK_FORMAT_R8G8_UINT, + RG8_UNORM = VK_FORMAT_R8G8_UNORM, + RGB16F = VK_FORMAT_R16G16B16_SFLOAT, + RGB16I = VK_FORMAT_R16G16B16_SINT, + RGB16_SNORM = VK_FORMAT_R16G16B16_SNORM, + RGB16U = VK_FORMAT_R16G16B16_UINT, + RGB16_UNORM = VK_FORMAT_R16G16B16_UNORM, + RGB32F = VK_FORMAT_R32G32B32_SFLOAT, + RGB32I = VK_FORMAT_R32G32B32_SINT, + RGB32U = VK_FORMAT_R32G32B32_UINT, + RGB8I = VK_FORMAT_R8G8B8_SINT, + RGB8_SNORM = VK_FORMAT_R8G8B8_SNORM, + RGB8U = VK_FORMAT_R8G8B8_UINT, + RGB8_UNORM = VK_FORMAT_R8G8B8_UNORM, + RGBA16F = VK_FORMAT_R16G16B16A16_SFLOAT, + RGBA16I = VK_FORMAT_R16G16B16A16_SINT, + RGBA16_SNORM = VK_FORMAT_R16G16B16A16_SNORM, + RGBA16U = VK_FORMAT_R16G16B16A16_UINT, + RGBA16_UNORM = VK_FORMAT_R16G16B16A16_UNORM, + RGBA32F = VK_FORMAT_R32G32B32A32_SFLOAT, + RGBA32I = VK_FORMAT_R32G32B32A32_SINT, + RGBA32U = VK_FORMAT_R32G32B32A32_UINT, + RGBA4_UNORM_PACK16 = VK_FORMAT_R4G4B4A4_UNORM_PACK16, + RGBA8I = VK_FORMAT_R8G8B8A8_SINT, + RGBA8_SNORM = VK_FORMAT_R8G8B8A8_SNORM, + RGBA8U = VK_FORMAT_R8G8B8A8_UINT, + RGBA8_UNORM = VK_FORMAT_R8G8B8A8_UNORM, + SBGR8 = VK_FORMAT_B8G8R8_SRGB, + SBGRA8 = VK_FORMAT_B8G8R8A8_SRGB, + SR8 = VK_FORMAT_R8_SRGB, + SRG8 = VK_FORMAT_R8G8_SRGB, + SRGB8 = VK_FORMAT_R8G8B8_SRGB, + SRGBA8 = VK_FORMAT_R8G8B8A8_SRGB, + UNDEFINED = VK_FORMAT_UNDEFINED, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PolygonMode : u8 { - FILL = VK_POLYGON_MODE_FILL, - LINE = VK_POLYGON_MODE_LINE, - POINT = VK_POLYGON_MODE_POINT, + FILL = VK_POLYGON_MODE_FILL, + LINE = VK_POLYGON_MODE_LINE, + POINT = VK_POLYGON_MODE_POINT, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PresentMode : u32 { - FIFO = VK_PRESENT_MODE_FIFO_KHR, - FIFO_RELAXED = VK_PRESENT_MODE_FIFO_RELAXED_KHR, - IMMEDIATE = VK_PRESENT_MODE_IMMEDIATE_KHR, - MAILBOX = VK_PRESENT_MODE_MAILBOX_KHR, - SHARED_CONTINUOUS_REFRESH = VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR, - SHARED_DEMAND_REFRESH = VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR, + FIFO = VK_PRESENT_MODE_FIFO_KHR, + FIFO_RELAXED = VK_PRESENT_MODE_FIFO_RELAXED_KHR, + IMMEDIATE = VK_PRESENT_MODE_IMMEDIATE_KHR, + MAILBOX = VK_PRESENT_MODE_MAILBOX_KHR, + SHARED_CONTINUOUS_REFRESH = VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR, + SHARED_DEMAND_REFRESH = VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PrimitiveTopology : u8 { - LINE_LIST = VK_PRIMITIVE_TOPOLOGY_LINE_LIST, - LINE_STRIP = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, - POINT_LIST = VK_PRIMITIVE_TOPOLOGY_POINT_LIST, - TRIANGLE_FAN = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, - TRIANGLE_LIST = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, - TRIANGLE_STRIP = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, + LINE_LIST = VK_PRIMITIVE_TOPOLOGY_LINE_LIST, + LINE_STRIP = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, + POINT_LIST = VK_PRIMITIVE_TOPOLOGY_POINT_LIST, + TRIANGLE_FAN = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, + TRIANGLE_LIST = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + TRIANGLE_STRIP = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class QueueFlag : u8 { - COMPUTE = VK_QUEUE_COMPUTE_BIT, - GRAPHICS = VK_QUEUE_GRAPHICS_BIT, - NONE = 0, - PROTECTED = VK_QUEUE_PROTECTED_BIT, - SPARSE_BINDING = VK_QUEUE_SPARSE_BINDING_BIT, - TRANSFER = VK_QUEUE_TRANSFER_BIT, + COMPUTE = VK_QUEUE_COMPUTE_BIT, + GRAPHICS = VK_QUEUE_GRAPHICS_BIT, + NONE = 0, + PROTECTED = VK_QUEUE_PROTECTED_BIT, + SPARSE_BINDING = VK_QUEUE_SPARSE_BINDING_BIT, + TRANSFER = VK_QUEUE_TRANSFER_BIT, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + + enum class ResolveModeFlag : u8 { + AVERAGE = VK_RESOLVE_MODE_AVERAGE_BIT, + EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID = VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID, + MAX = VK_RESOLVE_MODE_MAX_BIT, + MIN = VK_RESOLVE_MODE_MIN_BIT, + NONE = VK_RESOLVE_MODE_NONE, + SAMPLE_ZERO = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, + + }; + + template <> + inline constexpr auto details::IS_VULKAN_ENUMERATION = true; + enum class Result : i32 { - ERROR_DEVICE_LOST = VK_ERROR_DEVICE_LOST, - ERROR_EXTENSION_NOT_PRESENT = VK_ERROR_EXTENSION_NOT_PRESENT, - ERROR_FEATURE_NOT_PRESENT = VK_ERROR_FEATURE_NOT_PRESENT, - ERROR_FORMAT_NOT_SUPPORTED = VK_ERROR_FORMAT_NOT_SUPPORTED, - ERROR_FRAGMENTATION = VK_ERROR_FRAGMENTATION, - ERROR_FRAGMENTED_POOL = VK_ERROR_FRAGMENTED_POOL, - ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST = VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT, - ERROR_INCOMPATIBLE_DISPLAY = VK_ERROR_INCOMPATIBLE_DISPLAY_KHR, - ERROR_INCOMPATIBLE_DRIVER = VK_ERROR_INCOMPATIBLE_DRIVER, - ERROR_INITIALIZATION_FAILED = VK_ERROR_INITIALIZATION_FAILED, - ERROR_INVALID_EXTERNAL_HANDLE = VK_ERROR_INVALID_EXTERNAL_HANDLE, - ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, - ERROR_LAYER_NOT_PRESENT = VK_ERROR_LAYER_NOT_PRESENT, - ERROR_MEMORY_MAP_FAILED = VK_ERROR_MEMORY_MAP_FAILED, - ERROR_NATIVE_WINDOW_IN_USE = VK_ERROR_NATIVE_WINDOW_IN_USE_KHR, - ERROR_NOT_PERMITTED = VK_ERROR_NOT_PERMITTED, - ERROR_OUT_OF_DATE = VK_ERROR_OUT_OF_DATE_KHR, - ERROR_OUT_OF_DEVICE_MEMORY = VK_ERROR_OUT_OF_DEVICE_MEMORY, - ERROR_OUT_OF_HOST_MEMORY = VK_ERROR_OUT_OF_HOST_MEMORY, - ERROR_OUT_OF_POOL_MEMORY = VK_ERROR_OUT_OF_POOL_MEMORY, - ERROR_SURFACE_LOST = VK_ERROR_SURFACE_LOST_KHR, - ERROR_TOO_MANY_OBJECTS = VK_ERROR_TOO_MANY_OBJECTS, - ERROR_UNKNOWN = VK_ERROR_UNKNOWN, - ERROR_VALIDATION_FAILED = VK_ERROR_VALIDATION_FAILED_EXT, - EVENT_RESET = VK_EVENT_RESET, - EVENT_SET = VK_EVENT_SET, - INCOMPLETE = VK_INCOMPLETE, - NOT_READY = VK_NOT_READY, - OPERATION_DEFERRED = VK_OPERATION_DEFERRED_KHR, - OPERATION_NOT_DEFERRED = VK_OPERATION_NOT_DEFERRED_KHR, - PIPELINE_COMPILE_REQUIRED = VK_PIPELINE_COMPILE_REQUIRED, - SUBOPTIMAL = VK_SUBOPTIMAL_KHR, - SUCCESS = VK_SUCCESS, - THREAD_DONE = VK_THREAD_DONE_KHR, - THREAD_IDLE = VK_THREAD_IDLE_KHR, - TIMEOUT = VK_TIMEOUT, - }; - - template<> + ERROR_DEVICE_LOST = VK_ERROR_DEVICE_LOST, + ERROR_EXTENSION_NOT_PRESENT = VK_ERROR_EXTENSION_NOT_PRESENT, + ERROR_FEATURE_NOT_PRESENT = VK_ERROR_FEATURE_NOT_PRESENT, + ERROR_FORMAT_NOT_SUPPORTED = VK_ERROR_FORMAT_NOT_SUPPORTED, + ERROR_FRAGMENTATION = VK_ERROR_FRAGMENTATION, + ERROR_FRAGMENTED_POOL = VK_ERROR_FRAGMENTED_POOL, + ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST = VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT, + ERROR_INCOMPATIBLE_DISPLAY = VK_ERROR_INCOMPATIBLE_DISPLAY_KHR, + ERROR_INCOMPATIBLE_DRIVER = VK_ERROR_INCOMPATIBLE_DRIVER, + ERROR_INITIALIZATION_FAILED = VK_ERROR_INITIALIZATION_FAILED, + ERROR_INVALID_EXTERNAL_HANDLE = VK_ERROR_INVALID_EXTERNAL_HANDLE, + ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, + ERROR_LAYER_NOT_PRESENT = VK_ERROR_LAYER_NOT_PRESENT, + ERROR_MEMORY_MAP_FAILED = VK_ERROR_MEMORY_MAP_FAILED, + ERROR_NATIVE_WINDOW_IN_USE = VK_ERROR_NATIVE_WINDOW_IN_USE_KHR, + ERROR_NOT_PERMITTED = VK_ERROR_NOT_PERMITTED, + ERROR_OUT_OF_DATE = VK_ERROR_OUT_OF_DATE_KHR, + ERROR_OUT_OF_DEVICE_MEMORY = VK_ERROR_OUT_OF_DEVICE_MEMORY, + ERROR_OUT_OF_HOST_MEMORY = VK_ERROR_OUT_OF_HOST_MEMORY, + ERROR_OUT_OF_POOL_MEMORY = VK_ERROR_OUT_OF_POOL_MEMORY, + ERROR_SURFACE_LOST = VK_ERROR_SURFACE_LOST_KHR, + ERROR_TOO_MANY_OBJECTS = VK_ERROR_TOO_MANY_OBJECTS, + ERROR_UNKNOWN = VK_ERROR_UNKNOWN, + ERROR_VALIDATION_FAILED = VK_ERROR_VALIDATION_FAILED_EXT, + EVENT_RESET = VK_EVENT_RESET, + EVENT_SET = VK_EVENT_SET, + INCOMPLETE = VK_INCOMPLETE, + NOT_READY = VK_NOT_READY, + OPERATION_DEFERRED = VK_OPERATION_DEFERRED_KHR, + OPERATION_NOT_DEFERRED = VK_OPERATION_NOT_DEFERRED_KHR, + PIPELINE_COMPILE_REQUIRED = VK_PIPELINE_COMPILE_REQUIRED, + SUBOPTIMAL = VK_SUBOPTIMAL_KHR, + SUCCESS = VK_SUCCESS, + THREAD_DONE = VK_THREAD_DONE_KHR, + THREAD_IDLE = VK_THREAD_IDLE_KHR, + TIMEOUT = VK_TIMEOUT, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class SampleCountFlag : u8 { - C1 = VK_SAMPLE_COUNT_1_BIT, - C16 = VK_SAMPLE_COUNT_16_BIT, - C2 = VK_SAMPLE_COUNT_2_BIT, - C32 = VK_SAMPLE_COUNT_32_BIT, - C4 = VK_SAMPLE_COUNT_4_BIT, - C64 = VK_SAMPLE_COUNT_64_BIT, - C8 = VK_SAMPLE_COUNT_8_BIT, + C1 = VK_SAMPLE_COUNT_1_BIT, + C16 = VK_SAMPLE_COUNT_16_BIT, + C2 = VK_SAMPLE_COUNT_2_BIT, + C32 = VK_SAMPLE_COUNT_32_BIT, + C4 = VK_SAMPLE_COUNT_4_BIT, + C64 = VK_SAMPLE_COUNT_64_BIT, + C8 = VK_SAMPLE_COUNT_8_BIT, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class SamplerAddressMode : u8 { - CLAMP_TO_BORDER = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, - CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, - MIRROR_CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, - MIRRORED_REPEAT = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, - REPEAT = VK_SAMPLER_ADDRESS_MODE_REPEAT, + CLAMP_TO_BORDER = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, + CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + MIRROR_CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, + MIRRORED_REPEAT = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, + REPEAT = VK_SAMPLER_ADDRESS_MODE_REPEAT, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class SamplerMipmapMode : u8 { - LINEAR = VK_SAMPLER_MIPMAP_MODE_LINEAR, - NEAREST = VK_SAMPLER_MIPMAP_MODE_NEAREST, + LINEAR = VK_SAMPLER_MIPMAP_MODE_LINEAR, + NEAREST = VK_SAMPLER_MIPMAP_MODE_NEAREST, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ShaderStageFlag : u8 { - COMPUTE = VK_SHADER_STAGE_COMPUTE_BIT, - FRAGMENT = VK_SHADER_STAGE_FRAGMENT_BIT, - GEOMETRY = VK_SHADER_STAGE_GEOMETRY_BIT, - NONE = 0, - VERTEX = VK_SHADER_STAGE_VERTEX_BIT, + COMPUTE = VK_SHADER_STAGE_COMPUTE_BIT, + FRAGMENT = VK_SHADER_STAGE_FRAGMENT_BIT, + GEOMETRY = VK_SHADER_STAGE_GEOMETRY_BIT, + NONE = 0, + VERTEX = VK_SHADER_STAGE_VERTEX_BIT, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class StencilFaceFlag : u8 { - BACK = VK_STENCIL_FACE_BACK_BIT, - FRONT = VK_STENCIL_FACE_FRONT_BIT, - FRONT_AND_BACK = FRONT | BACK, + BACK = VK_STENCIL_FACE_BACK_BIT, + FRONT = VK_STENCIL_FACE_FRONT_BIT, + FRONT_AND_BACK = FRONT | BACK, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class VertexInputRate : u8 { - INSTANCE = VK_VERTEX_INPUT_RATE_INSTANCE, - VERTEX = VK_VERTEX_INPUT_RATE_VERTEX, + INSTANCE = VK_VERTEX_INPUT_RATE_INSTANCE, + VERTEX = VK_VERTEX_INPUT_RATE_VERTEX, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; + template requires(core::meta::IsPlainEnumeration or core::meta::Is) @@ -756,2726 +814,2660 @@ export { constexpr auto get_format_channel_count(PixelFormat format) noexcept -> u8; [[nodiscard]] constexpr auto get_format_element_count(PixelFormat format) noexcept -> u8; - } // namespace stormkit::gpu + } FLAG_ENUM(stormkit::gpu::AccessFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ, - stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE, - stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ, - stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE, - stormkit::gpu::AccessFlag::HOST_READ, - stormkit::gpu::AccessFlag::HOST_WRITE, - stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ, - stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ, - stormkit::gpu::AccessFlag::MEMORY_READ, - stormkit::gpu::AccessFlag::MEMORY_WRITE, - stormkit::gpu::AccessFlag::NONE, - stormkit::gpu::AccessFlag::SHADER_READ, - stormkit::gpu::AccessFlag::SHADER_WRITE, - stormkit::gpu::AccessFlag::TRANSFER_READ, - stormkit::gpu::AccessFlag::TRANSFER_WRITE, - stormkit::gpu::AccessFlag::UNIFORM_READ, - stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ, - - }; - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::AccessFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: return "AccessFlag::COLOR_ATTACHMENT_WRITE"; - case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE"; - case stormkit::gpu::AccessFlag::HOST_READ: return "AccessFlag::HOST_READ"; - case stormkit::gpu::AccessFlag::HOST_WRITE: return "AccessFlag::HOST_WRITE"; - case stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ: return "AccessFlag::INDIRECT_COMMAND_READ"; - case stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ: return "AccessFlag::INPUT_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::MEMORY_READ: return "AccessFlag::MEMORY_READ"; - case stormkit::gpu::AccessFlag::MEMORY_WRITE: return "AccessFlag::MEMORY_WRITE"; - case stormkit::gpu::AccessFlag::NONE: return "AccessFlag::NONE"; - case stormkit::gpu::AccessFlag::SHADER_READ: return "AccessFlag::SHADER_READ"; - case stormkit::gpu::AccessFlag::SHADER_WRITE: return "AccessFlag::SHADER_WRITE"; - case stormkit::gpu::AccessFlag::TRANSFER_READ: return "AccessFlag::TRANSFER_READ"; - case stormkit::gpu::AccessFlag::TRANSFER_WRITE: return "AccessFlag::TRANSFER_WRITE"; - case stormkit::gpu::AccessFlag::UNIFORM_READ: return "AccessFlag::UNIFORM_READ"; - case stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ: return "AccessFlag::VERTEX_ATTRIBUTE_READ"; + stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ, + stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE, + stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ, + stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE, + stormkit::gpu::AccessFlag::HOST_READ, + stormkit::gpu::AccessFlag::HOST_WRITE, + stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ, + stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ, + stormkit::gpu::AccessFlag::MEMORY_READ, + stormkit::gpu::AccessFlag::MEMORY_WRITE, + stormkit::gpu::AccessFlag::NONE, + stormkit::gpu::AccessFlag::SHADER_READ, + stormkit::gpu::AccessFlag::SHADER_WRITE, + stormkit::gpu::AccessFlag::TRANSFER_READ, + stormkit::gpu::AccessFlag::TRANSFER_WRITE, + stormkit::gpu::AccessFlag::UNIFORM_READ, + stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ, + + }; + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::AccessFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: return "AccessFlag::COLOR_ATTACHMENT_WRITE"; + case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE"; + case stormkit::gpu::AccessFlag::HOST_READ: return "AccessFlag::HOST_READ"; + case stormkit::gpu::AccessFlag::HOST_WRITE: return "AccessFlag::HOST_WRITE"; + case stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ: return "AccessFlag::INDIRECT_COMMAND_READ"; + case stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ: return "AccessFlag::INPUT_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::MEMORY_READ: return "AccessFlag::MEMORY_READ"; + case stormkit::gpu::AccessFlag::MEMORY_WRITE: return "AccessFlag::MEMORY_WRITE"; + case stormkit::gpu::AccessFlag::NONE: return "AccessFlag::NONE"; + case stormkit::gpu::AccessFlag::SHADER_READ: return "AccessFlag::SHADER_READ"; + case stormkit::gpu::AccessFlag::SHADER_WRITE: return "AccessFlag::SHADER_WRITE"; + case stormkit::gpu::AccessFlag::TRANSFER_READ: return "AccessFlag::TRANSFER_READ"; + case stormkit::gpu::AccessFlag::TRANSFER_WRITE: return "AccessFlag::TRANSFER_WRITE"; + case stormkit::gpu::AccessFlag::UNIFORM_READ: return "AccessFlag::UNIFORM_READ"; + case stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ: return "AccessFlag::VERTEX_ATTRIBUTE_READ"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::AccessFlag value) noexcept -> std::string { - switch (value) { - case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: return "AccessFlag::COLOR_ATTACHMENT_WRITE"; - case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE"; - case stormkit::gpu::AccessFlag::HOST_READ: return "AccessFlag::HOST_READ"; - case stormkit::gpu::AccessFlag::HOST_WRITE: return "AccessFlag::HOST_WRITE"; - case stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ: return "AccessFlag::INDIRECT_COMMAND_READ"; - case stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ: return "AccessFlag::INPUT_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::MEMORY_READ: return "AccessFlag::MEMORY_READ"; - case stormkit::gpu::AccessFlag::MEMORY_WRITE: return "AccessFlag::MEMORY_WRITE"; - case stormkit::gpu::AccessFlag::NONE: return "AccessFlag::NONE"; - case stormkit::gpu::AccessFlag::SHADER_READ: return "AccessFlag::SHADER_READ"; - case stormkit::gpu::AccessFlag::SHADER_WRITE: return "AccessFlag::SHADER_WRITE"; - case stormkit::gpu::AccessFlag::TRANSFER_READ: return "AccessFlag::TRANSFER_READ"; - case stormkit::gpu::AccessFlag::TRANSFER_WRITE: return "AccessFlag::TRANSFER_WRITE"; - case stormkit::gpu::AccessFlag::UNIFORM_READ: return "AccessFlag::UNIFORM_READ"; - case stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ: return "AccessFlag::VERTEX_ATTRIBUTE_READ"; + switch(value) { + case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: return "AccessFlag::COLOR_ATTACHMENT_WRITE"; + case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE"; + case stormkit::gpu::AccessFlag::HOST_READ: return "AccessFlag::HOST_READ"; + case stormkit::gpu::AccessFlag::HOST_WRITE: return "AccessFlag::HOST_WRITE"; + case stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ: return "AccessFlag::INDIRECT_COMMAND_READ"; + case stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ: return "AccessFlag::INPUT_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::MEMORY_READ: return "AccessFlag::MEMORY_READ"; + case stormkit::gpu::AccessFlag::MEMORY_WRITE: return "AccessFlag::MEMORY_WRITE"; + case stormkit::gpu::AccessFlag::NONE: return "AccessFlag::NONE"; + case stormkit::gpu::AccessFlag::SHADER_READ: return "AccessFlag::SHADER_READ"; + case stormkit::gpu::AccessFlag::SHADER_WRITE: return "AccessFlag::SHADER_WRITE"; + case stormkit::gpu::AccessFlag::TRANSFER_READ: return "AccessFlag::TRANSFER_READ"; + case stormkit::gpu::AccessFlag::TRANSFER_WRITE: return "AccessFlag::TRANSFER_WRITE"; + case stormkit::gpu::AccessFlag::UNIFORM_READ: return "AccessFlag::UNIFORM_READ"; + case stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ: return "AccessFlag::VERTEX_ATTRIBUTE_READ"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::AttachmentLoadOperation) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::AttachmentLoadOperation::CLEAR, - stormkit::gpu::AttachmentLoadOperation::DONT_CARE, - stormkit::gpu::AttachmentLoadOperation::LOAD, - + stormkit::gpu::AttachmentLoadOperation::CLEAR, + stormkit::gpu::AttachmentLoadOperation::DONT_CARE, + stormkit::gpu::AttachmentLoadOperation::LOAD, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::AttachmentLoadOperation - value) noexcept -> std::string_view { - switch (value) { - case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; - case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; - case stormkit::gpu::AttachmentLoadOperation::LOAD: return "AttachmentLoadOperation::LOAD"; + constexpr auto stormkit::core::as_string(stormkit::gpu::AttachmentLoadOperation value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; + case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; + case stormkit::gpu::AttachmentLoadOperation::LOAD: return "AttachmentLoadOperation::LOAD"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentLoadOperation - value) noexcept -> std::string { - switch (value) { - case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; - case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; - case stormkit::gpu::AttachmentLoadOperation::LOAD: return "AttachmentLoadOperation::LOAD"; + constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentLoadOperation value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; + case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; + case stormkit::gpu::AttachmentLoadOperation::LOAD: return "AttachmentLoadOperation::LOAD"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::AttachmentStoreOperation) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::AttachmentStoreOperation::DONT_CARE, - stormkit::gpu::AttachmentStoreOperation::STORE, - + stormkit::gpu::AttachmentStoreOperation::DONT_CARE, + stormkit::gpu::AttachmentStoreOperation::STORE, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::AttachmentStoreOperation - value) noexcept -> std::string_view { - switch (value) { - case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; - case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; + constexpr auto stormkit::core::as_string(stormkit::gpu::AttachmentStoreOperation value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; + case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentStoreOperation - value) noexcept -> std::string { - switch (value) { - case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; - case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; + constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentStoreOperation value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; + case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::BlendFactor) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::BlendFactor::CONSTANT_ALPHA, - stormkit::gpu::BlendFactor::CONSTANT_COLOR, - stormkit::gpu::BlendFactor::DST_ALPHA, - stormkit::gpu::BlendFactor::DST_COLOR, - stormkit::gpu::BlendFactor::ONE, - stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA, - stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR, - stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA, - stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR, - stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA, - stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR, - stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA, - stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR, - stormkit::gpu::BlendFactor::SRC1_ALPHA, - stormkit::gpu::BlendFactor::SRC1_COLOR, - stormkit::gpu::BlendFactor::SRC_ALPHA, - stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE, - stormkit::gpu::BlendFactor::SRC_COLOR, - stormkit::gpu::BlendFactor::ZERO, - - }; - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::BlendFactor value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::BlendFactor::CONSTANT_ALPHA: return "BlendFactor::CONSTANT_ALPHA"; - case stormkit::gpu::BlendFactor::CONSTANT_COLOR: return "BlendFactor::CONSTANT_COLOR"; - case stormkit::gpu::BlendFactor::DST_ALPHA: return "BlendFactor::DST_ALPHA"; - case stormkit::gpu::BlendFactor::DST_COLOR: return "BlendFactor::DST_COLOR"; - case stormkit::gpu::BlendFactor::ONE: return "BlendFactor::ONE"; - case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: return "BlendFactor::ONE_MINUS_CONSTANT_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR: return "BlendFactor::ONE_MINUS_CONSTANT_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA: return "BlendFactor::ONE_MINUS_DST_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR: return "BlendFactor::ONE_MINUS_DST_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA: return "BlendFactor::ONE_MINUS_SRC1_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR: return "BlendFactor::ONE_MINUS_SRC1_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA: return "BlendFactor::ONE_MINUS_SRC_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR: return "BlendFactor::ONE_MINUS_SRC_COLOR"; - case stormkit::gpu::BlendFactor::SRC1_ALPHA: return "BlendFactor::SRC1_ALPHA"; - case stormkit::gpu::BlendFactor::SRC1_COLOR: return "BlendFactor::SRC1_COLOR"; - case stormkit::gpu::BlendFactor::SRC_ALPHA: return "BlendFactor::SRC_ALPHA"; - case stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE: return "BlendFactor::SRC_ALPHA_SATURATE"; - case stormkit::gpu::BlendFactor::SRC_COLOR: return "BlendFactor::SRC_COLOR"; - case stormkit::gpu::BlendFactor::ZERO: return "BlendFactor::ZERO"; - } - std::unreachable(); - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::BlendFactor value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::BlendFactor::CONSTANT_ALPHA: return "BlendFactor::CONSTANT_ALPHA"; - case stormkit::gpu::BlendFactor::CONSTANT_COLOR: return "BlendFactor::CONSTANT_COLOR"; - case stormkit::gpu::BlendFactor::DST_ALPHA: return "BlendFactor::DST_ALPHA"; - case stormkit::gpu::BlendFactor::DST_COLOR: return "BlendFactor::DST_COLOR"; - case stormkit::gpu::BlendFactor::ONE: return "BlendFactor::ONE"; - case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: return "BlendFactor::ONE_MINUS_CONSTANT_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR: return "BlendFactor::ONE_MINUS_CONSTANT_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA: return "BlendFactor::ONE_MINUS_DST_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR: return "BlendFactor::ONE_MINUS_DST_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA: return "BlendFactor::ONE_MINUS_SRC1_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR: return "BlendFactor::ONE_MINUS_SRC1_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA: return "BlendFactor::ONE_MINUS_SRC_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR: return "BlendFactor::ONE_MINUS_SRC_COLOR"; - case stormkit::gpu::BlendFactor::SRC1_ALPHA: return "BlendFactor::SRC1_ALPHA"; - case stormkit::gpu::BlendFactor::SRC1_COLOR: return "BlendFactor::SRC1_COLOR"; - case stormkit::gpu::BlendFactor::SRC_ALPHA: return "BlendFactor::SRC_ALPHA"; - case stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE: return "BlendFactor::SRC_ALPHA_SATURATE"; - case stormkit::gpu::BlendFactor::SRC_COLOR: return "BlendFactor::SRC_COLOR"; - case stormkit::gpu::BlendFactor::ZERO: return "BlendFactor::ZERO"; + stormkit::gpu::BlendFactor::CONSTANT_ALPHA, + stormkit::gpu::BlendFactor::CONSTANT_COLOR, + stormkit::gpu::BlendFactor::DST_ALPHA, + stormkit::gpu::BlendFactor::DST_COLOR, + stormkit::gpu::BlendFactor::ONE, + stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA, + stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR, + stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA, + stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR, + stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA, + stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR, + stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA, + stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR, + stormkit::gpu::BlendFactor::SRC1_ALPHA, + stormkit::gpu::BlendFactor::SRC1_COLOR, + stormkit::gpu::BlendFactor::SRC_ALPHA, + stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE, + stormkit::gpu::BlendFactor::SRC_COLOR, + stormkit::gpu::BlendFactor::ZERO, + + }; + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::BlendFactor value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::BlendFactor::CONSTANT_ALPHA: return "BlendFactor::CONSTANT_ALPHA"; + case stormkit::gpu::BlendFactor::CONSTANT_COLOR: return "BlendFactor::CONSTANT_COLOR"; + case stormkit::gpu::BlendFactor::DST_ALPHA: return "BlendFactor::DST_ALPHA"; + case stormkit::gpu::BlendFactor::DST_COLOR: return "BlendFactor::DST_COLOR"; + case stormkit::gpu::BlendFactor::ONE: return "BlendFactor::ONE"; + case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: return "BlendFactor::ONE_MINUS_CONSTANT_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR: return "BlendFactor::ONE_MINUS_CONSTANT_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA: return "BlendFactor::ONE_MINUS_DST_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR: return "BlendFactor::ONE_MINUS_DST_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA: return "BlendFactor::ONE_MINUS_SRC1_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR: return "BlendFactor::ONE_MINUS_SRC1_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA: return "BlendFactor::ONE_MINUS_SRC_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR: return "BlendFactor::ONE_MINUS_SRC_COLOR"; + case stormkit::gpu::BlendFactor::SRC1_ALPHA: return "BlendFactor::SRC1_ALPHA"; + case stormkit::gpu::BlendFactor::SRC1_COLOR: return "BlendFactor::SRC1_COLOR"; + case stormkit::gpu::BlendFactor::SRC_ALPHA: return "BlendFactor::SRC_ALPHA"; + case stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE: return "BlendFactor::SRC_ALPHA_SATURATE"; + case stormkit::gpu::BlendFactor::SRC_COLOR: return "BlendFactor::SRC_COLOR"; + case stormkit::gpu::BlendFactor::ZERO: return "BlendFactor::ZERO"; + + } + std::unreachable(); + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::to_string(stormkit::gpu::BlendFactor value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::BlendFactor::CONSTANT_ALPHA: return "BlendFactor::CONSTANT_ALPHA"; + case stormkit::gpu::BlendFactor::CONSTANT_COLOR: return "BlendFactor::CONSTANT_COLOR"; + case stormkit::gpu::BlendFactor::DST_ALPHA: return "BlendFactor::DST_ALPHA"; + case stormkit::gpu::BlendFactor::DST_COLOR: return "BlendFactor::DST_COLOR"; + case stormkit::gpu::BlendFactor::ONE: return "BlendFactor::ONE"; + case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: return "BlendFactor::ONE_MINUS_CONSTANT_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR: return "BlendFactor::ONE_MINUS_CONSTANT_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA: return "BlendFactor::ONE_MINUS_DST_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR: return "BlendFactor::ONE_MINUS_DST_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA: return "BlendFactor::ONE_MINUS_SRC1_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR: return "BlendFactor::ONE_MINUS_SRC1_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA: return "BlendFactor::ONE_MINUS_SRC_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR: return "BlendFactor::ONE_MINUS_SRC_COLOR"; + case stormkit::gpu::BlendFactor::SRC1_ALPHA: return "BlendFactor::SRC1_ALPHA"; + case stormkit::gpu::BlendFactor::SRC1_COLOR: return "BlendFactor::SRC1_COLOR"; + case stormkit::gpu::BlendFactor::SRC_ALPHA: return "BlendFactor::SRC_ALPHA"; + case stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE: return "BlendFactor::SRC_ALPHA_SATURATE"; + case stormkit::gpu::BlendFactor::SRC_COLOR: return "BlendFactor::SRC_COLOR"; + case stormkit::gpu::BlendFactor::ZERO: return "BlendFactor::ZERO"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::BlendOperation) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::BlendOperation::ADD, stormkit::gpu::BlendOperation::MAX, - stormkit::gpu::BlendOperation::MIN, stormkit::gpu::BlendOperation::REVERSE_SUBTRACT, - stormkit::gpu::BlendOperation::SUBTRACT, - + stormkit::gpu::BlendOperation::ADD, + stormkit::gpu::BlendOperation::MAX, + stormkit::gpu::BlendOperation::MIN, + stormkit::gpu::BlendOperation::REVERSE_SUBTRACT, + stormkit::gpu::BlendOperation::SUBTRACT, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::BlendOperation value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::BlendOperation::ADD: return "BlendOperation::ADD"; - case stormkit::gpu::BlendOperation::MAX: return "BlendOperation::MAX"; - case stormkit::gpu::BlendOperation::MIN: return "BlendOperation::MIN"; - case stormkit::gpu::BlendOperation::REVERSE_SUBTRACT: return "BlendOperation::REVERSE_SUBTRACT"; - case stormkit::gpu::BlendOperation::SUBTRACT: return "BlendOperation::SUBTRACT"; + constexpr auto stormkit::core::as_string(stormkit::gpu::BlendOperation value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::BlendOperation::ADD: return "BlendOperation::ADD"; + case stormkit::gpu::BlendOperation::MAX: return "BlendOperation::MAX"; + case stormkit::gpu::BlendOperation::MIN: return "BlendOperation::MIN"; + case stormkit::gpu::BlendOperation::REVERSE_SUBTRACT: return "BlendOperation::REVERSE_SUBTRACT"; + case stormkit::gpu::BlendOperation::SUBTRACT: return "BlendOperation::SUBTRACT"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::BlendOperation value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::BlendOperation::ADD: return "BlendOperation::ADD"; - case stormkit::gpu::BlendOperation::MAX: return "BlendOperation::MAX"; - case stormkit::gpu::BlendOperation::MIN: return "BlendOperation::MIN"; - case stormkit::gpu::BlendOperation::REVERSE_SUBTRACT: return "BlendOperation::REVERSE_SUBTRACT"; - case stormkit::gpu::BlendOperation::SUBTRACT: return "BlendOperation::SUBTRACT"; + constexpr auto stormkit::core::to_string(stormkit::gpu::BlendOperation value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::BlendOperation::ADD: return "BlendOperation::ADD"; + case stormkit::gpu::BlendOperation::MAX: return "BlendOperation::MAX"; + case stormkit::gpu::BlendOperation::MIN: return "BlendOperation::MIN"; + case stormkit::gpu::BlendOperation::REVERSE_SUBTRACT: return "BlendOperation::REVERSE_SUBTRACT"; + case stormkit::gpu::BlendOperation::SUBTRACT: return "BlendOperation::SUBTRACT"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::BorderColor) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK, stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE, - stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK, stormkit::gpu::BorderColor::INT_OPAQUE_BLACK, - stormkit::gpu::BorderColor::INT_OPAQUE_WHITE, stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK, - + stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK, + stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE, + stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK, + stormkit::gpu::BorderColor::INT_OPAQUE_BLACK, + stormkit::gpu::BorderColor::INT_OPAQUE_WHITE, + stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::BorderColor value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: return "BorderColor::FLOAT_OPAQUE_BLACK"; - case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: return "BorderColor::FLOAT_OPAQUE_WHITE"; - case stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK: return "BorderColor::FLOAT_TRANSPARENT_BLACK"; - case stormkit::gpu::BorderColor::INT_OPAQUE_BLACK: return "BorderColor::INT_OPAQUE_BLACK"; - case stormkit::gpu::BorderColor::INT_OPAQUE_WHITE: return "BorderColor::INT_OPAQUE_WHITE"; - case stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK: return "BorderColor::INT_TRANSPARENT_BLACK"; + constexpr auto stormkit::core::as_string(stormkit::gpu::BorderColor value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: return "BorderColor::FLOAT_OPAQUE_BLACK"; + case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: return "BorderColor::FLOAT_OPAQUE_WHITE"; + case stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK: return "BorderColor::FLOAT_TRANSPARENT_BLACK"; + case stormkit::gpu::BorderColor::INT_OPAQUE_BLACK: return "BorderColor::INT_OPAQUE_BLACK"; + case stormkit::gpu::BorderColor::INT_OPAQUE_WHITE: return "BorderColor::INT_OPAQUE_WHITE"; + case stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK: return "BorderColor::INT_TRANSPARENT_BLACK"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::BorderColor value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: return "BorderColor::FLOAT_OPAQUE_BLACK"; - case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: return "BorderColor::FLOAT_OPAQUE_WHITE"; - case stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK: return "BorderColor::FLOAT_TRANSPARENT_BLACK"; - case stormkit::gpu::BorderColor::INT_OPAQUE_BLACK: return "BorderColor::INT_OPAQUE_BLACK"; - case stormkit::gpu::BorderColor::INT_OPAQUE_WHITE: return "BorderColor::INT_OPAQUE_WHITE"; - case stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK: return "BorderColor::INT_TRANSPARENT_BLACK"; + constexpr auto stormkit::core::to_string(stormkit::gpu::BorderColor value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: return "BorderColor::FLOAT_OPAQUE_BLACK"; + case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: return "BorderColor::FLOAT_OPAQUE_WHITE"; + case stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK: return "BorderColor::FLOAT_TRANSPARENT_BLACK"; + case stormkit::gpu::BorderColor::INT_OPAQUE_BLACK: return "BorderColor::INT_OPAQUE_BLACK"; + case stormkit::gpu::BorderColor::INT_OPAQUE_WHITE: return "BorderColor::INT_OPAQUE_WHITE"; + case stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK: return "BorderColor::INT_TRANSPARENT_BLACK"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::BufferUsageFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::BufferUsageFlag::INDEX, stormkit::gpu::BufferUsageFlag::INDIRECT, - stormkit::gpu::BufferUsageFlag::STORAGE, stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL, - stormkit::gpu::BufferUsageFlag::TRANSFER_DST, stormkit::gpu::BufferUsageFlag::TRANSFER_SRC, - stormkit::gpu::BufferUsageFlag::UNIFORM, stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL, - stormkit::gpu::BufferUsageFlag::VERTEX, - + stormkit::gpu::BufferUsageFlag::INDEX, + stormkit::gpu::BufferUsageFlag::INDIRECT, + stormkit::gpu::BufferUsageFlag::STORAGE, + stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL, + stormkit::gpu::BufferUsageFlag::TRANSFER_DST, + stormkit::gpu::BufferUsageFlag::TRANSFER_SRC, + stormkit::gpu::BufferUsageFlag::UNIFORM, + stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL, + stormkit::gpu::BufferUsageFlag::VERTEX, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::BufferUsageFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::BufferUsageFlag::INDEX: return "BufferUsageFlag::INDEX"; - case stormkit::gpu::BufferUsageFlag::INDIRECT: return "BufferUsageFlag::INDIRECT"; - case stormkit::gpu::BufferUsageFlag::STORAGE: return "BufferUsageFlag::STORAGE"; - case stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL: return "BufferUsageFlag::STORAGE_TEXEL"; - case stormkit::gpu::BufferUsageFlag::TRANSFER_DST: return "BufferUsageFlag::TRANSFER_DST"; - case stormkit::gpu::BufferUsageFlag::TRANSFER_SRC: return "BufferUsageFlag::TRANSFER_SRC"; - case stormkit::gpu::BufferUsageFlag::UNIFORM: return "BufferUsageFlag::UNIFORM"; - case stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL: return "BufferUsageFlag::UNIFORM_TEXEL"; - case stormkit::gpu::BufferUsageFlag::VERTEX: return "BufferUsageFlag::VERTEX"; + constexpr auto stormkit::core::as_string(stormkit::gpu::BufferUsageFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::BufferUsageFlag::INDEX: return "BufferUsageFlag::INDEX"; + case stormkit::gpu::BufferUsageFlag::INDIRECT: return "BufferUsageFlag::INDIRECT"; + case stormkit::gpu::BufferUsageFlag::STORAGE: return "BufferUsageFlag::STORAGE"; + case stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL: return "BufferUsageFlag::STORAGE_TEXEL"; + case stormkit::gpu::BufferUsageFlag::TRANSFER_DST: return "BufferUsageFlag::TRANSFER_DST"; + case stormkit::gpu::BufferUsageFlag::TRANSFER_SRC: return "BufferUsageFlag::TRANSFER_SRC"; + case stormkit::gpu::BufferUsageFlag::UNIFORM: return "BufferUsageFlag::UNIFORM"; + case stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL: return "BufferUsageFlag::UNIFORM_TEXEL"; + case stormkit::gpu::BufferUsageFlag::VERTEX: return "BufferUsageFlag::VERTEX"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::BufferUsageFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::BufferUsageFlag::INDEX: return "BufferUsageFlag::INDEX"; - case stormkit::gpu::BufferUsageFlag::INDIRECT: return "BufferUsageFlag::INDIRECT"; - case stormkit::gpu::BufferUsageFlag::STORAGE: return "BufferUsageFlag::STORAGE"; - case stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL: return "BufferUsageFlag::STORAGE_TEXEL"; - case stormkit::gpu::BufferUsageFlag::TRANSFER_DST: return "BufferUsageFlag::TRANSFER_DST"; - case stormkit::gpu::BufferUsageFlag::TRANSFER_SRC: return "BufferUsageFlag::TRANSFER_SRC"; - case stormkit::gpu::BufferUsageFlag::UNIFORM: return "BufferUsageFlag::UNIFORM"; - case stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL: return "BufferUsageFlag::UNIFORM_TEXEL"; - case stormkit::gpu::BufferUsageFlag::VERTEX: return "BufferUsageFlag::VERTEX"; + constexpr auto stormkit::core::to_string(stormkit::gpu::BufferUsageFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::BufferUsageFlag::INDEX: return "BufferUsageFlag::INDEX"; + case stormkit::gpu::BufferUsageFlag::INDIRECT: return "BufferUsageFlag::INDIRECT"; + case stormkit::gpu::BufferUsageFlag::STORAGE: return "BufferUsageFlag::STORAGE"; + case stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL: return "BufferUsageFlag::STORAGE_TEXEL"; + case stormkit::gpu::BufferUsageFlag::TRANSFER_DST: return "BufferUsageFlag::TRANSFER_DST"; + case stormkit::gpu::BufferUsageFlag::TRANSFER_SRC: return "BufferUsageFlag::TRANSFER_SRC"; + case stormkit::gpu::BufferUsageFlag::UNIFORM: return "BufferUsageFlag::UNIFORM"; + case stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL: return "BufferUsageFlag::UNIFORM_TEXEL"; + case stormkit::gpu::BufferUsageFlag::VERTEX: return "BufferUsageFlag::VERTEX"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ColorComponentFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ColorComponentFlag::A, stormkit::gpu::ColorComponentFlag::B, - stormkit::gpu::ColorComponentFlag::G, stormkit::gpu::ColorComponentFlag::NONE, - stormkit::gpu::ColorComponentFlag::R, stormkit::gpu::ColorComponentFlag::RG, - stormkit::gpu::ColorComponentFlag::RGB, stormkit::gpu::ColorComponentFlag::RGBA, - + stormkit::gpu::ColorComponentFlag::A, + stormkit::gpu::ColorComponentFlag::B, + stormkit::gpu::ColorComponentFlag::G, + stormkit::gpu::ColorComponentFlag::NONE, + stormkit::gpu::ColorComponentFlag::R, + stormkit::gpu::ColorComponentFlag::RG, + stormkit::gpu::ColorComponentFlag::RGB, + stormkit::gpu::ColorComponentFlag::RGBA, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ColorComponentFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ColorComponentFlag::A: return "ColorComponentFlag::A"; - case stormkit::gpu::ColorComponentFlag::B: return "ColorComponentFlag::B"; - case stormkit::gpu::ColorComponentFlag::G: return "ColorComponentFlag::G"; - case stormkit::gpu::ColorComponentFlag::NONE: return "ColorComponentFlag::NONE"; - case stormkit::gpu::ColorComponentFlag::R: return "ColorComponentFlag::R"; - case stormkit::gpu::ColorComponentFlag::RG: return "ColorComponentFlag::RG"; - case stormkit::gpu::ColorComponentFlag::RGB: return "ColorComponentFlag::RGB"; - case stormkit::gpu::ColorComponentFlag::RGBA: return "ColorComponentFlag::RGBA"; + constexpr auto stormkit::core::as_string(stormkit::gpu::ColorComponentFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ColorComponentFlag::A: return "ColorComponentFlag::A"; + case stormkit::gpu::ColorComponentFlag::B: return "ColorComponentFlag::B"; + case stormkit::gpu::ColorComponentFlag::G: return "ColorComponentFlag::G"; + case stormkit::gpu::ColorComponentFlag::NONE: return "ColorComponentFlag::NONE"; + case stormkit::gpu::ColorComponentFlag::R: return "ColorComponentFlag::R"; + case stormkit::gpu::ColorComponentFlag::RG: return "ColorComponentFlag::RG"; + case stormkit::gpu::ColorComponentFlag::RGB: return "ColorComponentFlag::RGB"; + case stormkit::gpu::ColorComponentFlag::RGBA: return "ColorComponentFlag::RGBA"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ColorComponentFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::ColorComponentFlag::A: return "ColorComponentFlag::A"; - case stormkit::gpu::ColorComponentFlag::B: return "ColorComponentFlag::B"; - case stormkit::gpu::ColorComponentFlag::G: return "ColorComponentFlag::G"; - case stormkit::gpu::ColorComponentFlag::NONE: return "ColorComponentFlag::NONE"; - case stormkit::gpu::ColorComponentFlag::R: return "ColorComponentFlag::R"; - case stormkit::gpu::ColorComponentFlag::RG: return "ColorComponentFlag::RG"; - case stormkit::gpu::ColorComponentFlag::RGB: return "ColorComponentFlag::RGB"; - case stormkit::gpu::ColorComponentFlag::RGBA: return "ColorComponentFlag::RGBA"; + constexpr auto stormkit::core::to_string(stormkit::gpu::ColorComponentFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::ColorComponentFlag::A: return "ColorComponentFlag::A"; + case stormkit::gpu::ColorComponentFlag::B: return "ColorComponentFlag::B"; + case stormkit::gpu::ColorComponentFlag::G: return "ColorComponentFlag::G"; + case stormkit::gpu::ColorComponentFlag::NONE: return "ColorComponentFlag::NONE"; + case stormkit::gpu::ColorComponentFlag::R: return "ColorComponentFlag::R"; + case stormkit::gpu::ColorComponentFlag::RG: return "ColorComponentFlag::RG"; + case stormkit::gpu::ColorComponentFlag::RGB: return "ColorComponentFlag::RGB"; + case stormkit::gpu::ColorComponentFlag::RGBA: return "ColorComponentFlag::RGBA"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ColorSpace) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ColorSpace::ADOBERGB_LINEAR, - stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR, - stormkit::gpu::ColorSpace::BT2020_LINEAR, - stormkit::gpu::ColorSpace::BT709_LINEAR, - stormkit::gpu::ColorSpace::BT709_NONLINEAR, - stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR, - stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD, - stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR, - stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR, - stormkit::gpu::ColorSpace::DOLBYVISION, - stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR, - stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR, - stormkit::gpu::ColorSpace::HDR10_HLG, - stormkit::gpu::ColorSpace::HDR10_ST2084, - stormkit::gpu::ColorSpace::PASS_THROUGH, - stormkit::gpu::ColorSpace::SRGB_NONLINEAR, - + stormkit::gpu::ColorSpace::ADOBERGB_LINEAR, + stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR, + stormkit::gpu::ColorSpace::BT2020_LINEAR, + stormkit::gpu::ColorSpace::BT709_LINEAR, + stormkit::gpu::ColorSpace::BT709_NONLINEAR, + stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR, + stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD, + stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR, + stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR, + stormkit::gpu::ColorSpace::DOLBYVISION, + stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR, + stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR, + stormkit::gpu::ColorSpace::HDR10_HLG, + stormkit::gpu::ColorSpace::HDR10_ST2084, + stormkit::gpu::ColorSpace::PASS_THROUGH, + stormkit::gpu::ColorSpace::SRGB_NONLINEAR, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ColorSpace value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; - case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: return "ColorSpace::ADOBERGB_NONLINEAR"; - case stormkit::gpu::ColorSpace::BT2020_LINEAR: return "ColorSpace::BT2020_LINEAR"; - case stormkit::gpu::ColorSpace::BT709_LINEAR: return "ColorSpace::BT709_LINEAR"; - case stormkit::gpu::ColorSpace::BT709_NONLINEAR: return "ColorSpace::BT709_NONLINEAR"; - case stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR: return "ColorSpace::DCI_P3_NONLINEAR"; - case stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD: return "ColorSpace::DISPLAY_NATIVE_AMD"; - case stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR: return "ColorSpace::DISPLAY_P3_LINEAR"; - case stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR: return "ColorSpace::DISPLAY_P3_NONLINEAR"; - case stormkit::gpu::ColorSpace::DOLBYVISION: return "ColorSpace::DOLBYVISION"; - case stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR: return "ColorSpace::EXTENDED_SRGB_LINEAR"; - case stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR: return "ColorSpace::EXTENDED_SRGB_NONLINEAR"; - case stormkit::gpu::ColorSpace::HDR10_HLG: return "ColorSpace::HDR10_HLG"; - case stormkit::gpu::ColorSpace::HDR10_ST2084: return "ColorSpace::HDR10_ST2084"; - case stormkit::gpu::ColorSpace::PASS_THROUGH: return "ColorSpace::PASS_THROUGH"; - case stormkit::gpu::ColorSpace::SRGB_NONLINEAR: return "ColorSpace::SRGB_NONLINEAR"; + constexpr auto stormkit::core::as_string(stormkit::gpu::ColorSpace value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; + case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: return "ColorSpace::ADOBERGB_NONLINEAR"; + case stormkit::gpu::ColorSpace::BT2020_LINEAR: return "ColorSpace::BT2020_LINEAR"; + case stormkit::gpu::ColorSpace::BT709_LINEAR: return "ColorSpace::BT709_LINEAR"; + case stormkit::gpu::ColorSpace::BT709_NONLINEAR: return "ColorSpace::BT709_NONLINEAR"; + case stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR: return "ColorSpace::DCI_P3_NONLINEAR"; + case stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD: return "ColorSpace::DISPLAY_NATIVE_AMD"; + case stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR: return "ColorSpace::DISPLAY_P3_LINEAR"; + case stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR: return "ColorSpace::DISPLAY_P3_NONLINEAR"; + case stormkit::gpu::ColorSpace::DOLBYVISION: return "ColorSpace::DOLBYVISION"; + case stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR: return "ColorSpace::EXTENDED_SRGB_LINEAR"; + case stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR: return "ColorSpace::EXTENDED_SRGB_NONLINEAR"; + case stormkit::gpu::ColorSpace::HDR10_HLG: return "ColorSpace::HDR10_HLG"; + case stormkit::gpu::ColorSpace::HDR10_ST2084: return "ColorSpace::HDR10_ST2084"; + case stormkit::gpu::ColorSpace::PASS_THROUGH: return "ColorSpace::PASS_THROUGH"; + case stormkit::gpu::ColorSpace::SRGB_NONLINEAR: return "ColorSpace::SRGB_NONLINEAR"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::ColorSpace value) noexcept -> std::string { - switch (value) { - case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; - case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: return "ColorSpace::ADOBERGB_NONLINEAR"; - case stormkit::gpu::ColorSpace::BT2020_LINEAR: return "ColorSpace::BT2020_LINEAR"; - case stormkit::gpu::ColorSpace::BT709_LINEAR: return "ColorSpace::BT709_LINEAR"; - case stormkit::gpu::ColorSpace::BT709_NONLINEAR: return "ColorSpace::BT709_NONLINEAR"; - case stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR: return "ColorSpace::DCI_P3_NONLINEAR"; - case stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD: return "ColorSpace::DISPLAY_NATIVE_AMD"; - case stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR: return "ColorSpace::DISPLAY_P3_LINEAR"; - case stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR: return "ColorSpace::DISPLAY_P3_NONLINEAR"; - case stormkit::gpu::ColorSpace::DOLBYVISION: return "ColorSpace::DOLBYVISION"; - case stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR: return "ColorSpace::EXTENDED_SRGB_LINEAR"; - case stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR: return "ColorSpace::EXTENDED_SRGB_NONLINEAR"; - case stormkit::gpu::ColorSpace::HDR10_HLG: return "ColorSpace::HDR10_HLG"; - case stormkit::gpu::ColorSpace::HDR10_ST2084: return "ColorSpace::HDR10_ST2084"; - case stormkit::gpu::ColorSpace::PASS_THROUGH: return "ColorSpace::PASS_THROUGH"; - case stormkit::gpu::ColorSpace::SRGB_NONLINEAR: return "ColorSpace::SRGB_NONLINEAR"; + switch(value) { + case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; + case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: return "ColorSpace::ADOBERGB_NONLINEAR"; + case stormkit::gpu::ColorSpace::BT2020_LINEAR: return "ColorSpace::BT2020_LINEAR"; + case stormkit::gpu::ColorSpace::BT709_LINEAR: return "ColorSpace::BT709_LINEAR"; + case stormkit::gpu::ColorSpace::BT709_NONLINEAR: return "ColorSpace::BT709_NONLINEAR"; + case stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR: return "ColorSpace::DCI_P3_NONLINEAR"; + case stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD: return "ColorSpace::DISPLAY_NATIVE_AMD"; + case stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR: return "ColorSpace::DISPLAY_P3_LINEAR"; + case stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR: return "ColorSpace::DISPLAY_P3_NONLINEAR"; + case stormkit::gpu::ColorSpace::DOLBYVISION: return "ColorSpace::DOLBYVISION"; + case stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR: return "ColorSpace::EXTENDED_SRGB_LINEAR"; + case stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR: return "ColorSpace::EXTENDED_SRGB_NONLINEAR"; + case stormkit::gpu::ColorSpace::HDR10_HLG: return "ColorSpace::HDR10_HLG"; + case stormkit::gpu::ColorSpace::HDR10_ST2084: return "ColorSpace::HDR10_ST2084"; + case stormkit::gpu::ColorSpace::PASS_THROUGH: return "ColorSpace::PASS_THROUGH"; + case stormkit::gpu::ColorSpace::SRGB_NONLINEAR: return "ColorSpace::SRGB_NONLINEAR"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::CommandBufferLevel) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::CommandBufferLevel::PRIMARY, - stormkit::gpu::CommandBufferLevel::SECONDARY, - + stormkit::gpu::CommandBufferLevel::PRIMARY, + stormkit::gpu::CommandBufferLevel::SECONDARY, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::CommandBufferLevel value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::CommandBufferLevel::PRIMARY: return "CommandBufferLevel::PRIMARY"; - case stormkit::gpu::CommandBufferLevel::SECONDARY: return "CommandBufferLevel::SECONDARY"; + constexpr auto stormkit::core::as_string(stormkit::gpu::CommandBufferLevel value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::CommandBufferLevel::PRIMARY: return "CommandBufferLevel::PRIMARY"; + case stormkit::gpu::CommandBufferLevel::SECONDARY: return "CommandBufferLevel::SECONDARY"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::CommandBufferLevel value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::CommandBufferLevel::PRIMARY: return "CommandBufferLevel::PRIMARY"; - case stormkit::gpu::CommandBufferLevel::SECONDARY: return "CommandBufferLevel::SECONDARY"; + constexpr auto stormkit::core::to_string(stormkit::gpu::CommandBufferLevel value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::CommandBufferLevel::PRIMARY: return "CommandBufferLevel::PRIMARY"; + case stormkit::gpu::CommandBufferLevel::SECONDARY: return "CommandBufferLevel::SECONDARY"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::CompareOperation) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::CompareOperation::ALWAYS, stormkit::gpu::CompareOperation::EQUAL, - stormkit::gpu::CompareOperation::GREATER, stormkit::gpu::CompareOperation::GREATER_OR_EQUAL, - stormkit::gpu::CompareOperation::LESS, stormkit::gpu::CompareOperation::LESS_OR_EQUAL, - stormkit::gpu::CompareOperation::NEVER, stormkit::gpu::CompareOperation::NOT_EQUAL, - + stormkit::gpu::CompareOperation::ALWAYS, + stormkit::gpu::CompareOperation::EQUAL, + stormkit::gpu::CompareOperation::GREATER, + stormkit::gpu::CompareOperation::GREATER_OR_EQUAL, + stormkit::gpu::CompareOperation::LESS, + stormkit::gpu::CompareOperation::LESS_OR_EQUAL, + stormkit::gpu::CompareOperation::NEVER, + stormkit::gpu::CompareOperation::NOT_EQUAL, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::CompareOperation value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::CompareOperation::ALWAYS: return "CompareOperation::ALWAYS"; - case stormkit::gpu::CompareOperation::EQUAL: return "CompareOperation::EQUAL"; - case stormkit::gpu::CompareOperation::GREATER: return "CompareOperation::GREATER"; - case stormkit::gpu::CompareOperation::GREATER_OR_EQUAL: return "CompareOperation::GREATER_OR_EQUAL"; - case stormkit::gpu::CompareOperation::LESS: return "CompareOperation::LESS"; - case stormkit::gpu::CompareOperation::LESS_OR_EQUAL: return "CompareOperation::LESS_OR_EQUAL"; - case stormkit::gpu::CompareOperation::NEVER: return "CompareOperation::NEVER"; - case stormkit::gpu::CompareOperation::NOT_EQUAL: return "CompareOperation::NOT_EQUAL"; + constexpr auto stormkit::core::as_string(stormkit::gpu::CompareOperation value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::CompareOperation::ALWAYS: return "CompareOperation::ALWAYS"; + case stormkit::gpu::CompareOperation::EQUAL: return "CompareOperation::EQUAL"; + case stormkit::gpu::CompareOperation::GREATER: return "CompareOperation::GREATER"; + case stormkit::gpu::CompareOperation::GREATER_OR_EQUAL: return "CompareOperation::GREATER_OR_EQUAL"; + case stormkit::gpu::CompareOperation::LESS: return "CompareOperation::LESS"; + case stormkit::gpu::CompareOperation::LESS_OR_EQUAL: return "CompareOperation::LESS_OR_EQUAL"; + case stormkit::gpu::CompareOperation::NEVER: return "CompareOperation::NEVER"; + case stormkit::gpu::CompareOperation::NOT_EQUAL: return "CompareOperation::NOT_EQUAL"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::CompareOperation value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::CompareOperation::ALWAYS: return "CompareOperation::ALWAYS"; - case stormkit::gpu::CompareOperation::EQUAL: return "CompareOperation::EQUAL"; - case stormkit::gpu::CompareOperation::GREATER: return "CompareOperation::GREATER"; - case stormkit::gpu::CompareOperation::GREATER_OR_EQUAL: return "CompareOperation::GREATER_OR_EQUAL"; - case stormkit::gpu::CompareOperation::LESS: return "CompareOperation::LESS"; - case stormkit::gpu::CompareOperation::LESS_OR_EQUAL: return "CompareOperation::LESS_OR_EQUAL"; - case stormkit::gpu::CompareOperation::NEVER: return "CompareOperation::NEVER"; - case stormkit::gpu::CompareOperation::NOT_EQUAL: return "CompareOperation::NOT_EQUAL"; + constexpr auto stormkit::core::to_string(stormkit::gpu::CompareOperation value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::CompareOperation::ALWAYS: return "CompareOperation::ALWAYS"; + case stormkit::gpu::CompareOperation::EQUAL: return "CompareOperation::EQUAL"; + case stormkit::gpu::CompareOperation::GREATER: return "CompareOperation::GREATER"; + case stormkit::gpu::CompareOperation::GREATER_OR_EQUAL: return "CompareOperation::GREATER_OR_EQUAL"; + case stormkit::gpu::CompareOperation::LESS: return "CompareOperation::LESS"; + case stormkit::gpu::CompareOperation::LESS_OR_EQUAL: return "CompareOperation::LESS_OR_EQUAL"; + case stormkit::gpu::CompareOperation::NEVER: return "CompareOperation::NEVER"; + case stormkit::gpu::CompareOperation::NOT_EQUAL: return "CompareOperation::NOT_EQUAL"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::CullModeFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::CullModeFlag::BACK, - stormkit::gpu::CullModeFlag::FRONT, - stormkit::gpu::CullModeFlag::FRONT_BACK, - stormkit::gpu::CullModeFlag::NONE, - + stormkit::gpu::CullModeFlag::BACK, + stormkit::gpu::CullModeFlag::FRONT, + stormkit::gpu::CullModeFlag::FRONT_BACK, + stormkit::gpu::CullModeFlag::NONE, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::CullModeFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::CullModeFlag::BACK: return "CullModeFlag::BACK"; - case stormkit::gpu::CullModeFlag::FRONT: return "CullModeFlag::FRONT"; - case stormkit::gpu::CullModeFlag::FRONT_BACK: return "CullModeFlag::FRONT_BACK"; - case stormkit::gpu::CullModeFlag::NONE: return "CullModeFlag::NONE"; + constexpr auto stormkit::core::as_string(stormkit::gpu::CullModeFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::CullModeFlag::BACK: return "CullModeFlag::BACK"; + case stormkit::gpu::CullModeFlag::FRONT: return "CullModeFlag::FRONT"; + case stormkit::gpu::CullModeFlag::FRONT_BACK: return "CullModeFlag::FRONT_BACK"; + case stormkit::gpu::CullModeFlag::NONE: return "CullModeFlag::NONE"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::CullModeFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::CullModeFlag::BACK: return "CullModeFlag::BACK"; - case stormkit::gpu::CullModeFlag::FRONT: return "CullModeFlag::FRONT"; - case stormkit::gpu::CullModeFlag::FRONT_BACK: return "CullModeFlag::FRONT_BACK"; - case stormkit::gpu::CullModeFlag::NONE: return "CullModeFlag::NONE"; + constexpr auto stormkit::core::to_string(stormkit::gpu::CullModeFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::CullModeFlag::BACK: return "CullModeFlag::BACK"; + case stormkit::gpu::CullModeFlag::FRONT: return "CullModeFlag::FRONT"; + case stormkit::gpu::CullModeFlag::FRONT_BACK: return "CullModeFlag::FRONT_BACK"; + case stormkit::gpu::CullModeFlag::NONE: return "CullModeFlag::NONE"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::DebugObjectType) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::DebugObjectType::BUFFER, - stormkit::gpu::DebugObjectType::BUFFER_VIEW, - stormkit::gpu::DebugObjectType::COMMAND_BUFFER, - stormkit::gpu::DebugObjectType::COMMAND_POOL, - stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK, - stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL, - stormkit::gpu::DebugObjectType::DESCRIPTOR_SET, - stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT, - stormkit::gpu::DebugObjectType::DEVICE, - stormkit::gpu::DebugObjectType::DEVICE_MEMORY, - stormkit::gpu::DebugObjectType::DISPLAY, - stormkit::gpu::DebugObjectType::EVENT, - stormkit::gpu::DebugObjectType::FENCE, - stormkit::gpu::DebugObjectType::FRAMEBUFFER, - stormkit::gpu::DebugObjectType::IMAGE, - stormkit::gpu::DebugObjectType::IMAGE_VIEW, - stormkit::gpu::DebugObjectType::INSTANCE, - stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE, - stormkit::gpu::DebugObjectType::PIPELINE, - stormkit::gpu::DebugObjectType::PIPELINE_CACHE, - stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT, - stormkit::gpu::DebugObjectType::QUERY_POOL, - stormkit::gpu::DebugObjectType::QUEUE, - stormkit::gpu::DebugObjectType::RENDER_PASS, - stormkit::gpu::DebugObjectType::SAMPLER, - stormkit::gpu::DebugObjectType::SEMAPHORE, - stormkit::gpu::DebugObjectType::SHADER_MODULE, - stormkit::gpu::DebugObjectType::SURFACE, - stormkit::gpu::DebugObjectType::SWAPCHAIN, - stormkit::gpu::DebugObjectType::UNKNOWN, - - }; - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::DebugObjectType value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::DebugObjectType::BUFFER: return "DebugObjectType::BUFFER"; - case stormkit::gpu::DebugObjectType::BUFFER_VIEW: return "DebugObjectType::BUFFER_VIEW"; - case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: return "DebugObjectType::COMMAND_BUFFER"; - case stormkit::gpu::DebugObjectType::COMMAND_POOL: return "DebugObjectType::COMMAND_POOL"; - case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: return "DebugObjectType::DEBUG_REPORT_CALLBACK"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: return "DebugObjectType::DESCRIPTOR_POOL"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: return "DebugObjectType::DESCRIPTOR_SET"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; - case stormkit::gpu::DebugObjectType::DEVICE: return "DebugObjectType::DEVICE"; - case stormkit::gpu::DebugObjectType::DEVICE_MEMORY: return "DebugObjectType::DEVICE_MEMORY"; - case stormkit::gpu::DebugObjectType::DISPLAY: return "DebugObjectType::DISPLAY"; - case stormkit::gpu::DebugObjectType::EVENT: return "DebugObjectType::EVENT"; - case stormkit::gpu::DebugObjectType::FENCE: return "DebugObjectType::FENCE"; - case stormkit::gpu::DebugObjectType::FRAMEBUFFER: return "DebugObjectType::FRAMEBUFFER"; - case stormkit::gpu::DebugObjectType::IMAGE: return "DebugObjectType::IMAGE"; - case stormkit::gpu::DebugObjectType::IMAGE_VIEW: return "DebugObjectType::IMAGE_VIEW"; - case stormkit::gpu::DebugObjectType::INSTANCE: return "DebugObjectType::INSTANCE"; - case stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE: return "DebugObjectType::PHYSICAL_DEVICE"; - case stormkit::gpu::DebugObjectType::PIPELINE: return "DebugObjectType::PIPELINE"; - case stormkit::gpu::DebugObjectType::PIPELINE_CACHE: return "DebugObjectType::PIPELINE_CACHE"; - case stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT: return "DebugObjectType::PIPELINE_LAYOUT"; - case stormkit::gpu::DebugObjectType::QUERY_POOL: return "DebugObjectType::QUERY_POOL"; - case stormkit::gpu::DebugObjectType::QUEUE: return "DebugObjectType::QUEUE"; - case stormkit::gpu::DebugObjectType::RENDER_PASS: return "DebugObjectType::RENDER_PASS"; - case stormkit::gpu::DebugObjectType::SAMPLER: return "DebugObjectType::SAMPLER"; - case stormkit::gpu::DebugObjectType::SEMAPHORE: return "DebugObjectType::SEMAPHORE"; - case stormkit::gpu::DebugObjectType::SHADER_MODULE: return "DebugObjectType::SHADER_MODULE"; - case stormkit::gpu::DebugObjectType::SURFACE: return "DebugObjectType::SURFACE"; - case stormkit::gpu::DebugObjectType::SWAPCHAIN: return "DebugObjectType::SWAPCHAIN"; - case stormkit::gpu::DebugObjectType::UNKNOWN: return "DebugObjectType::UNKNOWN"; - } - std::unreachable(); - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::DebugObjectType value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::DebugObjectType::BUFFER: return "DebugObjectType::BUFFER"; - case stormkit::gpu::DebugObjectType::BUFFER_VIEW: return "DebugObjectType::BUFFER_VIEW"; - case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: return "DebugObjectType::COMMAND_BUFFER"; - case stormkit::gpu::DebugObjectType::COMMAND_POOL: return "DebugObjectType::COMMAND_POOL"; - case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: return "DebugObjectType::DEBUG_REPORT_CALLBACK"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: return "DebugObjectType::DESCRIPTOR_POOL"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: return "DebugObjectType::DESCRIPTOR_SET"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; - case stormkit::gpu::DebugObjectType::DEVICE: return "DebugObjectType::DEVICE"; - case stormkit::gpu::DebugObjectType::DEVICE_MEMORY: return "DebugObjectType::DEVICE_MEMORY"; - case stormkit::gpu::DebugObjectType::DISPLAY: return "DebugObjectType::DISPLAY"; - case stormkit::gpu::DebugObjectType::EVENT: return "DebugObjectType::EVENT"; - case stormkit::gpu::DebugObjectType::FENCE: return "DebugObjectType::FENCE"; - case stormkit::gpu::DebugObjectType::FRAMEBUFFER: return "DebugObjectType::FRAMEBUFFER"; - case stormkit::gpu::DebugObjectType::IMAGE: return "DebugObjectType::IMAGE"; - case stormkit::gpu::DebugObjectType::IMAGE_VIEW: return "DebugObjectType::IMAGE_VIEW"; - case stormkit::gpu::DebugObjectType::INSTANCE: return "DebugObjectType::INSTANCE"; - case stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE: return "DebugObjectType::PHYSICAL_DEVICE"; - case stormkit::gpu::DebugObjectType::PIPELINE: return "DebugObjectType::PIPELINE"; - case stormkit::gpu::DebugObjectType::PIPELINE_CACHE: return "DebugObjectType::PIPELINE_CACHE"; - case stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT: return "DebugObjectType::PIPELINE_LAYOUT"; - case stormkit::gpu::DebugObjectType::QUERY_POOL: return "DebugObjectType::QUERY_POOL"; - case stormkit::gpu::DebugObjectType::QUEUE: return "DebugObjectType::QUEUE"; - case stormkit::gpu::DebugObjectType::RENDER_PASS: return "DebugObjectType::RENDER_PASS"; - case stormkit::gpu::DebugObjectType::SAMPLER: return "DebugObjectType::SAMPLER"; - case stormkit::gpu::DebugObjectType::SEMAPHORE: return "DebugObjectType::SEMAPHORE"; - case stormkit::gpu::DebugObjectType::SHADER_MODULE: return "DebugObjectType::SHADER_MODULE"; - case stormkit::gpu::DebugObjectType::SURFACE: return "DebugObjectType::SURFACE"; - case stormkit::gpu::DebugObjectType::SWAPCHAIN: return "DebugObjectType::SWAPCHAIN"; - case stormkit::gpu::DebugObjectType::UNKNOWN: return "DebugObjectType::UNKNOWN"; + stormkit::gpu::DebugObjectType::BUFFER, + stormkit::gpu::DebugObjectType::BUFFER_VIEW, + stormkit::gpu::DebugObjectType::COMMAND_BUFFER, + stormkit::gpu::DebugObjectType::COMMAND_POOL, + stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK, + stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL, + stormkit::gpu::DebugObjectType::DESCRIPTOR_SET, + stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT, + stormkit::gpu::DebugObjectType::DEVICE, + stormkit::gpu::DebugObjectType::DEVICE_MEMORY, + stormkit::gpu::DebugObjectType::DISPLAY, + stormkit::gpu::DebugObjectType::EVENT, + stormkit::gpu::DebugObjectType::FENCE, + stormkit::gpu::DebugObjectType::FRAMEBUFFER, + stormkit::gpu::DebugObjectType::IMAGE, + stormkit::gpu::DebugObjectType::IMAGE_VIEW, + stormkit::gpu::DebugObjectType::INSTANCE, + stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE, + stormkit::gpu::DebugObjectType::PIPELINE, + stormkit::gpu::DebugObjectType::PIPELINE_CACHE, + stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT, + stormkit::gpu::DebugObjectType::QUERY_POOL, + stormkit::gpu::DebugObjectType::QUEUE, + stormkit::gpu::DebugObjectType::RENDER_PASS, + stormkit::gpu::DebugObjectType::SAMPLER, + stormkit::gpu::DebugObjectType::SEMAPHORE, + stormkit::gpu::DebugObjectType::SHADER_MODULE, + stormkit::gpu::DebugObjectType::SURFACE, + stormkit::gpu::DebugObjectType::SWAPCHAIN, + stormkit::gpu::DebugObjectType::UNKNOWN, + + }; + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::DebugObjectType value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::DebugObjectType::BUFFER: return "DebugObjectType::BUFFER"; + case stormkit::gpu::DebugObjectType::BUFFER_VIEW: return "DebugObjectType::BUFFER_VIEW"; + case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: return "DebugObjectType::COMMAND_BUFFER"; + case stormkit::gpu::DebugObjectType::COMMAND_POOL: return "DebugObjectType::COMMAND_POOL"; + case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: return "DebugObjectType::DEBUG_REPORT_CALLBACK"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: return "DebugObjectType::DESCRIPTOR_POOL"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: return "DebugObjectType::DESCRIPTOR_SET"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; + case stormkit::gpu::DebugObjectType::DEVICE: return "DebugObjectType::DEVICE"; + case stormkit::gpu::DebugObjectType::DEVICE_MEMORY: return "DebugObjectType::DEVICE_MEMORY"; + case stormkit::gpu::DebugObjectType::DISPLAY: return "DebugObjectType::DISPLAY"; + case stormkit::gpu::DebugObjectType::EVENT: return "DebugObjectType::EVENT"; + case stormkit::gpu::DebugObjectType::FENCE: return "DebugObjectType::FENCE"; + case stormkit::gpu::DebugObjectType::FRAMEBUFFER: return "DebugObjectType::FRAMEBUFFER"; + case stormkit::gpu::DebugObjectType::IMAGE: return "DebugObjectType::IMAGE"; + case stormkit::gpu::DebugObjectType::IMAGE_VIEW: return "DebugObjectType::IMAGE_VIEW"; + case stormkit::gpu::DebugObjectType::INSTANCE: return "DebugObjectType::INSTANCE"; + case stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE: return "DebugObjectType::PHYSICAL_DEVICE"; + case stormkit::gpu::DebugObjectType::PIPELINE: return "DebugObjectType::PIPELINE"; + case stormkit::gpu::DebugObjectType::PIPELINE_CACHE: return "DebugObjectType::PIPELINE_CACHE"; + case stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT: return "DebugObjectType::PIPELINE_LAYOUT"; + case stormkit::gpu::DebugObjectType::QUERY_POOL: return "DebugObjectType::QUERY_POOL"; + case stormkit::gpu::DebugObjectType::QUEUE: return "DebugObjectType::QUEUE"; + case stormkit::gpu::DebugObjectType::RENDER_PASS: return "DebugObjectType::RENDER_PASS"; + case stormkit::gpu::DebugObjectType::SAMPLER: return "DebugObjectType::SAMPLER"; + case stormkit::gpu::DebugObjectType::SEMAPHORE: return "DebugObjectType::SEMAPHORE"; + case stormkit::gpu::DebugObjectType::SHADER_MODULE: return "DebugObjectType::SHADER_MODULE"; + case stormkit::gpu::DebugObjectType::SURFACE: return "DebugObjectType::SURFACE"; + case stormkit::gpu::DebugObjectType::SWAPCHAIN: return "DebugObjectType::SWAPCHAIN"; + case stormkit::gpu::DebugObjectType::UNKNOWN: return "DebugObjectType::UNKNOWN"; + + } + std::unreachable(); + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::to_string(stormkit::gpu::DebugObjectType value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::DebugObjectType::BUFFER: return "DebugObjectType::BUFFER"; + case stormkit::gpu::DebugObjectType::BUFFER_VIEW: return "DebugObjectType::BUFFER_VIEW"; + case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: return "DebugObjectType::COMMAND_BUFFER"; + case stormkit::gpu::DebugObjectType::COMMAND_POOL: return "DebugObjectType::COMMAND_POOL"; + case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: return "DebugObjectType::DEBUG_REPORT_CALLBACK"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: return "DebugObjectType::DESCRIPTOR_POOL"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: return "DebugObjectType::DESCRIPTOR_SET"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; + case stormkit::gpu::DebugObjectType::DEVICE: return "DebugObjectType::DEVICE"; + case stormkit::gpu::DebugObjectType::DEVICE_MEMORY: return "DebugObjectType::DEVICE_MEMORY"; + case stormkit::gpu::DebugObjectType::DISPLAY: return "DebugObjectType::DISPLAY"; + case stormkit::gpu::DebugObjectType::EVENT: return "DebugObjectType::EVENT"; + case stormkit::gpu::DebugObjectType::FENCE: return "DebugObjectType::FENCE"; + case stormkit::gpu::DebugObjectType::FRAMEBUFFER: return "DebugObjectType::FRAMEBUFFER"; + case stormkit::gpu::DebugObjectType::IMAGE: return "DebugObjectType::IMAGE"; + case stormkit::gpu::DebugObjectType::IMAGE_VIEW: return "DebugObjectType::IMAGE_VIEW"; + case stormkit::gpu::DebugObjectType::INSTANCE: return "DebugObjectType::INSTANCE"; + case stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE: return "DebugObjectType::PHYSICAL_DEVICE"; + case stormkit::gpu::DebugObjectType::PIPELINE: return "DebugObjectType::PIPELINE"; + case stormkit::gpu::DebugObjectType::PIPELINE_CACHE: return "DebugObjectType::PIPELINE_CACHE"; + case stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT: return "DebugObjectType::PIPELINE_LAYOUT"; + case stormkit::gpu::DebugObjectType::QUERY_POOL: return "DebugObjectType::QUERY_POOL"; + case stormkit::gpu::DebugObjectType::QUEUE: return "DebugObjectType::QUEUE"; + case stormkit::gpu::DebugObjectType::RENDER_PASS: return "DebugObjectType::RENDER_PASS"; + case stormkit::gpu::DebugObjectType::SAMPLER: return "DebugObjectType::SAMPLER"; + case stormkit::gpu::DebugObjectType::SEMAPHORE: return "DebugObjectType::SEMAPHORE"; + case stormkit::gpu::DebugObjectType::SHADER_MODULE: return "DebugObjectType::SHADER_MODULE"; + case stormkit::gpu::DebugObjectType::SURFACE: return "DebugObjectType::SURFACE"; + case stormkit::gpu::DebugObjectType::SWAPCHAIN: return "DebugObjectType::SWAPCHAIN"; + case stormkit::gpu::DebugObjectType::UNKNOWN: return "DebugObjectType::UNKNOWN"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::DependencyFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::DependencyFlag::BY_REGION, - stormkit::gpu::DependencyFlag::DEVICE_GROUP, - stormkit::gpu::DependencyFlag::NONE, - stormkit::gpu::DependencyFlag::VIEW_LOCAL, - + stormkit::gpu::DependencyFlag::BY_REGION, + stormkit::gpu::DependencyFlag::DEVICE_GROUP, + stormkit::gpu::DependencyFlag::NONE, + stormkit::gpu::DependencyFlag::VIEW_LOCAL, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::DependencyFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::DependencyFlag::BY_REGION: return "DependencyFlag::BY_REGION"; - case stormkit::gpu::DependencyFlag::DEVICE_GROUP: return "DependencyFlag::DEVICE_GROUP"; - case stormkit::gpu::DependencyFlag::NONE: return "DependencyFlag::NONE"; - case stormkit::gpu::DependencyFlag::VIEW_LOCAL: return "DependencyFlag::VIEW_LOCAL"; + constexpr auto stormkit::core::as_string(stormkit::gpu::DependencyFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::DependencyFlag::BY_REGION: return "DependencyFlag::BY_REGION"; + case stormkit::gpu::DependencyFlag::DEVICE_GROUP: return "DependencyFlag::DEVICE_GROUP"; + case stormkit::gpu::DependencyFlag::NONE: return "DependencyFlag::NONE"; + case stormkit::gpu::DependencyFlag::VIEW_LOCAL: return "DependencyFlag::VIEW_LOCAL"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::DependencyFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::DependencyFlag::BY_REGION: return "DependencyFlag::BY_REGION"; - case stormkit::gpu::DependencyFlag::DEVICE_GROUP: return "DependencyFlag::DEVICE_GROUP"; - case stormkit::gpu::DependencyFlag::NONE: return "DependencyFlag::NONE"; - case stormkit::gpu::DependencyFlag::VIEW_LOCAL: return "DependencyFlag::VIEW_LOCAL"; + constexpr auto stormkit::core::to_string(stormkit::gpu::DependencyFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::DependencyFlag::BY_REGION: return "DependencyFlag::BY_REGION"; + case stormkit::gpu::DependencyFlag::DEVICE_GROUP: return "DependencyFlag::DEVICE_GROUP"; + case stormkit::gpu::DependencyFlag::NONE: return "DependencyFlag::NONE"; + case stormkit::gpu::DependencyFlag::VIEW_LOCAL: return "DependencyFlag::VIEW_LOCAL"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::DescriptorType) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, stormkit::gpu::DescriptorType::INPUT_ATTACHMENT, - stormkit::gpu::DescriptorType::SAMPLED_IMAGE, stormkit::gpu::DescriptorType::SAMPLER, - stormkit::gpu::DescriptorType::STORAGE_BUFFER, stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC, - stormkit::gpu::DescriptorType::STORAGE_IMAGE, stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER, - stormkit::gpu::DescriptorType::UNIFORM_BUFFER, stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC, - stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER, - + stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, + stormkit::gpu::DescriptorType::INPUT_ATTACHMENT, + stormkit::gpu::DescriptorType::SAMPLED_IMAGE, + stormkit::gpu::DescriptorType::SAMPLER, + stormkit::gpu::DescriptorType::STORAGE_BUFFER, + stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC, + stormkit::gpu::DescriptorType::STORAGE_IMAGE, + stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER, + stormkit::gpu::DescriptorType::UNIFORM_BUFFER, + stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC, + stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::DescriptorType value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: return "DescriptorType::COMBINED_IMAGE_SAMPLER"; - case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: return "DescriptorType::INPUT_ATTACHMENT"; - case stormkit::gpu::DescriptorType::SAMPLED_IMAGE: return "DescriptorType::SAMPLED_IMAGE"; - case stormkit::gpu::DescriptorType::SAMPLER: return "DescriptorType::SAMPLER"; - case stormkit::gpu::DescriptorType::STORAGE_BUFFER: return "DescriptorType::STORAGE_BUFFER"; - case stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC: return "DescriptorType::STORAGE_BUFFER_DYNAMIC"; - case stormkit::gpu::DescriptorType::STORAGE_IMAGE: return "DescriptorType::STORAGE_IMAGE"; - case stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER: return "DescriptorType::STORAGE_TEXEL_BUFFER"; - case stormkit::gpu::DescriptorType::UNIFORM_BUFFER: return "DescriptorType::UNIFORM_BUFFER"; - case stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC: return "DescriptorType::UNIFORM_BUFFER_DYNAMIC"; - case stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER: return "DescriptorType::UNIFORM_TEXEL_BUFFER"; + constexpr auto stormkit::core::as_string(stormkit::gpu::DescriptorType value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: return "DescriptorType::COMBINED_IMAGE_SAMPLER"; + case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: return "DescriptorType::INPUT_ATTACHMENT"; + case stormkit::gpu::DescriptorType::SAMPLED_IMAGE: return "DescriptorType::SAMPLED_IMAGE"; + case stormkit::gpu::DescriptorType::SAMPLER: return "DescriptorType::SAMPLER"; + case stormkit::gpu::DescriptorType::STORAGE_BUFFER: return "DescriptorType::STORAGE_BUFFER"; + case stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC: return "DescriptorType::STORAGE_BUFFER_DYNAMIC"; + case stormkit::gpu::DescriptorType::STORAGE_IMAGE: return "DescriptorType::STORAGE_IMAGE"; + case stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER: return "DescriptorType::STORAGE_TEXEL_BUFFER"; + case stormkit::gpu::DescriptorType::UNIFORM_BUFFER: return "DescriptorType::UNIFORM_BUFFER"; + case stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC: return "DescriptorType::UNIFORM_BUFFER_DYNAMIC"; + case stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER: return "DescriptorType::UNIFORM_TEXEL_BUFFER"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::DescriptorType value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: return "DescriptorType::COMBINED_IMAGE_SAMPLER"; - case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: return "DescriptorType::INPUT_ATTACHMENT"; - case stormkit::gpu::DescriptorType::SAMPLED_IMAGE: return "DescriptorType::SAMPLED_IMAGE"; - case stormkit::gpu::DescriptorType::SAMPLER: return "DescriptorType::SAMPLER"; - case stormkit::gpu::DescriptorType::STORAGE_BUFFER: return "DescriptorType::STORAGE_BUFFER"; - case stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC: return "DescriptorType::STORAGE_BUFFER_DYNAMIC"; - case stormkit::gpu::DescriptorType::STORAGE_IMAGE: return "DescriptorType::STORAGE_IMAGE"; - case stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER: return "DescriptorType::STORAGE_TEXEL_BUFFER"; - case stormkit::gpu::DescriptorType::UNIFORM_BUFFER: return "DescriptorType::UNIFORM_BUFFER"; - case stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC: return "DescriptorType::UNIFORM_BUFFER_DYNAMIC"; - case stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER: return "DescriptorType::UNIFORM_TEXEL_BUFFER"; + constexpr auto stormkit::core::to_string(stormkit::gpu::DescriptorType value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: return "DescriptorType::COMBINED_IMAGE_SAMPLER"; + case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: return "DescriptorType::INPUT_ATTACHMENT"; + case stormkit::gpu::DescriptorType::SAMPLED_IMAGE: return "DescriptorType::SAMPLED_IMAGE"; + case stormkit::gpu::DescriptorType::SAMPLER: return "DescriptorType::SAMPLER"; + case stormkit::gpu::DescriptorType::STORAGE_BUFFER: return "DescriptorType::STORAGE_BUFFER"; + case stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC: return "DescriptorType::STORAGE_BUFFER_DYNAMIC"; + case stormkit::gpu::DescriptorType::STORAGE_IMAGE: return "DescriptorType::STORAGE_IMAGE"; + case stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER: return "DescriptorType::STORAGE_TEXEL_BUFFER"; + case stormkit::gpu::DescriptorType::UNIFORM_BUFFER: return "DescriptorType::UNIFORM_BUFFER"; + case stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC: return "DescriptorType::UNIFORM_BUFFER_DYNAMIC"; + case stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER: return "DescriptorType::UNIFORM_TEXEL_BUFFER"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::DynamicState) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::DynamicState::BLEND_CONSTANTS, stormkit::gpu::DynamicState::DEPTH_BIAS, - stormkit::gpu::DynamicState::DEPTH_BOUNDS, stormkit::gpu::DynamicState::LINE_WIDTH, - stormkit::gpu::DynamicState::SCISSOR, stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK, - stormkit::gpu::DynamicState::STENCIL_REFERENCE, stormkit::gpu::DynamicState::STENCIL_WRITE_MASK, - stormkit::gpu::DynamicState::VIEWPORT, - + stormkit::gpu::DynamicState::BLEND_CONSTANTS, + stormkit::gpu::DynamicState::DEPTH_BIAS, + stormkit::gpu::DynamicState::DEPTH_BOUNDS, + stormkit::gpu::DynamicState::LINE_WIDTH, + stormkit::gpu::DynamicState::SCISSOR, + stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK, + stormkit::gpu::DynamicState::STENCIL_REFERENCE, + stormkit::gpu::DynamicState::STENCIL_WRITE_MASK, + stormkit::gpu::DynamicState::VIEWPORT, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::DynamicState value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::DynamicState::BLEND_CONSTANTS: return "DynamicState::BLEND_CONSTANTS"; - case stormkit::gpu::DynamicState::DEPTH_BIAS: return "DynamicState::DEPTH_BIAS"; - case stormkit::gpu::DynamicState::DEPTH_BOUNDS: return "DynamicState::DEPTH_BOUNDS"; - case stormkit::gpu::DynamicState::LINE_WIDTH: return "DynamicState::LINE_WIDTH"; - case stormkit::gpu::DynamicState::SCISSOR: return "DynamicState::SCISSOR"; - case stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK: return "DynamicState::STENCIL_COMPARE_MASK"; - case stormkit::gpu::DynamicState::STENCIL_REFERENCE: return "DynamicState::STENCIL_REFERENCE"; - case stormkit::gpu::DynamicState::STENCIL_WRITE_MASK: return "DynamicState::STENCIL_WRITE_MASK"; - case stormkit::gpu::DynamicState::VIEWPORT: return "DynamicState::VIEWPORT"; + constexpr auto stormkit::core::as_string(stormkit::gpu::DynamicState value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::DynamicState::BLEND_CONSTANTS: return "DynamicState::BLEND_CONSTANTS"; + case stormkit::gpu::DynamicState::DEPTH_BIAS: return "DynamicState::DEPTH_BIAS"; + case stormkit::gpu::DynamicState::DEPTH_BOUNDS: return "DynamicState::DEPTH_BOUNDS"; + case stormkit::gpu::DynamicState::LINE_WIDTH: return "DynamicState::LINE_WIDTH"; + case stormkit::gpu::DynamicState::SCISSOR: return "DynamicState::SCISSOR"; + case stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK: return "DynamicState::STENCIL_COMPARE_MASK"; + case stormkit::gpu::DynamicState::STENCIL_REFERENCE: return "DynamicState::STENCIL_REFERENCE"; + case stormkit::gpu::DynamicState::STENCIL_WRITE_MASK: return "DynamicState::STENCIL_WRITE_MASK"; + case stormkit::gpu::DynamicState::VIEWPORT: return "DynamicState::VIEWPORT"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::DynamicState value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::DynamicState::BLEND_CONSTANTS: return "DynamicState::BLEND_CONSTANTS"; - case stormkit::gpu::DynamicState::DEPTH_BIAS: return "DynamicState::DEPTH_BIAS"; - case stormkit::gpu::DynamicState::DEPTH_BOUNDS: return "DynamicState::DEPTH_BOUNDS"; - case stormkit::gpu::DynamicState::LINE_WIDTH: return "DynamicState::LINE_WIDTH"; - case stormkit::gpu::DynamicState::SCISSOR: return "DynamicState::SCISSOR"; - case stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK: return "DynamicState::STENCIL_COMPARE_MASK"; - case stormkit::gpu::DynamicState::STENCIL_REFERENCE: return "DynamicState::STENCIL_REFERENCE"; - case stormkit::gpu::DynamicState::STENCIL_WRITE_MASK: return "DynamicState::STENCIL_WRITE_MASK"; - case stormkit::gpu::DynamicState::VIEWPORT: return "DynamicState::VIEWPORT"; + constexpr auto stormkit::core::to_string(stormkit::gpu::DynamicState value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::DynamicState::BLEND_CONSTANTS: return "DynamicState::BLEND_CONSTANTS"; + case stormkit::gpu::DynamicState::DEPTH_BIAS: return "DynamicState::DEPTH_BIAS"; + case stormkit::gpu::DynamicState::DEPTH_BOUNDS: return "DynamicState::DEPTH_BOUNDS"; + case stormkit::gpu::DynamicState::LINE_WIDTH: return "DynamicState::LINE_WIDTH"; + case stormkit::gpu::DynamicState::SCISSOR: return "DynamicState::SCISSOR"; + case stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK: return "DynamicState::STENCIL_COMPARE_MASK"; + case stormkit::gpu::DynamicState::STENCIL_REFERENCE: return "DynamicState::STENCIL_REFERENCE"; + case stormkit::gpu::DynamicState::STENCIL_WRITE_MASK: return "DynamicState::STENCIL_WRITE_MASK"; + case stormkit::gpu::DynamicState::VIEWPORT: return "DynamicState::VIEWPORT"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::Filter) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::Filter::CUBIC_IMG, - stormkit::gpu::Filter::LINEAR, - stormkit::gpu::Filter::NEAREST, - + stormkit::gpu::Filter::CUBIC_IMG, + stormkit::gpu::Filter::LINEAR, + stormkit::gpu::Filter::NEAREST, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::Filter value) noexcept -> std::string_view { - switch (value) { - case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; - case stormkit::gpu::Filter::LINEAR: return "Filter::LINEAR"; - case stormkit::gpu::Filter::NEAREST: return "Filter::NEAREST"; + switch(value) { + case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; + case stormkit::gpu::Filter::LINEAR: return "Filter::LINEAR"; + case stormkit::gpu::Filter::NEAREST: return "Filter::NEAREST"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::Filter value) noexcept -> std::string { - switch (value) { - case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; - case stormkit::gpu::Filter::LINEAR: return "Filter::LINEAR"; - case stormkit::gpu::Filter::NEAREST: return "Filter::NEAREST"; + switch(value) { + case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; + case stormkit::gpu::Filter::LINEAR: return "Filter::LINEAR"; + case stormkit::gpu::Filter::NEAREST: return "Filter::NEAREST"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::FormatFeatureFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::FormatFeatureFlag::BLIT_DST, - stormkit::gpu::FormatFeatureFlag::BLIT_SRC, - stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT, - stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND, - stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES, - stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT, - stormkit::gpu::FormatFeatureFlag::DISJOINT, - stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER, - stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE, - stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC, - stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER, - stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC, - stormkit::gpu::FormatFeatureFlag::TRANSFER_DST, - stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC, - stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER, - stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER, - - }; - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::FormatFeatureFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::FormatFeatureFlag::BLIT_DST: return "FormatFeatureFlag::BLIT_DST"; - case stormkit::gpu::FormatFeatureFlag::BLIT_SRC: return "FormatFeatureFlag::BLIT_SRC"; - case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT: return "FormatFeatureFlag::COLOR_ATTACHMENT"; - case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND: return "FormatFeatureFlag::COLOR_ATTACHMENT_BLEND"; - case stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES: return "FormatFeatureFlag::COSITED_CHROMA_SAMPLES"; - case stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT: return "FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT"; - case stormkit::gpu::FormatFeatureFlag::DISJOINT: return "FormatFeatureFlag::DISJOINT"; - case stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES: return "FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE: return "FormatFeatureFlag::SAMPLED_IMAGE"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR: - return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX: - return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT: - return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_" - "EXPLICIT"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE: - return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_" - "EXPLICIT_FORCEABLE"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER: - return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER: - return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_" - "FILTER"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE: return "FormatFeatureFlag::STORAGE_IMAGE"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC: return "FormatFeatureFlag::STORAGE_IMAGE_ATOMIC"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC: - return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC"; - case stormkit::gpu::FormatFeatureFlag::TRANSFER_DST: return "FormatFeatureFlag::TRANSFER_DST"; - case stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC: return "FormatFeatureFlag::TRANSFER_SRC"; - case stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER: return "FormatFeatureFlag::UNIFORM_TEXEL_BUFFER"; - case stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER: return "FormatFeatureFlag::VERTEX_BUFFER"; - } - std::unreachable(); - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::FormatFeatureFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::FormatFeatureFlag::BLIT_DST: return "FormatFeatureFlag::BLIT_DST"; - case stormkit::gpu::FormatFeatureFlag::BLIT_SRC: return "FormatFeatureFlag::BLIT_SRC"; - case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT: return "FormatFeatureFlag::COLOR_ATTACHMENT"; - case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND: return "FormatFeatureFlag::COLOR_ATTACHMENT_BLEND"; - case stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES: return "FormatFeatureFlag::COSITED_CHROMA_SAMPLES"; - case stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT: return "FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT"; - case stormkit::gpu::FormatFeatureFlag::DISJOINT: return "FormatFeatureFlag::DISJOINT"; - case stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES: return "FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE: return "FormatFeatureFlag::SAMPLED_IMAGE"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR: - return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX: - return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT: - return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_" - "EXPLICIT"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE: - return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_" - "EXPLICIT_FORCEABLE"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER: - return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER: - return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_" - "FILTER"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE: return "FormatFeatureFlag::STORAGE_IMAGE"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC: return "FormatFeatureFlag::STORAGE_IMAGE_ATOMIC"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC: - return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC"; - case stormkit::gpu::FormatFeatureFlag::TRANSFER_DST: return "FormatFeatureFlag::TRANSFER_DST"; - case stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC: return "FormatFeatureFlag::TRANSFER_SRC"; - case stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER: return "FormatFeatureFlag::UNIFORM_TEXEL_BUFFER"; - case stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER: return "FormatFeatureFlag::VERTEX_BUFFER"; + stormkit::gpu::FormatFeatureFlag::BLIT_DST, + stormkit::gpu::FormatFeatureFlag::BLIT_SRC, + stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT, + stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND, + stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES, + stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT, + stormkit::gpu::FormatFeatureFlag::DISJOINT, + stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER, + stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE, + stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC, + stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER, + stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC, + stormkit::gpu::FormatFeatureFlag::TRANSFER_DST, + stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC, + stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER, + stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER, + + }; + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::FormatFeatureFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::FormatFeatureFlag::BLIT_DST: return "FormatFeatureFlag::BLIT_DST"; + case stormkit::gpu::FormatFeatureFlag::BLIT_SRC: return "FormatFeatureFlag::BLIT_SRC"; + case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT: return "FormatFeatureFlag::COLOR_ATTACHMENT"; + case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND: return "FormatFeatureFlag::COLOR_ATTACHMENT_BLEND"; + case stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES: return "FormatFeatureFlag::COSITED_CHROMA_SAMPLES"; + case stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT: return "FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT"; + case stormkit::gpu::FormatFeatureFlag::DISJOINT: return "FormatFeatureFlag::DISJOINT"; + case stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES: return "FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE: return "FormatFeatureFlag::SAMPLED_IMAGE"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR: return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX: return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE: return "FormatFeatureFlag::STORAGE_IMAGE"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC: return "FormatFeatureFlag::STORAGE_IMAGE_ATOMIC"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC"; + case stormkit::gpu::FormatFeatureFlag::TRANSFER_DST: return "FormatFeatureFlag::TRANSFER_DST"; + case stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC: return "FormatFeatureFlag::TRANSFER_SRC"; + case stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER: return "FormatFeatureFlag::UNIFORM_TEXEL_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER: return "FormatFeatureFlag::VERTEX_BUFFER"; + + } + std::unreachable(); + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::to_string(stormkit::gpu::FormatFeatureFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::FormatFeatureFlag::BLIT_DST: return "FormatFeatureFlag::BLIT_DST"; + case stormkit::gpu::FormatFeatureFlag::BLIT_SRC: return "FormatFeatureFlag::BLIT_SRC"; + case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT: return "FormatFeatureFlag::COLOR_ATTACHMENT"; + case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND: return "FormatFeatureFlag::COLOR_ATTACHMENT_BLEND"; + case stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES: return "FormatFeatureFlag::COSITED_CHROMA_SAMPLES"; + case stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT: return "FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT"; + case stormkit::gpu::FormatFeatureFlag::DISJOINT: return "FormatFeatureFlag::DISJOINT"; + case stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES: return "FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE: return "FormatFeatureFlag::SAMPLED_IMAGE"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR: return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX: return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE: return "FormatFeatureFlag::STORAGE_IMAGE"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC: return "FormatFeatureFlag::STORAGE_IMAGE_ATOMIC"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC"; + case stormkit::gpu::FormatFeatureFlag::TRANSFER_DST: return "FormatFeatureFlag::TRANSFER_DST"; + case stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC: return "FormatFeatureFlag::TRANSFER_SRC"; + case stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER: return "FormatFeatureFlag::UNIFORM_TEXEL_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER: return "FormatFeatureFlag::VERTEX_BUFFER"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::FrontFace) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::FrontFace::CLOCKWISE, - stormkit::gpu::FrontFace::COUNTER_CLOCKWISE, - + stormkit::gpu::FrontFace::CLOCKWISE, + stormkit::gpu::FrontFace::COUNTER_CLOCKWISE, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::FrontFace value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; - case stormkit::gpu::FrontFace::COUNTER_CLOCKWISE: return "FrontFace::COUNTER_CLOCKWISE"; + constexpr auto stormkit::core::as_string(stormkit::gpu::FrontFace value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; + case stormkit::gpu::FrontFace::COUNTER_CLOCKWISE: return "FrontFace::COUNTER_CLOCKWISE"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::FrontFace value) noexcept -> std::string { - switch (value) { - case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; - case stormkit::gpu::FrontFace::COUNTER_CLOCKWISE: return "FrontFace::COUNTER_CLOCKWISE"; + switch(value) { + case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; + case stormkit::gpu::FrontFace::COUNTER_CLOCKWISE: return "FrontFace::COUNTER_CLOCKWISE"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::GeometryFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION, - stormkit::gpu::GeometryFlag::OPAQUE, - + stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION, + stormkit::gpu::GeometryFlag::OPAQUE, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::GeometryFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION: - return "GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION"; - case stormkit::gpu::GeometryFlag::OPAQUE: return "GeometryFlag::OPAQUE"; + constexpr auto stormkit::core::as_string(stormkit::gpu::GeometryFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION: return "GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION"; + case stormkit::gpu::GeometryFlag::OPAQUE: return "GeometryFlag::OPAQUE"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION: - return "GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION"; - case stormkit::gpu::GeometryFlag::OPAQUE: return "GeometryFlag::OPAQUE"; + constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION: return "GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION"; + case stormkit::gpu::GeometryFlag::OPAQUE: return "GeometryFlag::OPAQUE"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::GeometryType) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::GeometryType::AABBS, - stormkit::gpu::GeometryType::INSTANCES, - stormkit::gpu::GeometryType::TRIANGLES, - + stormkit::gpu::GeometryType::AABBS, + stormkit::gpu::GeometryType::INSTANCES, + stormkit::gpu::GeometryType::TRIANGLES, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::GeometryType value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::GeometryType::AABBS: return "GeometryType::AABBS"; - case stormkit::gpu::GeometryType::INSTANCES: return "GeometryType::INSTANCES"; - case stormkit::gpu::GeometryType::TRIANGLES: return "GeometryType::TRIANGLES"; + constexpr auto stormkit::core::as_string(stormkit::gpu::GeometryType value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::GeometryType::AABBS: return "GeometryType::AABBS"; + case stormkit::gpu::GeometryType::INSTANCES: return "GeometryType::INSTANCES"; + case stormkit::gpu::GeometryType::TRIANGLES: return "GeometryType::TRIANGLES"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryType value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::GeometryType::AABBS: return "GeometryType::AABBS"; - case stormkit::gpu::GeometryType::INSTANCES: return "GeometryType::INSTANCES"; - case stormkit::gpu::GeometryType::TRIANGLES: return "GeometryType::TRIANGLES"; + constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryType value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::GeometryType::AABBS: return "GeometryType::AABBS"; + case stormkit::gpu::GeometryType::INSTANCES: return "GeometryType::INSTANCES"; + case stormkit::gpu::GeometryType::TRIANGLES: return "GeometryType::TRIANGLES"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageAspectFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageAspectFlag::COLOR, - stormkit::gpu::ImageAspectFlag::DEPTH, - stormkit::gpu::ImageAspectFlag::NONE, - stormkit::gpu::ImageAspectFlag::STENCIL, - + stormkit::gpu::ImageAspectFlag::COLOR, + stormkit::gpu::ImageAspectFlag::DEPTH, + stormkit::gpu::ImageAspectFlag::NONE, + stormkit::gpu::ImageAspectFlag::STENCIL, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageAspectFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ImageAspectFlag::COLOR: return "ImageAspectFlag::COLOR"; - case stormkit::gpu::ImageAspectFlag::DEPTH: return "ImageAspectFlag::DEPTH"; - case stormkit::gpu::ImageAspectFlag::NONE: return "ImageAspectFlag::NONE"; - case stormkit::gpu::ImageAspectFlag::STENCIL: return "ImageAspectFlag::STENCIL"; + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageAspectFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ImageAspectFlag::COLOR: return "ImageAspectFlag::COLOR"; + case stormkit::gpu::ImageAspectFlag::DEPTH: return "ImageAspectFlag::DEPTH"; + case stormkit::gpu::ImageAspectFlag::NONE: return "ImageAspectFlag::NONE"; + case stormkit::gpu::ImageAspectFlag::STENCIL: return "ImageAspectFlag::STENCIL"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageAspectFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::ImageAspectFlag::COLOR: return "ImageAspectFlag::COLOR"; - case stormkit::gpu::ImageAspectFlag::DEPTH: return "ImageAspectFlag::DEPTH"; - case stormkit::gpu::ImageAspectFlag::NONE: return "ImageAspectFlag::NONE"; - case stormkit::gpu::ImageAspectFlag::STENCIL: return "ImageAspectFlag::STENCIL"; + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageAspectFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::ImageAspectFlag::COLOR: return "ImageAspectFlag::COLOR"; + case stormkit::gpu::ImageAspectFlag::DEPTH: return "ImageAspectFlag::DEPTH"; + case stormkit::gpu::ImageAspectFlag::NONE: return "ImageAspectFlag::NONE"; + case stormkit::gpu::ImageAspectFlag::STENCIL: return "ImageAspectFlag::STENCIL"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageCreateFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageCreateFlag::ALIAS, - stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE, - stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE, - stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE, - stormkit::gpu::ImageCreateFlag::DISJOINT, - stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE, - stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT, - stormkit::gpu::ImageCreateFlag::NONE, - stormkit::gpu::ImageCreateFlag::PROTECTED, - stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED, - stormkit::gpu::ImageCreateFlag::SPARSE_BINDING, - stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY, - stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS, - - }; - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageCreateFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ImageCreateFlag::ALIAS: return "ImageCreateFlag::ALIAS"; - case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE: - return "ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE: return "ImageCreateFlag::CUBE_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::DISJOINT: return "ImageCreateFlag::DISJOINT"; - case stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE: return "ImageCreateFlag::EXTENDED_USAGE"; - case stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT: return "ImageCreateFlag::MUTABLE_FORMAT"; - case stormkit::gpu::ImageCreateFlag::NONE: return "ImageCreateFlag::NONE"; - case stormkit::gpu::ImageCreateFlag::PROTECTED: return "ImageCreateFlag::PROTECTED"; - case stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED: return "ImageCreateFlag::SPARSE_ALIASED"; - case stormkit::gpu::ImageCreateFlag::SPARSE_BINDING: return "ImageCreateFlag::SPARSE_BINDING"; - case stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY: return "ImageCreateFlag::SPARSE_RESIDENCY"; - case stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS: - return "ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS"; - } - std::unreachable(); - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageCreateFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::ImageCreateFlag::ALIAS: return "ImageCreateFlag::ALIAS"; - case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE: - return "ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE: return "ImageCreateFlag::CUBE_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::DISJOINT: return "ImageCreateFlag::DISJOINT"; - case stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE: return "ImageCreateFlag::EXTENDED_USAGE"; - case stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT: return "ImageCreateFlag::MUTABLE_FORMAT"; - case stormkit::gpu::ImageCreateFlag::NONE: return "ImageCreateFlag::NONE"; - case stormkit::gpu::ImageCreateFlag::PROTECTED: return "ImageCreateFlag::PROTECTED"; - case stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED: return "ImageCreateFlag::SPARSE_ALIASED"; - case stormkit::gpu::ImageCreateFlag::SPARSE_BINDING: return "ImageCreateFlag::SPARSE_BINDING"; - case stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY: return "ImageCreateFlag::SPARSE_RESIDENCY"; - case stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS: - return "ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS"; + stormkit::gpu::ImageCreateFlag::ALIAS, + stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE, + stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE, + stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE, + stormkit::gpu::ImageCreateFlag::DISJOINT, + stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE, + stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT, + stormkit::gpu::ImageCreateFlag::NONE, + stormkit::gpu::ImageCreateFlag::PROTECTED, + stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED, + stormkit::gpu::ImageCreateFlag::SPARSE_BINDING, + stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY, + stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS, + + }; + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageCreateFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ImageCreateFlag::ALIAS: return "ImageCreateFlag::ALIAS"; + case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE: return "ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE: return "ImageCreateFlag::CUBE_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::DISJOINT: return "ImageCreateFlag::DISJOINT"; + case stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE: return "ImageCreateFlag::EXTENDED_USAGE"; + case stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT: return "ImageCreateFlag::MUTABLE_FORMAT"; + case stormkit::gpu::ImageCreateFlag::NONE: return "ImageCreateFlag::NONE"; + case stormkit::gpu::ImageCreateFlag::PROTECTED: return "ImageCreateFlag::PROTECTED"; + case stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED: return "ImageCreateFlag::SPARSE_ALIASED"; + case stormkit::gpu::ImageCreateFlag::SPARSE_BINDING: return "ImageCreateFlag::SPARSE_BINDING"; + case stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY: return "ImageCreateFlag::SPARSE_RESIDENCY"; + case stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS: return "ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS"; + + } + std::unreachable(); + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageCreateFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::ImageCreateFlag::ALIAS: return "ImageCreateFlag::ALIAS"; + case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE: return "ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE: return "ImageCreateFlag::CUBE_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::DISJOINT: return "ImageCreateFlag::DISJOINT"; + case stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE: return "ImageCreateFlag::EXTENDED_USAGE"; + case stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT: return "ImageCreateFlag::MUTABLE_FORMAT"; + case stormkit::gpu::ImageCreateFlag::NONE: return "ImageCreateFlag::NONE"; + case stormkit::gpu::ImageCreateFlag::PROTECTED: return "ImageCreateFlag::PROTECTED"; + case stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED: return "ImageCreateFlag::SPARSE_ALIASED"; + case stormkit::gpu::ImageCreateFlag::SPARSE_BINDING: return "ImageCreateFlag::SPARSE_BINDING"; + case stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY: return "ImageCreateFlag::SPARSE_RESIDENCY"; + case stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS: return "ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageLayout) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL, - stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, - stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, - stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL, - stormkit::gpu::ImageLayout::GENERAL, - stormkit::gpu::ImageLayout::PREINITIALIZED, - stormkit::gpu::ImageLayout::PRESENT_SRC, - stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL, - stormkit::gpu::ImageLayout::SHARED_PRESENT, - stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL, - stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL, - stormkit::gpu::ImageLayout::UNDEFINED, - - }; - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageLayout value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: - return "ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: - return "ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL: - return "ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL: - return "ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::GENERAL: return "ImageLayout::GENERAL"; - case stormkit::gpu::ImageLayout::PREINITIALIZED: return "ImageLayout::PREINITIALIZED"; - case stormkit::gpu::ImageLayout::PRESENT_SRC: return "ImageLayout::PRESENT_SRC"; - case stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL: return "ImageLayout::SHADER_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::SHARED_PRESENT: return "ImageLayout::SHARED_PRESENT"; - case stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL: return "ImageLayout::TRANSFER_DST_OPTIMAL"; - case stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL: return "ImageLayout::TRANSFER_SRC_OPTIMAL"; - case stormkit::gpu::ImageLayout::UNDEFINED: return "ImageLayout::UNDEFINED"; - } - std::unreachable(); - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageLayout value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: - return "ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: - return "ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL: - return "ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL: - return "ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::GENERAL: return "ImageLayout::GENERAL"; - case stormkit::gpu::ImageLayout::PREINITIALIZED: return "ImageLayout::PREINITIALIZED"; - case stormkit::gpu::ImageLayout::PRESENT_SRC: return "ImageLayout::PRESENT_SRC"; - case stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL: return "ImageLayout::SHADER_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::SHARED_PRESENT: return "ImageLayout::SHARED_PRESENT"; - case stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL: return "ImageLayout::TRANSFER_DST_OPTIMAL"; - case stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL: return "ImageLayout::TRANSFER_SRC_OPTIMAL"; - case stormkit::gpu::ImageLayout::UNDEFINED: return "ImageLayout::UNDEFINED"; + stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL, + stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL, + stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, + stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, + stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL, + stormkit::gpu::ImageLayout::GENERAL, + stormkit::gpu::ImageLayout::PREINITIALIZED, + stormkit::gpu::ImageLayout::PRESENT_SRC, + stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL, + stormkit::gpu::ImageLayout::SHARED_PRESENT, + stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL, + stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL, + stormkit::gpu::ImageLayout::UNDEFINED, + + }; + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageLayout value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL: return "ImageLayout::ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: return "ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: return "ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL: return "ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL: return "ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::GENERAL: return "ImageLayout::GENERAL"; + case stormkit::gpu::ImageLayout::PREINITIALIZED: return "ImageLayout::PREINITIALIZED"; + case stormkit::gpu::ImageLayout::PRESENT_SRC: return "ImageLayout::PRESENT_SRC"; + case stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL: return "ImageLayout::SHADER_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::SHARED_PRESENT: return "ImageLayout::SHARED_PRESENT"; + case stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL: return "ImageLayout::TRANSFER_DST_OPTIMAL"; + case stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL: return "ImageLayout::TRANSFER_SRC_OPTIMAL"; + case stormkit::gpu::ImageLayout::UNDEFINED: return "ImageLayout::UNDEFINED"; + + } + std::unreachable(); + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageLayout value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL: return "ImageLayout::ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: return "ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: return "ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL: return "ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL: return "ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::GENERAL: return "ImageLayout::GENERAL"; + case stormkit::gpu::ImageLayout::PREINITIALIZED: return "ImageLayout::PREINITIALIZED"; + case stormkit::gpu::ImageLayout::PRESENT_SRC: return "ImageLayout::PRESENT_SRC"; + case stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL: return "ImageLayout::SHADER_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::SHARED_PRESENT: return "ImageLayout::SHARED_PRESENT"; + case stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL: return "ImageLayout::TRANSFER_DST_OPTIMAL"; + case stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL: return "ImageLayout::TRANSFER_SRC_OPTIMAL"; + case stormkit::gpu::ImageLayout::UNDEFINED: return "ImageLayout::UNDEFINED"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageTiling) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageTiling::LINEAR, - stormkit::gpu::ImageTiling::OPTIMAL, - + stormkit::gpu::ImageTiling::LINEAR, + stormkit::gpu::ImageTiling::OPTIMAL, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageTiling value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ImageTiling::LINEAR: return "ImageTiling::LINEAR"; - case stormkit::gpu::ImageTiling::OPTIMAL: return "ImageTiling::OPTIMAL"; + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageTiling value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ImageTiling::LINEAR: return "ImageTiling::LINEAR"; + case stormkit::gpu::ImageTiling::OPTIMAL: return "ImageTiling::OPTIMAL"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageTiling value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::ImageTiling::LINEAR: return "ImageTiling::LINEAR"; - case stormkit::gpu::ImageTiling::OPTIMAL: return "ImageTiling::OPTIMAL"; + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageTiling value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::ImageTiling::LINEAR: return "ImageTiling::LINEAR"; + case stormkit::gpu::ImageTiling::OPTIMAL: return "ImageTiling::OPTIMAL"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageType) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageType::T1D, - stormkit::gpu::ImageType::T2D, - stormkit::gpu::ImageType::T3D, - + stormkit::gpu::ImageType::T1D, + stormkit::gpu::ImageType::T2D, + stormkit::gpu::ImageType::T3D, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageType value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; - case stormkit::gpu::ImageType::T2D: return "ImageType::T2D"; - case stormkit::gpu::ImageType::T3D: return "ImageType::T3D"; + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageType value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; + case stormkit::gpu::ImageType::T2D: return "ImageType::T2D"; + case stormkit::gpu::ImageType::T3D: return "ImageType::T3D"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::ImageType value) noexcept -> std::string { - switch (value) { - case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; - case stormkit::gpu::ImageType::T2D: return "ImageType::T2D"; - case stormkit::gpu::ImageType::T3D: return "ImageType::T3D"; + switch(value) { + case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; + case stormkit::gpu::ImageType::T2D: return "ImageType::T2D"; + case stormkit::gpu::ImageType::T3D: return "ImageType::T3D"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageUsageFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT, stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT, - stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT, stormkit::gpu::ImageUsageFlag::SAMPLED, - stormkit::gpu::ImageUsageFlag::STORAGE, stormkit::gpu::ImageUsageFlag::TRANSFER_DST, - stormkit::gpu::ImageUsageFlag::TRANSFER_SRC, stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT, - + stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT, + stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT, + stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT, + stormkit::gpu::ImageUsageFlag::SAMPLED, + stormkit::gpu::ImageUsageFlag::STORAGE, + stormkit::gpu::ImageUsageFlag::TRANSFER_DST, + stormkit::gpu::ImageUsageFlag::TRANSFER_SRC, + stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageUsageFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: return "ImageUsageFlag::COLOR_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT: return "ImageUsageFlag::INPUT_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::SAMPLED: return "ImageUsageFlag::SAMPLED"; - case stormkit::gpu::ImageUsageFlag::STORAGE: return "ImageUsageFlag::STORAGE"; - case stormkit::gpu::ImageUsageFlag::TRANSFER_DST: return "ImageUsageFlag::TRANSFER_DST"; - case stormkit::gpu::ImageUsageFlag::TRANSFER_SRC: return "ImageUsageFlag::TRANSFER_SRC"; - case stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT: return "ImageUsageFlag::TRANSIENT_ATTACHMENT"; + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageUsageFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: return "ImageUsageFlag::COLOR_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT: return "ImageUsageFlag::INPUT_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::SAMPLED: return "ImageUsageFlag::SAMPLED"; + case stormkit::gpu::ImageUsageFlag::STORAGE: return "ImageUsageFlag::STORAGE"; + case stormkit::gpu::ImageUsageFlag::TRANSFER_DST: return "ImageUsageFlag::TRANSFER_DST"; + case stormkit::gpu::ImageUsageFlag::TRANSFER_SRC: return "ImageUsageFlag::TRANSFER_SRC"; + case stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT: return "ImageUsageFlag::TRANSIENT_ATTACHMENT"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageUsageFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: return "ImageUsageFlag::COLOR_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT: return "ImageUsageFlag::INPUT_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::SAMPLED: return "ImageUsageFlag::SAMPLED"; - case stormkit::gpu::ImageUsageFlag::STORAGE: return "ImageUsageFlag::STORAGE"; - case stormkit::gpu::ImageUsageFlag::TRANSFER_DST: return "ImageUsageFlag::TRANSFER_DST"; - case stormkit::gpu::ImageUsageFlag::TRANSFER_SRC: return "ImageUsageFlag::TRANSFER_SRC"; - case stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT: return "ImageUsageFlag::TRANSIENT_ATTACHMENT"; + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageUsageFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: return "ImageUsageFlag::COLOR_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT: return "ImageUsageFlag::INPUT_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::SAMPLED: return "ImageUsageFlag::SAMPLED"; + case stormkit::gpu::ImageUsageFlag::STORAGE: return "ImageUsageFlag::STORAGE"; + case stormkit::gpu::ImageUsageFlag::TRANSFER_DST: return "ImageUsageFlag::TRANSFER_DST"; + case stormkit::gpu::ImageUsageFlag::TRANSFER_SRC: return "ImageUsageFlag::TRANSFER_SRC"; + case stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT: return "ImageUsageFlag::TRANSIENT_ATTACHMENT"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageViewType) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageViewType::CUBE, stormkit::gpu::ImageViewType::CUBE_ARRAY, - stormkit::gpu::ImageViewType::T1D, stormkit::gpu::ImageViewType::T1D_ARRAY, - stormkit::gpu::ImageViewType::T2D, stormkit::gpu::ImageViewType::T2D_ARRAY, - stormkit::gpu::ImageViewType::T3D, - + stormkit::gpu::ImageViewType::CUBE, + stormkit::gpu::ImageViewType::CUBE_ARRAY, + stormkit::gpu::ImageViewType::T1D, + stormkit::gpu::ImageViewType::T1D_ARRAY, + stormkit::gpu::ImageViewType::T2D, + stormkit::gpu::ImageViewType::T2D_ARRAY, + stormkit::gpu::ImageViewType::T3D, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageViewType value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ImageViewType::CUBE: return "ImageViewType::CUBE"; - case stormkit::gpu::ImageViewType::CUBE_ARRAY: return "ImageViewType::CUBE_ARRAY"; - case stormkit::gpu::ImageViewType::T1D: return "ImageViewType::T1D"; - case stormkit::gpu::ImageViewType::T1D_ARRAY: return "ImageViewType::T1D_ARRAY"; - case stormkit::gpu::ImageViewType::T2D: return "ImageViewType::T2D"; - case stormkit::gpu::ImageViewType::T2D_ARRAY: return "ImageViewType::T2D_ARRAY"; - case stormkit::gpu::ImageViewType::T3D: return "ImageViewType::T3D"; + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageViewType value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ImageViewType::CUBE: return "ImageViewType::CUBE"; + case stormkit::gpu::ImageViewType::CUBE_ARRAY: return "ImageViewType::CUBE_ARRAY"; + case stormkit::gpu::ImageViewType::T1D: return "ImageViewType::T1D"; + case stormkit::gpu::ImageViewType::T1D_ARRAY: return "ImageViewType::T1D_ARRAY"; + case stormkit::gpu::ImageViewType::T2D: return "ImageViewType::T2D"; + case stormkit::gpu::ImageViewType::T2D_ARRAY: return "ImageViewType::T2D_ARRAY"; + case stormkit::gpu::ImageViewType::T3D: return "ImageViewType::T3D"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageViewType value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::ImageViewType::CUBE: return "ImageViewType::CUBE"; - case stormkit::gpu::ImageViewType::CUBE_ARRAY: return "ImageViewType::CUBE_ARRAY"; - case stormkit::gpu::ImageViewType::T1D: return "ImageViewType::T1D"; - case stormkit::gpu::ImageViewType::T1D_ARRAY: return "ImageViewType::T1D_ARRAY"; - case stormkit::gpu::ImageViewType::T2D: return "ImageViewType::T2D"; - case stormkit::gpu::ImageViewType::T2D_ARRAY: return "ImageViewType::T2D_ARRAY"; - case stormkit::gpu::ImageViewType::T3D: return "ImageViewType::T3D"; + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageViewType value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::ImageViewType::CUBE: return "ImageViewType::CUBE"; + case stormkit::gpu::ImageViewType::CUBE_ARRAY: return "ImageViewType::CUBE_ARRAY"; + case stormkit::gpu::ImageViewType::T1D: return "ImageViewType::T1D"; + case stormkit::gpu::ImageViewType::T1D_ARRAY: return "ImageViewType::T1D_ARRAY"; + case stormkit::gpu::ImageViewType::T2D: return "ImageViewType::T2D"; + case stormkit::gpu::ImageViewType::T2D_ARRAY: return "ImageViewType::T2D_ARRAY"; + case stormkit::gpu::ImageViewType::T3D: return "ImageViewType::T3D"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::LogicOperation) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::LogicOperation::AND, stormkit::gpu::LogicOperation::AND_INVERTED, - stormkit::gpu::LogicOperation::AND_REVERSE, stormkit::gpu::LogicOperation::CLEAR, - stormkit::gpu::LogicOperation::COPY, stormkit::gpu::LogicOperation::COPY_INVERTED, - stormkit::gpu::LogicOperation::EQUIVALENT, stormkit::gpu::LogicOperation::INVERT, - stormkit::gpu::LogicOperation::NAND, stormkit::gpu::LogicOperation::NO_OP, - stormkit::gpu::LogicOperation::NOR, stormkit::gpu::LogicOperation::OR, - stormkit::gpu::LogicOperation::OR_INVERTED, stormkit::gpu::LogicOperation::OR_REVERSE, - stormkit::gpu::LogicOperation::SET, stormkit::gpu::LogicOperation::XOR, - - }; - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::LogicOperation value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::LogicOperation::AND: return "LogicOperation::AND"; - case stormkit::gpu::LogicOperation::AND_INVERTED: return "LogicOperation::AND_INVERTED"; - case stormkit::gpu::LogicOperation::AND_REVERSE: return "LogicOperation::AND_REVERSE"; - case stormkit::gpu::LogicOperation::CLEAR: return "LogicOperation::CLEAR"; - case stormkit::gpu::LogicOperation::COPY: return "LogicOperation::COPY"; - case stormkit::gpu::LogicOperation::COPY_INVERTED: return "LogicOperation::COPY_INVERTED"; - case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; - case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; - case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; - case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; - case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; - case stormkit::gpu::LogicOperation::OR: return "LogicOperation::OR"; - case stormkit::gpu::LogicOperation::OR_INVERTED: return "LogicOperation::OR_INVERTED"; - case stormkit::gpu::LogicOperation::OR_REVERSE: return "LogicOperation::OR_REVERSE"; - case stormkit::gpu::LogicOperation::SET: return "LogicOperation::SET"; - case stormkit::gpu::LogicOperation::XOR: return "LogicOperation::XOR"; - } - std::unreachable(); - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::LogicOperation value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::LogicOperation::AND: return "LogicOperation::AND"; - case stormkit::gpu::LogicOperation::AND_INVERTED: return "LogicOperation::AND_INVERTED"; - case stormkit::gpu::LogicOperation::AND_REVERSE: return "LogicOperation::AND_REVERSE"; - case stormkit::gpu::LogicOperation::CLEAR: return "LogicOperation::CLEAR"; - case stormkit::gpu::LogicOperation::COPY: return "LogicOperation::COPY"; - case stormkit::gpu::LogicOperation::COPY_INVERTED: return "LogicOperation::COPY_INVERTED"; - case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; - case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; - case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; - case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; - case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; - case stormkit::gpu::LogicOperation::OR: return "LogicOperation::OR"; - case stormkit::gpu::LogicOperation::OR_INVERTED: return "LogicOperation::OR_INVERTED"; - case stormkit::gpu::LogicOperation::OR_REVERSE: return "LogicOperation::OR_REVERSE"; - case stormkit::gpu::LogicOperation::SET: return "LogicOperation::SET"; - case stormkit::gpu::LogicOperation::XOR: return "LogicOperation::XOR"; + stormkit::gpu::LogicOperation::AND, + stormkit::gpu::LogicOperation::AND_INVERTED, + stormkit::gpu::LogicOperation::AND_REVERSE, + stormkit::gpu::LogicOperation::CLEAR, + stormkit::gpu::LogicOperation::COPY, + stormkit::gpu::LogicOperation::COPY_INVERTED, + stormkit::gpu::LogicOperation::EQUIVALENT, + stormkit::gpu::LogicOperation::INVERT, + stormkit::gpu::LogicOperation::NAND, + stormkit::gpu::LogicOperation::NO_OP, + stormkit::gpu::LogicOperation::NOR, + stormkit::gpu::LogicOperation::OR, + stormkit::gpu::LogicOperation::OR_INVERTED, + stormkit::gpu::LogicOperation::OR_REVERSE, + stormkit::gpu::LogicOperation::SET, + stormkit::gpu::LogicOperation::XOR, + + }; + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::LogicOperation value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::LogicOperation::AND: return "LogicOperation::AND"; + case stormkit::gpu::LogicOperation::AND_INVERTED: return "LogicOperation::AND_INVERTED"; + case stormkit::gpu::LogicOperation::AND_REVERSE: return "LogicOperation::AND_REVERSE"; + case stormkit::gpu::LogicOperation::CLEAR: return "LogicOperation::CLEAR"; + case stormkit::gpu::LogicOperation::COPY: return "LogicOperation::COPY"; + case stormkit::gpu::LogicOperation::COPY_INVERTED: return "LogicOperation::COPY_INVERTED"; + case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; + case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; + case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; + case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; + case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; + case stormkit::gpu::LogicOperation::OR: return "LogicOperation::OR"; + case stormkit::gpu::LogicOperation::OR_INVERTED: return "LogicOperation::OR_INVERTED"; + case stormkit::gpu::LogicOperation::OR_REVERSE: return "LogicOperation::OR_REVERSE"; + case stormkit::gpu::LogicOperation::SET: return "LogicOperation::SET"; + case stormkit::gpu::LogicOperation::XOR: return "LogicOperation::XOR"; + + } + std::unreachable(); + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::to_string(stormkit::gpu::LogicOperation value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::LogicOperation::AND: return "LogicOperation::AND"; + case stormkit::gpu::LogicOperation::AND_INVERTED: return "LogicOperation::AND_INVERTED"; + case stormkit::gpu::LogicOperation::AND_REVERSE: return "LogicOperation::AND_REVERSE"; + case stormkit::gpu::LogicOperation::CLEAR: return "LogicOperation::CLEAR"; + case stormkit::gpu::LogicOperation::COPY: return "LogicOperation::COPY"; + case stormkit::gpu::LogicOperation::COPY_INVERTED: return "LogicOperation::COPY_INVERTED"; + case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; + case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; + case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; + case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; + case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; + case stormkit::gpu::LogicOperation::OR: return "LogicOperation::OR"; + case stormkit::gpu::LogicOperation::OR_INVERTED: return "LogicOperation::OR_INVERTED"; + case stormkit::gpu::LogicOperation::OR_REVERSE: return "LogicOperation::OR_REVERSE"; + case stormkit::gpu::LogicOperation::SET: return "LogicOperation::SET"; + case stormkit::gpu::LogicOperation::XOR: return "LogicOperation::XOR"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::MemoryPropertyFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL, - stormkit::gpu::MemoryPropertyFlag::HOST_CACHED, - stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT, - stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE, - + stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL, + stormkit::gpu::MemoryPropertyFlag::HOST_CACHED, + stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT, + stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::MemoryPropertyFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: return "MemoryPropertyFlag::DEVICE_LOCAL"; - case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: return "MemoryPropertyFlag::HOST_CACHED"; - case stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT: return "MemoryPropertyFlag::HOST_COHERENT"; - case stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE: return "MemoryPropertyFlag::HOST_VISIBLE"; + constexpr auto stormkit::core::as_string(stormkit::gpu::MemoryPropertyFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: return "MemoryPropertyFlag::DEVICE_LOCAL"; + case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: return "MemoryPropertyFlag::HOST_CACHED"; + case stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT: return "MemoryPropertyFlag::HOST_COHERENT"; + case stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE: return "MemoryPropertyFlag::HOST_VISIBLE"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::MemoryPropertyFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: return "MemoryPropertyFlag::DEVICE_LOCAL"; - case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: return "MemoryPropertyFlag::HOST_CACHED"; - case stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT: return "MemoryPropertyFlag::HOST_COHERENT"; - case stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE: return "MemoryPropertyFlag::HOST_VISIBLE"; + constexpr auto stormkit::core::to_string(stormkit::gpu::MemoryPropertyFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: return "MemoryPropertyFlag::DEVICE_LOCAL"; + case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: return "MemoryPropertyFlag::HOST_CACHED"; + case stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT: return "MemoryPropertyFlag::HOST_COHERENT"; + case stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE: return "MemoryPropertyFlag::HOST_VISIBLE"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PhysicalDeviceType) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PhysicalDeviceType::CPU, - stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU, - stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU, - stormkit::gpu::PhysicalDeviceType::OTHER, - stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU, - + stormkit::gpu::PhysicalDeviceType::CPU, + stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU, + stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU, + stormkit::gpu::PhysicalDeviceType::OTHER, + stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PhysicalDeviceType value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::PhysicalDeviceType::CPU: return "PhysicalDeviceType::CPU"; - case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: return "PhysicalDeviceType::DISCRETE_GPU"; - case stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU: return "PhysicalDeviceType::INTEGRATED_GPU"; - case stormkit::gpu::PhysicalDeviceType::OTHER: return "PhysicalDeviceType::OTHER"; - case stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU: return "PhysicalDeviceType::VIRTUAL_GPU"; + constexpr auto stormkit::core::as_string(stormkit::gpu::PhysicalDeviceType value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::PhysicalDeviceType::CPU: return "PhysicalDeviceType::CPU"; + case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: return "PhysicalDeviceType::DISCRETE_GPU"; + case stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU: return "PhysicalDeviceType::INTEGRATED_GPU"; + case stormkit::gpu::PhysicalDeviceType::OTHER: return "PhysicalDeviceType::OTHER"; + case stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU: return "PhysicalDeviceType::VIRTUAL_GPU"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::PhysicalDeviceType value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::PhysicalDeviceType::CPU: return "PhysicalDeviceType::CPU"; - case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: return "PhysicalDeviceType::DISCRETE_GPU"; - case stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU: return "PhysicalDeviceType::INTEGRATED_GPU"; - case stormkit::gpu::PhysicalDeviceType::OTHER: return "PhysicalDeviceType::OTHER"; - case stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU: return "PhysicalDeviceType::VIRTUAL_GPU"; + constexpr auto stormkit::core::to_string(stormkit::gpu::PhysicalDeviceType value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::PhysicalDeviceType::CPU: return "PhysicalDeviceType::CPU"; + case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: return "PhysicalDeviceType::DISCRETE_GPU"; + case stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU: return "PhysicalDeviceType::INTEGRATED_GPU"; + case stormkit::gpu::PhysicalDeviceType::OTHER: return "PhysicalDeviceType::OTHER"; + case stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU: return "PhysicalDeviceType::VIRTUAL_GPU"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PipelineBindPoint) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PipelineBindPoint::COMPUTE, - stormkit::gpu::PipelineBindPoint::GRAPHICS, - + stormkit::gpu::PipelineBindPoint::COMPUTE, + stormkit::gpu::PipelineBindPoint::GRAPHICS, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PipelineBindPoint value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::PipelineBindPoint::COMPUTE: return "PipelineBindPoint::COMPUTE"; - case stormkit::gpu::PipelineBindPoint::GRAPHICS: return "PipelineBindPoint::GRAPHICS"; + constexpr auto stormkit::core::as_string(stormkit::gpu::PipelineBindPoint value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::PipelineBindPoint::COMPUTE: return "PipelineBindPoint::COMPUTE"; + case stormkit::gpu::PipelineBindPoint::GRAPHICS: return "PipelineBindPoint::GRAPHICS"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineBindPoint value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::PipelineBindPoint::COMPUTE: return "PipelineBindPoint::COMPUTE"; - case stormkit::gpu::PipelineBindPoint::GRAPHICS: return "PipelineBindPoint::GRAPHICS"; + constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineBindPoint value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::PipelineBindPoint::COMPUTE: return "PipelineBindPoint::COMPUTE"; + case stormkit::gpu::PipelineBindPoint::GRAPHICS: return "PipelineBindPoint::GRAPHICS"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PipelineStageFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PipelineStageFlag::ALL_COMMANDS, - stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS, - stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE, - stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT, - stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER, - stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT, - stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS, - stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER, - stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER, - stormkit::gpu::PipelineStageFlag::HOST, - stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS, - stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER, - stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER, - stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE, - stormkit::gpu::PipelineStageFlag::TRANSFER, - stormkit::gpu::PipelineStageFlag::VERTEX_INPUT, - stormkit::gpu::PipelineStageFlag::VERTEX_SHADER, - - }; - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PipelineStageFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: return "PipelineStageFlag::ALL_COMMANDS"; - case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: return "PipelineStageFlag::ALL_GRAPHICS"; - case stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE: return "PipelineStageFlag::BOTTOM_OF_PIPE"; - case stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT: return "PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT"; - case stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER: return "PipelineStageFlag::COMPUTE_SHADER"; - case stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT: return "PipelineStageFlag::DRAW_INDIRECT"; - case stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS: return "PipelineStageFlag::EARLY_FRAGMENT_TESTS"; - case stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER: return "PipelineStageFlag::FRAGMENT_SHADER"; - case stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER: return "PipelineStageFlag::GEOMETRY_SHADER"; - case stormkit::gpu::PipelineStageFlag::HOST: return "PipelineStageFlag::HOST"; - case stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS: return "PipelineStageFlag::LATE_FRAGMENT_TESTS"; - case stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER: - return "PipelineStageFlag::TESSELLATION_CONTROL_SHADER"; - case stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER: - return "PipelineStageFlag::TESSELLATION_EVALUATION_SHADER"; - case stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE: return "PipelineStageFlag::TOP_OF_PIPE"; - case stormkit::gpu::PipelineStageFlag::TRANSFER: return "PipelineStageFlag::TRANSFER"; - case stormkit::gpu::PipelineStageFlag::VERTEX_INPUT: return "PipelineStageFlag::VERTEX_INPUT"; - case stormkit::gpu::PipelineStageFlag::VERTEX_SHADER: return "PipelineStageFlag::VERTEX_SHADER"; - } - std::unreachable(); - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineStageFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: return "PipelineStageFlag::ALL_COMMANDS"; - case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: return "PipelineStageFlag::ALL_GRAPHICS"; - case stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE: return "PipelineStageFlag::BOTTOM_OF_PIPE"; - case stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT: return "PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT"; - case stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER: return "PipelineStageFlag::COMPUTE_SHADER"; - case stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT: return "PipelineStageFlag::DRAW_INDIRECT"; - case stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS: return "PipelineStageFlag::EARLY_FRAGMENT_TESTS"; - case stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER: return "PipelineStageFlag::FRAGMENT_SHADER"; - case stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER: return "PipelineStageFlag::GEOMETRY_SHADER"; - case stormkit::gpu::PipelineStageFlag::HOST: return "PipelineStageFlag::HOST"; - case stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS: return "PipelineStageFlag::LATE_FRAGMENT_TESTS"; - case stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER: - return "PipelineStageFlag::TESSELLATION_CONTROL_SHADER"; - case stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER: - return "PipelineStageFlag::TESSELLATION_EVALUATION_SHADER"; - case stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE: return "PipelineStageFlag::TOP_OF_PIPE"; - case stormkit::gpu::PipelineStageFlag::TRANSFER: return "PipelineStageFlag::TRANSFER"; - case stormkit::gpu::PipelineStageFlag::VERTEX_INPUT: return "PipelineStageFlag::VERTEX_INPUT"; - case stormkit::gpu::PipelineStageFlag::VERTEX_SHADER: return "PipelineStageFlag::VERTEX_SHADER"; + stormkit::gpu::PipelineStageFlag::ALL_COMMANDS, + stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS, + stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE, + stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT, + stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER, + stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT, + stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS, + stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER, + stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER, + stormkit::gpu::PipelineStageFlag::HOST, + stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS, + stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER, + stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER, + stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE, + stormkit::gpu::PipelineStageFlag::TRANSFER, + stormkit::gpu::PipelineStageFlag::VERTEX_INPUT, + stormkit::gpu::PipelineStageFlag::VERTEX_SHADER, + + }; + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::PipelineStageFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: return "PipelineStageFlag::ALL_COMMANDS"; + case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: return "PipelineStageFlag::ALL_GRAPHICS"; + case stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE: return "PipelineStageFlag::BOTTOM_OF_PIPE"; + case stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT: return "PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT"; + case stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER: return "PipelineStageFlag::COMPUTE_SHADER"; + case stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT: return "PipelineStageFlag::DRAW_INDIRECT"; + case stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS: return "PipelineStageFlag::EARLY_FRAGMENT_TESTS"; + case stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER: return "PipelineStageFlag::FRAGMENT_SHADER"; + case stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER: return "PipelineStageFlag::GEOMETRY_SHADER"; + case stormkit::gpu::PipelineStageFlag::HOST: return "PipelineStageFlag::HOST"; + case stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS: return "PipelineStageFlag::LATE_FRAGMENT_TESTS"; + case stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER: return "PipelineStageFlag::TESSELLATION_CONTROL_SHADER"; + case stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER: return "PipelineStageFlag::TESSELLATION_EVALUATION_SHADER"; + case stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE: return "PipelineStageFlag::TOP_OF_PIPE"; + case stormkit::gpu::PipelineStageFlag::TRANSFER: return "PipelineStageFlag::TRANSFER"; + case stormkit::gpu::PipelineStageFlag::VERTEX_INPUT: return "PipelineStageFlag::VERTEX_INPUT"; + case stormkit::gpu::PipelineStageFlag::VERTEX_SHADER: return "PipelineStageFlag::VERTEX_SHADER"; + + } + std::unreachable(); + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineStageFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: return "PipelineStageFlag::ALL_COMMANDS"; + case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: return "PipelineStageFlag::ALL_GRAPHICS"; + case stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE: return "PipelineStageFlag::BOTTOM_OF_PIPE"; + case stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT: return "PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT"; + case stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER: return "PipelineStageFlag::COMPUTE_SHADER"; + case stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT: return "PipelineStageFlag::DRAW_INDIRECT"; + case stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS: return "PipelineStageFlag::EARLY_FRAGMENT_TESTS"; + case stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER: return "PipelineStageFlag::FRAGMENT_SHADER"; + case stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER: return "PipelineStageFlag::GEOMETRY_SHADER"; + case stormkit::gpu::PipelineStageFlag::HOST: return "PipelineStageFlag::HOST"; + case stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS: return "PipelineStageFlag::LATE_FRAGMENT_TESTS"; + case stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER: return "PipelineStageFlag::TESSELLATION_CONTROL_SHADER"; + case stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER: return "PipelineStageFlag::TESSELLATION_EVALUATION_SHADER"; + case stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE: return "PipelineStageFlag::TOP_OF_PIPE"; + case stormkit::gpu::PipelineStageFlag::TRANSFER: return "PipelineStageFlag::TRANSFER"; + case stormkit::gpu::PipelineStageFlag::VERTEX_INPUT: return "PipelineStageFlag::VERTEX_INPUT"; + case stormkit::gpu::PipelineStageFlag::VERTEX_SHADER: return "PipelineStageFlag::VERTEX_SHADER"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PixelFormat) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16, - stormkit::gpu::PixelFormat::A2_RGB10I_PACK32, - stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32, - stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32, - stormkit::gpu::PixelFormat::A2_RGB10U_PACK32, - stormkit::gpu::PixelFormat::B10_GR11UF_PACK32, - stormkit::gpu::PixelFormat::BGR8_UNORM, - stormkit::gpu::PixelFormat::BGRA8_UNORM, - stormkit::gpu::PixelFormat::DEPTH16_UNORM, - stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U, - stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32, - stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U, - stormkit::gpu::PixelFormat::DEPTH32F, - stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U, - stormkit::gpu::PixelFormat::R16F, - stormkit::gpu::PixelFormat::R16I, - stormkit::gpu::PixelFormat::R16_SNORM, - stormkit::gpu::PixelFormat::R16U, - stormkit::gpu::PixelFormat::R16_UNORM, - stormkit::gpu::PixelFormat::R32F, - stormkit::gpu::PixelFormat::R32I, - stormkit::gpu::PixelFormat::R32U, - stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16, - stormkit::gpu::PixelFormat::R8I, - stormkit::gpu::PixelFormat::R8_SNORM, - stormkit::gpu::PixelFormat::R8U, - stormkit::gpu::PixelFormat::R8_UNORM, - stormkit::gpu::PixelFormat::RG16F, - stormkit::gpu::PixelFormat::RG16I, - stormkit::gpu::PixelFormat::RG16_SNORM, - stormkit::gpu::PixelFormat::RG16U, - stormkit::gpu::PixelFormat::RG16_UNORM, - stormkit::gpu::PixelFormat::RG32F, - stormkit::gpu::PixelFormat::RG32I, - stormkit::gpu::PixelFormat::RG32U, - stormkit::gpu::PixelFormat::RG8I, - stormkit::gpu::PixelFormat::RG8_SNORM, - stormkit::gpu::PixelFormat::RG8U, - stormkit::gpu::PixelFormat::RG8_UNORM, - stormkit::gpu::PixelFormat::RGB16F, - stormkit::gpu::PixelFormat::RGB16I, - stormkit::gpu::PixelFormat::RGB16_SNORM, - stormkit::gpu::PixelFormat::RGB16U, - stormkit::gpu::PixelFormat::RGB16_UNORM, - stormkit::gpu::PixelFormat::RGB32F, - stormkit::gpu::PixelFormat::RGB32I, - stormkit::gpu::PixelFormat::RGB32U, - stormkit::gpu::PixelFormat::RGB8I, - stormkit::gpu::PixelFormat::RGB8_SNORM, - stormkit::gpu::PixelFormat::RGB8U, - stormkit::gpu::PixelFormat::RGB8_UNORM, - stormkit::gpu::PixelFormat::RGBA16F, - stormkit::gpu::PixelFormat::RGBA16I, - stormkit::gpu::PixelFormat::RGBA16_SNORM, - stormkit::gpu::PixelFormat::RGBA16U, - stormkit::gpu::PixelFormat::RGBA16_UNORM, - stormkit::gpu::PixelFormat::RGBA32F, - stormkit::gpu::PixelFormat::RGBA32I, - stormkit::gpu::PixelFormat::RGBA32U, - stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16, - stormkit::gpu::PixelFormat::RGBA8I, - stormkit::gpu::PixelFormat::RGBA8_SNORM, - stormkit::gpu::PixelFormat::RGBA8U, - stormkit::gpu::PixelFormat::RGBA8_UNORM, - stormkit::gpu::PixelFormat::SBGR8, - stormkit::gpu::PixelFormat::SBGRA8, - stormkit::gpu::PixelFormat::SR8, - stormkit::gpu::PixelFormat::SRG8, - stormkit::gpu::PixelFormat::SRGB8, - stormkit::gpu::PixelFormat::SRGBA8, - stormkit::gpu::PixelFormat::UNDEFINED, - - }; - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PixelFormat value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; - case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; - case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; - case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; - case stormkit::gpu::PixelFormat::DEPTH16_UNORM: return "PixelFormat::DEPTH16_UNORM"; - case stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U: return "PixelFormat::DEPTH16_UNORM_STENCIL8U"; - case stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32: return "PixelFormat::DEPTH24_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U: return "PixelFormat::DEPTH24_UNORM_STENCIL8U"; - case stormkit::gpu::PixelFormat::DEPTH32F: return "PixelFormat::DEPTH32F"; - case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; - case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; - case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; - case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; - case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; - case stormkit::gpu::PixelFormat::R16_UNORM: return "PixelFormat::R16_UNORM"; - case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; - case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; - case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; - case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; - case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; - case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; - case stormkit::gpu::PixelFormat::R8_UNORM: return "PixelFormat::R8_UNORM"; - case stormkit::gpu::PixelFormat::RG16F: return "PixelFormat::RG16F"; - case stormkit::gpu::PixelFormat::RG16I: return "PixelFormat::RG16I"; - case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; - case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; - case stormkit::gpu::PixelFormat::RG16_UNORM: return "PixelFormat::RG16_UNORM"; - case stormkit::gpu::PixelFormat::RG32F: return "PixelFormat::RG32F"; - case stormkit::gpu::PixelFormat::RG32I: return "PixelFormat::RG32I"; - case stormkit::gpu::PixelFormat::RG32U: return "PixelFormat::RG32U"; - case stormkit::gpu::PixelFormat::RG8I: return "PixelFormat::RG8I"; - case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; - case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; - case stormkit::gpu::PixelFormat::RG8_UNORM: return "PixelFormat::RG8_UNORM"; - case stormkit::gpu::PixelFormat::RGB16F: return "PixelFormat::RGB16F"; - case stormkit::gpu::PixelFormat::RGB16I: return "PixelFormat::RGB16I"; - case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; - case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; - case stormkit::gpu::PixelFormat::RGB16_UNORM: return "PixelFormat::RGB16_UNORM"; - case stormkit::gpu::PixelFormat::RGB32F: return "PixelFormat::RGB32F"; - case stormkit::gpu::PixelFormat::RGB32I: return "PixelFormat::RGB32I"; - case stormkit::gpu::PixelFormat::RGB32U: return "PixelFormat::RGB32U"; - case stormkit::gpu::PixelFormat::RGB8I: return "PixelFormat::RGB8I"; - case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; - case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; - case stormkit::gpu::PixelFormat::RGB8_UNORM: return "PixelFormat::RGB8_UNORM"; - case stormkit::gpu::PixelFormat::RGBA16F: return "PixelFormat::RGBA16F"; - case stormkit::gpu::PixelFormat::RGBA16I: return "PixelFormat::RGBA16I"; - case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; - case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; - case stormkit::gpu::PixelFormat::RGBA16_UNORM: return "PixelFormat::RGBA16_UNORM"; - case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; - case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; - case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; - case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; - case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; - case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; - case stormkit::gpu::PixelFormat::RGBA8_UNORM: return "PixelFormat::RGBA8_UNORM"; - case stormkit::gpu::PixelFormat::SBGR8: return "PixelFormat::SBGR8"; - case stormkit::gpu::PixelFormat::SBGRA8: return "PixelFormat::SBGRA8"; - case stormkit::gpu::PixelFormat::SR8: return "PixelFormat::SR8"; - case stormkit::gpu::PixelFormat::SRG8: return "PixelFormat::SRG8"; - case stormkit::gpu::PixelFormat::SRGB8: return "PixelFormat::SRGB8"; - case stormkit::gpu::PixelFormat::SRGBA8: return "PixelFormat::SRGBA8"; - case stormkit::gpu::PixelFormat::UNDEFINED: return "PixelFormat::UNDEFINED"; - } - std::unreachable(); - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::PixelFormat value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; - case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; - case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; - case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; - case stormkit::gpu::PixelFormat::DEPTH16_UNORM: return "PixelFormat::DEPTH16_UNORM"; - case stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U: return "PixelFormat::DEPTH16_UNORM_STENCIL8U"; - case stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32: return "PixelFormat::DEPTH24_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U: return "PixelFormat::DEPTH24_UNORM_STENCIL8U"; - case stormkit::gpu::PixelFormat::DEPTH32F: return "PixelFormat::DEPTH32F"; - case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; - case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; - case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; - case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; - case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; - case stormkit::gpu::PixelFormat::R16_UNORM: return "PixelFormat::R16_UNORM"; - case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; - case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; - case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; - case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; - case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; - case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; - case stormkit::gpu::PixelFormat::R8_UNORM: return "PixelFormat::R8_UNORM"; - case stormkit::gpu::PixelFormat::RG16F: return "PixelFormat::RG16F"; - case stormkit::gpu::PixelFormat::RG16I: return "PixelFormat::RG16I"; - case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; - case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; - case stormkit::gpu::PixelFormat::RG16_UNORM: return "PixelFormat::RG16_UNORM"; - case stormkit::gpu::PixelFormat::RG32F: return "PixelFormat::RG32F"; - case stormkit::gpu::PixelFormat::RG32I: return "PixelFormat::RG32I"; - case stormkit::gpu::PixelFormat::RG32U: return "PixelFormat::RG32U"; - case stormkit::gpu::PixelFormat::RG8I: return "PixelFormat::RG8I"; - case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; - case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; - case stormkit::gpu::PixelFormat::RG8_UNORM: return "PixelFormat::RG8_UNORM"; - case stormkit::gpu::PixelFormat::RGB16F: return "PixelFormat::RGB16F"; - case stormkit::gpu::PixelFormat::RGB16I: return "PixelFormat::RGB16I"; - case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; - case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; - case stormkit::gpu::PixelFormat::RGB16_UNORM: return "PixelFormat::RGB16_UNORM"; - case stormkit::gpu::PixelFormat::RGB32F: return "PixelFormat::RGB32F"; - case stormkit::gpu::PixelFormat::RGB32I: return "PixelFormat::RGB32I"; - case stormkit::gpu::PixelFormat::RGB32U: return "PixelFormat::RGB32U"; - case stormkit::gpu::PixelFormat::RGB8I: return "PixelFormat::RGB8I"; - case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; - case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; - case stormkit::gpu::PixelFormat::RGB8_UNORM: return "PixelFormat::RGB8_UNORM"; - case stormkit::gpu::PixelFormat::RGBA16F: return "PixelFormat::RGBA16F"; - case stormkit::gpu::PixelFormat::RGBA16I: return "PixelFormat::RGBA16I"; - case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; - case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; - case stormkit::gpu::PixelFormat::RGBA16_UNORM: return "PixelFormat::RGBA16_UNORM"; - case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; - case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; - case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; - case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; - case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; - case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; - case stormkit::gpu::PixelFormat::RGBA8_UNORM: return "PixelFormat::RGBA8_UNORM"; - case stormkit::gpu::PixelFormat::SBGR8: return "PixelFormat::SBGR8"; - case stormkit::gpu::PixelFormat::SBGRA8: return "PixelFormat::SBGRA8"; - case stormkit::gpu::PixelFormat::SR8: return "PixelFormat::SR8"; - case stormkit::gpu::PixelFormat::SRG8: return "PixelFormat::SRG8"; - case stormkit::gpu::PixelFormat::SRGB8: return "PixelFormat::SRGB8"; - case stormkit::gpu::PixelFormat::SRGBA8: return "PixelFormat::SRGBA8"; - case stormkit::gpu::PixelFormat::UNDEFINED: return "PixelFormat::UNDEFINED"; + stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16, + stormkit::gpu::PixelFormat::A2_RGB10I_PACK32, + stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32, + stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32, + stormkit::gpu::PixelFormat::A2_RGB10U_PACK32, + stormkit::gpu::PixelFormat::B10_GR11UF_PACK32, + stormkit::gpu::PixelFormat::BGR8_UNORM, + stormkit::gpu::PixelFormat::BGRA8_UNORM, + stormkit::gpu::PixelFormat::DEPTH16_UNORM, + stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U, + stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32, + stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U, + stormkit::gpu::PixelFormat::DEPTH32F, + stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U, + stormkit::gpu::PixelFormat::R16F, + stormkit::gpu::PixelFormat::R16I, + stormkit::gpu::PixelFormat::R16_SNORM, + stormkit::gpu::PixelFormat::R16U, + stormkit::gpu::PixelFormat::R16_UNORM, + stormkit::gpu::PixelFormat::R32F, + stormkit::gpu::PixelFormat::R32I, + stormkit::gpu::PixelFormat::R32U, + stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16, + stormkit::gpu::PixelFormat::R8I, + stormkit::gpu::PixelFormat::R8_SNORM, + stormkit::gpu::PixelFormat::R8U, + stormkit::gpu::PixelFormat::R8_UNORM, + stormkit::gpu::PixelFormat::RG16F, + stormkit::gpu::PixelFormat::RG16I, + stormkit::gpu::PixelFormat::RG16_SNORM, + stormkit::gpu::PixelFormat::RG16U, + stormkit::gpu::PixelFormat::RG16_UNORM, + stormkit::gpu::PixelFormat::RG32F, + stormkit::gpu::PixelFormat::RG32I, + stormkit::gpu::PixelFormat::RG32U, + stormkit::gpu::PixelFormat::RG8I, + stormkit::gpu::PixelFormat::RG8_SNORM, + stormkit::gpu::PixelFormat::RG8U, + stormkit::gpu::PixelFormat::RG8_UNORM, + stormkit::gpu::PixelFormat::RGB16F, + stormkit::gpu::PixelFormat::RGB16I, + stormkit::gpu::PixelFormat::RGB16_SNORM, + stormkit::gpu::PixelFormat::RGB16U, + stormkit::gpu::PixelFormat::RGB16_UNORM, + stormkit::gpu::PixelFormat::RGB32F, + stormkit::gpu::PixelFormat::RGB32I, + stormkit::gpu::PixelFormat::RGB32U, + stormkit::gpu::PixelFormat::RGB8I, + stormkit::gpu::PixelFormat::RGB8_SNORM, + stormkit::gpu::PixelFormat::RGB8U, + stormkit::gpu::PixelFormat::RGB8_UNORM, + stormkit::gpu::PixelFormat::RGBA16F, + stormkit::gpu::PixelFormat::RGBA16I, + stormkit::gpu::PixelFormat::RGBA16_SNORM, + stormkit::gpu::PixelFormat::RGBA16U, + stormkit::gpu::PixelFormat::RGBA16_UNORM, + stormkit::gpu::PixelFormat::RGBA32F, + stormkit::gpu::PixelFormat::RGBA32I, + stormkit::gpu::PixelFormat::RGBA32U, + stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16, + stormkit::gpu::PixelFormat::RGBA8I, + stormkit::gpu::PixelFormat::RGBA8_SNORM, + stormkit::gpu::PixelFormat::RGBA8U, + stormkit::gpu::PixelFormat::RGBA8_UNORM, + stormkit::gpu::PixelFormat::SBGR8, + stormkit::gpu::PixelFormat::SBGRA8, + stormkit::gpu::PixelFormat::SR8, + stormkit::gpu::PixelFormat::SRG8, + stormkit::gpu::PixelFormat::SRGB8, + stormkit::gpu::PixelFormat::SRGBA8, + stormkit::gpu::PixelFormat::UNDEFINED, + + }; + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::PixelFormat value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; + case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; + case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; + case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; + case stormkit::gpu::PixelFormat::DEPTH16_UNORM: return "PixelFormat::DEPTH16_UNORM"; + case stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U: return "PixelFormat::DEPTH16_UNORM_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32: return "PixelFormat::DEPTH24_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U: return "PixelFormat::DEPTH24_UNORM_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH32F: return "PixelFormat::DEPTH32F"; + case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; + case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; + case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; + case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; + case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; + case stormkit::gpu::PixelFormat::R16_UNORM: return "PixelFormat::R16_UNORM"; + case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; + case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; + case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; + case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; + case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; + case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; + case stormkit::gpu::PixelFormat::R8_UNORM: return "PixelFormat::R8_UNORM"; + case stormkit::gpu::PixelFormat::RG16F: return "PixelFormat::RG16F"; + case stormkit::gpu::PixelFormat::RG16I: return "PixelFormat::RG16I"; + case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; + case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; + case stormkit::gpu::PixelFormat::RG16_UNORM: return "PixelFormat::RG16_UNORM"; + case stormkit::gpu::PixelFormat::RG32F: return "PixelFormat::RG32F"; + case stormkit::gpu::PixelFormat::RG32I: return "PixelFormat::RG32I"; + case stormkit::gpu::PixelFormat::RG32U: return "PixelFormat::RG32U"; + case stormkit::gpu::PixelFormat::RG8I: return "PixelFormat::RG8I"; + case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; + case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; + case stormkit::gpu::PixelFormat::RG8_UNORM: return "PixelFormat::RG8_UNORM"; + case stormkit::gpu::PixelFormat::RGB16F: return "PixelFormat::RGB16F"; + case stormkit::gpu::PixelFormat::RGB16I: return "PixelFormat::RGB16I"; + case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; + case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; + case stormkit::gpu::PixelFormat::RGB16_UNORM: return "PixelFormat::RGB16_UNORM"; + case stormkit::gpu::PixelFormat::RGB32F: return "PixelFormat::RGB32F"; + case stormkit::gpu::PixelFormat::RGB32I: return "PixelFormat::RGB32I"; + case stormkit::gpu::PixelFormat::RGB32U: return "PixelFormat::RGB32U"; + case stormkit::gpu::PixelFormat::RGB8I: return "PixelFormat::RGB8I"; + case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; + case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; + case stormkit::gpu::PixelFormat::RGB8_UNORM: return "PixelFormat::RGB8_UNORM"; + case stormkit::gpu::PixelFormat::RGBA16F: return "PixelFormat::RGBA16F"; + case stormkit::gpu::PixelFormat::RGBA16I: return "PixelFormat::RGBA16I"; + case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; + case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; + case stormkit::gpu::PixelFormat::RGBA16_UNORM: return "PixelFormat::RGBA16_UNORM"; + case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; + case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; + case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; + case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; + case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; + case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; + case stormkit::gpu::PixelFormat::RGBA8_UNORM: return "PixelFormat::RGBA8_UNORM"; + case stormkit::gpu::PixelFormat::SBGR8: return "PixelFormat::SBGR8"; + case stormkit::gpu::PixelFormat::SBGRA8: return "PixelFormat::SBGRA8"; + case stormkit::gpu::PixelFormat::SR8: return "PixelFormat::SR8"; + case stormkit::gpu::PixelFormat::SRG8: return "PixelFormat::SRG8"; + case stormkit::gpu::PixelFormat::SRGB8: return "PixelFormat::SRGB8"; + case stormkit::gpu::PixelFormat::SRGBA8: return "PixelFormat::SRGBA8"; + case stormkit::gpu::PixelFormat::UNDEFINED: return "PixelFormat::UNDEFINED"; + + } + std::unreachable(); + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::to_string(stormkit::gpu::PixelFormat value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; + case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; + case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; + case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; + case stormkit::gpu::PixelFormat::DEPTH16_UNORM: return "PixelFormat::DEPTH16_UNORM"; + case stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U: return "PixelFormat::DEPTH16_UNORM_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32: return "PixelFormat::DEPTH24_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U: return "PixelFormat::DEPTH24_UNORM_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH32F: return "PixelFormat::DEPTH32F"; + case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; + case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; + case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; + case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; + case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; + case stormkit::gpu::PixelFormat::R16_UNORM: return "PixelFormat::R16_UNORM"; + case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; + case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; + case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; + case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; + case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; + case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; + case stormkit::gpu::PixelFormat::R8_UNORM: return "PixelFormat::R8_UNORM"; + case stormkit::gpu::PixelFormat::RG16F: return "PixelFormat::RG16F"; + case stormkit::gpu::PixelFormat::RG16I: return "PixelFormat::RG16I"; + case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; + case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; + case stormkit::gpu::PixelFormat::RG16_UNORM: return "PixelFormat::RG16_UNORM"; + case stormkit::gpu::PixelFormat::RG32F: return "PixelFormat::RG32F"; + case stormkit::gpu::PixelFormat::RG32I: return "PixelFormat::RG32I"; + case stormkit::gpu::PixelFormat::RG32U: return "PixelFormat::RG32U"; + case stormkit::gpu::PixelFormat::RG8I: return "PixelFormat::RG8I"; + case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; + case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; + case stormkit::gpu::PixelFormat::RG8_UNORM: return "PixelFormat::RG8_UNORM"; + case stormkit::gpu::PixelFormat::RGB16F: return "PixelFormat::RGB16F"; + case stormkit::gpu::PixelFormat::RGB16I: return "PixelFormat::RGB16I"; + case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; + case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; + case stormkit::gpu::PixelFormat::RGB16_UNORM: return "PixelFormat::RGB16_UNORM"; + case stormkit::gpu::PixelFormat::RGB32F: return "PixelFormat::RGB32F"; + case stormkit::gpu::PixelFormat::RGB32I: return "PixelFormat::RGB32I"; + case stormkit::gpu::PixelFormat::RGB32U: return "PixelFormat::RGB32U"; + case stormkit::gpu::PixelFormat::RGB8I: return "PixelFormat::RGB8I"; + case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; + case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; + case stormkit::gpu::PixelFormat::RGB8_UNORM: return "PixelFormat::RGB8_UNORM"; + case stormkit::gpu::PixelFormat::RGBA16F: return "PixelFormat::RGBA16F"; + case stormkit::gpu::PixelFormat::RGBA16I: return "PixelFormat::RGBA16I"; + case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; + case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; + case stormkit::gpu::PixelFormat::RGBA16_UNORM: return "PixelFormat::RGBA16_UNORM"; + case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; + case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; + case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; + case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; + case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; + case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; + case stormkit::gpu::PixelFormat::RGBA8_UNORM: return "PixelFormat::RGBA8_UNORM"; + case stormkit::gpu::PixelFormat::SBGR8: return "PixelFormat::SBGR8"; + case stormkit::gpu::PixelFormat::SBGRA8: return "PixelFormat::SBGRA8"; + case stormkit::gpu::PixelFormat::SR8: return "PixelFormat::SR8"; + case stormkit::gpu::PixelFormat::SRG8: return "PixelFormat::SRG8"; + case stormkit::gpu::PixelFormat::SRGB8: return "PixelFormat::SRGB8"; + case stormkit::gpu::PixelFormat::SRGBA8: return "PixelFormat::SRGBA8"; + case stormkit::gpu::PixelFormat::UNDEFINED: return "PixelFormat::UNDEFINED"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PolygonMode) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PolygonMode::FILL, - stormkit::gpu::PolygonMode::LINE, - stormkit::gpu::PolygonMode::POINT, - + stormkit::gpu::PolygonMode::FILL, + stormkit::gpu::PolygonMode::LINE, + stormkit::gpu::PolygonMode::POINT, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PolygonMode value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::PolygonMode::FILL: return "PolygonMode::FILL"; - case stormkit::gpu::PolygonMode::LINE: return "PolygonMode::LINE"; - case stormkit::gpu::PolygonMode::POINT: return "PolygonMode::POINT"; + constexpr auto stormkit::core::as_string(stormkit::gpu::PolygonMode value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::PolygonMode::FILL: return "PolygonMode::FILL"; + case stormkit::gpu::PolygonMode::LINE: return "PolygonMode::LINE"; + case stormkit::gpu::PolygonMode::POINT: return "PolygonMode::POINT"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::PolygonMode value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::PolygonMode::FILL: return "PolygonMode::FILL"; - case stormkit::gpu::PolygonMode::LINE: return "PolygonMode::LINE"; - case stormkit::gpu::PolygonMode::POINT: return "PolygonMode::POINT"; + constexpr auto stormkit::core::to_string(stormkit::gpu::PolygonMode value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::PolygonMode::FILL: return "PolygonMode::FILL"; + case stormkit::gpu::PolygonMode::LINE: return "PolygonMode::LINE"; + case stormkit::gpu::PolygonMode::POINT: return "PolygonMode::POINT"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PresentMode) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PresentMode::FIFO, - stormkit::gpu::PresentMode::FIFO_RELAXED, - stormkit::gpu::PresentMode::IMMEDIATE, - stormkit::gpu::PresentMode::MAILBOX, - stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH, - stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH, - + stormkit::gpu::PresentMode::FIFO, + stormkit::gpu::PresentMode::FIFO_RELAXED, + stormkit::gpu::PresentMode::IMMEDIATE, + stormkit::gpu::PresentMode::MAILBOX, + stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH, + stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PresentMode value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::PresentMode::FIFO: return "PresentMode::FIFO"; - case stormkit::gpu::PresentMode::FIFO_RELAXED: return "PresentMode::FIFO_RELAXED"; - case stormkit::gpu::PresentMode::IMMEDIATE: return "PresentMode::IMMEDIATE"; - case stormkit::gpu::PresentMode::MAILBOX: return "PresentMode::MAILBOX"; - case stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH: return "PresentMode::SHARED_CONTINUOUS_REFRESH"; - case stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH: return "PresentMode::SHARED_DEMAND_REFRESH"; + constexpr auto stormkit::core::as_string(stormkit::gpu::PresentMode value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::PresentMode::FIFO: return "PresentMode::FIFO"; + case stormkit::gpu::PresentMode::FIFO_RELAXED: return "PresentMode::FIFO_RELAXED"; + case stormkit::gpu::PresentMode::IMMEDIATE: return "PresentMode::IMMEDIATE"; + case stormkit::gpu::PresentMode::MAILBOX: return "PresentMode::MAILBOX"; + case stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH: return "PresentMode::SHARED_CONTINUOUS_REFRESH"; + case stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH: return "PresentMode::SHARED_DEMAND_REFRESH"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::PresentMode value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::PresentMode::FIFO: return "PresentMode::FIFO"; - case stormkit::gpu::PresentMode::FIFO_RELAXED: return "PresentMode::FIFO_RELAXED"; - case stormkit::gpu::PresentMode::IMMEDIATE: return "PresentMode::IMMEDIATE"; - case stormkit::gpu::PresentMode::MAILBOX: return "PresentMode::MAILBOX"; - case stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH: return "PresentMode::SHARED_CONTINUOUS_REFRESH"; - case stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH: return "PresentMode::SHARED_DEMAND_REFRESH"; + constexpr auto stormkit::core::to_string(stormkit::gpu::PresentMode value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::PresentMode::FIFO: return "PresentMode::FIFO"; + case stormkit::gpu::PresentMode::FIFO_RELAXED: return "PresentMode::FIFO_RELAXED"; + case stormkit::gpu::PresentMode::IMMEDIATE: return "PresentMode::IMMEDIATE"; + case stormkit::gpu::PresentMode::MAILBOX: return "PresentMode::MAILBOX"; + case stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH: return "PresentMode::SHARED_CONTINUOUS_REFRESH"; + case stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH: return "PresentMode::SHARED_DEMAND_REFRESH"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PrimitiveTopology) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PrimitiveTopology::LINE_LIST, stormkit::gpu::PrimitiveTopology::LINE_STRIP, - stormkit::gpu::PrimitiveTopology::POINT_LIST, stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN, - stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST, stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP, - + stormkit::gpu::PrimitiveTopology::LINE_LIST, + stormkit::gpu::PrimitiveTopology::LINE_STRIP, + stormkit::gpu::PrimitiveTopology::POINT_LIST, + stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN, + stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST, + stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PrimitiveTopology value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::PrimitiveTopology::LINE_LIST: return "PrimitiveTopology::LINE_LIST"; - case stormkit::gpu::PrimitiveTopology::LINE_STRIP: return "PrimitiveTopology::LINE_STRIP"; - case stormkit::gpu::PrimitiveTopology::POINT_LIST: return "PrimitiveTopology::POINT_LIST"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN: return "PrimitiveTopology::TRIANGLE_FAN"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST: return "PrimitiveTopology::TRIANGLE_LIST"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP: return "PrimitiveTopology::TRIANGLE_STRIP"; + constexpr auto stormkit::core::as_string(stormkit::gpu::PrimitiveTopology value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::PrimitiveTopology::LINE_LIST: return "PrimitiveTopology::LINE_LIST"; + case stormkit::gpu::PrimitiveTopology::LINE_STRIP: return "PrimitiveTopology::LINE_STRIP"; + case stormkit::gpu::PrimitiveTopology::POINT_LIST: return "PrimitiveTopology::POINT_LIST"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN: return "PrimitiveTopology::TRIANGLE_FAN"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST: return "PrimitiveTopology::TRIANGLE_LIST"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP: return "PrimitiveTopology::TRIANGLE_STRIP"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::PrimitiveTopology value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::PrimitiveTopology::LINE_LIST: return "PrimitiveTopology::LINE_LIST"; - case stormkit::gpu::PrimitiveTopology::LINE_STRIP: return "PrimitiveTopology::LINE_STRIP"; - case stormkit::gpu::PrimitiveTopology::POINT_LIST: return "PrimitiveTopology::POINT_LIST"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN: return "PrimitiveTopology::TRIANGLE_FAN"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST: return "PrimitiveTopology::TRIANGLE_LIST"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP: return "PrimitiveTopology::TRIANGLE_STRIP"; + constexpr auto stormkit::core::to_string(stormkit::gpu::PrimitiveTopology value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::PrimitiveTopology::LINE_LIST: return "PrimitiveTopology::LINE_LIST"; + case stormkit::gpu::PrimitiveTopology::LINE_STRIP: return "PrimitiveTopology::LINE_STRIP"; + case stormkit::gpu::PrimitiveTopology::POINT_LIST: return "PrimitiveTopology::POINT_LIST"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN: return "PrimitiveTopology::TRIANGLE_FAN"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST: return "PrimitiveTopology::TRIANGLE_LIST"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP: return "PrimitiveTopology::TRIANGLE_STRIP"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::QueueFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::QueueFlag::COMPUTE, stormkit::gpu::QueueFlag::GRAPHICS, stormkit::gpu::QueueFlag::NONE, - stormkit::gpu::QueueFlag::PROTECTED, stormkit::gpu::QueueFlag::SPARSE_BINDING, stormkit::gpu::QueueFlag::TRANSFER, - + stormkit::gpu::QueueFlag::COMPUTE, + stormkit::gpu::QueueFlag::GRAPHICS, + stormkit::gpu::QueueFlag::NONE, + stormkit::gpu::QueueFlag::PROTECTED, + stormkit::gpu::QueueFlag::SPARSE_BINDING, + stormkit::gpu::QueueFlag::TRANSFER, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::QueueFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; - case stormkit::gpu::QueueFlag::GRAPHICS: return "QueueFlag::GRAPHICS"; - case stormkit::gpu::QueueFlag::NONE: return "QueueFlag::NONE"; - case stormkit::gpu::QueueFlag::PROTECTED: return "QueueFlag::PROTECTED"; - case stormkit::gpu::QueueFlag::SPARSE_BINDING: return "QueueFlag::SPARSE_BINDING"; - case stormkit::gpu::QueueFlag::TRANSFER: return "QueueFlag::TRANSFER"; + constexpr auto stormkit::core::as_string(stormkit::gpu::QueueFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; + case stormkit::gpu::QueueFlag::GRAPHICS: return "QueueFlag::GRAPHICS"; + case stormkit::gpu::QueueFlag::NONE: return "QueueFlag::NONE"; + case stormkit::gpu::QueueFlag::PROTECTED: return "QueueFlag::PROTECTED"; + case stormkit::gpu::QueueFlag::SPARSE_BINDING: return "QueueFlag::SPARSE_BINDING"; + case stormkit::gpu::QueueFlag::TRANSFER: return "QueueFlag::TRANSFER"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::QueueFlag value) noexcept -> std::string { - switch (value) { - case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; - case stormkit::gpu::QueueFlag::GRAPHICS: return "QueueFlag::GRAPHICS"; - case stormkit::gpu::QueueFlag::NONE: return "QueueFlag::NONE"; - case stormkit::gpu::QueueFlag::PROTECTED: return "QueueFlag::PROTECTED"; - case stormkit::gpu::QueueFlag::SPARSE_BINDING: return "QueueFlag::SPARSE_BINDING"; - case stormkit::gpu::QueueFlag::TRANSFER: return "QueueFlag::TRANSFER"; + switch(value) { + case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; + case stormkit::gpu::QueueFlag::GRAPHICS: return "QueueFlag::GRAPHICS"; + case stormkit::gpu::QueueFlag::NONE: return "QueueFlag::NONE"; + case stormkit::gpu::QueueFlag::PROTECTED: return "QueueFlag::PROTECTED"; + case stormkit::gpu::QueueFlag::SPARSE_BINDING: return "QueueFlag::SPARSE_BINDING"; + case stormkit::gpu::QueueFlag::TRANSFER: return "QueueFlag::TRANSFER"; + + } + std::unreachable(); + } + FLAG_ENUM(stormkit::gpu::ResolveModeFlag) + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { + return std::array { + stormkit::gpu::ResolveModeFlag::AVERAGE, + stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID, + stormkit::gpu::ResolveModeFlag::MAX, + stormkit::gpu::ResolveModeFlag::MIN, + stormkit::gpu::ResolveModeFlag::NONE, + stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO, + + }; + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::ResolveModeFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ResolveModeFlag::AVERAGE: return "ResolveModeFlag::AVERAGE"; + case stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID: return "ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID"; + case stormkit::gpu::ResolveModeFlag::MAX: return "ResolveModeFlag::MAX"; + case stormkit::gpu::ResolveModeFlag::MIN: return "ResolveModeFlag::MIN"; + case stormkit::gpu::ResolveModeFlag::NONE: return "ResolveModeFlag::NONE"; + case stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO: return "ResolveModeFlag::SAMPLE_ZERO"; + + } + std::unreachable(); + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::to_string(stormkit::gpu::ResolveModeFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::ResolveModeFlag::AVERAGE: return "ResolveModeFlag::AVERAGE"; + case stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID: return "ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID"; + case stormkit::gpu::ResolveModeFlag::MAX: return "ResolveModeFlag::MAX"; + case stormkit::gpu::ResolveModeFlag::MIN: return "ResolveModeFlag::MIN"; + case stormkit::gpu::ResolveModeFlag::NONE: return "ResolveModeFlag::NONE"; + case stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO: return "ResolveModeFlag::SAMPLE_ZERO"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::Result) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::Result::ERROR_DEVICE_LOST, - stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT, - stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT, - stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED, - stormkit::gpu::Result::ERROR_FRAGMENTATION, - stormkit::gpu::Result::ERROR_FRAGMENTED_POOL, - stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST, - stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY, - stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER, - stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED, - stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE, - stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, - stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT, - stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED, - stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE, - stormkit::gpu::Result::ERROR_NOT_PERMITTED, - stormkit::gpu::Result::ERROR_OUT_OF_DATE, - stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY, - stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY, - stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY, - stormkit::gpu::Result::ERROR_SURFACE_LOST, - stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS, - stormkit::gpu::Result::ERROR_UNKNOWN, - stormkit::gpu::Result::ERROR_VALIDATION_FAILED, - stormkit::gpu::Result::EVENT_RESET, - stormkit::gpu::Result::EVENT_SET, - stormkit::gpu::Result::INCOMPLETE, - stormkit::gpu::Result::NOT_READY, - stormkit::gpu::Result::OPERATION_DEFERRED, - stormkit::gpu::Result::OPERATION_NOT_DEFERRED, - stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED, - stormkit::gpu::Result::SUBOPTIMAL, - stormkit::gpu::Result::SUCCESS, - stormkit::gpu::Result::THREAD_DONE, - stormkit::gpu::Result::THREAD_IDLE, - stormkit::gpu::Result::TIMEOUT, - + stormkit::gpu::Result::ERROR_DEVICE_LOST, + stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT, + stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT, + stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED, + stormkit::gpu::Result::ERROR_FRAGMENTATION, + stormkit::gpu::Result::ERROR_FRAGMENTED_POOL, + stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST, + stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY, + stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER, + stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED, + stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE, + stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, + stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT, + stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED, + stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE, + stormkit::gpu::Result::ERROR_NOT_PERMITTED, + stormkit::gpu::Result::ERROR_OUT_OF_DATE, + stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY, + stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY, + stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY, + stormkit::gpu::Result::ERROR_SURFACE_LOST, + stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS, + stormkit::gpu::Result::ERROR_UNKNOWN, + stormkit::gpu::Result::ERROR_VALIDATION_FAILED, + stormkit::gpu::Result::EVENT_RESET, + stormkit::gpu::Result::EVENT_SET, + stormkit::gpu::Result::INCOMPLETE, + stormkit::gpu::Result::NOT_READY, + stormkit::gpu::Result::OPERATION_DEFERRED, + stormkit::gpu::Result::OPERATION_NOT_DEFERRED, + stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED, + stormkit::gpu::Result::SUBOPTIMAL, + stormkit::gpu::Result::SUCCESS, + stormkit::gpu::Result::THREAD_DONE, + stormkit::gpu::Result::THREAD_IDLE, + stormkit::gpu::Result::TIMEOUT, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::Result value) noexcept -> std::string_view { - switch (value) { - case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; - case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: return "Result::ERROR_EXTENSION_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT: return "Result::ERROR_FEATURE_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED: return "Result::ERROR_FORMAT_NOT_SUPPORTED"; - case stormkit::gpu::Result::ERROR_FRAGMENTATION: return "Result::ERROR_FRAGMENTATION"; - case stormkit::gpu::Result::ERROR_FRAGMENTED_POOL: return "Result::ERROR_FRAGMENTED_POOL"; - case stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST: - return "Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST"; - case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY: return "Result::ERROR_INCOMPATIBLE_DISPLAY"; - case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER: return "Result::ERROR_INCOMPATIBLE_DRIVER"; - case stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED: return "Result::ERROR_INITIALIZATION_FAILED"; - case stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE: return "Result::ERROR_INVALID_EXTERNAL_HANDLE"; - case stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: - return "Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; - case stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT: return "Result::ERROR_LAYER_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED: return "Result::ERROR_MEMORY_MAP_FAILED"; - case stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE: return "Result::ERROR_NATIVE_WINDOW_IN_USE"; - case stormkit::gpu::Result::ERROR_NOT_PERMITTED: return "Result::ERROR_NOT_PERMITTED"; - case stormkit::gpu::Result::ERROR_OUT_OF_DATE: return "Result::ERROR_OUT_OF_DATE"; - case stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY: return "Result::ERROR_OUT_OF_DEVICE_MEMORY"; - case stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY: return "Result::ERROR_OUT_OF_HOST_MEMORY"; - case stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY: return "Result::ERROR_OUT_OF_POOL_MEMORY"; - case stormkit::gpu::Result::ERROR_SURFACE_LOST: return "Result::ERROR_SURFACE_LOST"; - case stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS: return "Result::ERROR_TOO_MANY_OBJECTS"; - case stormkit::gpu::Result::ERROR_UNKNOWN: return "Result::ERROR_UNKNOWN"; - case stormkit::gpu::Result::ERROR_VALIDATION_FAILED: return "Result::ERROR_VALIDATION_FAILED"; - case stormkit::gpu::Result::EVENT_RESET: return "Result::EVENT_RESET"; - case stormkit::gpu::Result::EVENT_SET: return "Result::EVENT_SET"; - case stormkit::gpu::Result::INCOMPLETE: return "Result::INCOMPLETE"; - case stormkit::gpu::Result::NOT_READY: return "Result::NOT_READY"; - case stormkit::gpu::Result::OPERATION_DEFERRED: return "Result::OPERATION_DEFERRED"; - case stormkit::gpu::Result::OPERATION_NOT_DEFERRED: return "Result::OPERATION_NOT_DEFERRED"; - case stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED: return "Result::PIPELINE_COMPILE_REQUIRED"; - case stormkit::gpu::Result::SUBOPTIMAL: return "Result::SUBOPTIMAL"; - case stormkit::gpu::Result::SUCCESS: return "Result::SUCCESS"; - case stormkit::gpu::Result::THREAD_DONE: return "Result::THREAD_DONE"; - case stormkit::gpu::Result::THREAD_IDLE: return "Result::THREAD_IDLE"; - case stormkit::gpu::Result::TIMEOUT: return "Result::TIMEOUT"; + switch(value) { + case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; + case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: return "Result::ERROR_EXTENSION_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT: return "Result::ERROR_FEATURE_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED: return "Result::ERROR_FORMAT_NOT_SUPPORTED"; + case stormkit::gpu::Result::ERROR_FRAGMENTATION: return "Result::ERROR_FRAGMENTATION"; + case stormkit::gpu::Result::ERROR_FRAGMENTED_POOL: return "Result::ERROR_FRAGMENTED_POOL"; + case stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST: return "Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST"; + case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY: return "Result::ERROR_INCOMPATIBLE_DISPLAY"; + case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER: return "Result::ERROR_INCOMPATIBLE_DRIVER"; + case stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED: return "Result::ERROR_INITIALIZATION_FAILED"; + case stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE: return "Result::ERROR_INVALID_EXTERNAL_HANDLE"; + case stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: return "Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; + case stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT: return "Result::ERROR_LAYER_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED: return "Result::ERROR_MEMORY_MAP_FAILED"; + case stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE: return "Result::ERROR_NATIVE_WINDOW_IN_USE"; + case stormkit::gpu::Result::ERROR_NOT_PERMITTED: return "Result::ERROR_NOT_PERMITTED"; + case stormkit::gpu::Result::ERROR_OUT_OF_DATE: return "Result::ERROR_OUT_OF_DATE"; + case stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY: return "Result::ERROR_OUT_OF_DEVICE_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY: return "Result::ERROR_OUT_OF_HOST_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY: return "Result::ERROR_OUT_OF_POOL_MEMORY"; + case stormkit::gpu::Result::ERROR_SURFACE_LOST: return "Result::ERROR_SURFACE_LOST"; + case stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS: return "Result::ERROR_TOO_MANY_OBJECTS"; + case stormkit::gpu::Result::ERROR_UNKNOWN: return "Result::ERROR_UNKNOWN"; + case stormkit::gpu::Result::ERROR_VALIDATION_FAILED: return "Result::ERROR_VALIDATION_FAILED"; + case stormkit::gpu::Result::EVENT_RESET: return "Result::EVENT_RESET"; + case stormkit::gpu::Result::EVENT_SET: return "Result::EVENT_SET"; + case stormkit::gpu::Result::INCOMPLETE: return "Result::INCOMPLETE"; + case stormkit::gpu::Result::NOT_READY: return "Result::NOT_READY"; + case stormkit::gpu::Result::OPERATION_DEFERRED: return "Result::OPERATION_DEFERRED"; + case stormkit::gpu::Result::OPERATION_NOT_DEFERRED: return "Result::OPERATION_NOT_DEFERRED"; + case stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED: return "Result::PIPELINE_COMPILE_REQUIRED"; + case stormkit::gpu::Result::SUBOPTIMAL: return "Result::SUBOPTIMAL"; + case stormkit::gpu::Result::SUCCESS: return "Result::SUCCESS"; + case stormkit::gpu::Result::THREAD_DONE: return "Result::THREAD_DONE"; + case stormkit::gpu::Result::THREAD_IDLE: return "Result::THREAD_IDLE"; + case stormkit::gpu::Result::TIMEOUT: return "Result::TIMEOUT"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::Result value) noexcept -> std::string { - switch (value) { - case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; - case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: return "Result::ERROR_EXTENSION_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT: return "Result::ERROR_FEATURE_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED: return "Result::ERROR_FORMAT_NOT_SUPPORTED"; - case stormkit::gpu::Result::ERROR_FRAGMENTATION: return "Result::ERROR_FRAGMENTATION"; - case stormkit::gpu::Result::ERROR_FRAGMENTED_POOL: return "Result::ERROR_FRAGMENTED_POOL"; - case stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST: - return "Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST"; - case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY: return "Result::ERROR_INCOMPATIBLE_DISPLAY"; - case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER: return "Result::ERROR_INCOMPATIBLE_DRIVER"; - case stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED: return "Result::ERROR_INITIALIZATION_FAILED"; - case stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE: return "Result::ERROR_INVALID_EXTERNAL_HANDLE"; - case stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: - return "Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; - case stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT: return "Result::ERROR_LAYER_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED: return "Result::ERROR_MEMORY_MAP_FAILED"; - case stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE: return "Result::ERROR_NATIVE_WINDOW_IN_USE"; - case stormkit::gpu::Result::ERROR_NOT_PERMITTED: return "Result::ERROR_NOT_PERMITTED"; - case stormkit::gpu::Result::ERROR_OUT_OF_DATE: return "Result::ERROR_OUT_OF_DATE"; - case stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY: return "Result::ERROR_OUT_OF_DEVICE_MEMORY"; - case stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY: return "Result::ERROR_OUT_OF_HOST_MEMORY"; - case stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY: return "Result::ERROR_OUT_OF_POOL_MEMORY"; - case stormkit::gpu::Result::ERROR_SURFACE_LOST: return "Result::ERROR_SURFACE_LOST"; - case stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS: return "Result::ERROR_TOO_MANY_OBJECTS"; - case stormkit::gpu::Result::ERROR_UNKNOWN: return "Result::ERROR_UNKNOWN"; - case stormkit::gpu::Result::ERROR_VALIDATION_FAILED: return "Result::ERROR_VALIDATION_FAILED"; - case stormkit::gpu::Result::EVENT_RESET: return "Result::EVENT_RESET"; - case stormkit::gpu::Result::EVENT_SET: return "Result::EVENT_SET"; - case stormkit::gpu::Result::INCOMPLETE: return "Result::INCOMPLETE"; - case stormkit::gpu::Result::NOT_READY: return "Result::NOT_READY"; - case stormkit::gpu::Result::OPERATION_DEFERRED: return "Result::OPERATION_DEFERRED"; - case stormkit::gpu::Result::OPERATION_NOT_DEFERRED: return "Result::OPERATION_NOT_DEFERRED"; - case stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED: return "Result::PIPELINE_COMPILE_REQUIRED"; - case stormkit::gpu::Result::SUBOPTIMAL: return "Result::SUBOPTIMAL"; - case stormkit::gpu::Result::SUCCESS: return "Result::SUCCESS"; - case stormkit::gpu::Result::THREAD_DONE: return "Result::THREAD_DONE"; - case stormkit::gpu::Result::THREAD_IDLE: return "Result::THREAD_IDLE"; - case stormkit::gpu::Result::TIMEOUT: return "Result::TIMEOUT"; + switch(value) { + case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; + case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: return "Result::ERROR_EXTENSION_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT: return "Result::ERROR_FEATURE_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED: return "Result::ERROR_FORMAT_NOT_SUPPORTED"; + case stormkit::gpu::Result::ERROR_FRAGMENTATION: return "Result::ERROR_FRAGMENTATION"; + case stormkit::gpu::Result::ERROR_FRAGMENTED_POOL: return "Result::ERROR_FRAGMENTED_POOL"; + case stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST: return "Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST"; + case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY: return "Result::ERROR_INCOMPATIBLE_DISPLAY"; + case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER: return "Result::ERROR_INCOMPATIBLE_DRIVER"; + case stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED: return "Result::ERROR_INITIALIZATION_FAILED"; + case stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE: return "Result::ERROR_INVALID_EXTERNAL_HANDLE"; + case stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: return "Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; + case stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT: return "Result::ERROR_LAYER_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED: return "Result::ERROR_MEMORY_MAP_FAILED"; + case stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE: return "Result::ERROR_NATIVE_WINDOW_IN_USE"; + case stormkit::gpu::Result::ERROR_NOT_PERMITTED: return "Result::ERROR_NOT_PERMITTED"; + case stormkit::gpu::Result::ERROR_OUT_OF_DATE: return "Result::ERROR_OUT_OF_DATE"; + case stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY: return "Result::ERROR_OUT_OF_DEVICE_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY: return "Result::ERROR_OUT_OF_HOST_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY: return "Result::ERROR_OUT_OF_POOL_MEMORY"; + case stormkit::gpu::Result::ERROR_SURFACE_LOST: return "Result::ERROR_SURFACE_LOST"; + case stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS: return "Result::ERROR_TOO_MANY_OBJECTS"; + case stormkit::gpu::Result::ERROR_UNKNOWN: return "Result::ERROR_UNKNOWN"; + case stormkit::gpu::Result::ERROR_VALIDATION_FAILED: return "Result::ERROR_VALIDATION_FAILED"; + case stormkit::gpu::Result::EVENT_RESET: return "Result::EVENT_RESET"; + case stormkit::gpu::Result::EVENT_SET: return "Result::EVENT_SET"; + case stormkit::gpu::Result::INCOMPLETE: return "Result::INCOMPLETE"; + case stormkit::gpu::Result::NOT_READY: return "Result::NOT_READY"; + case stormkit::gpu::Result::OPERATION_DEFERRED: return "Result::OPERATION_DEFERRED"; + case stormkit::gpu::Result::OPERATION_NOT_DEFERRED: return "Result::OPERATION_NOT_DEFERRED"; + case stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED: return "Result::PIPELINE_COMPILE_REQUIRED"; + case stormkit::gpu::Result::SUBOPTIMAL: return "Result::SUBOPTIMAL"; + case stormkit::gpu::Result::SUCCESS: return "Result::SUCCESS"; + case stormkit::gpu::Result::THREAD_DONE: return "Result::THREAD_DONE"; + case stormkit::gpu::Result::THREAD_IDLE: return "Result::THREAD_IDLE"; + case stormkit::gpu::Result::TIMEOUT: return "Result::TIMEOUT"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::SampleCountFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::SampleCountFlag::C1, stormkit::gpu::SampleCountFlag::C16, stormkit::gpu::SampleCountFlag::C2, - stormkit::gpu::SampleCountFlag::C32, stormkit::gpu::SampleCountFlag::C4, stormkit::gpu::SampleCountFlag::C64, - stormkit::gpu::SampleCountFlag::C8, - + stormkit::gpu::SampleCountFlag::C1, + stormkit::gpu::SampleCountFlag::C16, + stormkit::gpu::SampleCountFlag::C2, + stormkit::gpu::SampleCountFlag::C32, + stormkit::gpu::SampleCountFlag::C4, + stormkit::gpu::SampleCountFlag::C64, + stormkit::gpu::SampleCountFlag::C8, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::SampleCountFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::SampleCountFlag::C1: return "SampleCountFlag::C1"; - case stormkit::gpu::SampleCountFlag::C16: return "SampleCountFlag::C16"; - case stormkit::gpu::SampleCountFlag::C2: return "SampleCountFlag::C2"; - case stormkit::gpu::SampleCountFlag::C32: return "SampleCountFlag::C32"; - case stormkit::gpu::SampleCountFlag::C4: return "SampleCountFlag::C4"; - case stormkit::gpu::SampleCountFlag::C64: return "SampleCountFlag::C64"; - case stormkit::gpu::SampleCountFlag::C8: return "SampleCountFlag::C8"; + constexpr auto stormkit::core::as_string(stormkit::gpu::SampleCountFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::SampleCountFlag::C1: return "SampleCountFlag::C1"; + case stormkit::gpu::SampleCountFlag::C16: return "SampleCountFlag::C16"; + case stormkit::gpu::SampleCountFlag::C2: return "SampleCountFlag::C2"; + case stormkit::gpu::SampleCountFlag::C32: return "SampleCountFlag::C32"; + case stormkit::gpu::SampleCountFlag::C4: return "SampleCountFlag::C4"; + case stormkit::gpu::SampleCountFlag::C64: return "SampleCountFlag::C64"; + case stormkit::gpu::SampleCountFlag::C8: return "SampleCountFlag::C8"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::SampleCountFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::SampleCountFlag::C1: return "SampleCountFlag::C1"; - case stormkit::gpu::SampleCountFlag::C16: return "SampleCountFlag::C16"; - case stormkit::gpu::SampleCountFlag::C2: return "SampleCountFlag::C2"; - case stormkit::gpu::SampleCountFlag::C32: return "SampleCountFlag::C32"; - case stormkit::gpu::SampleCountFlag::C4: return "SampleCountFlag::C4"; - case stormkit::gpu::SampleCountFlag::C64: return "SampleCountFlag::C64"; - case stormkit::gpu::SampleCountFlag::C8: return "SampleCountFlag::C8"; + constexpr auto stormkit::core::to_string(stormkit::gpu::SampleCountFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::SampleCountFlag::C1: return "SampleCountFlag::C1"; + case stormkit::gpu::SampleCountFlag::C16: return "SampleCountFlag::C16"; + case stormkit::gpu::SampleCountFlag::C2: return "SampleCountFlag::C2"; + case stormkit::gpu::SampleCountFlag::C32: return "SampleCountFlag::C32"; + case stormkit::gpu::SampleCountFlag::C4: return "SampleCountFlag::C4"; + case stormkit::gpu::SampleCountFlag::C64: return "SampleCountFlag::C64"; + case stormkit::gpu::SampleCountFlag::C8: return "SampleCountFlag::C8"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::SamplerAddressMode) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER, - stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE, - stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE, - stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT, - stormkit::gpu::SamplerAddressMode::REPEAT, - + stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER, + stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE, + stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE, + stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT, + stormkit::gpu::SamplerAddressMode::REPEAT, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::SamplerAddressMode value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; - case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; - case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; + constexpr auto stormkit::core::as_string(stormkit::gpu::SamplerAddressMode value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; + case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; + case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerAddressMode value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; - case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; - case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; + constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerAddressMode value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; + case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; + case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::SamplerMipmapMode) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::SamplerMipmapMode::LINEAR, - stormkit::gpu::SamplerMipmapMode::NEAREST, - + stormkit::gpu::SamplerMipmapMode::LINEAR, + stormkit::gpu::SamplerMipmapMode::NEAREST, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::SamplerMipmapMode value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::SamplerMipmapMode::LINEAR: return "SamplerMipmapMode::LINEAR"; - case stormkit::gpu::SamplerMipmapMode::NEAREST: return "SamplerMipmapMode::NEAREST"; + constexpr auto stormkit::core::as_string(stormkit::gpu::SamplerMipmapMode value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::SamplerMipmapMode::LINEAR: return "SamplerMipmapMode::LINEAR"; + case stormkit::gpu::SamplerMipmapMode::NEAREST: return "SamplerMipmapMode::NEAREST"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerMipmapMode value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::SamplerMipmapMode::LINEAR: return "SamplerMipmapMode::LINEAR"; - case stormkit::gpu::SamplerMipmapMode::NEAREST: return "SamplerMipmapMode::NEAREST"; + constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerMipmapMode value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::SamplerMipmapMode::LINEAR: return "SamplerMipmapMode::LINEAR"; + case stormkit::gpu::SamplerMipmapMode::NEAREST: return "SamplerMipmapMode::NEAREST"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ShaderStageFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ShaderStageFlag::COMPUTE, stormkit::gpu::ShaderStageFlag::FRAGMENT, - stormkit::gpu::ShaderStageFlag::GEOMETRY, stormkit::gpu::ShaderStageFlag::NONE, - stormkit::gpu::ShaderStageFlag::VERTEX, - + stormkit::gpu::ShaderStageFlag::COMPUTE, + stormkit::gpu::ShaderStageFlag::FRAGMENT, + stormkit::gpu::ShaderStageFlag::GEOMETRY, + stormkit::gpu::ShaderStageFlag::NONE, + stormkit::gpu::ShaderStageFlag::VERTEX, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ShaderStageFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ShaderStageFlag::COMPUTE: return "ShaderStageFlag::COMPUTE"; - case stormkit::gpu::ShaderStageFlag::FRAGMENT: return "ShaderStageFlag::FRAGMENT"; - case stormkit::gpu::ShaderStageFlag::GEOMETRY: return "ShaderStageFlag::GEOMETRY"; - case stormkit::gpu::ShaderStageFlag::NONE: return "ShaderStageFlag::NONE"; - case stormkit::gpu::ShaderStageFlag::VERTEX: return "ShaderStageFlag::VERTEX"; + constexpr auto stormkit::core::as_string(stormkit::gpu::ShaderStageFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ShaderStageFlag::COMPUTE: return "ShaderStageFlag::COMPUTE"; + case stormkit::gpu::ShaderStageFlag::FRAGMENT: return "ShaderStageFlag::FRAGMENT"; + case stormkit::gpu::ShaderStageFlag::GEOMETRY: return "ShaderStageFlag::GEOMETRY"; + case stormkit::gpu::ShaderStageFlag::NONE: return "ShaderStageFlag::NONE"; + case stormkit::gpu::ShaderStageFlag::VERTEX: return "ShaderStageFlag::VERTEX"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ShaderStageFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::ShaderStageFlag::COMPUTE: return "ShaderStageFlag::COMPUTE"; - case stormkit::gpu::ShaderStageFlag::FRAGMENT: return "ShaderStageFlag::FRAGMENT"; - case stormkit::gpu::ShaderStageFlag::GEOMETRY: return "ShaderStageFlag::GEOMETRY"; - case stormkit::gpu::ShaderStageFlag::NONE: return "ShaderStageFlag::NONE"; - case stormkit::gpu::ShaderStageFlag::VERTEX: return "ShaderStageFlag::VERTEX"; + constexpr auto stormkit::core::to_string(stormkit::gpu::ShaderStageFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::ShaderStageFlag::COMPUTE: return "ShaderStageFlag::COMPUTE"; + case stormkit::gpu::ShaderStageFlag::FRAGMENT: return "ShaderStageFlag::FRAGMENT"; + case stormkit::gpu::ShaderStageFlag::GEOMETRY: return "ShaderStageFlag::GEOMETRY"; + case stormkit::gpu::ShaderStageFlag::NONE: return "ShaderStageFlag::NONE"; + case stormkit::gpu::ShaderStageFlag::VERTEX: return "ShaderStageFlag::VERTEX"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::StencilFaceFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::StencilFaceFlag::BACK, - stormkit::gpu::StencilFaceFlag::FRONT, - stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK, - + stormkit::gpu::StencilFaceFlag::BACK, + stormkit::gpu::StencilFaceFlag::FRONT, + stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::StencilFaceFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::StencilFaceFlag::BACK: return "StencilFaceFlag::BACK"; - case stormkit::gpu::StencilFaceFlag::FRONT: return "StencilFaceFlag::FRONT"; - case stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK: return "StencilFaceFlag::FRONT_AND_BACK"; + constexpr auto stormkit::core::as_string(stormkit::gpu::StencilFaceFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::StencilFaceFlag::BACK: return "StencilFaceFlag::BACK"; + case stormkit::gpu::StencilFaceFlag::FRONT: return "StencilFaceFlag::FRONT"; + case stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK: return "StencilFaceFlag::FRONT_AND_BACK"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::StencilFaceFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::StencilFaceFlag::BACK: return "StencilFaceFlag::BACK"; - case stormkit::gpu::StencilFaceFlag::FRONT: return "StencilFaceFlag::FRONT"; - case stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK: return "StencilFaceFlag::FRONT_AND_BACK"; + constexpr auto stormkit::core::to_string(stormkit::gpu::StencilFaceFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::StencilFaceFlag::BACK: return "StencilFaceFlag::BACK"; + case stormkit::gpu::StencilFaceFlag::FRONT: return "StencilFaceFlag::FRONT"; + case stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK: return "StencilFaceFlag::FRONT_AND_BACK"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::VertexInputRate) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::VertexInputRate::INSTANCE, - stormkit::gpu::VertexInputRate::VERTEX, - + stormkit::gpu::VertexInputRate::INSTANCE, + stormkit::gpu::VertexInputRate::VERTEX, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::VertexInputRate value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::VertexInputRate::INSTANCE: return "VertexInputRate::INSTANCE"; - case stormkit::gpu::VertexInputRate::VERTEX: return "VertexInputRate::VERTEX"; + constexpr auto stormkit::core::as_string(stormkit::gpu::VertexInputRate value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::VertexInputRate::INSTANCE: return "VertexInputRate::INSTANCE"; + case stormkit::gpu::VertexInputRate::VERTEX: return "VertexInputRate::VERTEX"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::VertexInputRate value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::VertexInputRate::INSTANCE: return "VertexInputRate::INSTANCE"; - case stormkit::gpu::VertexInputRate::VERTEX: return "VertexInputRate::VERTEX"; + constexpr auto stormkit::core::to_string(stormkit::gpu::VertexInputRate value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::VertexInputRate::INSTANCE: return "VertexInputRate::INSTANCE"; + case stormkit::gpu::VertexInputRate::VERTEX: return "VertexInputRate::VERTEX"; + } std::unreachable(); } + + // enum class Format : u8 { + // BYTE, + // BYTE2, + // BYTE3, + // BYTE4, - // enum class Format : u8 { - // BYTE, - // BYTE2, - // BYTE3, - // BYTE4, - - // BYTE_NORM, - // BYTE2_NORM, - // BYTE3_NORM, - // BYTE4_NORM, + // BYTE_NORM, + // BYTE2_NORM, + // BYTE3_NORM, + // BYTE4_NORM, - // BYTE_SCALED, - // BYTE2_SCALED, - // BYTE3_SCALED, - // BYTE4_SCALED, + // BYTE_SCALED, + // BYTE2_SCALED, + // BYTE3_SCALED, + // BYTE4_SCALED, - // UBYTE, - // UBYTE2, - // UBYTE3, - // UBYTE4, + // UBYTE, + // UBYTE2, + // UBYTE3, + // UBYTE4, - // UBYTE_NORM, - // UBYTE2_NORM, - // UBYTE3_NORM, - // UBYTE4_NORM, + // UBYTE_NORM, + // UBYTE2_NORM, + // UBYTE3_NORM, + // UBYTE4_NORM, - // UBYTE_UCALED, - // UBYTE2_UCALED, - // UBYTE3_UCALED, - // UBYTE4_UCALED, + // UBYTE_UCALED, + // UBYTE2_UCALED, + // UBYTE3_UCALED, + // UBYTE4_UCALED, - // SHORT, - // SHORT2, - // SHORT3, - // SHORT4, + // SHORT, + // SHORT2, + // SHORT3, + // SHORT4, - // SHORT_NORM, - // SHORT2_NORM, - // SHORT3_NORM, - // SHORT4_NORM, + // SHORT_NORM, + // SHORT2_NORM, + // SHORT3_NORM, + // SHORT4_NORM, - // SHORT_SCALED, - // SHORT2_SCALED, - // SHORT3_SCALED, - // SHORT4_SCALED, + // SHORT_SCALED, + // SHORT2_SCALED, + // SHORT3_SCALED, + // SHORT4_SCALED, - // USHORT, - // USHORT2, - // USHORT3, - // USHORT4, + // USHORT, + // USHORT2, + // USHORT3, + // USHORT4, - // USHORT_NORM, - // USHORT2_NORM, - // USHORT3_NORM, - // USHORT4_NORM, + // USHORT_NORM, + // USHORT2_NORM, + // USHORT3_NORM, + // USHORT4_NORM, - // USHORT_UCALED, - // USHORT2_UCALED, - // USHORT3_UCALED, - // USHORT4_UCALED, + // USHORT_UCALED, + // USHORT2_UCALED, + // USHORT3_UCALED, + // USHORT4_UCALED, - // INT, - // INT2, - // INT3, - // INT4, + // INT, + // INT2, + // INT3, + // INT4, - // UINT, - // UINT2, - // UINT3, - // UINT4, + // UINT, + // UINT2, + // UINT3, + // UINT4, - // LONG, - // LONG2, - // LONG3, - // LONG4, + // LONG, + // LONG2, + // LONG3, + // LONG4, - // ULONG, - // ULONG2, - // ULONG3, - // ULONG4, + // ULONG, + // ULONG2, + // ULONG3, + // ULONG4, + + // FLOAT, + // FLOAT2, + // FLOAT3, + // FLOAT4, - // FLOAT, - // FLOAT2, - // FLOAT3, - // FLOAT4, - - // DOUBLE, - // DOUBLE2, - // DOUBLE3, - // DOUBLE4, - - // UNDEFINED, - // }; + // DOUBLE, + // DOUBLE2, + // DOUBLE3, + // DOUBLE4, + + // UNDEFINED, + // }; } //////////////////////////////////////////////////////////////////// @@ -3657,7 +3649,7 @@ namespace stormkit::gpu { requires(core::meta::IsPlainEnumeration or core::meta::Is) STORMKIT_FORCE_INLINE STORMKIT_INTRINSIC - constexpr auto to_vk(U value) noexcept -> T { + constexpr auto to_vk(U value) noexcept -> T{ return narrow(value); } @@ -3670,252 +3662,237 @@ namespace stormkit::gpu { constexpr auto from_vk(U value) noexcept -> T { return narrow(value); } -} // namespace stormkit::gpu - -template stormkit::gpu::AccessFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::AccessFlag stormkit::gpu::from_vk(VkAccessFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); -template VkAccessFlagBits stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); - -template stormkit::gpu::AttachmentLoadOperation stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::AttachmentLoadOperation stormkit::gpu::from_vk(VkAttachmentLoadOp); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); -template VkAttachmentLoadOp stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); - -template stormkit::gpu::AttachmentStoreOperation stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::AttachmentStoreOperation stormkit::gpu::from_vk(VkAttachmentStoreOp); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); -template VkAttachmentStoreOp stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); - -template stormkit::gpu::BlendFactor stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::BlendFactor stormkit::gpu::from_vk(VkBlendFactor); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); -template VkBlendFactor stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); - -template stormkit::gpu::BlendOperation stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::BlendOperation stormkit::gpu::from_vk(VkBlendOp); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); -template VkBlendOp stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); - -template stormkit::gpu::BorderColor stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::BorderColor stormkit::gpu::from_vk(VkBorderColor); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BorderColor); -template VkBorderColor stormkit::gpu::to_vk(stormkit::gpu::BorderColor); - -template stormkit::gpu::BufferUsageFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::BufferUsageFlag stormkit::gpu::from_vk(VkBufferUsageFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); -template VkBufferUsageFlagBits stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); - -template stormkit::gpu::ColorComponentFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ColorComponentFlag stormkit::gpu::from_vk(VkColorComponentFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); -template VkColorComponentFlagBits stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); - -template stormkit::gpu::ColorSpace stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ColorSpace stormkit::gpu::from_vk(VkColorSpaceKHR); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); -template VkColorSpaceKHR stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); - -template stormkit::gpu::CommandBufferLevel stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::CommandBufferLevel stormkit::gpu::from_vk(VkCommandBufferLevel); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); -template VkCommandBufferLevel stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); - -template stormkit::gpu::CompareOperation stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::CompareOperation stormkit::gpu::from_vk(VkCompareOp); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); -template VkCompareOp stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); - -template stormkit::gpu::CullModeFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::CullModeFlag stormkit::gpu::from_vk(VkCullModeFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); -template VkCullModeFlagBits stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); - -template stormkit::gpu::DebugObjectType stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::DebugObjectType stormkit::gpu::from_vk(VkObjectType); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); -template VkObjectType stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); - -template stormkit::gpu::DependencyFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::DependencyFlag stormkit::gpu::from_vk(VkDependencyFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); -template VkDependencyFlagBits stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); - -template stormkit::gpu::DescriptorType stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::DescriptorType stormkit::gpu::from_vk(VkDescriptorType); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); -template VkDescriptorType stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); - -template stormkit::gpu::DynamicState stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::DynamicState stormkit::gpu::from_vk(VkDynamicState); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DynamicState); -template VkDynamicState stormkit::gpu::to_vk(stormkit::gpu::DynamicState); - -template stormkit::gpu::Filter stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::Filter stormkit::gpu::from_vk(VkFilter); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::Filter); -template VkFilter stormkit::gpu::to_vk(stormkit::gpu::Filter); - -template stormkit::gpu::FormatFeatureFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::FormatFeatureFlag stormkit::gpu::from_vk(VkFormatFeatureFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); -template VkFormatFeatureFlagBits stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); - -template stormkit::gpu::FrontFace stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::FrontFace stormkit::gpu::from_vk(VkFrontFace); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::FrontFace); -template VkFrontFace stormkit::gpu::to_vk(stormkit::gpu::FrontFace); - -template stormkit::gpu::GeometryFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::GeometryFlag stormkit::gpu::from_vk(VkGeometryFlagBitsKHR); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); -template VkGeometryFlagBitsKHR stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); - -template stormkit::gpu::GeometryType stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::GeometryType stormkit::gpu::from_vk(VkGeometryTypeKHR); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::GeometryType); -template VkGeometryTypeKHR stormkit::gpu::to_vk(stormkit::gpu::GeometryType); - -template stormkit::gpu::ImageAspectFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageAspectFlag stormkit::gpu::from_vk(VkImageAspectFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); -template VkImageAspectFlagBits stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); - -template stormkit::gpu::ImageCreateFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageCreateFlag stormkit::gpu::from_vk(VkImageCreateFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); -template VkImageCreateFlagBits stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); - -template stormkit::gpu::ImageLayout stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageLayout stormkit::gpu::from_vk(VkImageLayout); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); -template VkImageLayout stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); - -template stormkit::gpu::ImageTiling stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageTiling stormkit::gpu::from_vk(VkImageTiling); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); -template VkImageTiling stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); - -template stormkit::gpu::ImageType stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageType stormkit::gpu::from_vk(VkImageType); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageType); -template VkImageType stormkit::gpu::to_vk(stormkit::gpu::ImageType); - -template stormkit::gpu::ImageUsageFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageUsageFlag stormkit::gpu::from_vk(VkImageUsageFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); -template VkImageUsageFlagBits stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); - -template stormkit::gpu::ImageViewType stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageViewType stormkit::gpu::from_vk(VkImageViewType); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); -template VkImageViewType stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); - -template stormkit::gpu::LogicOperation stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::LogicOperation stormkit::gpu::from_vk(VkLogicOp); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); -template VkLogicOp stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); - -template stormkit::gpu::MemoryPropertyFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::MemoryPropertyFlag stormkit::gpu::from_vk(VkMemoryPropertyFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); -template VkMemoryPropertyFlagBits stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); - -template stormkit::gpu::PhysicalDeviceType stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PhysicalDeviceType stormkit::gpu::from_vk(VkPhysicalDeviceType); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); -template VkPhysicalDeviceType stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); - -template stormkit::gpu::PipelineBindPoint stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PipelineBindPoint stormkit::gpu::from_vk(VkPipelineBindPoint); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); -template VkPipelineBindPoint stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); - -template stormkit::gpu::PipelineStageFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PipelineStageFlag stormkit::gpu::from_vk(VkPipelineStageFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); -template VkPipelineStageFlagBits stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); - -template stormkit::gpu::PixelFormat stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PixelFormat stormkit::gpu::from_vk(VkFormat); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); -template VkFormat stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); - -template stormkit::gpu::PolygonMode stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PolygonMode stormkit::gpu::from_vk(VkPolygonMode); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); -template VkPolygonMode stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); - -template stormkit::gpu::PresentMode stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PresentMode stormkit::gpu::from_vk(VkPresentModeKHR); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PresentMode); -template VkPresentModeKHR stormkit::gpu::to_vk(stormkit::gpu::PresentMode); - -template stormkit::gpu::PrimitiveTopology stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PrimitiveTopology stormkit::gpu::from_vk(VkPrimitiveTopology); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); -template VkPrimitiveTopology stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); - -template stormkit::gpu::QueueFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::QueueFlag stormkit::gpu::from_vk(VkQueueFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); -template VkQueueFlagBits stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); - -template stormkit::gpu::Result stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::Result stormkit::gpu::from_vk(VkResult); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::Result); -template VkResult stormkit::gpu::to_vk(stormkit::gpu::Result); - -template stormkit::gpu::SampleCountFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::SampleCountFlag stormkit::gpu::from_vk(VkSampleCountFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); -template VkSampleCountFlagBits stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); - -template stormkit::gpu::SamplerAddressMode stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::SamplerAddressMode stormkit::gpu::from_vk(VkSamplerAddressMode); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); -template VkSamplerAddressMode stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); - -template stormkit::gpu::SamplerMipmapMode stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::SamplerMipmapMode stormkit::gpu::from_vk(VkSamplerMipmapMode); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); -template VkSamplerMipmapMode stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); - -template stormkit::gpu::ShaderStageFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ShaderStageFlag stormkit::gpu::from_vk(VkShaderStageFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); -template VkShaderStageFlagBits stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); - -template stormkit::gpu::StencilFaceFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::StencilFaceFlag stormkit::gpu::from_vk(VkStencilFaceFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); -template VkStencilFaceFlagBits stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); - -template stormkit::gpu::VertexInputRate stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::VertexInputRate stormkit::gpu::from_vk(VkVertexInputRate); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); -template VkVertexInputRate stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); +} + + + template stormkit::gpu::AccessFlag stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::AccessFlag stormkit::gpu::from_vk(VkAccessFlagBits); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); + template VkAccessFlagBits stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); + + template stormkit::gpu::AttachmentLoadOperation stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::AttachmentLoadOperation stormkit::gpu::from_vk(VkAttachmentLoadOp); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); + template VkAttachmentLoadOp stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); + + template stormkit::gpu::AttachmentStoreOperation stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::AttachmentStoreOperation stormkit::gpu::from_vk(VkAttachmentStoreOp); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); + template VkAttachmentStoreOp stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); + + template stormkit::gpu::BlendFactor stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::BlendFactor stormkit::gpu::from_vk(VkBlendFactor); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); + template VkBlendFactor stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); + + template stormkit::gpu::BlendOperation stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::BlendOperation stormkit::gpu::from_vk(VkBlendOp); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); + template VkBlendOp stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); + + template stormkit::gpu::BorderColor stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::BorderColor stormkit::gpu::from_vk(VkBorderColor); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BorderColor); + template VkBorderColor stormkit::gpu::to_vk(stormkit::gpu::BorderColor); + + template stormkit::gpu::BufferUsageFlag stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::BufferUsageFlag stormkit::gpu::from_vk(VkBufferUsageFlagBits); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); + template VkBufferUsageFlagBits stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); + + template stormkit::gpu::ColorComponentFlag stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::ColorComponentFlag stormkit::gpu::from_vk(VkColorComponentFlagBits); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); + template VkColorComponentFlagBits stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); + + template stormkit::gpu::ColorSpace stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::ColorSpace stormkit::gpu::from_vk(VkColorSpaceKHR); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); + template VkColorSpaceKHR stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); + + template stormkit::gpu::CommandBufferLevel stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::CommandBufferLevel stormkit::gpu::from_vk(VkCommandBufferLevel); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); + template VkCommandBufferLevel stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); + + template stormkit::gpu::CompareOperation stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::CompareOperation stormkit::gpu::from_vk(VkCompareOp); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); + template VkCompareOp stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); + + template stormkit::gpu::CullModeFlag stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::CullModeFlag stormkit::gpu::from_vk(VkCullModeFlagBits); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); + template VkCullModeFlagBits stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); + + template stormkit::gpu::DebugObjectType stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::DebugObjectType stormkit::gpu::from_vk(VkObjectType); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); + template VkObjectType stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); + + template stormkit::gpu::DependencyFlag stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::DependencyFlag stormkit::gpu::from_vk(VkDependencyFlagBits); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); + template VkDependencyFlagBits stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); + + template stormkit::gpu::DescriptorType stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::DescriptorType stormkit::gpu::from_vk(VkDescriptorType); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); + template VkDescriptorType stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); + + template stormkit::gpu::DynamicState stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::DynamicState stormkit::gpu::from_vk(VkDynamicState); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DynamicState); + template VkDynamicState stormkit::gpu::to_vk(stormkit::gpu::DynamicState); + + template stormkit::gpu::Filter stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::Filter stormkit::gpu::from_vk(VkFilter); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::Filter); + template VkFilter stormkit::gpu::to_vk(stormkit::gpu::Filter); + + template stormkit::gpu::FormatFeatureFlag stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::FormatFeatureFlag stormkit::gpu::from_vk(VkFormatFeatureFlagBits); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); + template VkFormatFeatureFlagBits stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); + + template stormkit::gpu::FrontFace stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::FrontFace stormkit::gpu::from_vk(VkFrontFace); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::FrontFace); + template VkFrontFace stormkit::gpu::to_vk(stormkit::gpu::FrontFace); + + template stormkit::gpu::GeometryFlag stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::GeometryFlag stormkit::gpu::from_vk(VkGeometryFlagBitsKHR); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); + template VkGeometryFlagBitsKHR stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); + + template stormkit::gpu::GeometryType stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::GeometryType stormkit::gpu::from_vk(VkGeometryTypeKHR); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::GeometryType); + template VkGeometryTypeKHR stormkit::gpu::to_vk(stormkit::gpu::GeometryType); + + template stormkit::gpu::ImageAspectFlag stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::ImageAspectFlag stormkit::gpu::from_vk(VkImageAspectFlagBits); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); + template VkImageAspectFlagBits stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); + + template stormkit::gpu::ImageCreateFlag stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::ImageCreateFlag stormkit::gpu::from_vk(VkImageCreateFlagBits); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); + template VkImageCreateFlagBits stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); + + template stormkit::gpu::ImageLayout stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::ImageLayout stormkit::gpu::from_vk(VkImageLayout); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); + template VkImageLayout stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); + + template stormkit::gpu::ImageTiling stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::ImageTiling stormkit::gpu::from_vk(VkImageTiling); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); + template VkImageTiling stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); + + template stormkit::gpu::ImageType stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::ImageType stormkit::gpu::from_vk(VkImageType); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageType); + template VkImageType stormkit::gpu::to_vk(stormkit::gpu::ImageType); + + template stormkit::gpu::ImageUsageFlag stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::ImageUsageFlag stormkit::gpu::from_vk(VkImageUsageFlagBits); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); + template VkImageUsageFlagBits stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); + + template stormkit::gpu::ImageViewType stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::ImageViewType stormkit::gpu::from_vk(VkImageViewType); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); + template VkImageViewType stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); + + template stormkit::gpu::LogicOperation stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::LogicOperation stormkit::gpu::from_vk(VkLogicOp); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); + template VkLogicOp stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); + + template stormkit::gpu::MemoryPropertyFlag stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::MemoryPropertyFlag stormkit::gpu::from_vk(VkMemoryPropertyFlagBits); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); + template VkMemoryPropertyFlagBits stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); + + template stormkit::gpu::PhysicalDeviceType stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::PhysicalDeviceType stormkit::gpu::from_vk(VkPhysicalDeviceType); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); + template VkPhysicalDeviceType stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); + + template stormkit::gpu::PipelineBindPoint stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::PipelineBindPoint stormkit::gpu::from_vk(VkPipelineBindPoint); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); + template VkPipelineBindPoint stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); + + template stormkit::gpu::PipelineStageFlag stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::PipelineStageFlag stormkit::gpu::from_vk(VkPipelineStageFlagBits); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); + template VkPipelineStageFlagBits stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); + + template stormkit::gpu::PixelFormat stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::PixelFormat stormkit::gpu::from_vk(VkFormat); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); + template VkFormat stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); + + template stormkit::gpu::PolygonMode stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::PolygonMode stormkit::gpu::from_vk(VkPolygonMode); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); + template VkPolygonMode stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); + + template stormkit::gpu::PresentMode stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::PresentMode stormkit::gpu::from_vk(VkPresentModeKHR); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PresentMode); + template VkPresentModeKHR stormkit::gpu::to_vk(stormkit::gpu::PresentMode); + + template stormkit::gpu::PrimitiveTopology stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::PrimitiveTopology stormkit::gpu::from_vk(VkPrimitiveTopology); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); + template VkPrimitiveTopology stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); + + template stormkit::gpu::QueueFlag stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::QueueFlag stormkit::gpu::from_vk(VkQueueFlagBits); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); + template VkQueueFlagBits stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); + + template stormkit::gpu::ResolveModeFlag stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::ResolveModeFlag stormkit::gpu::from_vk(VkResolveModeFlagBits); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ResolveModeFlag); + template VkResolveModeFlagBits stormkit::gpu::to_vk(stormkit::gpu::ResolveModeFlag); + + template stormkit::gpu::Result stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::Result stormkit::gpu::from_vk(VkResult); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::Result); + template VkResult stormkit::gpu::to_vk(stormkit::gpu::Result); + + template stormkit::gpu::SampleCountFlag stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::SampleCountFlag stormkit::gpu::from_vk(VkSampleCountFlagBits); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); + template VkSampleCountFlagBits stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); + + template stormkit::gpu::SamplerAddressMode stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::SamplerAddressMode stormkit::gpu::from_vk(VkSamplerAddressMode); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); + template VkSamplerAddressMode stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); + + template stormkit::gpu::SamplerMipmapMode stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::SamplerMipmapMode stormkit::gpu::from_vk(VkSamplerMipmapMode); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); + template VkSamplerMipmapMode stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); + + template stormkit::gpu::ShaderStageFlag stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::ShaderStageFlag stormkit::gpu::from_vk(VkShaderStageFlagBits); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); + template VkShaderStageFlagBits stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); + + template stormkit::gpu::StencilFaceFlag stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::StencilFaceFlag stormkit::gpu::from_vk(VkStencilFaceFlagBits); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); + template VkStencilFaceFlagBits stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); + + template stormkit::gpu::VertexInputRate stormkit::gpu::from_vk(VkFlags); + template stormkit::gpu::VertexInputRate stormkit::gpu::from_vk(VkVertexInputRate); + template VkFlags stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); + template VkVertexInputRate stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); + + diff --git a/modules/stormkit/gpu/core/vulkan/mapping.json b/modules/stormkit/gpu/core/vulkan/mapping.json index 657643eda..5f4407b2b 100644 --- a/modules/stormkit/gpu/core/vulkan/mapping.json +++ b/modules/stormkit/gpu/core/vulkan/mapping.json @@ -16,7 +16,7 @@ "type": "u8", "vktype": "VkQueueFlagBits", "values": { - "NONE": { "vulkan": "0", "webgpu": "" }, + "NONE": { "vulkan": "0", "webgpu": "" }, "GRAPHICS": { "vulkan": "VK_QUEUE_GRAPHICS_BIT", "webgpu": "" }, "COMPUTE": { "vulkan": "VK_QUEUE_COMPUTE_BIT", "webgpu": "" }, "TRANSFER": { "vulkan": "VK_QUEUE_TRANSFER_BIT", "webgpu": "" }, @@ -151,22 +151,22 @@ "type": "u8", "vktype": "VkLogicOp", "values": { - "CLEAR": { "vulkan": "VK_LOGIC_OP_CLEAR", "webgpu": ""}, - "AND": { "vulkan": "VK_LOGIC_OP_AND", "webgpu": ""}, - "AND_REVERSE": { "vulkan": "VK_LOGIC_OP_AND_REVERSE", "webgpu": ""}, - "COPY": { "vulkan": "VK_LOGIC_OP_COPY", "webgpu": ""}, - "AND_INVERTED": { "vulkan": "VK_LOGIC_OP_AND_INVERTED", "webgpu": ""}, - "NO_OP": { "vulkan": "VK_LOGIC_OP_NO_OP", "webgpu": ""}, - "XOR": { "vulkan": "VK_LOGIC_OP_XOR", "webgpu": ""}, - "OR": { "vulkan": "VK_LOGIC_OP_OR", "webgpu": ""}, - "NOR": { "vulkan": "VK_LOGIC_OP_NOR", "webgpu": ""}, - "EQUIVALENT": { "vulkan": "VK_LOGIC_OP_EQUIVALENT", "webgpu": ""}, - "INVERT": { "vulkan": "VK_LOGIC_OP_INVERT", "webgpu": ""}, - "OR_REVERSE": { "vulkan": "VK_LOGIC_OP_OR_REVERSE", "webgpu": ""}, - "COPY_INVERTED": { "vulkan": "VK_LOGIC_OP_COPY_INVERTED","webgpu": ""}, - "OR_INVERTED": { "vulkan": "VK_LOGIC_OP_OR_INVERTED", "webgpu": ""}, - "NAND": { "vulkan": "VK_LOGIC_OP_NAND", "webgpu": ""}, - "SET": { "vulkan": "VK_LOGIC_OP_SET", "webgpu": ""} + "CLEAR": { "vulkan": "VK_LOGIC_OP_CLEAR", "webgpu": "" }, + "AND": { "vulkan": "VK_LOGIC_OP_AND", "webgpu": "" }, + "AND_REVERSE": { "vulkan": "VK_LOGIC_OP_AND_REVERSE", "webgpu": "" }, + "COPY": { "vulkan": "VK_LOGIC_OP_COPY", "webgpu": "" }, + "AND_INVERTED": { "vulkan": "VK_LOGIC_OP_AND_INVERTED", "webgpu": "" }, + "NO_OP": { "vulkan": "VK_LOGIC_OP_NO_OP", "webgpu": "" }, + "XOR": { "vulkan": "VK_LOGIC_OP_XOR", "webgpu": "" }, + "OR": { "vulkan": "VK_LOGIC_OP_OR", "webgpu": "" }, + "NOR": { "vulkan": "VK_LOGIC_OP_NOR", "webgpu": "" }, + "EQUIVALENT": { "vulkan": "VK_LOGIC_OP_EQUIVALENT", "webgpu": "" }, + "INVERT": { "vulkan": "VK_LOGIC_OP_INVERT", "webgpu": "" }, + "OR_REVERSE": { "vulkan": "VK_LOGIC_OP_OR_REVERSE", "webgpu": "" }, + "COPY_INVERTED": { "vulkan": "VK_LOGIC_OP_COPY_INVERTED","webgpu": "" }, + "OR_INVERTED": { "vulkan": "VK_LOGIC_OP_OR_INVERTED", "webgpu": "" }, + "NAND": { "vulkan": "VK_LOGIC_OP_NAND", "webgpu": "" }, + "SET": { "vulkan": "VK_LOGIC_OP_SET", "webgpu": "" } } }, "PixelFormat": { @@ -174,77 +174,77 @@ "type": "u32", "vktype": "VkFormat", "values": { - "UNDEFINED": { "vulkan": "VK_FORMAT_UNDEFINED", "webgpu": ""}, - "R8_SNORM": { "vulkan": "VK_FORMAT_R8_SNORM", "webgpu": ""}, - "RG8_SNORM": { "vulkan": "VK_FORMAT_R8G8_SNORM", "webgpu": ""}, - "RGB8_SNORM": { "vulkan": "VK_FORMAT_R8G8B8_SNORM", "webgpu": ""}, - "RGBA8_SNORM": { "vulkan": "VK_FORMAT_R8G8B8A8_SNORM", "webgpu": ""}, - "R8_UNORM": { "vulkan": "VK_FORMAT_R8_UNORM", "webgpu": ""}, - "RG8_UNORM": { "vulkan": "VK_FORMAT_R8G8_UNORM", "webgpu": ""}, - "RGB8_UNORM": { "vulkan": "VK_FORMAT_R8G8B8_UNORM", "webgpu": ""}, - "RGBA8_UNORM": { "vulkan": "VK_FORMAT_R8G8B8A8_UNORM", "webgpu": ""}, - "R16_SNORM": { "vulkan": "VK_FORMAT_R16_SNORM", "webgpu": ""}, - "RG16_SNORM": { "vulkan": "VK_FORMAT_R16G16_SNORM", "webgpu": ""}, - "RGB16_SNORM": { "vulkan": "VK_FORMAT_R16G16B16_SNORM", "webgpu": ""}, - "RGBA16_SNORM": { "vulkan": "VK_FORMAT_R16G16B16A16_SNORM", "webgpu": ""}, - "R16_UNORM": { "vulkan": "VK_FORMAT_R16_UNORM", "webgpu": ""}, - "RG16_UNORM": { "vulkan": "VK_FORMAT_R16G16_UNORM", "webgpu": ""}, - "RGB16_UNORM": { "vulkan": "VK_FORMAT_R16G16B16_UNORM", "webgpu": ""}, - "RGBA16_UNORM": { "vulkan": "VK_FORMAT_R16G16B16A16_UNORM", "webgpu": ""}, - "A2_RGB10_UNORM_PACK32": { "vulkan": "VK_FORMAT_A2R10G10B10_UNORM_PACK32", "webgpu": ""}, - "A2_RGB10_SNORM_PACK32": { "vulkan": "VK_FORMAT_A2R10G10B10_SNORM_PACK32", "webgpu": ""}, - "A2_RGB10U_PACK32": { "vulkan": "VK_FORMAT_A2R10G10B10_UINT_PACK32", "webgpu": ""}, - "A2_RGB10I_PACK32": { "vulkan": "VK_FORMAT_A2R10G10B10_SINT_PACK32", "webgpu": ""}, - "RGBA4_UNORM_PACK16": { "vulkan": "VK_FORMAT_R4G4B4A4_UNORM_PACK16", "webgpu": ""}, - "A1_RGB5_UNORM_PACK16": { "vulkan": "VK_FORMAT_A1R5G5B5_UNORM_PACK16", "webgpu": ""}, - "R5_G6_B5_UNORM_PACK16": { "vulkan": "VK_FORMAT_R5G6B5_UNORM_PACK16", "webgpu": ""}, - "BGR8_UNORM": { "vulkan": "VK_FORMAT_B8G8R8_UNORM", "webgpu": ""}, - "BGRA8_UNORM": { "vulkan": "VK_FORMAT_B8G8R8A8_UNORM", "webgpu": ""}, - "R8I": { "vulkan": "VK_FORMAT_R8_SINT", "webgpu": ""}, - "RG8I": { "vulkan": "VK_FORMAT_R8G8_SINT", "webgpu": ""}, - "RGB8I": { "vulkan": "VK_FORMAT_R8G8B8_SINT", "webgpu": ""}, - "RGBA8I": { "vulkan": "VK_FORMAT_R8G8B8A8_SINT", "webgpu": ""}, - "R8U": { "vulkan": "VK_FORMAT_R8_UINT", "webgpu": ""}, - "RG8U": { "vulkan": "VK_FORMAT_R8G8_UINT", "webgpu": ""}, - "RGB8U": { "vulkan": "VK_FORMAT_R8G8B8_UINT", "webgpu": ""}, - "RGBA8U": { "vulkan": "VK_FORMAT_R8G8B8A8_UINT", "webgpu": ""}, - "R16I": { "vulkan": "VK_FORMAT_R16_SINT", "webgpu": ""}, - "RG16I": { "vulkan": "VK_FORMAT_R16G16_SINT", "webgpu": ""}, - "RGB16I": { "vulkan": "VK_FORMAT_R16G16B16_SINT", "webgpu": ""}, - "RGBA16I": { "vulkan": "VK_FORMAT_R16G16B16A16_SINT", "webgpu": ""}, - "R16U": { "vulkan": "VK_FORMAT_R16_UINT", "webgpu": ""}, - "RG16U": { "vulkan": "VK_FORMAT_R16G16_UINT", "webgpu": ""}, - "RGB16U": { "vulkan": "VK_FORMAT_R16G16B16_UINT", "webgpu": ""}, - "RGBA16U": { "vulkan": "VK_FORMAT_R16G16B16A16_UINT", "webgpu": ""}, - "R32I": { "vulkan": "VK_FORMAT_R32_SINT", "webgpu": ""}, - "RG32I": { "vulkan": "VK_FORMAT_R32G32_SINT", "webgpu": ""}, - "RGB32I": { "vulkan": "VK_FORMAT_R32G32B32_SINT", "webgpu": ""}, - "RGBA32I": { "vulkan": "VK_FORMAT_R32G32B32A32_SINT", "webgpu": ""}, - "R32U": { "vulkan": "VK_FORMAT_R32_UINT", "webgpu": ""}, - "RG32U": { "vulkan": "VK_FORMAT_R32G32_UINT", "webgpu": ""}, - "RGB32U": { "vulkan": "VK_FORMAT_R32G32B32_UINT", "webgpu": ""}, - "RGBA32U": { "vulkan": "VK_FORMAT_R32G32B32A32_UINT", "webgpu": ""}, - "R16F": { "vulkan": "VK_FORMAT_R16_SFLOAT", "webgpu": ""}, - "RG16F": { "vulkan": "VK_FORMAT_R16G16_SFLOAT", "webgpu": ""}, - "RGB16F": { "vulkan": "VK_FORMAT_R16G16B16_SFLOAT", "webgpu": ""}, - "RGBA16F": { "vulkan": "VK_FORMAT_R16G16B16A16_SFLOAT", "webgpu": ""}, - "R32F": { "vulkan": "VK_FORMAT_R32_SFLOAT", "webgpu": ""}, - "RG32F": { "vulkan": "VK_FORMAT_R32G32_SFLOAT", "webgpu": ""}, - "RGB32F": { "vulkan": "VK_FORMAT_R32G32B32_SFLOAT", "webgpu": ""}, - "RGBA32F": { "vulkan": "VK_FORMAT_R32G32B32A32_SFLOAT", "webgpu": ""}, - "B10_GR11UF_PACK32": { "vulkan": "VK_FORMAT_B10G11R11_UFLOAT_PACK32", "webgpu": ""}, - "SR8": { "vulkan": "VK_FORMAT_R8_SRGB", "webgpu": ""}, - "SRG8": { "vulkan": "VK_FORMAT_R8G8_SRGB", "webgpu": ""}, - "SRGB8": { "vulkan": "VK_FORMAT_R8G8B8_SRGB", "webgpu": ""}, - "SRGBA8": { "vulkan": "VK_FORMAT_R8G8B8A8_SRGB", "webgpu": ""}, - "SBGR8": { "vulkan": "VK_FORMAT_B8G8R8_SRGB", "webgpu": ""}, - "SBGRA8": { "vulkan": "VK_FORMAT_B8G8R8A8_SRGB", "webgpu": ""}, - "DEPTH16_UNORM": { "vulkan": "VK_FORMAT_D16_UNORM", "webgpu": ""}, - "DEPTH24_UNORM_PACK32": { "vulkan": "VK_FORMAT_X8_D24_UNORM_PACK32", "webgpu": ""}, - "DEPTH32F": { "vulkan": "VK_FORMAT_D32_SFLOAT", "webgpu": ""}, - "DEPTH16_UNORM_STENCIL8U": { "vulkan": "VK_FORMAT_D16_UNORM_S8_UINT", "webgpu": ""}, - "DEPTH24_UNORM_STENCIL8U": { "vulkan": "VK_FORMAT_D24_UNORM_S8_UINT", "webgpu": ""}, - "DEPTH32F_STENCIL8U": { "vulkan": "VK_FORMAT_D32_SFLOAT_S8_UINT", "webgpu": ""} + "UNDEFINED": { "vulkan": "VK_FORMAT_UNDEFINED", "webgpu": "" }, + "R8_SNORM": { "vulkan": "VK_FORMAT_R8_SNORM", "webgpu": "" }, + "RG8_SNORM": { "vulkan": "VK_FORMAT_R8G8_SNORM", "webgpu": "" }, + "RGB8_SNORM": { "vulkan": "VK_FORMAT_R8G8B8_SNORM", "webgpu": "" }, + "RGBA8_SNORM": { "vulkan": "VK_FORMAT_R8G8B8A8_SNORM", "webgpu": "" }, + "R8_UNORM": { "vulkan": "VK_FORMAT_R8_UNORM", "webgpu": "" }, + "RG8_UNORM": { "vulkan": "VK_FORMAT_R8G8_UNORM", "webgpu": "" }, + "RGB8_UNORM": { "vulkan": "VK_FORMAT_R8G8B8_UNORM", "webgpu": "" }, + "RGBA8_UNORM": { "vulkan": "VK_FORMAT_R8G8B8A8_UNORM", "webgpu": "" }, + "R16_SNORM": { "vulkan": "VK_FORMAT_R16_SNORM", "webgpu": "" }, + "RG16_SNORM": { "vulkan": "VK_FORMAT_R16G16_SNORM", "webgpu": "" }, + "RGB16_SNORM": { "vulkan": "VK_FORMAT_R16G16B16_SNORM", "webgpu": "" }, + "RGBA16_SNORM": { "vulkan": "VK_FORMAT_R16G16B16A16_SNORM", "webgpu": "" }, + "R16_UNORM": { "vulkan": "VK_FORMAT_R16_UNORM", "webgpu": "" }, + "RG16_UNORM": { "vulkan": "VK_FORMAT_R16G16_UNORM", "webgpu": "" }, + "RGB16_UNORM": { "vulkan": "VK_FORMAT_R16G16B16_UNORM", "webgpu": "" }, + "RGBA16_UNORM": { "vulkan": "VK_FORMAT_R16G16B16A16_UNORM", "webgpu": "" }, + "A2_RGB10_UNORM_PACK32": { "vulkan": "VK_FORMAT_A2R10G10B10_UNORM_PACK32", "webgpu": "" }, + "A2_RGB10_SNORM_PACK32": { "vulkan": "VK_FORMAT_A2R10G10B10_SNORM_PACK32", "webgpu": "" }, + "A2_RGB10U_PACK32": { "vulkan": "VK_FORMAT_A2R10G10B10_UINT_PACK32", "webgpu": "" }, + "A2_RGB10I_PACK32": { "vulkan": "VK_FORMAT_A2R10G10B10_SINT_PACK32", "webgpu": "" }, + "RGBA4_UNORM_PACK16": { "vulkan": "VK_FORMAT_R4G4B4A4_UNORM_PACK16", "webgpu": "" }, + "A1_RGB5_UNORM_PACK16": { "vulkan": "VK_FORMAT_A1R5G5B5_UNORM_PACK16", "webgpu": "" }, + "R5_G6_B5_UNORM_PACK16": { "vulkan": "VK_FORMAT_R5G6B5_UNORM_PACK16", "webgpu": "" }, + "BGR8_UNORM": { "vulkan": "VK_FORMAT_B8G8R8_UNORM", "webgpu": "" }, + "BGRA8_UNORM": { "vulkan": "VK_FORMAT_B8G8R8A8_UNORM", "webgpu": "" }, + "R8I": { "vulkan": "VK_FORMAT_R8_SINT", "webgpu": "" }, + "RG8I": { "vulkan": "VK_FORMAT_R8G8_SINT", "webgpu": "" }, + "RGB8I": { "vulkan": "VK_FORMAT_R8G8B8_SINT", "webgpu": "" }, + "RGBA8I": { "vulkan": "VK_FORMAT_R8G8B8A8_SINT", "webgpu": "" }, + "R8U": { "vulkan": "VK_FORMAT_R8_UINT", "webgpu": "" }, + "RG8U": { "vulkan": "VK_FORMAT_R8G8_UINT", "webgpu": "" }, + "RGB8U": { "vulkan": "VK_FORMAT_R8G8B8_UINT", "webgpu": "" }, + "RGBA8U": { "vulkan": "VK_FORMAT_R8G8B8A8_UINT", "webgpu": "" }, + "R16I": { "vulkan": "VK_FORMAT_R16_SINT", "webgpu": "" }, + "RG16I": { "vulkan": "VK_FORMAT_R16G16_SINT", "webgpu": "" }, + "RGB16I": { "vulkan": "VK_FORMAT_R16G16B16_SINT", "webgpu": "" }, + "RGBA16I": { "vulkan": "VK_FORMAT_R16G16B16A16_SINT", "webgpu": "" }, + "R16U": { "vulkan": "VK_FORMAT_R16_UINT", "webgpu": "" }, + "RG16U": { "vulkan": "VK_FORMAT_R16G16_UINT", "webgpu": "" }, + "RGB16U": { "vulkan": "VK_FORMAT_R16G16B16_UINT", "webgpu": "" }, + "RGBA16U": { "vulkan": "VK_FORMAT_R16G16B16A16_UINT", "webgpu": "" }, + "R32I": { "vulkan": "VK_FORMAT_R32_SINT", "webgpu": "" }, + "RG32I": { "vulkan": "VK_FORMAT_R32G32_SINT", "webgpu": "" }, + "RGB32I": { "vulkan": "VK_FORMAT_R32G32B32_SINT", "webgpu": "" }, + "RGBA32I": { "vulkan": "VK_FORMAT_R32G32B32A32_SINT", "webgpu": "" }, + "R32U": { "vulkan": "VK_FORMAT_R32_UINT", "webgpu": "" }, + "RG32U": { "vulkan": "VK_FORMAT_R32G32_UINT", "webgpu": "" }, + "RGB32U": { "vulkan": "VK_FORMAT_R32G32B32_UINT", "webgpu": "" }, + "RGBA32U": { "vulkan": "VK_FORMAT_R32G32B32A32_UINT", "webgpu": "" }, + "R16F": { "vulkan": "VK_FORMAT_R16_SFLOAT", "webgpu": "" }, + "RG16F": { "vulkan": "VK_FORMAT_R16G16_SFLOAT", "webgpu": "" }, + "RGB16F": { "vulkan": "VK_FORMAT_R16G16B16_SFLOAT", "webgpu": "" }, + "RGBA16F": { "vulkan": "VK_FORMAT_R16G16B16A16_SFLOAT", "webgpu": "" }, + "R32F": { "vulkan": "VK_FORMAT_R32_SFLOAT", "webgpu": "" }, + "RG32F": { "vulkan": "VK_FORMAT_R32G32_SFLOAT", "webgpu": "" }, + "RGB32F": { "vulkan": "VK_FORMAT_R32G32B32_SFLOAT", "webgpu": "" }, + "RGBA32F": { "vulkan": "VK_FORMAT_R32G32B32A32_SFLOAT", "webgpu": "" }, + "B10_GR11UF_PACK32": { "vulkan": "VK_FORMAT_B10G11R11_UFLOAT_PACK32", "webgpu": "" }, + "SR8": { "vulkan": "VK_FORMAT_R8_SRGB", "webgpu": "" }, + "SRG8": { "vulkan": "VK_FORMAT_R8G8_SRGB", "webgpu": "" }, + "SRGB8": { "vulkan": "VK_FORMAT_R8G8B8_SRGB", "webgpu": "" }, + "SRGBA8": { "vulkan": "VK_FORMAT_R8G8B8A8_SRGB", "webgpu": "" }, + "SBGR8": { "vulkan": "VK_FORMAT_B8G8R8_SRGB", "webgpu": "" }, + "SBGRA8": { "vulkan": "VK_FORMAT_B8G8R8A8_SRGB", "webgpu": "" }, + "DEPTH16_UNORM": { "vulkan": "VK_FORMAT_D16_UNORM", "webgpu": "" }, + "DEPTH24_UNORM_PACK32": { "vulkan": "VK_FORMAT_X8_D24_UNORM_PACK32", "webgpu": "" }, + "DEPTH32F": { "vulkan": "VK_FORMAT_D32_SFLOAT", "webgpu": "" }, + "DEPTH16_UNORM_STENCIL8U": { "vulkan": "VK_FORMAT_D16_UNORM_S8_UINT", "webgpu": "" }, + "DEPTH24_UNORM_STENCIL8U": { "vulkan": "VK_FORMAT_D24_UNORM_S8_UINT", "webgpu": "" }, + "DEPTH32F_STENCIL8U": { "vulkan": "VK_FORMAT_D32_SFLOAT_S8_UINT", "webgpu": "" } } }, "AttachmentLoadOperation": { @@ -252,9 +252,9 @@ "type": "u8", "vktype": "VkAttachmentLoadOp", "values": { - "LOAD": { "vulkan": "VK_ATTACHMENT_LOAD_OP_LOAD", "webgpu": ""}, - "CLEAR": { "vulkan": "VK_ATTACHMENT_LOAD_OP_CLEAR", "webgpu": ""}, - "DONT_CARE": { "vulkan": "VK_ATTACHMENT_LOAD_OP_DONT_CARE", "webgpu": ""} + "LOAD": { "vulkan": "VK_ATTACHMENT_LOAD_OP_LOAD", "webgpu": "" }, + "CLEAR": { "vulkan": "VK_ATTACHMENT_LOAD_OP_CLEAR", "webgpu": "" }, + "DONT_CARE": { "vulkan": "VK_ATTACHMENT_LOAD_OP_DONT_CARE", "webgpu": "" } } }, "AttachmentStoreOperation": { @@ -262,8 +262,8 @@ "type": "u8", "vktype": "VkAttachmentStoreOp", "values": { - "STORE": { "vulkan": "VK_ATTACHMENT_STORE_OP_STORE", "webgpu": ""}, - "DONT_CARE": { "vulkan": "VK_ATTACHMENT_STORE_OP_DONT_CARE", "webgpu": ""} + "STORE": { "vulkan": "VK_ATTACHMENT_STORE_OP_STORE", "webgpu": "" }, + "DONT_CARE": { "vulkan": "VK_ATTACHMENT_STORE_OP_DONT_CARE", "webgpu": "" } } }, "PipelineBindPoint": { @@ -271,8 +271,8 @@ "type": "u8", "vktype": "VkPipelineBindPoint", "values": { - "GRAPHICS": { "vulkan": "VK_PIPELINE_BIND_POINT_GRAPHICS", "webgpu": ""}, - "COMPUTE": { "vulkan": "VK_PIPELINE_BIND_POINT_COMPUTE", "webgpu": ""} + "GRAPHICS": { "vulkan": "VK_PIPELINE_BIND_POINT_GRAPHICS", "webgpu": "" }, + "COMPUTE": { "vulkan": "VK_PIPELINE_BIND_POINT_COMPUTE", "webgpu": "" } } }, "ImageLayout": { @@ -280,19 +280,20 @@ "type": "u32", "vktype": "VkImageLayout", "values": { - "UNDEFINED": { "vulkan": "VK_IMAGE_LAYOUT_UNDEFINED", "webgpu": "" }, - "GENERAL": { "vulkan": "VK_IMAGE_LAYOUT_GENERAL", "webgpu": "" }, - "COLOR_ATTACHMENT_OPTIMAL": { "vulkan": "VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL", "webgpu": "" }, - "DEPTH_STENCIL_ATTACHMENT_OPTIMAL": { "vulkan": "VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL", "webgpu": "" }, - "DEPTH_STENCIL_READ_ONLY_OPTIMAL": { "vulkan": "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL", "webgpu": "" }, - "SHADER_READ_ONLY_OPTIMAL": { "vulkan": "VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL", "webgpu": "" }, - "TRANSFER_SRC_OPTIMAL": { "vulkan": "VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL", "webgpu": "" }, - "TRANSFER_DST_OPTIMAL": { "vulkan": "VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL", "webgpu": "" }, - "PREINITIALIZED": { "vulkan": "VK_IMAGE_LAYOUT_PREINITIALIZED", "webgpu": "" }, + "UNDEFINED": { "vulkan": "VK_IMAGE_LAYOUT_UNDEFINED", "webgpu": "" }, + "GENERAL": { "vulkan": "VK_IMAGE_LAYOUT_GENERAL", "webgpu": "" }, + "ATTACHMENT_OPTIMAL": { "vulkan": "VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL", "webgpu": "" }, + "COLOR_ATTACHMENT_OPTIMAL": { "vulkan": "VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL", "webgpu": "" }, + "DEPTH_STENCIL_ATTACHMENT_OPTIMAL": { "vulkan": "VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL", "webgpu": "" }, + "DEPTH_STENCIL_READ_ONLY_OPTIMAL": { "vulkan": "VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL", "webgpu": "" }, + "SHADER_READ_ONLY_OPTIMAL": { "vulkan": "VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL", "webgpu": "" }, + "TRANSFER_SRC_OPTIMAL": { "vulkan": "VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL", "webgpu": "" }, + "TRANSFER_DST_OPTIMAL": { "vulkan": "VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL", "webgpu": "" }, + "PREINITIALIZED": { "vulkan": "VK_IMAGE_LAYOUT_PREINITIALIZED", "webgpu": "" }, "DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL": { "vulkan": "VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL", "webgpu": "" }, "DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL": { "vulkan": "VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL", "webgpu": "" }, - "PRESENT_SRC": { "vulkan": "VK_IMAGE_LAYOUT_PRESENT_SRC_KHR", "webgpu": "" }, - "SHARED_PRESENT": { "vulkan": "VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR", "webgpu": "" } + "PRESENT_SRC": { "vulkan": "VK_IMAGE_LAYOUT_PRESENT_SRC_KHR", "webgpu": "" }, + "SHARED_PRESENT": { "vulkan": "VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR", "webgpu": "" } } }, "ImageAspectFlag": { @@ -300,10 +301,10 @@ "type": "u8", "vktype": "VkImageAspectFlagBits", "values": { - "NONE": { "vulkan": "VK_IMAGE_ASPECT_NONE_KHR", "webgpu": ""}, - "COLOR": { "vulkan": "VK_IMAGE_ASPECT_COLOR_BIT", "webgpu": ""}, - "DEPTH": { "vulkan": "VK_IMAGE_ASPECT_DEPTH_BIT", "webgpu": ""}, - "STENCIL": { "vulkan": "VK_IMAGE_ASPECT_STENCIL_BIT", "webgpu": ""} + "NONE": { "vulkan": "VK_IMAGE_ASPECT_NONE_KHR", "webgpu": "" }, + "COLOR": { "vulkan": "VK_IMAGE_ASPECT_COLOR_BIT", "webgpu": "" }, + "DEPTH": { "vulkan": "VK_IMAGE_ASPECT_DEPTH_BIT", "webgpu": "" }, + "STENCIL": { "vulkan": "VK_IMAGE_ASPECT_STENCIL_BIT", "webgpu": "" } } }, "VertexInputRate": { @@ -311,8 +312,8 @@ "type": "u8", "vktype": "VkVertexInputRate", "values": { - "VERTEX": { "vulkan": "VK_VERTEX_INPUT_RATE_VERTEX", "webgpu": ""}, - "INSTANCE": { "vulkan": "VK_VERTEX_INPUT_RATE_INSTANCE", "webgpu": ""} + "VERTEX": { "vulkan": "VK_VERTEX_INPUT_RATE_VERTEX", "webgpu": "" }, + "INSTANCE": { "vulkan": "VK_VERTEX_INPUT_RATE_INSTANCE", "webgpu": "" } } }, "ImageCreateFlag": { @@ -320,19 +321,19 @@ "type": "u16", "vktype": "VkImageCreateFlagBits", "values": { - "NONE": { "vulkan": "0", "webgpu": "" }, - "SPARSE_BINDING": { "vulkan": "VK_IMAGE_CREATE_SPARSE_BINDING_BIT", "webgpu": ""}, - "SPARSE_RESIDENCY": { "vulkan": "VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT", "webgpu": ""}, - "SPARSE_ALIASED": { "vulkan": "VK_IMAGE_CREATE_SPARSE_ALIASED_BIT", "webgpu": ""}, - "MUTABLE_FORMAT": { "vulkan": "VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT", "webgpu": ""}, - "CUBE_COMPATIBLE": { "vulkan": "VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT", "webgpu": ""}, - "ALIAS": { "vulkan": "VK_IMAGE_CREATE_ALIAS_BIT", "webgpu": ""}, + "NONE": { "vulkan": "0", "webgpu": "" }, + "SPARSE_BINDING": { "vulkan": "VK_IMAGE_CREATE_SPARSE_BINDING_BIT", "webgpu": ""}, + "SPARSE_RESIDENCY": { "vulkan": "VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT", "webgpu": ""}, + "SPARSE_ALIASED": { "vulkan": "VK_IMAGE_CREATE_SPARSE_ALIASED_BIT", "webgpu": ""}, + "MUTABLE_FORMAT": { "vulkan": "VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT", "webgpu": ""}, + "CUBE_COMPATIBLE": { "vulkan": "VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT", "webgpu": ""}, + "ALIAS": { "vulkan": "VK_IMAGE_CREATE_ALIAS_BIT", "webgpu": ""}, "SPLIT_INSTANCE_BIND_REGIONS": { "vulkan": "VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT", "webgpu": ""}, - "ARRAY_2D_COMPATIBLE": { "vulkan": "VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT", "webgpu": ""}, + "ARRAY_2D_COMPATIBLE": { "vulkan": "VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT", "webgpu": ""}, "BLOCK_TEXEL_VIEW_COMPATIBLE": { "vulkan": "VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT", "webgpu": ""}, - "EXTENDED_USAGE": { "vulkan": "VK_IMAGE_CREATE_EXTENDED_USAGE_BIT", "webgpu": ""}, - "PROTECTED": { "vulkan": "VK_IMAGE_CREATE_PROTECTED_BIT", "webgpu": ""}, - "DISJOINT": { "vulkan": "VK_IMAGE_CREATE_DISJOINT_BIT", "webgpu": ""} + "EXTENDED_USAGE": { "vulkan": "VK_IMAGE_CREATE_EXTENDED_USAGE_BIT", "webgpu": ""}, + "PROTECTED": { "vulkan": "VK_IMAGE_CREATE_PROTECTED_BIT", "webgpu": ""}, + "DISJOINT": { "vulkan": "VK_IMAGE_CREATE_DISJOINT_BIT", "webgpu": ""} } }, "BufferUsageFlag": { @@ -340,15 +341,15 @@ "type": "u16", "vktype": "VkBufferUsageFlagBits", "values": { - "VERTEX": { "vulkan": "VK_BUFFER_USAGE_VERTEX_BUFFER_BIT", "webgpu": ""}, - "INDEX": { "vulkan": "VK_BUFFER_USAGE_INDEX_BUFFER_BIT", "webgpu": ""}, - "TRANSFER_SRC": { "vulkan": "VK_BUFFER_USAGE_TRANSFER_SRC_BIT", "webgpu": ""}, - "TRANSFER_DST": { "vulkan": "VK_BUFFER_USAGE_TRANSFER_DST_BIT", "webgpu": ""}, - "UNIFORM": { "vulkan": "VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT", "webgpu": ""}, - "STORAGE": { "vulkan": "VK_BUFFER_USAGE_STORAGE_BUFFER_BIT", "webgpu": ""}, + "VERTEX": { "vulkan": "VK_BUFFER_USAGE_VERTEX_BUFFER_BIT", "webgpu": ""}, + "INDEX": { "vulkan": "VK_BUFFER_USAGE_INDEX_BUFFER_BIT", "webgpu": ""}, + "TRANSFER_SRC": { "vulkan": "VK_BUFFER_USAGE_TRANSFER_SRC_BIT", "webgpu": ""}, + "TRANSFER_DST": { "vulkan": "VK_BUFFER_USAGE_TRANSFER_DST_BIT", "webgpu": ""}, + "UNIFORM": { "vulkan": "VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT", "webgpu": ""}, + "STORAGE": { "vulkan": "VK_BUFFER_USAGE_STORAGE_BUFFER_BIT", "webgpu": ""}, "UNIFORM_TEXEL": { "vulkan": "VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT", "webgpu": ""}, "STORAGE_TEXEL": { "vulkan": "VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT", "webgpu": ""}, - "INDIRECT": { "vulkan": "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT", "webgpu": ""} + "INDIRECT": { "vulkan": "VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT", "webgpu": ""} } }, "ImageUsageFlag": { @@ -356,14 +357,14 @@ "type": "u16", "vktype": "VkImageUsageFlagBits", "values": { - "TRANSFER_SRC": { "vulkan": "VK_IMAGE_USAGE_TRANSFER_SRC_BIT", "webgpu": "" }, - "TRANSFER_DST": { "vulkan": "VK_IMAGE_USAGE_TRANSFER_DST_BIT", "webgpu": "" }, - "SAMPLED": { "vulkan": "VK_IMAGE_USAGE_SAMPLED_BIT", "webgpu": "" }, - "STORAGE": { "vulkan": "VK_IMAGE_USAGE_STORAGE_BIT", "webgpu": "" }, - "COLOR_ATTACHMENT": { "vulkan": "VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT", "webgpu": "" }, + "TRANSFER_SRC": { "vulkan": "VK_IMAGE_USAGE_TRANSFER_SRC_BIT", "webgpu": "" }, + "TRANSFER_DST": { "vulkan": "VK_IMAGE_USAGE_TRANSFER_DST_BIT", "webgpu": "" }, + "SAMPLED": { "vulkan": "VK_IMAGE_USAGE_SAMPLED_BIT", "webgpu": "" }, + "STORAGE": { "vulkan": "VK_IMAGE_USAGE_STORAGE_BIT", "webgpu": "" }, + "COLOR_ATTACHMENT": { "vulkan": "VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT", "webgpu": "" }, "DEPTH_STENCIL_ATTACHMENT": { "vulkan": "VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT", "webgpu": "" }, - "TRANSIENT_ATTACHMENT": { "vulkan": "VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT", "webgpu": "" }, - "INPUT_ATTACHMENT": { "vulkan": "VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT", "webgpu": "" } + "TRANSIENT_ATTACHMENT": { "vulkan": "VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT", "webgpu": "" }, + "INPUT_ATTACHMENT": { "vulkan": "VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT", "webgpu": "" } } }, "MemoryPropertyFlag": { @@ -371,10 +372,10 @@ "type": "u8", "vktype": "VkMemoryPropertyFlagBits", "values": { - "DEVICE_LOCAL": { "vulkan": "VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT", "webgpu": ""}, - "HOST_VISIBLE": { "vulkan": "VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT", "webgpu": ""}, + "DEVICE_LOCAL": { "vulkan": "VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT", "webgpu": ""}, + "HOST_VISIBLE": { "vulkan": "VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT", "webgpu": ""}, "HOST_COHERENT": { "vulkan": "VK_MEMORY_PROPERTY_HOST_COHERENT_BIT", "webgpu": ""}, - "HOST_CACHED": { "vulkan": "VK_MEMORY_PROPERTY_HOST_CACHED_BIT", "webgpu": ""} + "HOST_CACHED": { "vulkan": "VK_MEMORY_PROPERTY_HOST_CACHED_BIT", "webgpu": ""} } }, "CommandBufferLevel": { @@ -382,7 +383,7 @@ "type": "u8", "vktype": "VkCommandBufferLevel", "values": { - "PRIMARY": { "vulkan": "VK_COMMAND_BUFFER_LEVEL_PRIMARY", "webgpu": "" }, + "PRIMARY": { "vulkan": "VK_COMMAND_BUFFER_LEVEL_PRIMARY", "webgpu": "" }, "SECONDARY": { "vulkan": "VK_COMMAND_BUFFER_LEVEL_SECONDARY", "webgpu": "" } } }, @@ -391,17 +392,17 @@ "type": "u8", "vktype": "VkDescriptorType", "values": { - "SAMPLER": { "vulkan": "VK_DESCRIPTOR_TYPE_SAMPLER", "webgpu": "" }, + "SAMPLER": { "vulkan": "VK_DESCRIPTOR_TYPE_SAMPLER", "webgpu": "" }, "COMBINED_IMAGE_SAMPLER": { "vulkan": "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER", "webgpu": "" }, - "SAMPLED_IMAGE": { "vulkan": "VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE", "webgpu": "" }, - "STORAGE_IMAGE": { "vulkan": "VK_DESCRIPTOR_TYPE_STORAGE_IMAGE", "webgpu": "" }, - "UNIFORM_TEXEL_BUFFER": { "vulkan": "VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER", "webgpu": "" }, - "STORAGE_TEXEL_BUFFER": { "vulkan": "VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER", "webgpu": "" }, - "UNIFORM_BUFFER": { "vulkan": "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER", "webgpu": "" }, - "STORAGE_BUFFER": { "vulkan": "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER", "webgpu": "" }, + "SAMPLED_IMAGE": { "vulkan": "VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE", "webgpu": "" }, + "STORAGE_IMAGE": { "vulkan": "VK_DESCRIPTOR_TYPE_STORAGE_IMAGE", "webgpu": "" }, + "UNIFORM_TEXEL_BUFFER": { "vulkan": "VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER", "webgpu": "" }, + "STORAGE_TEXEL_BUFFER": { "vulkan": "VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER", "webgpu": "" }, + "UNIFORM_BUFFER": { "vulkan": "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER", "webgpu": "" }, + "STORAGE_BUFFER": { "vulkan": "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER", "webgpu": "" }, "UNIFORM_BUFFER_DYNAMIC": { "vulkan": "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC", "webgpu": "" }, "STORAGE_BUFFER_DYNAMIC": { "vulkan": "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC", "webgpu": "" }, - "INPUT_ATTACHMENT": { "vulkan": "VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT", "webgpu": "" } + "INPUT_ATTACHMENT": { "vulkan": "VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT", "webgpu": "" } } }, "CompareOperation": { @@ -409,14 +410,14 @@ "type": "u8", "vktype": "VkCompareOp", "values": { - "NEVER": { "vulkan": "VK_COMPARE_OP_NEVER", "webgpu": "" }, - "LESS": { "vulkan": "VK_COMPARE_OP_LESS", "webgpu": "" }, - "EQUAL": { "vulkan": "VK_COMPARE_OP_EQUAL", "webgpu": "" }, - "LESS_OR_EQUAL": { "vulkan": "VK_COMPARE_OP_LESS_OR_EQUAL", "webgpu": "" }, - "GREATER": { "vulkan": "VK_COMPARE_OP_GREATER", "webgpu": "" }, - "NOT_EQUAL": { "vulkan": "VK_COMPARE_OP_NOT_EQUAL", "webgpu": "" }, + "NEVER": { "vulkan": "VK_COMPARE_OP_NEVER", "webgpu": "" }, + "LESS": { "vulkan": "VK_COMPARE_OP_LESS", "webgpu": "" }, + "EQUAL": { "vulkan": "VK_COMPARE_OP_EQUAL", "webgpu": "" }, + "LESS_OR_EQUAL": { "vulkan": "VK_COMPARE_OP_LESS_OR_EQUAL", "webgpu": "" }, + "GREATER": { "vulkan": "VK_COMPARE_OP_GREATER", "webgpu": "" }, + "NOT_EQUAL": { "vulkan": "VK_COMPARE_OP_NOT_EQUAL", "webgpu": "" }, "GREATER_OR_EQUAL": { "vulkan": "VK_COMPARE_OP_GREATER_OR_EQUAL", "webgpu": "" }, - "ALWAYS": { "vulkan": "VK_COMPARE_OP_ALWAYS", "webgpu": "" } + "ALWAYS": { "vulkan": "VK_COMPARE_OP_ALWAYS", "webgpu": "" } } }, "Filter": { @@ -424,8 +425,8 @@ "type": "u32", "vktype": "VkFilter", "values": { - "NEAREST": { "vulkan": "VK_FILTER_NEAREST", "webgpu": "" }, - "LINEAR": { "vulkan": "VK_FILTER_LINEAR", "webgpu": "" }, + "NEAREST": { "vulkan": "VK_FILTER_NEAREST", "webgpu": "" }, + "LINEAR": { "vulkan": "VK_FILTER_LINEAR", "webgpu": "" }, "CUBIC_IMG": { "vulkan": "VK_FILTER_CUBIC_IMG", "webgpu": "" } } }, @@ -434,10 +435,10 @@ "type": "u8", "vktype": "VkSamplerAddressMode", "values": { - "REPEAT": { "vulkan": "VK_SAMPLER_ADDRESS_MODE_REPEAT", "webgpu": "" }, - "MIRRORED_REPEAT": { "vulkan": "VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT", "webgpu": "" }, - "CLAMP_TO_EDGE": { "vulkan": "VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE", "webgpu": "" }, - "CLAMP_TO_BORDER": { "vulkan": "VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER", "webgpu": "" }, + "REPEAT": { "vulkan": "VK_SAMPLER_ADDRESS_MODE_REPEAT", "webgpu": "" }, + "MIRRORED_REPEAT": { "vulkan": "VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT", "webgpu": "" }, + "CLAMP_TO_EDGE": { "vulkan": "VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE", "webgpu": "" }, + "CLAMP_TO_BORDER": { "vulkan": "VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER", "webgpu": "" }, "MIRROR_CLAMP_TO_EDGE": { "vulkan": "VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE", "webgpu": "" } } }, @@ -447,11 +448,11 @@ "vktype": "VkBorderColor", "values": { "FLOAT_TRANSPARENT_BLACK": { "vulkan": "VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK", "webgpu": "" }, - "INT_TRANSPARENT_BLACK": { "vulkan": "VK_BORDER_COLOR_INT_TRANSPARENT_BLACK", "webgpu": "" }, - "FLOAT_OPAQUE_BLACK": { "vulkan": "VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK", "webgpu": "" }, - "INT_OPAQUE_BLACK": { "vulkan": "VK_BORDER_COLOR_INT_OPAQUE_BLACK", "webgpu": "" }, - "FLOAT_OPAQUE_WHITE": { "vulkan": "VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE", "webgpu": "" }, - "INT_OPAQUE_WHITE": { "vulkan": "VK_BORDER_COLOR_INT_OPAQUE_WHITE", "webgpu": "" } + "INT_TRANSPARENT_BLACK": { "vulkan": "VK_BORDER_COLOR_INT_TRANSPARENT_BLACK", "webgpu": "" }, + "FLOAT_OPAQUE_BLACK": { "vulkan": "VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK", "webgpu": "" }, + "INT_OPAQUE_BLACK": { "vulkan": "VK_BORDER_COLOR_INT_OPAQUE_BLACK", "webgpu": "" }, + "FLOAT_OPAQUE_WHITE": { "vulkan": "VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE", "webgpu": "" }, + "INT_OPAQUE_WHITE": { "vulkan": "VK_BORDER_COLOR_INT_OPAQUE_WHITE", "webgpu": "" } } }, "SamplerMipmapMode": { @@ -460,7 +461,7 @@ "vktype": "VkSamplerMipmapMode", "values": { "NEAREST": { "vulkan": "VK_SAMPLER_MIPMAP_MODE_NEAREST", "webgpu": "" }, - "LINEAR": { "vulkan": "VK_SAMPLER_MIPMAP_MODE_LINEAR", "webgpu": "" } + "LINEAR": { "vulkan": "VK_SAMPLER_MIPMAP_MODE_LINEAR", "webgpu": "" } } }, "Result": { @@ -468,42 +469,42 @@ "type": "i32", "vktype": "VkResult", "values": { - "SUCCESS": { "vulkan": "VK_SUCCESS", "webgpu": "" }, - "NOT_READY": { "vulkan": "VK_NOT_READY", "webgpu": "" }, - "TIMEOUT": { "vulkan": "VK_TIMEOUT", "webgpu": "" }, - "EVENT_SET": { "vulkan": "VK_EVENT_SET", "webgpu": "" }, - "EVENT_RESET": { "vulkan": "VK_EVENT_RESET", "webgpu": "" }, - "INCOMPLETE": { "vulkan": "VK_INCOMPLETE", "webgpu": "" }, - "ERROR_OUT_OF_HOST_MEMORY": { "vulkan": "VK_ERROR_OUT_OF_HOST_MEMORY", "webgpu": "" }, - "ERROR_OUT_OF_DEVICE_MEMORY": { "vulkan": "VK_ERROR_OUT_OF_DEVICE_MEMORY", "webgpu": "" }, - "ERROR_INITIALIZATION_FAILED": { "vulkan": "VK_ERROR_INITIALIZATION_FAILED", "webgpu": "" }, - "ERROR_DEVICE_LOST": { "vulkan": "VK_ERROR_DEVICE_LOST", "webgpu": "" }, - "ERROR_MEMORY_MAP_FAILED": { "vulkan": "VK_ERROR_MEMORY_MAP_FAILED", "webgpu": "" }, - "ERROR_LAYER_NOT_PRESENT": { "vulkan": "VK_ERROR_LAYER_NOT_PRESENT", "webgpu": "" }, - "ERROR_EXTENSION_NOT_PRESENT": { "vulkan": "VK_ERROR_EXTENSION_NOT_PRESENT", "webgpu": "" }, - "ERROR_FEATURE_NOT_PRESENT": { "vulkan": "VK_ERROR_FEATURE_NOT_PRESENT", "webgpu": "" }, - "ERROR_INCOMPATIBLE_DRIVER": { "vulkan": "VK_ERROR_INCOMPATIBLE_DRIVER", "webgpu": "" }, - "ERROR_TOO_MANY_OBJECTS": { "vulkan": "VK_ERROR_TOO_MANY_OBJECTS", "webgpu": "" }, - "ERROR_FORMAT_NOT_SUPPORTED": { "vulkan": "VK_ERROR_FORMAT_NOT_SUPPORTED", "webgpu": "" }, - "ERROR_FRAGMENTED_POOL": { "vulkan": "VK_ERROR_FRAGMENTED_POOL", "webgpu": "" }, - "ERROR_UNKNOWN": { "vulkan": "VK_ERROR_UNKNOWN", "webgpu": "" }, - "ERROR_OUT_OF_POOL_MEMORY": { "vulkan": "VK_ERROR_OUT_OF_POOL_MEMORY", "webgpu": "" }, - "ERROR_INVALID_EXTERNAL_HANDLE": { "vulkan": "VK_ERROR_INVALID_EXTERNAL_HANDLE", "webgpu": "" }, - "ERROR_FRAGMENTATION": { "vulkan": "VK_ERROR_FRAGMENTATION", "webgpu": "" }, - "ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS": { "vulkan": "VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS", "webgpu": "" }, - "ERROR_SURFACE_LOST": { "vulkan": "VK_ERROR_SURFACE_LOST_KHR", "webgpu": "" }, - "ERROR_NATIVE_WINDOW_IN_USE": { "vulkan": "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR", "webgpu": "" }, - "SUBOPTIMAL": { "vulkan": "VK_SUBOPTIMAL_KHR", "webgpu": "" }, - "ERROR_OUT_OF_DATE": { "vulkan": "VK_ERROR_OUT_OF_DATE_KHR", "webgpu": "" }, - "ERROR_INCOMPATIBLE_DISPLAY": { "vulkan": "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR", "webgpu": "" }, - "ERROR_VALIDATION_FAILED": { "vulkan": "VK_ERROR_VALIDATION_FAILED_EXT", "webgpu": "" }, - "ERROR_NOT_PERMITTED": { "vulkan": "VK_ERROR_NOT_PERMITTED", "webgpu": "" }, + "SUCCESS": { "vulkan": "VK_SUCCESS", "webgpu": "" }, + "NOT_READY": { "vulkan": "VK_NOT_READY", "webgpu": "" }, + "TIMEOUT": { "vulkan": "VK_TIMEOUT", "webgpu": "" }, + "EVENT_SET": { "vulkan": "VK_EVENT_SET", "webgpu": "" }, + "EVENT_RESET": { "vulkan": "VK_EVENT_RESET", "webgpu": "" }, + "INCOMPLETE": { "vulkan": "VK_INCOMPLETE", "webgpu": "" }, + "ERROR_OUT_OF_HOST_MEMORY": { "vulkan": "VK_ERROR_OUT_OF_HOST_MEMORY", "webgpu": "" }, + "ERROR_OUT_OF_DEVICE_MEMORY": { "vulkan": "VK_ERROR_OUT_OF_DEVICE_MEMORY", "webgpu": "" }, + "ERROR_INITIALIZATION_FAILED": { "vulkan": "VK_ERROR_INITIALIZATION_FAILED", "webgpu": "" }, + "ERROR_DEVICE_LOST": { "vulkan": "VK_ERROR_DEVICE_LOST", "webgpu": "" }, + "ERROR_MEMORY_MAP_FAILED": { "vulkan": "VK_ERROR_MEMORY_MAP_FAILED", "webgpu": "" }, + "ERROR_LAYER_NOT_PRESENT": { "vulkan": "VK_ERROR_LAYER_NOT_PRESENT", "webgpu": "" }, + "ERROR_EXTENSION_NOT_PRESENT": { "vulkan": "VK_ERROR_EXTENSION_NOT_PRESENT", "webgpu": "" }, + "ERROR_FEATURE_NOT_PRESENT": { "vulkan": "VK_ERROR_FEATURE_NOT_PRESENT", "webgpu": "" }, + "ERROR_INCOMPATIBLE_DRIVER": { "vulkan": "VK_ERROR_INCOMPATIBLE_DRIVER", "webgpu": "" }, + "ERROR_TOO_MANY_OBJECTS": { "vulkan": "VK_ERROR_TOO_MANY_OBJECTS", "webgpu": "" }, + "ERROR_FORMAT_NOT_SUPPORTED": { "vulkan": "VK_ERROR_FORMAT_NOT_SUPPORTED", "webgpu": "" }, + "ERROR_FRAGMENTED_POOL": { "vulkan": "VK_ERROR_FRAGMENTED_POOL", "webgpu": "" }, + "ERROR_UNKNOWN": { "vulkan": "VK_ERROR_UNKNOWN", "webgpu": "" }, + "ERROR_OUT_OF_POOL_MEMORY": { "vulkan": "VK_ERROR_OUT_OF_POOL_MEMORY", "webgpu": "" }, + "ERROR_INVALID_EXTERNAL_HANDLE": { "vulkan": "VK_ERROR_INVALID_EXTERNAL_HANDLE", "webgpu": "" }, + "ERROR_FRAGMENTATION": { "vulkan": "VK_ERROR_FRAGMENTATION", "webgpu": "" }, + "ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS": { "vulkan": "VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS", "webgpu": "" }, + "ERROR_SURFACE_LOST": { "vulkan": "VK_ERROR_SURFACE_LOST_KHR", "webgpu": "" }, + "ERROR_NATIVE_WINDOW_IN_USE": { "vulkan": "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR", "webgpu": "" }, + "SUBOPTIMAL": { "vulkan": "VK_SUBOPTIMAL_KHR", "webgpu": "" }, + "ERROR_OUT_OF_DATE": { "vulkan": "VK_ERROR_OUT_OF_DATE_KHR", "webgpu": "" }, + "ERROR_INCOMPATIBLE_DISPLAY": { "vulkan": "VK_ERROR_INCOMPATIBLE_DISPLAY_KHR", "webgpu": "" }, + "ERROR_VALIDATION_FAILED": { "vulkan": "VK_ERROR_VALIDATION_FAILED_EXT", "webgpu": "" }, + "ERROR_NOT_PERMITTED": { "vulkan": "VK_ERROR_NOT_PERMITTED", "webgpu": "" }, "ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST": { "vulkan": "VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT", "webgpu": "" }, - "THREAD_IDLE": { "vulkan": "VK_THREAD_IDLE_KHR", "webgpu": "" }, - "THREAD_DONE": { "vulkan": "VK_THREAD_DONE_KHR", "webgpu": "" }, - "OPERATION_DEFERRED": { "vulkan": "VK_OPERATION_DEFERRED_KHR", "webgpu": "" }, - "OPERATION_NOT_DEFERRED": { "vulkan": "VK_OPERATION_NOT_DEFERRED_KHR", "webgpu": "" }, - "PIPELINE_COMPILE_REQUIRED": { "vulkan": "VK_PIPELINE_COMPILE_REQUIRED", "webgpu": "" } + "THREAD_IDLE": { "vulkan": "VK_THREAD_IDLE_KHR", "webgpu": "" }, + "THREAD_DONE": { "vulkan": "VK_THREAD_DONE_KHR", "webgpu": "" }, + "OPERATION_DEFERRED": { "vulkan": "VK_OPERATION_DEFERRED_KHR", "webgpu": "" }, + "OPERATION_NOT_DEFERRED": { "vulkan": "VK_OPERATION_NOT_DEFERRED_KHR", "webgpu": "" }, + "PIPELINE_COMPILE_REQUIRED": { "vulkan": "VK_PIPELINE_COMPILE_REQUIRED", "webgpu": "" } } }, "ImageType": { @@ -511,9 +512,9 @@ "type": "u8", "vktype": "VkImageType", "values": { - "T1D": { "vulkan": "VK_IMAGE_TYPE_1D", "webgpu": ""}, - "T2D": { "vulkan": "VK_IMAGE_TYPE_2D", "webgpu": ""}, - "T3D": { "vulkan": "VK_IMAGE_TYPE_3D", "webgpu": ""} + "T1D": { "vulkan": "VK_IMAGE_TYPE_1D", "webgpu": "" }, + "T2D": { "vulkan": "VK_IMAGE_TYPE_2D", "webgpu": "" }, + "T3D": { "vulkan": "VK_IMAGE_TYPE_3D", "webgpu": "" } } }, "ImageViewType": { @@ -521,12 +522,12 @@ "type": "u8", "vktype": "VkImageViewType", "values": { - "T1D": { "vulkan": "VK_IMAGE_VIEW_TYPE_1D", "webgpu": "" }, - "T2D": { "vulkan": "VK_IMAGE_VIEW_TYPE_2D", "webgpu": "" }, - "T3D": { "vulkan": "VK_IMAGE_VIEW_TYPE_3D", "webgpu": "" }, - "CUBE": { "vulkan": "VK_IMAGE_VIEW_TYPE_CUBE", "webgpu": "" }, - "T1D_ARRAY": { "vulkan": "VK_IMAGE_VIEW_TYPE_1D_ARRAY", "webgpu": "" }, - "T2D_ARRAY": { "vulkan": "VK_IMAGE_VIEW_TYPE_2D_ARRAY", "webgpu": "" }, + "T1D": { "vulkan": "VK_IMAGE_VIEW_TYPE_1D", "webgpu": "" }, + "T2D": { "vulkan": "VK_IMAGE_VIEW_TYPE_2D", "webgpu": "" }, + "T3D": { "vulkan": "VK_IMAGE_VIEW_TYPE_3D", "webgpu": "" }, + "CUBE": { "vulkan": "VK_IMAGE_VIEW_TYPE_CUBE", "webgpu": "" }, + "T1D_ARRAY": { "vulkan": "VK_IMAGE_VIEW_TYPE_1D_ARRAY", "webgpu": "" }, + "T2D_ARRAY": { "vulkan": "VK_IMAGE_VIEW_TYPE_2D_ARRAY", "webgpu": "" }, "CUBE_ARRAY": { "vulkan": "VK_IMAGE_VIEW_TYPE_CUBE_ARRAY", "webgpu": "" } } }, @@ -535,36 +536,36 @@ "type": "u32", "vktype": "VkObjectType", "values": { - "UNKNOWN": { "vulkan": "VK_OBJECT_TYPE_UNKNOWN", "webgpu": "" }, - "INSTANCE": { "vulkan": "VK_OBJECT_TYPE_INSTANCE", "webgpu": "" }, - "PHYSICAL_DEVICE": { "vulkan": "VK_OBJECT_TYPE_PHYSICAL_DEVICE", "webgpu": "" }, - "DEVICE": { "vulkan": "VK_OBJECT_TYPE_DEVICE", "webgpu": "" }, - "QUEUE": { "vulkan": "VK_OBJECT_TYPE_QUEUE", "webgpu": "" }, - "SEMAPHORE": { "vulkan": "VK_OBJECT_TYPE_SEMAPHORE", "webgpu": "" }, - "COMMAND_BUFFER": { "vulkan": "VK_OBJECT_TYPE_COMMAND_BUFFER", "webgpu": "" }, - "FENCE": { "vulkan": "VK_OBJECT_TYPE_FENCE", "webgpu": "" }, - "DEVICE_MEMORY": { "vulkan": "VK_OBJECT_TYPE_DEVICE_MEMORY", "webgpu": "" }, - "BUFFER": { "vulkan": "VK_OBJECT_TYPE_BUFFER", "webgpu": "" }, - "IMAGE": { "vulkan": "VK_OBJECT_TYPE_IMAGE", "webgpu": "" }, - "EVENT": { "vulkan": "VK_OBJECT_TYPE_EVENT", "webgpu": "" }, - "QUERY_POOL": { "vulkan": "VK_OBJECT_TYPE_QUERY_POOL", "webgpu": "" }, - "BUFFER_VIEW": { "vulkan": "VK_OBJECT_TYPE_BUFFER_VIEW", "webgpu": "" }, - "IMAGE_VIEW": { "vulkan": "VK_OBJECT_TYPE_IMAGE_VIEW", "webgpu": "" }, - "SHADER_MODULE": { "vulkan": "VK_OBJECT_TYPE_SHADER_MODULE", "webgpu": "" }, - "PIPELINE_CACHE": { "vulkan": "VK_OBJECT_TYPE_PIPELINE_CACHE", "webgpu": "" }, - "PIPELINE_LAYOUT": { "vulkan": "VK_OBJECT_TYPE_PIPELINE_LAYOUT", "webgpu": "" }, - "RENDER_PASS": { "vulkan": "VK_OBJECT_TYPE_RENDER_PASS", "webgpu": "" }, - "PIPELINE": { "vulkan": "VK_OBJECT_TYPE_PIPELINE", "webgpu": "" }, - "DESCRIPTOR_SET_LAYOUT": { "vulkan": "VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT", "webgpu": "" }, - "SAMPLER": { "vulkan": "VK_OBJECT_TYPE_SAMPLER", "webgpu": "" }, - "DESCRIPTOR_POOL": { "vulkan": "VK_OBJECT_TYPE_DESCRIPTOR_POOL", "webgpu": "" }, - "DESCRIPTOR_SET": { "vulkan": "VK_OBJECT_TYPE_DESCRIPTOR_SET", "webgpu": "" }, - "FRAMEBUFFER": { "vulkan": "VK_OBJECT_TYPE_FRAMEBUFFER", "webgpu": "" }, - "COMMAND_POOL": { "vulkan": "VK_OBJECT_TYPE_COMMAND_POOL", "webgpu": "" }, - "SURFACE": { "vulkan": "VK_OBJECT_TYPE_SURFACE_KHR", "webgpu": "" }, - "SWAPCHAIN": { "vulkan": "VK_OBJECT_TYPE_SWAPCHAIN_KHR", "webgpu": "" }, + "UNKNOWN": { "vulkan": "VK_OBJECT_TYPE_UNKNOWN", "webgpu": "" }, + "INSTANCE": { "vulkan": "VK_OBJECT_TYPE_INSTANCE", "webgpu": "" }, + "PHYSICAL_DEVICE": { "vulkan": "VK_OBJECT_TYPE_PHYSICAL_DEVICE", "webgpu": "" }, + "DEVICE": { "vulkan": "VK_OBJECT_TYPE_DEVICE", "webgpu": "" }, + "QUEUE": { "vulkan": "VK_OBJECT_TYPE_QUEUE", "webgpu": "" }, + "SEMAPHORE": { "vulkan": "VK_OBJECT_TYPE_SEMAPHORE", "webgpu": "" }, + "COMMAND_BUFFER": { "vulkan": "VK_OBJECT_TYPE_COMMAND_BUFFER", "webgpu": "" }, + "FENCE": { "vulkan": "VK_OBJECT_TYPE_FENCE", "webgpu": "" }, + "DEVICE_MEMORY": { "vulkan": "VK_OBJECT_TYPE_DEVICE_MEMORY", "webgpu": "" }, + "BUFFER": { "vulkan": "VK_OBJECT_TYPE_BUFFER", "webgpu": "" }, + "IMAGE": { "vulkan": "VK_OBJECT_TYPE_IMAGE", "webgpu": "" }, + "EVENT": { "vulkan": "VK_OBJECT_TYPE_EVENT", "webgpu": "" }, + "QUERY_POOL": { "vulkan": "VK_OBJECT_TYPE_QUERY_POOL", "webgpu": "" }, + "BUFFER_VIEW": { "vulkan": "VK_OBJECT_TYPE_BUFFER_VIEW", "webgpu": "" }, + "IMAGE_VIEW": { "vulkan": "VK_OBJECT_TYPE_IMAGE_VIEW", "webgpu": "" }, + "SHADER_MODULE": { "vulkan": "VK_OBJECT_TYPE_SHADER_MODULE", "webgpu": "" }, + "PIPELINE_CACHE": { "vulkan": "VK_OBJECT_TYPE_PIPELINE_CACHE", "webgpu": "" }, + "PIPELINE_LAYOUT": { "vulkan": "VK_OBJECT_TYPE_PIPELINE_LAYOUT", "webgpu": "" }, + "RENDER_PASS": { "vulkan": "VK_OBJECT_TYPE_RENDER_PASS", "webgpu": "" }, + "PIPELINE": { "vulkan": "VK_OBJECT_TYPE_PIPELINE", "webgpu": "" }, + "DESCRIPTOR_SET_LAYOUT": { "vulkan": "VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT", "webgpu": "" }, + "SAMPLER": { "vulkan": "VK_OBJECT_TYPE_SAMPLER", "webgpu": "" }, + "DESCRIPTOR_POOL": { "vulkan": "VK_OBJECT_TYPE_DESCRIPTOR_POOL", "webgpu": "" }, + "DESCRIPTOR_SET": { "vulkan": "VK_OBJECT_TYPE_DESCRIPTOR_SET", "webgpu": "" }, + "FRAMEBUFFER": { "vulkan": "VK_OBJECT_TYPE_FRAMEBUFFER", "webgpu": "" }, + "COMMAND_POOL": { "vulkan": "VK_OBJECT_TYPE_COMMAND_POOL", "webgpu": "" }, + "SURFACE": { "vulkan": "VK_OBJECT_TYPE_SURFACE_KHR", "webgpu": "" }, + "SWAPCHAIN": { "vulkan": "VK_OBJECT_TYPE_SWAPCHAIN_KHR", "webgpu": "" }, "DEBUG_REPORT_CALLBACK": { "vulkan": "VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT", "webgpu": "" }, - "DISPLAY": { "vulkan": "VK_OBJECT_TYPE_DISPLAY_KHR", "webgpu": "" } + "DISPLAY": { "vulkan": "VK_OBJECT_TYPE_DISPLAY_KHR", "webgpu": "" } } }, "AccessFlag": { @@ -573,22 +574,22 @@ "vktype": "VkAccessFlagBits", "values": { "NONE": {"vulkan": "0", "webgpu": "" }, - "INDIRECT_COMMAND_READ": { "vulkan": "VK_ACCESS_INDIRECT_COMMAND_READ_BIT", "webgpu": "" }, - "VERTEX_ATTRIBUTE_READ": { "vulkan": "VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT", "webgpu": "" }, - "UNIFORM_READ": { "vulkan": "VK_ACCESS_UNIFORM_READ_BIT", "webgpu": "" }, - "INPUT_ATTACHMENT_READ": { "vulkan": "VK_ACCESS_INPUT_ATTACHMENT_READ_BIT", "webgpu": "" }, - "SHADER_READ": { "vulkan": "VK_ACCESS_SHADER_READ_BIT", "webgpu": "" }, - "SHADER_WRITE": { "vulkan": "VK_ACCESS_SHADER_WRITE_BIT", "webgpu": "" }, - "COLOR_ATTACHMENT_READ": { "vulkan": "VK_ACCESS_COLOR_ATTACHMENT_READ_BIT", "webgpu": "" }, - "COLOR_ATTACHMENT_WRITE": { "vulkan": "VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT", "webgpu": "" }, - "DEPTH_STENCIL_ATTACHMENT_READ": { "vulkan": "VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT", "webgpu": "" }, + "INDIRECT_COMMAND_READ": { "vulkan": "VK_ACCESS_INDIRECT_COMMAND_READ_BIT", "webgpu": "" }, + "VERTEX_ATTRIBUTE_READ": { "vulkan": "VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT", "webgpu": "" }, + "UNIFORM_READ": { "vulkan": "VK_ACCESS_UNIFORM_READ_BIT", "webgpu": "" }, + "INPUT_ATTACHMENT_READ": { "vulkan": "VK_ACCESS_INPUT_ATTACHMENT_READ_BIT", "webgpu": "" }, + "SHADER_READ": { "vulkan": "VK_ACCESS_SHADER_READ_BIT", "webgpu": "" }, + "SHADER_WRITE": { "vulkan": "VK_ACCESS_SHADER_WRITE_BIT", "webgpu": "" }, + "COLOR_ATTACHMENT_READ": { "vulkan": "VK_ACCESS_COLOR_ATTACHMENT_READ_BIT", "webgpu": "" }, + "COLOR_ATTACHMENT_WRITE": { "vulkan": "VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT", "webgpu": "" }, + "DEPTH_STENCIL_ATTACHMENT_READ": { "vulkan": "VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT", "webgpu": "" }, "DEPTH_STENCIL_ATTACHMENT_WRITE": { "vulkan": "VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT", "webgpu": "" }, - "TRANSFER_READ": { "vulkan": "VK_ACCESS_TRANSFER_READ_BIT", "webgpu": "" }, - "TRANSFER_WRITE": { "vulkan": "VK_ACCESS_TRANSFER_WRITE_BIT", "webgpu": "" }, - "HOST_READ": { "vulkan": "VK_ACCESS_HOST_READ_BIT", "webgpu": "" }, - "HOST_WRITE": { "vulkan": "VK_ACCESS_HOST_WRITE_BIT", "webgpu": "" }, - "MEMORY_READ": { "vulkan": "VK_ACCESS_MEMORY_READ_BIT", "webgpu": "" }, - "MEMORY_WRITE": { "vulkan": "VK_ACCESS_MEMORY_WRITE_BIT", "webgpu": "" } + "TRANSFER_READ": { "vulkan": "VK_ACCESS_TRANSFER_READ_BIT", "webgpu": "" }, + "TRANSFER_WRITE": { "vulkan": "VK_ACCESS_TRANSFER_WRITE_BIT", "webgpu": "" }, + "HOST_READ": { "vulkan": "VK_ACCESS_HOST_READ_BIT", "webgpu": "" }, + "HOST_WRITE": { "vulkan": "VK_ACCESS_HOST_WRITE_BIT", "webgpu": "" }, + "MEMORY_READ": { "vulkan": "VK_ACCESS_MEMORY_READ_BIT", "webgpu": "" }, + "MEMORY_WRITE": { "vulkan": "VK_ACCESS_MEMORY_WRITE_BIT", "webgpu": "" } } }, "PipelineStageFlag": { @@ -596,23 +597,23 @@ "type": "u32", "vktype": "VkPipelineStageFlagBits", "values": { - "TOP_OF_PIPE": { "vulkan": "VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT", "webgpu": ""}, - "DRAW_INDIRECT": { "vulkan": "VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT", "webgpu": ""}, - "VERTEX_INPUT": { "vulkan": "VK_PIPELINE_STAGE_VERTEX_INPUT_BIT", "webgpu": ""}, - "VERTEX_SHADER": { "vulkan": "VK_PIPELINE_STAGE_VERTEX_SHADER_BIT", "webgpu": ""}, - "TESSELLATION_CONTROL_SHADER": { "vulkan": "VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT", "webgpu": ""}, - "TESSELLATION_EVALUATION_SHADER": { "vulkan": "VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT", "webgpu": ""}, - "GEOMETRY_SHADER": { "vulkan": "VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT", "webgpu": ""}, - "FRAGMENT_SHADER": { "vulkan": "VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT", "webgpu": ""}, - "EARLY_FRAGMENT_TESTS": { "vulkan": "VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT", "webgpu": ""}, - "LATE_FRAGMENT_TESTS": { "vulkan": "VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT", "webgpu": ""}, - "COLOR_ATTACHMENT_OUTPUT": { "vulkan": "VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT", "webgpu": ""}, - "COMPUTE_SHADER": { "vulkan": "VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT", "webgpu": ""}, - "TRANSFER": { "vulkan": "VK_PIPELINE_STAGE_TRANSFER_BIT", "webgpu": ""}, - "BOTTOM_OF_PIPE": { "vulkan": "VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT", "webgpu": ""}, - "HOST": { "vulkan": "VK_PIPELINE_STAGE_HOST_BIT", "webgpu": ""}, - "ALL_GRAPHICS": { "vulkan": "VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT", "webgpu": ""}, - "ALL_COMMANDS": { "vulkan": "VK_PIPELINE_STAGE_ALL_COMMANDS_BIT", "webgpu": ""} + "TOP_OF_PIPE": { "vulkan": "VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT", "webgpu": "" }, + "DRAW_INDIRECT": { "vulkan": "VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT", "webgpu": "" }, + "VERTEX_INPUT": { "vulkan": "VK_PIPELINE_STAGE_VERTEX_INPUT_BIT", "webgpu": "" }, + "VERTEX_SHADER": { "vulkan": "VK_PIPELINE_STAGE_VERTEX_SHADER_BIT", "webgpu": "" }, + "TESSELLATION_CONTROL_SHADER": { "vulkan": "VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT", "webgpu": "" }, + "TESSELLATION_EVALUATION_SHADER": { "vulkan": "VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT", "webgpu": "" }, + "GEOMETRY_SHADER": { "vulkan": "VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT", "webgpu": "" }, + "FRAGMENT_SHADER": { "vulkan": "VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT", "webgpu": "" }, + "EARLY_FRAGMENT_TESTS": { "vulkan": "VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT", "webgpu": "" }, + "LATE_FRAGMENT_TESTS": { "vulkan": "VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT", "webgpu": "" }, + "COLOR_ATTACHMENT_OUTPUT": { "vulkan": "VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT", "webgpu": "" }, + "COMPUTE_SHADER": { "vulkan": "VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT", "webgpu": "" }, + "TRANSFER": { "vulkan": "VK_PIPELINE_STAGE_TRANSFER_BIT", "webgpu": "" }, + "BOTTOM_OF_PIPE": { "vulkan": "VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT", "webgpu": "" }, + "HOST": { "vulkan": "VK_PIPELINE_STAGE_HOST_BIT", "webgpu": "" }, + "ALL_GRAPHICS": { "vulkan": "VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT", "webgpu": "" }, + "ALL_COMMANDS": { "vulkan": "VK_PIPELINE_STAGE_ALL_COMMANDS_BIT", "webgpu": "" } } }, "DependencyFlag": { @@ -620,10 +621,10 @@ "type": "u8", "vktype": "VkDependencyFlagBits", "values": { - "NONE": { "vulkan": "0", "webgpu": "" }, - "BY_REGION": { "vulkan": "VK_DEPENDENCY_BY_REGION_BIT", "webgpu": "" }, + "NONE": { "vulkan": "0", "webgpu": "" }, + "BY_REGION": { "vulkan": "VK_DEPENDENCY_BY_REGION_BIT", "webgpu": "" }, "DEVICE_GROUP": { "vulkan": "VK_DEPENDENCY_DEVICE_GROUP_BIT", "webgpu": "" }, - "VIEW_LOCAL": { "vulkan": "VK_DEPENDENCY_VIEW_LOCAL_BIT", "webgpu": "" } + "VIEW_LOCAL": { "vulkan": "VK_DEPENDENCY_VIEW_LOCAL_BIT", "webgpu": "" } } }, "DynamicState": { @@ -631,15 +632,15 @@ "type": "u8", "vktype": "VkDynamicState", "values": { - "VIEWPORT": { "vulkan": "VK_DYNAMIC_STATE_VIEWPORT", "webgpu": "" }, - "SCISSOR": { "vulkan": "VK_DYNAMIC_STATE_SCISSOR", "webgpu": "" }, - "LINE_WIDTH": { "vulkan": "VK_DYNAMIC_STATE_LINE_WIDTH", "webgpu": "" }, - "DEPTH_BIAS": { "vulkan": "VK_DYNAMIC_STATE_DEPTH_BIAS", "webgpu": "" }, - "BLEND_CONSTANTS": { "vulkan": "VK_DYNAMIC_STATE_BLEND_CONSTANTS", "webgpu": "" }, - "DEPTH_BOUNDS": { "vulkan": "VK_DYNAMIC_STATE_DEPTH_BOUNDS", "webgpu": "" }, + "VIEWPORT": { "vulkan": "VK_DYNAMIC_STATE_VIEWPORT", "webgpu": "" }, + "SCISSOR": { "vulkan": "VK_DYNAMIC_STATE_SCISSOR", "webgpu": "" }, + "LINE_WIDTH": { "vulkan": "VK_DYNAMIC_STATE_LINE_WIDTH", "webgpu": "" }, + "DEPTH_BIAS": { "vulkan": "VK_DYNAMIC_STATE_DEPTH_BIAS", "webgpu": "" }, + "BLEND_CONSTANTS": { "vulkan": "VK_DYNAMIC_STATE_BLEND_CONSTANTS", "webgpu": "" }, + "DEPTH_BOUNDS": { "vulkan": "VK_DYNAMIC_STATE_DEPTH_BOUNDS", "webgpu": "" }, "STENCIL_COMPARE_MASK": { "vulkan": "VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK", "webgpu": "" }, - "STENCIL_WRITE_MASK": { "vulkan": "VK_DYNAMIC_STATE_STENCIL_WRITE_MASK", "webgpu": "" }, - "STENCIL_REFERENCE": { "vulkan": "VK_DYNAMIC_STATE_STENCIL_REFERENCE", "webgpu": "" } + "STENCIL_WRITE_MASK": { "vulkan": "VK_DYNAMIC_STATE_STENCIL_WRITE_MASK", "webgpu": "" }, + "STENCIL_REFERENCE": { "vulkan": "VK_DYNAMIC_STATE_STENCIL_REFERENCE", "webgpu": "" } } }, "ImageTiling": { @@ -648,7 +649,7 @@ "vktype": "VkImageTiling", "values": { "OPTIMAL": { "vulkan": "VK_IMAGE_TILING_OPTIMAL", "webgpu": "" }, - "LINEAR": { "vulkan": "VK_IMAGE_TILING_LINEAR", "webgpu": "" } + "LINEAR": { "vulkan": "VK_IMAGE_TILING_LINEAR", "webgpu": "" } } }, "StencilFaceFlag": { @@ -657,8 +658,8 @@ "vktype": "VkStencilFaceFlagBits", "values": { "FRONT": { "vulkan": "VK_STENCIL_FACE_FRONT_BIT", "webgpu": "" }, - "BACK": { "vulkan": "VK_STENCIL_FACE_BACK_BIT", "webgpu": "" }, - "FRONT_AND_BACK": { "vulkan": "FRONT | BACK", "webgpu": "" } + "BACK": { "vulkan": "VK_STENCIL_FACE_BACK_BIT", "webgpu": "" }, + "FRONT_AND_BACK": { "vulkan": "FRONT | BACK", "webgpu": "" } } }, "GeometryType": { @@ -667,7 +668,7 @@ "vktype": "VkGeometryTypeKHR", "values": { "TRIANGLES": { "vulkan": "VK_GEOMETRY_TYPE_TRIANGLES_KHR", "webgpu": "" }, - "AABBS": { "vulkan": "VK_GEOMETRY_TYPE_AABBS_KHR", "webgpu": "" }, + "AABBS": { "vulkan": "VK_GEOMETRY_TYPE_AABBS_KHR", "webgpu": "" }, "INSTANCES": { "vulkan": "VK_GEOMETRY_TYPE_INSTANCES_KHR", "webgpu": "" } } }, @@ -676,7 +677,7 @@ "type": "u8", "vktype": "VkGeometryFlagBitsKHR", "values": { - "OPAQUE": { "vulkan": "VK_GEOMETRY_OPAQUE_BIT_KHR", "webgpu": "" }, + "OPAQUE": { "vulkan": "VK_GEOMETRY_OPAQUE_BIT_KHR", "webgpu": "" }, "NO_DUPLICATE_ANY_HIT_INVOCATION": { "vulkan": "VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR", "webgpu": "" } } }, @@ -685,22 +686,22 @@ "type": "u32", "vktype": "VkColorSpaceKHR", "values": { - "SRGB_NONLINEAR": { "vulkan": "VK_COLOR_SPACE_SRGB_NONLINEAR_KHR", "webgpu": "" }, - "DISPLAY_P3_NONLINEAR": { "vulkan": "VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT", "webgpu": "" }, - "EXTENDED_SRGB_LINEAR": { "vulkan": "VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT", "webgpu": "" }, - "DCI_P3_NONLINEAR": { "vulkan": "VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT", "webgpu": "" }, - "BT709_LINEAR": { "vulkan": "VK_COLOR_SPACE_BT709_LINEAR_EXT", "webgpu": "" }, - "BT709_NONLINEAR": { "vulkan": "VK_COLOR_SPACE_BT709_NONLINEAR_EXT", "webgpu": "" }, - "BT2020_LINEAR": { "vulkan": "VK_COLOR_SPACE_BT2020_LINEAR_EXT", "webgpu": "" }, - "HDR10_ST2084": { "vulkan": "VK_COLOR_SPACE_HDR10_ST2084_EXT", "webgpu": "" }, - "DOLBYVISION": { "vulkan": "VK_COLOR_SPACE_DOLBYVISION_EXT", "webgpu": "" }, - "HDR10_HLG": { "vulkan": "VK_COLOR_SPACE_HDR10_HLG_EXT", "webgpu": "" }, - "ADOBERGB_LINEAR": { "vulkan": "VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT", "webgpu": "" }, - "ADOBERGB_NONLINEAR": { "vulkan": "VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT", "webgpu": "" }, - "PASS_THROUGH": { "vulkan": "VK_COLOR_SPACE_PASS_THROUGH_EXT", "webgpu": "" }, + "SRGB_NONLINEAR": { "vulkan": "VK_COLOR_SPACE_SRGB_NONLINEAR_KHR", "webgpu": "" }, + "DISPLAY_P3_NONLINEAR": { "vulkan": "VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT", "webgpu": "" }, + "EXTENDED_SRGB_LINEAR": { "vulkan": "VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT", "webgpu": "" }, + "DCI_P3_NONLINEAR": { "vulkan": "VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT", "webgpu": "" }, + "BT709_LINEAR": { "vulkan": "VK_COLOR_SPACE_BT709_LINEAR_EXT", "webgpu": "" }, + "BT709_NONLINEAR": { "vulkan": "VK_COLOR_SPACE_BT709_NONLINEAR_EXT", "webgpu": "" }, + "BT2020_LINEAR": { "vulkan": "VK_COLOR_SPACE_BT2020_LINEAR_EXT", "webgpu": "" }, + "HDR10_ST2084": { "vulkan": "VK_COLOR_SPACE_HDR10_ST2084_EXT", "webgpu": "" }, + "DOLBYVISION": { "vulkan": "VK_COLOR_SPACE_DOLBYVISION_EXT", "webgpu": "" }, + "HDR10_HLG": { "vulkan": "VK_COLOR_SPACE_HDR10_HLG_EXT", "webgpu": "" }, + "ADOBERGB_LINEAR": { "vulkan": "VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT", "webgpu": "" }, + "ADOBERGB_NONLINEAR": { "vulkan": "VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT", "webgpu": "" }, + "PASS_THROUGH": { "vulkan": "VK_COLOR_SPACE_PASS_THROUGH_EXT", "webgpu": "" }, "EXTENDED_SRGB_NONLINEAR": { "vulkan": "VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT", "webgpu": "" }, - "DISPLAY_NATIVE_AMD": { "vulkan": "VK_COLOR_SPACE_DISPLAY_NATIVE_AMD", "webgpu": "" }, - "DISPLAY_P3_LINEAR": { "vulkan": "VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT", "webgpu": "" } + "DISPLAY_NATIVE_AMD": { "vulkan": "VK_COLOR_SPACE_DISPLAY_NATIVE_AMD", "webgpu": "" }, + "DISPLAY_P3_LINEAR": { "vulkan": "VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT", "webgpu": "" } } }, "PresentMode": { @@ -708,11 +709,11 @@ "type": "u32", "vktype": "VkPresentModeKHR", "values": { - "IMMEDIATE": { "vulkan": "VK_PRESENT_MODE_IMMEDIATE_KHR", "webgpu": "" }, - "MAILBOX": { "vulkan": "VK_PRESENT_MODE_MAILBOX_KHR", "webgpu": "" }, - "FIFO": { "vulkan": "VK_PRESENT_MODE_FIFO_KHR", "webgpu": "" }, - "FIFO_RELAXED": { "vulkan": "VK_PRESENT_MODE_FIFO_RELAXED_KHR", "webgpu": "" }, - "SHARED_DEMAND_REFRESH": { "vulkan": "VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR", "webgpu": "" }, + "IMMEDIATE": { "vulkan": "VK_PRESENT_MODE_IMMEDIATE_KHR", "webgpu": "" }, + "MAILBOX": { "vulkan": "VK_PRESENT_MODE_MAILBOX_KHR", "webgpu": "" }, + "FIFO": { "vulkan": "VK_PRESENT_MODE_FIFO_KHR", "webgpu": "" }, + "FIFO_RELAXED": { "vulkan": "VK_PRESENT_MODE_FIFO_RELAXED_KHR", "webgpu": "" }, + "SHARED_DEMAND_REFRESH": { "vulkan": "VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR", "webgpu": "" }, "SHARED_CONTINUOUS_REFRESH": { "vulkan": "VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR", "webgpu": "" } } }, @@ -721,29 +722,42 @@ "type": "u32", "vktype": "VkFormatFeatureFlagBits", "values": { - "SAMPLED_IMAGE": { "vulkan": "VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT", "webgpu": ""}, - "STORAGE_IMAGE": { "vulkan": "VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT", "webgpu": ""}, - "STORAGE_IMAGE_ATOMIC": { "vulkan": "VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT", "webgpu": ""}, - "UNIFORM_TEXEL_BUFFER": { "vulkan": "VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT", "webgpu": ""}, - "STORAGE_TEXEL_BUFFER": { "vulkan": "VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT", "webgpu": ""}, - "STORAGE_TEXEL_BUFFER_ATOMIC": { "vulkan": "VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT", "webgpu": ""}, - "VERTEX_BUFFER": { "vulkan": "VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT", "webgpu": ""}, - "COLOR_ATTACHMENT": { "vulkan": "VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT", "webgpu": ""}, - "COLOR_ATTACHMENT_BLEND": { "vulkan": "VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT", "webgpu": ""}, - "DEPTH_STENCIL_ATTACHMENT": { "vulkan": "VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT", "webgpu": ""}, - "BLIT_SRC": { "vulkan": "VK_FORMAT_FEATURE_BLIT_SRC_BIT", "webgpu": ""}, - "BLIT_DST": { "vulkan": "VK_FORMAT_FEATURE_BLIT_DST_BIT", "webgpu": ""}, - "SAMPLED_IMAGE_FILTER_LINEAR": { "vulkan": "VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT", "webgpu": ""}, - "TRANSFER_SRC": { "vulkan": "VK_FORMAT_FEATURE_TRANSFER_SRC_BIT", "webgpu": ""}, - "TRANSFER_DST": { "vulkan": "VK_FORMAT_FEATURE_TRANSFER_DST_BIT", "webgpu": ""}, - "MIDPOINT_CHROMA_SAMPLES": { "vulkan": "VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT", "webgpu": ""}, - "SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER": { "vulkan": "VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT", "webgpu": ""}, - "SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER": { "vulkan": "VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT", "webgpu": ""}, - "SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT": { "vulkan": "VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT", "webgpu": ""}, - "SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE": { "vulkan": "VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT", "webgpu": ""}, - "DISJOINT": { "vulkan": "VK_FORMAT_FEATURE_DISJOINT_BIT", "webgpu": ""}, - "COSITED_CHROMA_SAMPLES": { "vulkan": "VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT", "webgpu": ""}, - "SAMPLED_IMAGE_FILTER_MINMAX": { "vulkan": "VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT", "webgpu": ""} - } + "SAMPLED_IMAGE": { "vulkan": "VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT", "webgpu": "" }, + "STORAGE_IMAGE": { "vulkan": "VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT", "webgpu": "" }, + "STORAGE_IMAGE_ATOMIC": { "vulkan": "VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT", "webgpu": "" }, + "UNIFORM_TEXEL_BUFFER": { "vulkan": "VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT", "webgpu": "" }, + "STORAGE_TEXEL_BUFFER": { "vulkan": "VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT", "webgpu": "" }, + "STORAGE_TEXEL_BUFFER_ATOMIC": { "vulkan": "VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT", "webgpu": "" }, + "VERTEX_BUFFER": { "vulkan": "VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT", "webgpu": "" }, + "COLOR_ATTACHMENT": { "vulkan": "VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT", "webgpu": "" }, + "COLOR_ATTACHMENT_BLEND": { "vulkan": "VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT", "webgpu": "" }, + "DEPTH_STENCIL_ATTACHMENT": { "vulkan": "VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT", "webgpu": "" }, + "BLIT_SRC": { "vulkan": "VK_FORMAT_FEATURE_BLIT_SRC_BIT", "webgpu": "" }, + "BLIT_DST": { "vulkan": "VK_FORMAT_FEATURE_BLIT_DST_BIT", "webgpu": "" }, + "SAMPLED_IMAGE_FILTER_LINEAR": { "vulkan": "VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT", "webgpu": "" }, + "TRANSFER_SRC": { "vulkan": "VK_FORMAT_FEATURE_TRANSFER_SRC_BIT", "webgpu": "" }, + "TRANSFER_DST": { "vulkan": "VK_FORMAT_FEATURE_TRANSFER_DST_BIT", "webgpu": "" }, + "MIDPOINT_CHROMA_SAMPLES": { "vulkan": "VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT", "webgpu": "" }, + "SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER": { "vulkan": "VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT", "webgpu": "" }, + "SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER": { "vulkan": "VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT", "webgpu": "" }, + "SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT": { "vulkan": "VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT", "webgpu": "" }, + "SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE": { "vulkan": "VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT", "webgpu": "" }, + "DISJOINT": { "vulkan": "VK_FORMAT_FEATURE_DISJOINT_BIT", "webgpu": "" }, + "COSITED_CHROMA_SAMPLES": { "vulkan": "VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT", "webgpu": "" }, + "SAMPLED_IMAGE_FILTER_MINMAX": { "vulkan": "VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT", "webgpu": "" } + } + }, + "ResolveModeFlag": { + "flag": true, + "type": "u8", + "vktype": "VkResolveModeFlagBits", + "values": { + "NONE": { "vulkan": "VK_RESOLVE_MODE_NONE", "webgpu": "" }, + "SAMPLE_ZERO": { "vulkan": "VK_RESOLVE_MODE_SAMPLE_ZERO_BIT", "webgpu": "" }, + "AVERAGE": { "vulkan": "VK_RESOLVE_MODE_AVERAGE_BIT", "webgpu": "" }, + "MIN": { "vulkan": "VK_RESOLVE_MODE_MIN_BIT", "webgpu": "" }, + "MAX": { "vulkan": "VK_RESOLVE_MODE_MAX_BIT", "webgpu": "" }, + "EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID": { "vulkan": "VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID", "webgpu": "" } + } } } diff --git a/modules/stormkit/gpu/core/vulkan/structs.mpp b/modules/stormkit/gpu/core/vulkan/structs.mpp index d7cd70386..ec77da84d 100644 --- a/modules/stormkit/gpu/core/vulkan/structs.mpp +++ b/modules/stormkit/gpu/core/vulkan/structs.mpp @@ -48,6 +48,9 @@ export namespace stormkit::gpu { [[nodiscard]] constexpr auto to_vk(const Viewport& viewport) noexcept -> VkViewport; + [[nodiscard]] + constexpr auto to_vk(const math::recti& rect) noexcept -> VkRect2D; + [[nodiscard]] constexpr auto to_vk(const Scissor& viewport) noexcept -> VkRect2D; @@ -86,6 +89,15 @@ namespace stormkit::gpu { return value.native_handle(); } + ///////////////////////////////////// + ///////////////////////////////////// + constexpr auto to_vk(const math::recti& rect) noexcept -> VkRect2D { + return VkRect2D { + .offset = { rect.x, rect.y }, + .extent = { as(rect.width.value), as(rect.height.value) } + }; + } + ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_PURE diff --git a/modules/stormkit/gpu/execution/command_buffer.mpp b/modules/stormkit/gpu/execution/command_buffer.mpp index 82ef18e14..793181435 100644 --- a/modules/stormkit/gpu/execution/command_buffer.mpp +++ b/modules/stormkit/gpu/execution/command_buffer.mpp @@ -88,6 +88,34 @@ export namespace stormkit::gpu { OptionalRef framebuffer = std::nullopt; }; + struct RenderingInfo { + struct Attachment { + struct Resolve { + Ref image_view; + ResolveModeFlag mode; + gpu::ImageLayout layout = ImageLayout::ATTACHMENT_OPTIMAL; + }; + + Ref image_view; + gpu::ImageLayout layout = ImageLayout::ATTACHMENT_OPTIMAL; + + std::optional resolve = std::nullopt; + + AttachmentLoadOperation load_op = AttachmentLoadOperation::CLEAR; + AttachmentStoreOperation store_op = AttachmentStoreOperation::STORE; + + std::optional clear_value = std::nullopt; + }; + + math::recti render_area; + u32 layer_count = 1u; + u32 view_mask = 0u; + + std::vector color_attachments; + std::optional depth_attachment = std::nullopt; + std::optional stencil_attachment = std::nullopt; + }; + class STORMKIT_API CommandBuffer { struct PrivateFuncTag {}; @@ -131,6 +159,7 @@ export namespace stormkit::gpu { -> CommandBuffer&; auto end_debug_region() noexcept -> CommandBuffer&; + auto begin_rendering(const RenderingInfo& info) noexcept -> CommandBuffer&; auto begin_render_pass(const RenderPass& render_pass, const FrameBuffer& framebuffer, std::span clear_values = std::array { ClearValue { @@ -138,6 +167,7 @@ export namespace stormkit::gpu { bool secondary_commandbuffers = false) noexcept -> CommandBuffer&; auto next_sub_pass() noexcept -> CommandBuffer&; auto end_render_pass() noexcept -> CommandBuffer&; + auto end_rendering() noexcept -> CommandBuffer&; auto bind_pipeline(const Pipeline& pipeline) noexcept -> CommandBuffer&; auto set_viewport(u32 first_viewport, std::span viewports) noexcept -> CommandBuffer&; @@ -320,14 +350,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Queue::~Queue() noexcept - = default; + inline Queue::~Queue() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Queue::Queue(Queue&&) noexcept - = default; + inline Queue::Queue(Queue&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// @@ -428,14 +456,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline CommandBuffer::~CommandBuffer() noexcept - = default; + inline CommandBuffer::~CommandBuffer() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline CommandBuffer::CommandBuffer(CommandBuffer&&) noexcept - = default; + inline CommandBuffer::CommandBuffer(CommandBuffer&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// @@ -575,6 +601,16 @@ namespace stormkit::gpu { return *this; } + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto CommandBuffer::end_rendering() noexcept -> CommandBuffer& { + EXPECTS(m_state == State::RECORDING); + + vk_call(m_vk_device_table->vkCmdEndRendering, m_vk_handle); + return *this; + } + ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE @@ -779,14 +815,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline CommandPool::~CommandPool() noexcept - = default; + inline CommandPool::~CommandPool() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline CommandPool::CommandPool(CommandPool&&) noexcept - = default; + inline CommandPool::CommandPool(CommandPool&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// diff --git a/modules/stormkit/gpu/execution/pipeline.mpp b/modules/stormkit/gpu/execution/pipeline.mpp index d36959362..f2f82b94c 100644 --- a/modules/stormkit/gpu/execution/pipeline.mpp +++ b/modules/stormkit/gpu/execution/pipeline.mpp @@ -98,7 +98,7 @@ export namespace stormkit::gpu { auto operator=(PipelineLayout&&) noexcept -> PipelineLayout&; [[nodiscard]] - auto rasterLayout() const noexcept -> const RasterPipelineLayout&; + auto raster_layout() const noexcept -> const RasterPipelineLayout&; [[nodiscard]] auto native_handle() const noexcept -> VkPipelineLayout; @@ -130,6 +130,12 @@ export namespace stormkit::gpu { const PipelineLayout& layout, const RenderPass& render_pass, OptionalRef cache = std::nullopt) noexcept -> Expected; + + static auto create(const Device& device, + const RasterPipelineState& state, + const PipelineLayout& layout, + const RasterPipelineRenderingInfo& rendering_info, + OptionalRef cache = std::nullopt) noexcept -> Expected; ~Pipeline() noexcept; Pipeline(const Pipeline&) = delete; @@ -151,7 +157,10 @@ export namespace stormkit::gpu { Pipeline(const Device&, const RasterPipelineState&, PrivateFuncTag) noexcept; private: - auto do_init(const PipelineLayout&, const RenderPass&, OptionalRef) noexcept -> Expected; + auto do_init(const PipelineLayout&, + OptionalRef, + OptionalRef, + OptionalRef) noexcept -> Expected; Type m_type; std::variant m_state; @@ -316,7 +325,20 @@ namespace stormkit::gpu { const RenderPass& render_pass, OptionalRef cache) noexcept -> Expected { auto pipeline = Pipeline { device, state, PrivateFuncTag {} }; - Try(pipeline.do_init(layout, render_pass, std::move(cache))); + Try(pipeline.do_init(layout, as_opt_ref(render_pass), std::nullopt, std::move(cache))); + Return pipeline; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Pipeline::create(const Device& device, + const RasterPipelineState& state, + const PipelineLayout& layout, + const RasterPipelineRenderingInfo& rendering_info, + OptionalRef cache) noexcept -> Expected { + auto pipeline = Pipeline { device, state, PrivateFuncTag {} }; + Try(pipeline.do_init(layout, std::nullopt, as_opt_ref(rendering_info), std::move(cache))); Return pipeline; } diff --git a/modules/stormkit/gpu/execution/raster_pipeline.mpp b/modules/stormkit/gpu/execution/raster_pipeline.mpp index d763be178..e3e667f31 100644 --- a/modules/stormkit/gpu/execution/raster_pipeline.mpp +++ b/modules/stormkit/gpu/execution/raster_pipeline.mpp @@ -104,6 +104,13 @@ export namespace stormkit::gpu { float max_depth_bounds = 1.f; }; + struct RasterPipelineRenderingInfo { + u32 view_mask = 0u; + std::vector color_attachment_formats; + std::optional depth_attachment_format = std::nullopt; + std::optional stencil_attachment_format = std::nullopt; + }; + struct RasterPipelineLayout { std::vector> descriptor_set_layouts = {}; std::vector push_constant_ranges = {}; diff --git a/src/gpu/core/device.cpp b/src/gpu/core/device.cpp index 69caee254..d2099bb38 100644 --- a/src/gpu/core/device.cpp +++ b/src/gpu/core/device.cpp @@ -35,6 +35,7 @@ namespace { constexpr auto BASE_EXTENSIONS = std::array { VK_KHR_MAINTENANCE_3_EXTENSION_NAME, + VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, // "VK_KHR_maintenance4"sv, "VK_KHR_maintenance5"sv, "VK_KHR_maintenance6"sv }; constexpr auto SWAPCHAIN_EXTENSIONS = std::array { @@ -268,15 +269,22 @@ namespace stormkit::gpu { }; }); - const auto& capabilities = m_physical_device->capabilities(); - const auto enabled_features = [&capabilities] noexcept { - auto out = zeroed(); - out.sampleRateShading = capabilities.features.sampler_rate_shading; - out.multiDrawIndirect = capabilities.features.multi_draw_indirect; - out.fillModeNonSolid = capabilities.features.fill_Mode_non_solid; - out.samplerAnisotropy = capabilities.features.sampler_anisotropy; - return out; - }(); + const auto& capabilities = m_physical_device->capabilities(); + const auto enabled_1_0_features = VkPhysicalDeviceFeatures { .multiDrawIndirect = true, .samplerAnisotropy = true }; + const auto enabled_1_2_features = VkPhysicalDeviceVulkan12Features { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, + .pNext = nullptr, + .descriptorIndexing = true, + .descriptorBindingVariableDescriptorCount = true, + .runtimeDescriptorArray = true, + .bufferDeviceAddress = true + }; + const auto enabled_1_3_features = VkPhysicalDeviceVulkan13Features { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, + .pNext = std::bit_cast(&enabled_1_2_features), + .synchronization2 = true, + .dynamicRendering = true + }; const auto device_extensions = m_physical_device->extensions(); @@ -309,27 +317,27 @@ namespace stormkit::gpu { }(); device_logger.ilog("Enabled device extensions: {}", extensions); - const auto acceleration_feature = [] static noexcept { - auto out = zeroed(); - out.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR; - out.pNext = nullptr; - return out; - }(); - const auto rt_pipeline_feature = [&acceleration_feature] noexcept { - auto out = zeroed(); - out.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR; - out.pNext = std::bit_cast(&acceleration_feature); - return out; - }; - - const auto next = [&]() -> void* { - if (raytracing_available and info.enable_raytracing) return std::bit_cast(&rt_pipeline_feature); - return nullptr; - }(); + // const auto acceleration_feature = [] static noexcept { + // auto out = zeroed(); + // out.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR; + // out.pNext = nullptr; + // return out; + // }(); + // const auto rt_pipeline_feature = [&acceleration_feature] noexcept { + // auto out = zeroed(); + // out.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_FEATURES_KHR; + // out.pNext = std::bit_cast(&acceleration_feature); + // return out; + // }; + + // const auto next = [&]() -> void* { + // if (raytracing_available and info.enable_raytracing) return std::bit_cast(&rt_pipeline_feature); + // return nullptr; + // }(); const auto create_info = VkDeviceCreateInfo { .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, - .pNext = next, + .pNext = std::bit_cast(&enabled_1_3_features), .flags = 0, .queueCreateInfoCount = as(stdr::size(queue_create_infos)), .pQueueCreateInfos = stdr::data(queue_create_infos), @@ -337,7 +345,7 @@ namespace stormkit::gpu { .ppEnabledLayerNames = nullptr, .enabledExtensionCount = as(stdr::size(extensions)), .ppEnabledExtensionNames = stdr::data(extensions), - .pEnabledFeatures = &enabled_features, + .pEnabledFeatures = &enabled_1_0_features, }; auto allocator_create_info = VmaAllocatorCreateInfo { diff --git a/src/gpu/core/instance.cpp b/src/gpu/core/instance.cpp index de7d420d4..ca1c43803 100644 --- a/src/gpu/core/instance.cpp +++ b/src/gpu/core/instance.cpp @@ -27,7 +27,7 @@ namespace stormkit::gpu { namespace { constexpr auto VALIDATION_LAYERS = std::array { "VK_LAYER_KHRONOS_validation", - "VK_LAYER_LUNARG_api_dump", + // "VK_LAYER_LUNARG_api_dump", "VK_LAYER_LUNARG_monitor", }; constexpr auto OPTIONAL_VALIDATION_LAYERS = std::array { @@ -169,7 +169,7 @@ namespace stormkit::gpu { .applicationVersion = vk_make_version(0, 0, 0), .pEngineName = ENGINE_NAME, .engineVersion = STORMKIT_VK_VERSION, - .apiVersion = VK_API_VERSION_1_1, + .apiVersion = VK_API_VERSION_1_3, }; const auto create_info = VkInstanceCreateInfo { diff --git a/src/gpu/execution/command_buffer.cpp b/src/gpu/execution/command_buffer.cpp index 0384d2bbf..7855c9ffd 100644 --- a/src/gpu/execution/command_buffer.cpp +++ b/src/gpu/execution/command_buffer.cpp @@ -27,26 +27,26 @@ namespace stdv = std::views; namespace stormkit::gpu { namespace { - constexpr auto OLD_LAYOUT_ACCESS_MAP = frozen::make_unordered_map>({ - { VK_IMAGE_LAYOUT_UNDEFINED, { VK_ACCESS_NONE, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT } }, - { VK_IMAGE_LAYOUT_PREINITIALIZED, { VK_ACCESS_NONE, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT } }, - { VK_IMAGE_LAYOUT_GENERAL, - { VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT } }, - { VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - { VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT } }, - { VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - { VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT } }, - { VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, - { VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT } }, - { VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - { VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT } }, - { VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, { VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT } }, - { VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, { VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT } }, - { VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, { VK_ACCESS_MEMORY_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT } }, + constexpr auto + OLD_LAYOUT_ACCESS_MAP = frozen::make_unordered_map>({ + { VK_IMAGE_LAYOUT_UNDEFINED, { VK_ACCESS_NONE, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT } }, + { VK_IMAGE_LAYOUT_PREINITIALIZED, { VK_ACCESS_NONE, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT } }, + { VK_IMAGE_LAYOUT_GENERAL, + { VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT } }, + { VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + { VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT } }, + { VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + { VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT } }, + { VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, + { VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT } }, + { VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + { VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT } }, + { VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, { VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT } }, + { VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, { VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT } }, + { VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, { VK_ACCESS_MEMORY_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT } }, }); constexpr auto NEW_LAYOUT_ACCESS_MAP = frozen::make_unordered_map()); } + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::begin_rendering(const RenderingInfo& info) noexcept -> CommandBuffer& { + EXPECTS(m_state == State::RECORDING); + + auto to_vk_attachment = [](const auto& attachment) static noexcept { + auto attachment_info = VkRenderingAttachmentInfo { + .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, + .pNext = nullptr, + .imageView = to_vk(attachment.image_view), + .imageLayout = to_vk(attachment.layout), + .resolveMode = {}, + .resolveImageView = nullptr, + .resolveImageLayout = {}, + .loadOp = to_vk(attachment.load_op), + .storeOp = to_vk(attachment.store_op), + .clearValue = {}, + }; + + if (attachment.resolve) { + auto& resolve = *attachment.resolve; + + attachment_info.resolveMode = to_vk(resolve.mode); + attachment_info.resolveImageView = to_vk(resolve.image_view); + attachment_info.resolveImageLayout = to_vk(resolve.layout); + } + if (attachment.clear_value) { + attachment_info + .clearValue = std::visit(Overloaded { + [](const ClearColor& clear_color) static noexcept -> decltype(auto) { + return VkClearValue { + .color = VkClearColorValue { .float32 = { clear_color.color.red, + clear_color.color.blue, + clear_color.color.green, + clear_color.color.alpha } }, + }; + }, + [](const ClearDepthStencil& clear_depth_stencil) static noexcept -> decltype(auto) { + return VkClearValue { + .depthStencil = VkClearDepthStencilValue { .depth = clear_depth_stencil + .depth, + .stencil = clear_depth_stencil + .stencil }, + }; + } }, + *attachment.clear_value); + } + + return attachment_info; + }; + + const auto color_attachments = info.color_attachments | stdv::transform(to_vk_attachment) | stdr::to(); + const auto depth_attachment = info.depth_attachment ? to_vk_attachment(*info.depth_attachment) + : VkRenderingAttachmentInfo {}; + const auto stencil_attachment = info.stencil_attachment ? to_vk_attachment(*info.stencil_attachment) + : VkRenderingAttachmentInfo {}; + + const auto rendering_info = VkRenderingInfo { + .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, + .pNext = nullptr, + .flags = 0, + .renderArea = to_vk(info.render_area), + .layerCount = info.layer_count, + .viewMask = info.view_mask, + .colorAttachmentCount = as(stdr::size(color_attachments)), + .pColorAttachments = stdr::data(color_attachments), + .pDepthAttachment = info.depth_attachment ? &depth_attachment : nullptr, + .pStencilAttachment = info.stencil_attachment ? &stencil_attachment : nullptr, + }; + + vk_call(m_vk_device_table->vkCmdBeginRenderingKHR, m_vk_handle, &rendering_info); + return *this; + } + ///////////////////////////////////// ///////////////////////////////////// auto CommandBuffer::begin_render_pass(const RenderPass& render_pass, @@ -258,7 +332,7 @@ namespace stormkit::gpu { | stdv::transform([](auto&& buffer_image_copy) noexcept { const auto image_subresource = VkImageSubresourceLayers { .aspectMask = to_vk(buffer_image_copy.subresource_layers - .aspect_mask), + .aspect_mask), .mipLevel = buffer_image_copy.subresource_layers.mip_level, .baseArrayLayer = buffer_image_copy.subresource_layers.base_array_layer, .layerCount = buffer_image_copy.subresource_layers.layer_count, @@ -300,7 +374,7 @@ namespace stormkit::gpu { | stdv::transform([](auto&& buffer_image_copy) noexcept { const auto image_subresource = VkImageSubresourceLayers { .aspectMask = to_vk(buffer_image_copy.subresource_layers - .aspect_mask), + .aspect_mask), .mipLevel = buffer_image_copy.subresource_layers.mip_level, .baseArrayLayer = buffer_image_copy.subresource_layers.base_array_layer, .layerCount = buffer_image_copy.subresource_layers.layer_count, diff --git a/src/gpu/execution/pipeline.cpp b/src/gpu/execution/pipeline.cpp index a5d0b675b..723680df8 100644 --- a/src/gpu/execution/pipeline.cpp +++ b/src/gpu/execution/pipeline.cpp @@ -20,11 +20,16 @@ namespace stdv = std::views; namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto Pipeline::do_init(const PipelineLayout& layout, - const RenderPass& render_pass, - OptionalRef pipeline_cache) noexcept -> Expected { + auto Pipeline::do_init(const PipelineLayout& layout, + OptionalRef render_pass, + OptionalRef rendering_info, + OptionalRef pipeline_cache) noexcept -> Expected { const auto& state = as(m_state); + if (not render_pass) expects(rendering_info != std::nullopt); + else + expects(render_pass != std::nullopt); + const auto binding_descriptions = state.vertex_input_state.binding_descriptions | stdv::transform([](auto&& binding_description) static noexcept { return VkVertexInputBindingDescription { @@ -177,9 +182,36 @@ namespace stormkit::gpu { .maxDepthBounds = state.depth_stencil_state.max_depth_bounds }; + const auto [_, render_info] = [&]() { + auto info = VkPipelineRenderingCreateInfo {}; + if (not rendering_info) return std::make_pair(std::vector {}, std::move(info)); + + auto formats = rendering_info->color_attachment_formats + | stdv::transform(monadic::to_vk()) + | stdr::to(); + + info = VkPipelineRenderingCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, + .pNext = nullptr, + .viewMask = rendering_info->view_mask, + .colorAttachmentCount = as(stdr::size(formats)), + .pColorAttachmentFormats = stdr::data(formats), + .depthAttachmentFormat = {}, + .stencilAttachmentFormat = {} + }; + + if (rendering_info->depth_attachment_format) + info.depthAttachmentFormat = to_vk(*rendering_info->depth_attachment_format); + + if (rendering_info->stencil_attachment_format) + info.stencilAttachmentFormat = to_vk(*rendering_info->stencil_attachment_format); + + return std::make_pair(std::move(formats), std::move(info)); + }(); + const auto create_info = VkGraphicsPipelineCreateInfo { .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, - .pNext = nullptr, + .pNext = not render_pass ? &render_info : nullptr, .flags = 0, .stageCount = as(stdr::size(shaders)), .pStages = stdr::data(shaders), @@ -193,7 +225,7 @@ namespace stormkit::gpu { .pColorBlendState = &color_blending, .pDynamicState = &dynamic_state, .layout = to_vk(layout), - .renderPass = to_vk(render_pass), + .renderPass = render_pass ? to_vk(render_pass) : nullptr, .subpass = 0, .basePipelineHandle = nullptr, .basePipelineIndex = -1, diff --git a/xmake/rules/stormkit_flags.xmake.lua b/xmake/rules/stormkit_flags.xmake.lua index bc59183cf..77901b54e 100644 --- a/xmake/rules/stormkit_flags.xmake.lua +++ b/xmake/rules/stormkit_flags.xmake.lua @@ -25,12 +25,6 @@ rule("stormkit.flags", function() or get_config("toolchain") == "gcc" then target:add("syslinks", "dl") - - if is_mode("debug") then - target:add("cxflags", "-no-pie") - target:add("ldflags", "-fno-pie") - target:add("shflags", "-fno-pie") - end end end) on_load("windows", function(target) From 1a246f2d20f88b64b32e9c0be4d3f6595bd8e22c Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 1 Feb 2026 17:55:26 +0100 Subject: [PATCH 032/194] (gpu) use dynamic rendering for all examples --- examples/gpu/common/app.mpp | 34 +- examples/gpu/imgui/src/main.cpp | 197 ++++---- examples/gpu/textured_cube/src/main.cpp | 620 +++++++++++------------- examples/gpu/textured_cube/xmake.lua | 6 +- examples/gpu/triangle/src/main.cpp | 33 +- examples/gpu/triangle/xmake.lua | 5 +- examples/wsi/luau/src/main.cpp | 8 +- examples/wsi/luau/xmake.lua | 4 +- 8 files changed, 410 insertions(+), 497 deletions(-) diff --git a/examples/gpu/common/app.mpp b/examples/gpu/common/app.mpp index 9ef9e3245..ed4a89e2b 100644 --- a/examples/gpu/common/app.mpp +++ b/examples/gpu/common/app.mpp @@ -2,6 +2,10 @@ // This file is subject to the license terms in the LICENSE file // found in the top-level of this distribution +module; + +#include + export module gpu_app; import std; @@ -57,16 +61,15 @@ export namespace base { auto init_gpu(std::string_view example_name) noexcept -> void { // initialize gpu backend (vulkan or webgpu depending the platform) - *gpu::initialize_backend().transform_error(monadic::assert("Failed to initialize gpu backend")); + TryAssertDiscard(gpu::initialize_backend(), "Failed to initialize gpu backend"); // create gpu instance and attach surface to window - m_instance = gpu::Instance::create(std::string { example_name }, true) - .transform_error(monadic::assert("Failed to initialize gpu instance")) - .value(); + m_instance = TryAssert(gpu::Instance::create(std::string { example_name }, true), + "Failed to initialize gpu instance"); + + m_surface = TryAssert(gpu::Surface::create_from_window(m_instance, m_window), + "Failed to initialize window gpu surface"); - m_surface = gpu::Surface::create_from_window(m_instance, m_window) - .transform_error(monadic::assert("Failed to initialize window gpu surface")) - .value(); // pick the best physical device const auto& physical_devices = m_instance->physical_devices(); if (stdr::empty(physical_devices)) { @@ -77,7 +80,7 @@ export namespace base { m_physical_device = as_opt_ref(physical_devices.front()); auto score = gpu::score_physical_device(*m_physical_device); - for (auto i = 1u; i < stdr::size(physical_devices); ++i) { + for (auto i : range(1_u32, stdr::size(physical_devices))) { const auto& d = physical_devices[i]; const auto d_score = gpu::score_physical_device(d); if (d_score > score) { @@ -89,22 +92,17 @@ export namespace base { log::Logger::ilog("Picked gpu: {}", *m_physical_device); // create gpu device - m_device = gpu::Device::create(*m_physical_device, m_instance) - .transform_error(monadic::assert("Failed to initialize gpu device")) - .value(); + m_device = TryAssert(gpu::Device::create(*m_physical_device, m_instance), "Failed to initialize gpu device"); // create swapchain const auto window_extent = m_window->extent(); - m_swapchain = gpu::SwapChain::create(m_device, m_surface, window_extent) - .transform_error(monadic::assert("Failed to create swapchain")) - .value(); + m_swapchain = TryAssert(gpu::SwapChain::create(m_device, m_surface, window_extent), "Failed to create swapchain"); m_raster_queue = gpu::Queue::create(m_device, m_device->raster_queue_entry()); - m_command_pool = gpu::CommandPool::create(m_device) - .transform_error(monadic::assert("Failed to create raster queue " - "command pool")) - .value(); + m_command_pool = TryAssert(gpu::CommandPool::create(m_device), + "Failed to create raster queue " + "command pool"); } }; } // namespace base diff --git a/examples/gpu/imgui/src/main.cpp b/examples/gpu/imgui/src/main.cpp index 1f2ee4f62..734601c1a 100644 --- a/examples/gpu/imgui/src/main.cpp +++ b/examples/gpu/imgui/src/main.cpp @@ -7,6 +7,7 @@ import std; import stormkit; import gpu_app; +#include #include #include #include @@ -33,11 +34,15 @@ struct SubmissionResource { struct SwapchainImageResource { Ref image; gpu::ImageView view; - gpu::FrameBuffer framebuffer; gpu::Semaphore render_finished; }; -static constexpr auto BUFFERING_COUNT = 2; +namespace { + constexpr auto BUFFERING_COUNT = 2; + constexpr auto POOL_SIZES = std::array { + gpu::DescriptorPool::Size { .type = gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, .descriptor_count = BUFFERING_COUNT } + }; +} // namespace class Application: public base::Application { public: @@ -48,40 +53,23 @@ class Application: public base::Application { auto init_resources() -> void { // initialilze descriptor pool - static constexpr auto POOL_SIZES = std::array { - gpu::DescriptorPool::Size { .type = gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, .descriptor_count = BUFFERING_COUNT } - }; - m_descriptor_pool = gpu::DescriptorPool::create(m_device, POOL_SIZES, BUFFERING_COUNT) - .transform_error(monadic::assert("Failed to create descriptor pool")) - .value(); - - // initialize render pass - m_render_pass = gpu::RenderPass::create(m_device, - { .attachments = { { .format = m_swapchain->pixel_format() } }, - .subpasses = { { .bind_point = gpu::PipelineBindPoint::GRAPHICS, - .color_attachment_refs = { { .attachment_id = 0u } } } } }) - .transform_error(monadic::assert("Failed to create render pass")) - .value(); - - const auto window_extent = m_window->extent(); + m_descriptor_pool = TryAssert(gpu::DescriptorPool::create(m_device, POOL_SIZES, BUFFERING_COUNT), + "Failed to create descriptor pool"); // create present engine resources m_submission_resources = init_by>([&](auto& out) noexcept { out.reserve(BUFFERING_COUNT); for (auto _ : range(BUFFERING_COUNT)) { out.push_back({ - .in_flight = gpu::Fence::create_signaled(m_device) - .transform_error(monadic::assert("Failed to create swapchain image " - "in flight fence")) - .value(), - .image_available = gpu::Semaphore::create(m_device) - .transform_error(monadic::assert("Failed to create " - "present wait semaphore")) - .value(), - .render_cmb = m_command_pool->create_command_buffer() - .transform_error(monadic::assert("Failed to create transition " - "command buffers")) - .value(), + .in_flight = TryAssert(gpu::Fence::create_signaled(m_device), + "Failed to create swapchain image " + "in flight fence"), + .image_available = TryAssert(gpu::Semaphore::create(m_device), + "Failed to create " + "present wait semaphore"), + .render_cmb = TryAssert(m_command_pool->create_command_buffer(), + "Failed to create transition " + "command buffers"), }); } }); @@ -90,56 +78,44 @@ class Application: public base::Application { const auto& images = m_swapchain->images(); const auto image_count = stdr::size(images); - auto transition_cmbs = m_command_pool->create_command_buffers(image_count) - .transform_error(monadic::assert("Failed to create transition command buffers")) - .value(); + auto transition_cmbs = TryAssert(m_command_pool->create_command_buffers(image_count), + "Failed to create transition command buffers"); m_image_resources.reserve(stdr::size(images)); auto image_index = 0u; for (const auto& swap_image : images) { - auto view = gpu::ImageView::create(m_device, swap_image) - .transform_error(core::monadic::assert("Failed to create swapchain image view")) - .value(); - auto framebuffer = m_render_pass->create_frame_buffer(m_device, window_extent, to_refs(view)) - .transform_error(core::monadic::assert(std::format("Failed to create framebuffer for image {}", - image_index))) - .value(); - - m_image_resources.push_back({ - .image = as_ref(swap_image), - .view = std::move(view), - .framebuffer = std::move(framebuffer), - .render_finished = gpu::Semaphore::create(m_device) - .transform_error(core::monadic::assert("Failed to create render " - "signal semaphore")) - .value(), - }); + auto view = TryAssert(gpu::ImageView::create(m_device, swap_image), "Failed to create swapchain image view"); + + m_image_resources + .push_back({ .image = as_ref(swap_image), + .view = std::move(view), + .render_finished = TryAssert(gpu::Semaphore::create(m_device), + "Failed to create render " + "signal semaphore") }); auto& transition_cmb = transition_cmbs[image_index]; - auto _ = *transition_cmb.begin(true) - .transform_error(monadic::assert("Failed to begin texture transition command buffer")) - .value() - ->begin_debug_region(std::format("transition image {}", image_index)) - .transition_image_layout(swap_image, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::PRESENT_SRC) - .end_debug_region() - .end() - .transform_error(monadic::assert("Failed to begin texture transition command " - "buffer")); + TryAssertDiscard(transition_cmb.begin(true), "Failed to begin texture transition command buffer"); + + transition_cmb.begin_debug_region(std::format("transition image {}", image_index)) + .transition_image_layout(swap_image, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::PRESENT_SRC) + .end_debug_region(); + + TryAssertDiscard(transition_cmb.end(), + "Failed to begin texture transition command " + "buffer"); ++image_index; } - const auto fence = gpu::Fence::create(m_device) - .transform_error(monadic::assert("Failed to create transition fence")) - .value(); + + const auto fence = TryAssert(gpu::Fence::create(m_device), "Failed to create transition fence"); const auto cmbs = to_refs(transition_cmbs); - m_raster_queue->submit({ .command_buffers = cmbs }, as_ref(fence)) - .transform_error(monadic::assert("Failed to submit texture transition command buffers")) - .value(); + TryAssert(m_raster_queue->submit({ .command_buffers = cmbs }, as_ref(fence)), + "Failed to submit texture transition command buffers"); // wait for transition to be done - auto _ = fence.wait().transform_error(monadic::assert()); + TryAssert(fence.wait(), ""); } auto init_imgui() -> void { @@ -149,8 +125,9 @@ class Application: public base::Application { io.DisplaySize.x = m_window->extent().to().width; io.DisplaySize.y = m_window->extent().to().height; + const auto format = to_vk(m_swapchain->pixel_format()); /*const*/ auto init_info = ImGui_ImplVulkan_InitInfo { - .ApiVersion = VK_API_VERSION_1_1, + .ApiVersion = VK_API_VERSION_1_3, .Instance = m_instance->native_handle(), .PhysicalDevice = m_physical_device->native_handle(), .Device = m_device->native_handle(), @@ -162,12 +139,21 @@ class Application: public base::Application { .ImageCount = BUFFERING_COUNT, .PipelineCache = nullptr, .PipelineInfoMain = { - .RenderPass = m_render_pass->native_handle(), - .Subpass = 0, - .MSAASamples = VK_SAMPLE_COUNT_1_BIT, - .PipelineRenderingCreateInfo = {}, + .RenderPass = nullptr, + .Subpass = {}, + .MSAASamples = {}, + .PipelineRenderingCreateInfo = { + .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, + .pNext = nullptr, + .viewMask = 0, + .colorAttachmentCount = 1, + .pColorAttachmentFormats = &format, + .depthAttachmentFormat = {}, + .stencilAttachmentFormat = {} + + }, }, - .UseDynamicRendering = false, + .UseDynamicRendering = true, .Allocator = nullptr, .CheckVkResultFn = [](auto result) static noexcept { @@ -229,54 +215,54 @@ class Application: public base::Application { const auto& wait = submission_resource.image_available; auto& in_flight = submission_resource.in_flight; - const auto acquire_next_image = bind_front(&gpu::SwapChain::acquire_next_image, &*m_swapchain, 100ms, std::cref(wait)); - const auto extract_index = [](auto&& _result) static noexcept { - auto&& [result, _image_index] = _result; - return _image_index; - }; + TryAssert(in_flight.wait(), "Failed to wait in_flight fence"); + in_flight.reset(); - const auto image_index = in_flight.wait() - .transform([&in_flight](auto&&) mutable noexcept { in_flight.reset(); }) - .and_then(acquire_next_image) - .transform(extract_index) - .transform_error(monadic::assert("Failed to acquire next swapchain image")) - .value(); + const auto&& [_, image_index] = TryAssert(m_swapchain->acquire_next_image(100ms, wait), + "Failed to acquire next swapchain image"); const auto& swapchain_image_resource = m_image_resources[image_index]; - const auto& framebuffer = swapchain_image_resource.framebuffer; const auto& signal = swapchain_image_resource.render_finished; static constexpr auto PIPELINE_FLAGS = std::array { gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT }; + const auto window_extent = m_window->extent().to(); + const auto rendering_info = gpu::RenderingInfo { + .render_area = { .x = 0, .y = 0, .width = window_extent.width, .height = window_extent.height }, + .color_attachments = { { .image_view = as_ref(swapchain_image_resource.view), + .layout = gpu::ImageLayout::ATTACHMENT_OPTIMAL, + .clear_value = gpu::ClearColor { .color = RGBColorDef::SILVER } } } + }; + // render in it auto& render_cmb = submission_resource.render_cmb; - render_cmb.reset() - .transform_error(monadic::assert("Failed to reset render command buffer")) - .value() - ->begin() - .transform_error(monadic::assert("Failed to begin render command buffer")) - .value() - ->begin_debug_region("Render imgui") - .begin_render_pass(m_render_pass, framebuffer); + TryAssertDiscard(render_cmb.reset(), "Failed to reset render command buffer"); + TryAssertDiscard(render_cmb.begin(), "Failed to begin render command buffer"); + + render_cmb + .transition_image_layout(swapchain_image_resource.image, + gpu::ImageLayout::PRESENT_SRC, + gpu::ImageLayout::ATTACHMENT_OPTIMAL) + .begin_debug_region("Render imgui") + .begin_rendering(rendering_info); ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), render_cmb.native_handle()); - *render_cmb.end_render_pass() - .end_debug_region() - .end() - .transform_error(monadic::assert("Failed to end render command buffer")) - .value() - ->submit(m_raster_queue, as_refs(wait), PIPELINE_FLAGS, as_refs(signal), as_ref(in_flight)) - .transform_error(monadic::assert("Failed to submit render command buffer")); + render_cmb.end_rendering() + .end_debug_region() + .transition_image_layout(swapchain_image_resource.image, + gpu::ImageLayout::ATTACHMENT_OPTIMAL, + gpu::ImageLayout::PRESENT_SRC); + + TryAssertDiscard(render_cmb.end(), "Failed to end render command buffer"); + TryAssertDiscard(render_cmb.submit(m_raster_queue, as_refs(wait), PIPELINE_FLAGS, as_refs(signal), as_ref(in_flight)), + "Failed to submit render command buffer"); // present it - auto update_current_frame = [this](auto&&) mutable noexcept { - if (++m_current_frame >= BUFFERING_COUNT) m_current_frame = 0; - }; + TryAssertDiscard(m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)), + "Failed to present swapchain image"); - *m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)) - .transform(update_current_frame) - .transform_error(monadic::assert("Failed to present swapchain image")); + if (++m_current_frame >= BUFFERING_COUNT) m_current_frame = 0; } auto deinit() { @@ -287,7 +273,6 @@ class Application: public base::Application { constexpr auto example_name() const noexcept -> std::string_view { return "Imgui"; } private: - DeferInit m_render_pass; DeferInit m_descriptor_pool; std::vector m_submission_resources; std::vector m_image_resources; diff --git a/examples/gpu/textured_cube/src/main.cpp b/examples/gpu/textured_cube/src/main.cpp index b84a8420f..c4362737f 100644 --- a/examples/gpu/textured_cube/src/main.cpp +++ b/examples/gpu/textured_cube/src/main.cpp @@ -10,21 +10,23 @@ import stormkit; import gpu_app; #include +#include #include #include LOGGER("stormkit.examples.gpu.textured_cube"); #ifndef SHADER_DIR - #define SHADER_DIR "." + #define SHADER_DIR "../share/stormkit/shaders/" #endif #ifndef TEXTURE_DIR - #define TEXTURE_DIR "." + #define TEXTURE_DIR "../share/stormkit/textures/" #endif -namespace stdc = std::chrono; -namespace stdr = std::ranges; +namespace stdc = std::chrono; +namespace stdr = std::ranges; +namespace stdfs = std::filesystem; using clock = stdc::high_resolution_clock; @@ -45,7 +47,6 @@ struct SwapchainImageResource { gpu::ImageView view; gpu::Image depth_image; gpu::ImageView depth_view; - gpu::FrameBuffer framebuffer; gpu::Semaphore render_finished; }; @@ -54,116 +55,120 @@ struct Vertex { math::vec2f uv; static constexpr auto attribute_descriptions() noexcept -> std::array { - return { - gpu::VertexInputAttributeDescription { 0, 0, gpu::PixelFormat::RGB32F, offsetof(Vertex, position) }, - gpu::VertexInputAttributeDescription { 1, 0, gpu::PixelFormat::RG32F, offsetof(Vertex, uv) }, - }; + return to_array({ + { .location = 0, .binding = 0, .format = gpu::PixelFormat::RGB32F, .offset = offsetof(Vertex, position) }, + { .location = 1, .binding = 0, .format = gpu::PixelFormat::RG32F, .offset = offsetof(Vertex, uv) } + }); } static constexpr auto binding_description() noexcept -> gpu::VertexBindingDescription { - return { 0, sizeof(Vertex), gpu::VertexInputRate::VERTEX }; + return { .binding = 0, .stride = sizeof(Vertex), .input_rate = gpu::VertexInputRate::VERTEX }; } }; -static constexpr auto VERTICES = std::array { - Vertex { { -1.f, -1.f, -1.f }, { 2.f / 3.f, 3.f / 4.f } }, // -X side - { { -1.f, -1.f, 1.f }, { 1.f / 3.f, 3.f / 4.f } }, - { { -1.f, 1.f, 1.f }, { 1.f / 3.f, 1.f } }, - { { -1.f, 1.f, 1.f }, { 1.f / 3.f, 1.f } }, - { { -1.f, 1.f, -1.f }, { 2.f / 3.f, 1.f } }, - { { -1.f, -1.f, -1.f }, { 2.f / 3.f, 3.f / 4.f } }, - - { { -1.f, -1.f, -1.f }, { 1.f / 3.f, 2.f / 4.f } }, // -Z side - { { 1.f, 1.f, -1.f }, { 0.f, 1.f / 4.f } }, - { { 1.f, -1.f, -1.f }, { 0.f, 2.f / 4.f } }, - { { -1.f, -1.f, -1.f }, { 1.f / 3.f, 2.f / 4.f } }, - { { -1.f, 1.f, -1.f }, { 1.f / 3.f, 1.f / 4.f } }, - { { 1.f, 1.f, -1.f }, { 0.f, 1.f / 4.f } }, - - { { -1.f, -1.f, -1.f }, { 2.f / 3.f, 2.f / 4.f } }, // -Y side - { { 1.f, -1.f, -1.f }, { 2.f / 3.f, 3.f / 4.f } }, - { { 1.f, -1.f, 1.f }, { 1.f / 3.f, 3.f / 4.f } }, - { { -1.f, -1.f, -1.f }, { 2.f / 3.f, 2.f / 4.f } }, - { { 1.f, -1.f, 1.f }, { 1.f / 3.f, 3.f / 4.f } }, - { { -1.f, -1.f, 1.f }, { 1.f / 3.f, 2.f / 4.f } }, - - { { -1.f, 1.f, -1.f }, { 2.f / 3.f, 0.f } }, // +Y side - { { -1.f, 1.f, 1.f }, { 1.f / 3.f, 0.f } }, - { { 1.f, 1.f, 1.f }, { 1.f / 3.f, 1.f / 4.f } }, - { { -1.f, 1.f, -1.f }, { 2.f / 3.f, 0.f } }, - { { 1.f, 1.f, 1.f }, { 1.f / 3.f, 1.f / 4.f } }, - { { 1.f, 1.f, -1.f }, { 2.f / 3.f, 1.f / 4.f } }, - - { { 1.f, 1.f, -1.f }, { 2.f / 3.f, 1.f / 4.f } }, // +X side - { { 1.f, 1.f, 1.f }, { 1.f / 3.f, 1.f / 4.f } }, - { { 1.f, -1.f, 1.f }, { 1.f / 3.f, 2.f / 4.f } }, - { { 1.f, -1.f, 1.f }, { 1.f / 3.f, 2.f / 4.f } }, - { { 1.f, -1.f, -1.f }, { 2.f / 3.f, 2.f / 4.f } }, - { { 1.f, 1.f, -1.f }, { 2.f / 3.f, 1.f / 4.f } }, - - { { -1.f, 1.f, 1.f }, { 2.f / 3.f, 1.f / 4.f } }, // +Z side - { { -1.f, -1.f, 1.f }, { 2.f / 3.f, 2.f / 4.f } }, - { { 1.f, 1.f, 1.f }, { 1.f, 1.f / 4.f } }, - { { -1.f, -1.f, 1.f }, { 2.f / 3.f, 2.f / 4.f } }, - { { 1.f, -1.f, 1.f }, { 1.f, 2.f / 4.f } }, - { { 1.f, 1.f, 1.f }, { 1.f, 1.f / 4.f } }, -}; - struct ViewerData { math::mat4f proj; math::mat4f view; math::mat4f model; static constexpr auto layout_binding() -> gpu::DescriptorSetLayoutBinding { - return { 0, gpu::DescriptorType::UNIFORM_BUFFER, gpu::ShaderStageFlag::VERTEX, 1 }; + return { .binding = 0, + .type = gpu::DescriptorType::UNIFORM_BUFFER, + .stages = gpu::ShaderStageFlag::VERTEX, + .descriptor_count = 1 }; } }; -static constexpr auto VERTICES_SIZE = sizeof(Vertex) * stdr::size(VERTICES); +namespace { + const auto SHADER = stdfs::path { SHADER_DIR } / "textured_cube.spv"; + const auto TEXTURE = stdfs::path { TEXTURE_DIR } / "cube.png"; + constexpr auto VERTICES = std::array { + Vertex { { -1.f, -1.f, -1.f }, { 2.f / 3.f, 3.f / 4.f } }, // -X side + { { -1.f, -1.f, 1.f }, { 1.f / 3.f, 3.f / 4.f } }, + { { -1.f, 1.f, 1.f }, { 1.f / 3.f, 1.f } }, + { { -1.f, 1.f, 1.f }, { 1.f / 3.f, 1.f } }, + { { -1.f, 1.f, -1.f }, { 2.f / 3.f, 1.f } }, + { { -1.f, -1.f, -1.f }, { 2.f / 3.f, 3.f / 4.f } }, + + { { -1.f, -1.f, -1.f }, { 1.f / 3.f, 2.f / 4.f } }, // -Z side + { { 1.f, 1.f, -1.f }, { 0.f, 1.f / 4.f } }, + { { 1.f, -1.f, -1.f }, { 0.f, 2.f / 4.f } }, + { { -1.f, -1.f, -1.f }, { 1.f / 3.f, 2.f / 4.f } }, + { { -1.f, 1.f, -1.f }, { 1.f / 3.f, 1.f / 4.f } }, + { { 1.f, 1.f, -1.f }, { 0.f, 1.f / 4.f } }, + + { { -1.f, -1.f, -1.f }, { 2.f / 3.f, 2.f / 4.f } }, // -Y side + { { 1.f, -1.f, -1.f }, { 2.f / 3.f, 3.f / 4.f } }, + { { 1.f, -1.f, 1.f }, { 1.f / 3.f, 3.f / 4.f } }, + { { -1.f, -1.f, -1.f }, { 2.f / 3.f, 2.f / 4.f } }, + { { 1.f, -1.f, 1.f }, { 1.f / 3.f, 3.f / 4.f } }, + { { -1.f, -1.f, 1.f }, { 1.f / 3.f, 2.f / 4.f } }, + + { { -1.f, 1.f, -1.f }, { 2.f / 3.f, 0.f } }, // +Y side + { { -1.f, 1.f, 1.f }, { 1.f / 3.f, 0.f } }, + { { 1.f, 1.f, 1.f }, { 1.f / 3.f, 1.f / 4.f } }, + { { -1.f, 1.f, -1.f }, { 2.f / 3.f, 0.f } }, + { { 1.f, 1.f, 1.f }, { 1.f / 3.f, 1.f / 4.f } }, + { { 1.f, 1.f, -1.f }, { 2.f / 3.f, 1.f / 4.f } }, + + { { 1.f, 1.f, -1.f }, { 2.f / 3.f, 1.f / 4.f } }, // +X side + { { 1.f, 1.f, 1.f }, { 1.f / 3.f, 1.f / 4.f } }, + { { 1.f, -1.f, 1.f }, { 1.f / 3.f, 2.f / 4.f } }, + { { 1.f, -1.f, 1.f }, { 1.f / 3.f, 2.f / 4.f } }, + { { 1.f, -1.f, -1.f }, { 2.f / 3.f, 2.f / 4.f } }, + { { 1.f, 1.f, -1.f }, { 2.f / 3.f, 1.f / 4.f } }, + + { { -1.f, 1.f, 1.f }, { 2.f / 3.f, 1.f / 4.f } }, // +Z side + { { -1.f, -1.f, 1.f }, { 2.f / 3.f, 2.f / 4.f } }, + { { 1.f, 1.f, 1.f }, { 1.f, 1.f / 4.f } }, + { { -1.f, -1.f, 1.f }, { 2.f / 3.f, 2.f / 4.f } }, + { { 1.f, -1.f, 1.f }, { 1.f, 2.f / 4.f } }, + { { 1.f, 1.f, 1.f }, { 1.f, 1.f / 4.f } }, + }; -static constexpr auto BUFFERING_COUNT = 2; + constexpr auto VERTICES_SIZE = sizeof(Vertex) * stdr::size(VERTICES); + constexpr auto BUFFERING_COUNT = 2; + constexpr auto POOL_SIZES = to_array({ + { + .type = gpu::DescriptorType::UNIFORM_BUFFER, + .descriptor_count = BUFFERING_COUNT, + }, + { + .type = gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, + .descriptor_count = BUFFERING_COUNT, + } + }); + + constexpr auto OFFSETS = std::array { 0_u64 }; + constexpr auto PIPELINE_FLAGS = std::array { gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT }; +} // namespace class Application: public base::Application { public: auto init_example() { - static constexpr auto POOL_SIZES = std::array { - gpu::DescriptorPool::Size { - .type = gpu::DescriptorType::UNIFORM_BUFFER, - .descriptor_count = BUFFERING_COUNT, - }, - gpu::DescriptorPool::Size { .type = gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, .descriptor_count = BUFFERING_COUNT } - }; - m_descriptor_pool = gpu::DescriptorPool::create(m_device, POOL_SIZES, BUFFERING_COUNT * 2) - .transform_error(monadic::assert("Failed to create descriptor pool")) - .value(); + m_descriptor_pool = TryAssert(gpu::DescriptorPool::create(m_device, POOL_SIZES, BUFFERING_COUNT * 2), + "Failed to create descriptor pool"); // load shaders - m_vertex_shader = gpu::Shader::load_from_file(m_device, - SHADER_DIR "/shaders/textured_cube.spv", - gpu::ShaderStageFlag::VERTEX) - .transform_error(monadic::assert(std::format("Failed to load vertex shader {}", - SHADER_DIR "/shaders/textured_cube.spv"))) - .value(); - - m_fragment_shader = gpu::Shader::load_from_file(m_device, - SHADER_DIR "/shaders/textured_cube.spv", - gpu::ShaderStageFlag::FRAGMENT) - .transform_error(monadic::assert(std::format("Failed to load fragment shader {}", - SHADER_DIR "/shaders/textured_cube.spv"))) - .value(); - - m_descriptor_set_layout = gpu::DescriptorSetLayout::create(m_device, - into_dyn_array(ViewerData::layout_binding(), - gpu::DescriptorSetLayoutBinding { - 1, - gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, - gpu::ShaderStageFlag::FRAGMENT, - 1 })) - .transform_error(monadic::assert("Failed to create descriptor set layout")) - .value(); - m_pipeline_layout = gpu::PipelineLayout::create(m_device, { .descriptor_set_layouts = to_refs(m_descriptor_set_layout) }) - .transform_error(monadic::assert("Failed to create pipeline layout")) - .value(); + m_vertex_shader = TryAssert(gpu::Shader::load_from_file(m_device, SHADER, gpu::ShaderStageFlag::VERTEX), + std::format("Failed to load vertex shader {}", SHADER.string())); + + m_fragment_shader = TryAssert(gpu::Shader::load_from_file(m_device, SHADER, gpu::ShaderStageFlag::FRAGMENT), + std::format("Failed to load fragment shader {}", SHADER.string())); + + m_descriptor_set_layout = TryAssert(gpu::DescriptorSetLayout:: + create(m_device, + into_dyn_array(ViewerData::layout_binding(), + gpu::DescriptorSetLayoutBinding { + 1, + gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, + gpu::ShaderStageFlag::FRAGMENT, + 1 })), + "Failed to create descriptor set layout"); + + m_pipeline_layout = TryAssert(gpu::PipelineLayout::create(m_device, + { .descriptor_set_layouts = to_refs(m_descriptor_set_layout) }), + "Failed to create pipeline layout"); // initialize render pass const auto depth_format = [this] { const auto formats_properties = m_physical_device->formats_properties(); @@ -192,20 +197,6 @@ class Application: public base::Application { return flag; }(); - m_render_pass - = gpu::RenderPass:: - create(m_device, - { .attachments = { { - .format = m_swapchain->pixel_format(), - }, { - .format = depth_format, - .destination_layout = gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL - }}, - .subpasses = { gpu::Subpass{ .bind_point = gpu::PipelineBindPoint::GRAPHICS, - .color_attachment_refs = { { .attachment_id = 0u }, }, .depth_attachment_ref = gpu::Subpass::Ref{.attachment_id = 1u, .layout = gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL, }, }, }, }) - .transform_error(monadic::assert("Failed to create render pass")) - .value(); - // initialize render pipeline const auto window_extent = m_window->extent(); const auto window_viewport = gpu::Viewport { @@ -219,62 +210,57 @@ class Application: public base::Application { }; const auto state = gpu::RasterPipelineState { - .input_assembly_state = { .topology = gpu::PrimitiveTopology::TRIANGLE_LIST, }, - .viewport_state = { .viewports = { window_viewport }, - .scissors = { scissor }, }, - .rasterization_state = { - .cull_mode = gpu::CullModeFlag::BACK, - .front_face = gpu::FrontFace::CLOCKWISE, - }, - .color_blend_state - = { .attachments = { { .blend_enable = true, - .src_color_blend_factor = gpu::BlendFactor::SRC_ALPHA, - .dst_color_blend_factor = gpu::BlendFactor::ONE_MINUS_SRC_ALPHA, - .src_alpha_blend_factor = gpu::BlendFactor::SRC_ALPHA, - .dst_alpha_blend_factor = gpu::BlendFactor::ONE_MINUS_SRC_ALPHA, - .alpha_blend_operation = gpu::BlendOperation::ADD, }, }, }, - .shader_state = to_refs(m_vertex_shader, m_fragment_shader), - .vertex_input_state = { - .binding_descriptions = into_dyn_array(Vertex::binding_description()), - .input_attribute_descriptions = to_dyn_array(Vertex::attribute_descriptions()), - }, - .depth_stencil_state = { - .depth_test_enable = true, - .depth_write_enable = true - }, - }; + .input_assembly_state = { .topology = gpu::PrimitiveTopology::TRIANGLE_LIST, }, + .viewport_state = { .viewports = { window_viewport }, + .scissors = { scissor }, }, + .rasterization_state = { + .cull_mode = gpu::CullModeFlag::BACK, + .front_face = gpu::FrontFace::CLOCKWISE, + }, + .color_blend_state + = { .attachments = { { .blend_enable = true, + .src_color_blend_factor = gpu::BlendFactor::SRC_ALPHA, + .dst_color_blend_factor = gpu::BlendFactor::ONE_MINUS_SRC_ALPHA, + .src_alpha_blend_factor = gpu::BlendFactor::SRC_ALPHA, + .dst_alpha_blend_factor = gpu::BlendFactor::ONE_MINUS_SRC_ALPHA, + .alpha_blend_operation = gpu::BlendOperation::ADD, }, }, }, + .shader_state = to_refs(m_vertex_shader, m_fragment_shader), + .vertex_input_state = { + .binding_descriptions = into_dyn_array(Vertex::binding_description()), + .input_attribute_descriptions = to_dyn_array(Vertex::attribute_descriptions()), + }, + .depth_stencil_state = { + .depth_test_enable = true, + .depth_write_enable = true + }, + }; + + const auto rendering_info = gpu::RasterPipelineRenderingInfo { + .color_attachment_formats = { m_swapchain->pixel_format() }, + .depth_attachment_format = depth_format, + }; - m_pipeline = gpu::Pipeline::create(m_device, state, m_pipeline_layout, m_render_pass) - .transform_error(monadic::assert("Failed to create raster pipeline")) - .value(); + m_pipeline = TryAssert(gpu::Pipeline::create(m_device, state, m_pipeline_layout, rendering_info), + "Failed to create raster pipeline"); // load texture auto image = image::Image {}; - image.load_from_file(TEXTURE_DIR "/textures/cube.png") - .transform_error(monadic::assert(std::format("Failed to load texture file {}", TEXTURE_DIR "/textures/cube.png"))) - .value(); - - m_texture = gpu::Image::create(m_device, - { .extent = image.extent(), - .format = gpu::PixelFormat::RGBA8_UNORM, - .usages = gpu::ImageUsageFlag::SAMPLED | gpu::ImageUsageFlag::TRANSFER_DST, - .property = gpu::MemoryPropertyFlag::DEVICE_LOCAL }) - .transform_error(monadic::assert("Failed to allocate texture")) - .value(); - - { - auto staging_buffer = gpu::Buffer::create(m_device, - { .usages = gpu::BufferUsageFlag::TRANSFER_SRC, .size = image.size() }) - .transform_error(monadic::assert("Failed to allocate gpu texture staging buffer")) - .value(); + TryAssert(image.load_from_file(TEXTURE), std::format("Failed to load texture file {}", TEXTURE.string())); - staging_buffer.upload(image.data()) - .transform_error(monadic::assert("Failed to upload texture data to staging buffer")) - .value(); + m_texture = TryAssert(gpu::Image::create(m_device, + { .extent = image.extent(), + .format = gpu::PixelFormat::RGBA8_UNORM, + .usages = gpu::ImageUsageFlag::SAMPLED | gpu::ImageUsageFlag::TRANSFER_DST, + .property = gpu::MemoryPropertyFlag::DEVICE_LOCAL }), + "Failed to allocate texture"); - auto cpy_fence = gpu::Fence::create(m_device) - .transform_error(monadic::assert("Failed to create copy texture buffer fence")) - .value(); + { + auto cpy_fence = TryAssert(gpu::Fence::create(m_device), "Failed to create copy texture buffer fence"); + auto staging_buffer = TryAssert(gpu::Buffer::create(m_device, + { .usages = gpu::BufferUsageFlag::TRANSFER_SRC, + .size = image.size() }), + "Failed to allocate gpu texture staging buffer"); + TryAssert(staging_buffer.upload(image.data()), "Failed to upload texture data to staging buffer"); const auto copy = { gpu::BufferImageCopy { @@ -285,68 +271,44 @@ class Application: public base::Application { .offset = {}, .extent = image.extent() } }; - auto copy_cmb = m_command_pool->create_command_buffer() - .transform_error(monadic::assert("Failed to allocate copy texture buffer " - "commandbuffer")) - .value(); - - copy_cmb.begin() - .transform_error(monadic::assert("Failed to begin texture upload command buffer")) - .value() - ->begin_debug_region("Upload texture data") + auto copy_cmb = TryAssert(m_command_pool->create_command_buffer(), "Failed to allocate copy texture buffer"); + + TryAssert(copy_cmb.begin(), "Failed to begin texture upload command buffer"); + + copy_cmb.begin_debug_region("Upload texture data") .transition_image_layout(m_texture, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::TRANSFER_DST_OPTIMAL) .copy_buffer_to_image(staging_buffer, m_texture, as_view(copy)) .transition_image_layout(m_texture, gpu::ImageLayout::TRANSFER_DST_OPTIMAL, gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL) - .end_debug_region() - .end() - .transform_error(monadic::assert("Failed to end texture upload command buffer")) - .value() - ->submit(m_raster_queue, {}, {}, {}, as_ref(cpy_fence)) - .transform_error(monadic::assert("Failed to submit texture upload command buffer")) - .value(); - - auto _ = cpy_fence.wait().transform_error(monadic::assert()); - } + .end_debug_region(); - m_texture_view = gpu::ImageView::create(m_device, m_texture) - .transform_error(monadic::assert("Failed to create texture view")) - .value(); + TryAssertDiscard(copy_cmb.end(), "Failed to end texture upload command buffer"); + TryAssertDiscard(copy_cmb.submit(m_raster_queue, {}, {}, {}, as_ref(cpy_fence)), + "Failed to submit texture upload command buffer"); - m_sampler = gpu::Sampler::create(m_device, {}).transform_error(monadic::assert("Failed to create sampler")).value(); + TryAssertDiscard(cpy_fence.wait(), "Failed to create texture view"); + } - // create present engine resources + m_texture_view = TryAssert(gpu::ImageView::create(m_device, m_texture), "Failed to create texture view"); + m_sampler = TryAssert(gpu::Sampler::create(m_device, {}), "Failed to create sampler"); m_submission_resources = std::vector {}; m_submission_resources.reserve(BUFFERING_COUNT); for (auto _ : range(BUFFERING_COUNT)) { - m_submission_resources.push_back({ - .in_flight = gpu::Fence::create_signaled(m_device) - .transform_error(core::monadic::assert("Failed to create swapchain image " - "in flight fence")) - .value(), - .image_available = gpu::Semaphore::create(m_device) - .transform_error(core::monadic::assert("Failed to create present " - "wait semaphore")) - .value(), - .render_cmb = m_command_pool->create_command_buffer() - .transform_error(monadic::assert("Failed to create " - "transition command " - "buffers")) - .value(), - .viewer_buffer = gpu::Buffer::create(m_device, - { - .usages = gpu::BufferUsageFlag::UNIFORM, - .size = sizeof(ViewerData), - }, - true) - .transform_error(monadic::assert("Failed to allocate gpu viewer buffer")) - .value(), - .descriptor_set = m_descriptor_pool->create_descriptor_set(m_descriptor_set_layout) - .transform_error(monadic::assert("Failed to create descriptor set")) - .value(), - }); + m_submission_resources + .push_back({ .in_flight = TryAssert(gpu::Fence::create_signaled(m_device), "Failed to create swapchain image"), + .image_available = TryAssert(gpu::Semaphore::create(m_device), "Failed to create present image"), + .render_cmb = TryAssert(m_command_pool->create_command_buffer(), "Failed to create buffers"), + .viewer_buffer = TryAssert(gpu::Buffer::create(m_device, + { + .usages = gpu::BufferUsageFlag::UNIFORM, + .size = sizeof(ViewerData), + }, + true), + "Failed to allocate gpu viewer buffer"), + .descriptor_set = TryAssert(m_descriptor_pool->create_descriptor_set(m_descriptor_set_layout), + "Failed to create descriptor set") }); auto& res = m_submission_resources.back(); const auto sets = std::array { gpu::BufferDescriptor { @@ -368,128 +330,99 @@ class Application: public base::Application { const auto& images = m_swapchain->images(); const auto image_count = stdr::size(images); - auto transition_cmbs = m_command_pool->create_command_buffers(image_count) - .transform_error(monadic::assert("Failed to create transition command buffers")) - .value(); + auto transition_cmbs = TryAssert(m_command_pool->create_command_buffers(image_count), + "Failed to create transition command buffers"); m_image_resources = std::vector {}; m_image_resources.reserve(stdr::size(images)); auto image_index = 0u; for (const auto& swap_image : images) { - auto view = gpu::ImageView::create(m_device, swap_image) - .transform_error(core::monadic::assert("Failed to create swapchain image view")) - .value(); - - auto depth_image = gpu::Image::create(m_device, - gpu::Image::CreateInfo { - .extent = swap_image.extent(), - .format = depth_format, - .usages = gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT, - .property = gpu::MemoryPropertyFlag::DEVICE_LOCAL }) - .transform_error(core::monadic::assert("Failed to create depth image")) - .value(); - - auto depth_view = gpu::ImageView::create(m_device, - depth_image, - gpu::ImageViewType::T2D, - { .aspect_mask = depth_aspect_flag }) - .transform_error(core::monadic::assert("Failed to create depth image view")) - .value(); - - auto framebuffer = m_render_pass->create_frame_buffer(m_device, window_extent, to_refs(view, depth_view)) - .transform_error(core::monadic::assert(std::format("Failed to create framebuffer for image {}", - image_index))) - .value(); - - m_image_resources.push_back({ - .image = as_ref(swap_image), - .view = std::move(view), - .depth_image = std::move(depth_image), - .depth_view = std::move(depth_view), - .framebuffer = std::move(framebuffer), - .render_finished = gpu::Semaphore::create(m_device) - .transform_error(core::monadic::assert("Failed to create render " - "signal semaphore")) - .value(), - }); + auto view = TryAssert(gpu::ImageView::create(m_device, swap_image), "Failed to create swapchain image view"); + auto depth_image = TryAssert(gpu::Image::create(m_device, + gpu::Image::CreateInfo { + .extent = swap_image.extent(), + .format = depth_format, + .usages = gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT, + .property = gpu::MemoryPropertyFlag::DEVICE_LOCAL }), + "Failed to create depth image"); + + auto depth_view = TryAssert(gpu::ImageView::create(m_device, + depth_image, + gpu::ImageViewType::T2D, + { .aspect_mask = depth_aspect_flag }), + "Failed to create depth image view"); + + m_image_resources + .push_back({ .image = as_ref(swap_image), + .view = std::move(view), + .depth_image = std::move(depth_image), + .depth_view = std::move(depth_view), + .render_finished = TryAssert(gpu::Semaphore::create(m_device), "Failed to create render") }); const auto& resources = m_image_resources.back(); auto& transition_cmb = transition_cmbs[image_index]; - *transition_cmb.begin(true) - .transform_error(monadic::assert("Failed to begin texture transition command buffer")) - .value() - ->begin_debug_region(std::format("transition image {}", image_index)) - .transition_image_layout(swap_image, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::PRESENT_SRC) - .transition_image_layout(resources.depth_image, - gpu::ImageLayout::UNDEFINED, - gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - { .aspect_mask = depth_aspect_flag }) - .end_debug_region() - .end() - .transform_error(monadic::assert("Failed to begin texture transition command buffer")) - .transform(monadic::discard()); + TryAssertDiscard(transition_cmb.begin(true), "Failed to begin texture transition command buffer"); + + transition_cmb.begin_debug_region(std::format("transition image {}", image_index)) + .transition_image_layout(swap_image, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::PRESENT_SRC) + .transition_image_layout(resources.depth_image, + gpu::ImageLayout::UNDEFINED, + gpu::ImageLayout::ATTACHMENT_OPTIMAL, + { .aspect_mask = depth_aspect_flag }) + .end_debug_region(); + + TryAssertDiscard(transition_cmb.end(), "Failed to begin texture transition command buffer"); ++image_index; } - const auto fence = gpu::Fence::create(m_device) - .transform_error(monadic::assert("Failed to create transition fence")) - .value(); + const auto fence = TryAssert(gpu::Fence::create(m_device), "Failed to create transition fence"); const auto cmbs = to_refs(transition_cmbs); - m_raster_queue->submit({ .command_buffers = cmbs }, as_ref(fence)) - .transform_error(monadic::assert("Failed to submit texture transition command buffers")) - .value(); + TryAssertDiscard(m_raster_queue->submit({ .command_buffers = cmbs }, as_ref(fence)), + "Failed to submit texture transition command buffers"); // setup vertex buffer - m_vertex_buffer = gpu::Buffer::create(m_device, - { .usages = gpu::BufferUsageFlag::VERTEX | gpu::BufferUsageFlag::TRANSFER_DST, - .size = VERTICES_SIZE, - .property = gpu::MemoryPropertyFlag::DEVICE_LOCAL }) - .transform_error(monadic::assert("Failed to allocate gpu vertex buffer")) - .value(); + m_vertex_buffer = TryAssert(gpu::Buffer::create(m_device, + { .usages = gpu::BufferUsageFlag::VERTEX + | gpu::BufferUsageFlag::TRANSFER_DST, + .size = VERTICES_SIZE, + .property = gpu::MemoryPropertyFlag::DEVICE_LOCAL }), + "Failed to allocate gpu vertex buffer"); { - auto staging_buffer = gpu::Buffer::create(m_device, - { .usages = gpu::BufferUsageFlag::TRANSFER_SRC, .size = VERTICES_SIZE }) - .transform_error(monadic::assert("Failed to allocate gpu vertex staging buffer")) - .value(); - - staging_buffer.upload(VERTICES) - .transform_error(monadic::assert("Failed to upload vertex data to staging buffer")) - .value(); - - auto cpy_fence = gpu::Fence::create(m_device) - .transform_error(monadic::assert("Failed to create copy vertex buffer fence")) - .value(); - - auto copy_cmb = m_command_pool->create_command_buffer() - .transform_error(monadic::assert("Failed to allocate copy vertex buffer " - "commandbuffer")) - .value(); - - copy_cmb.begin() - .transform_error(monadic::assert("Failed to begin vertices upload command buffer")) - .value() - ->begin_debug_region("Upload vertex data to vertex buffer") + auto staging_buffer = TryAssert(gpu::Buffer::create(m_device, + { .usages = gpu::BufferUsageFlag::TRANSFER_SRC, + .size = VERTICES_SIZE }), + "Failed to allocate gpu vertex staging buffer"); + + TryAssert(staging_buffer.upload(VERTICES), "Failed to upload vertex data to staging buffer"); + + auto cpy_fence = TryAssert(gpu::Fence::create(m_device), "Failed to create copy vertex buffer fence"); + + auto copy_cmb = TryAssert(m_command_pool->create_command_buffer(), "Failed to allocate copy vertex buffer"); + TryAssert(copy_cmb.begin(), "Failed to begin vertices upload command buffer"); + + copy_cmb.begin_debug_region("Upload vertex data to vertex buffer") .copy_buffer(staging_buffer, m_vertex_buffer, VERTICES_SIZE) - .end_debug_region() - .end() - .transform_error(monadic::assert("Failed to begin vertices upload command buffer")) - .value() - ->submit(m_raster_queue, {}, {}, {}, as_ref(cpy_fence)); + .end_debug_region(); - auto _ = cpy_fence.wait().transform_error(monadic::assert()); + TryAssertDiscard(copy_cmb.end(), "Failed to begin vertices upload command buffer"); + TryAssertDiscard(copy_cmb.submit(m_raster_queue, {}, {}, {}, as_ref(cpy_fence)), + "Failed to submit vertices upload command buffer"); + TryAssert(cpy_fence.wait(), "Failed to acquire next swapchain image"); } - // wait for transition to be done - auto _ = fence.wait().transform_error(monadic::assert()); + TryAssert(fence.wait(), ""); } auto run_example() { - using SecondF = stdc::duration; + LOG_MODULE.flush(); + + const auto current_time = clock::now(); + const auto window_extent = m_window->extent(); const auto window_extent_f32 = window_extent.to(); auto viewer_data = ViewerData { @@ -497,9 +430,6 @@ class Application: public base::Application { .view = math::look_at(math::vec3f { 0.f, 3.f, 5.f }, { 0.f, 0.f, 0.f }, { 0.f, 1.f, 0.f }), .model = math::mat4f::identity(), }; - LOG_MODULE.flush(); - - const auto current_time = clock::now(); // get next swapchain image auto& submission_resource = m_submission_resources[m_current_frame]; @@ -507,73 +437,64 @@ class Application: public base::Application { const auto& wait = submission_resource.image_available; auto& in_flight = submission_resource.in_flight; - const auto acquire_next_image = bind_front(&gpu::SwapChain::acquire_next_image, &*m_swapchain, 100ms, std::cref(wait)); - const auto extract_index = [](auto&& _result) static noexcept { - auto&& [result, _image_index] = _result; - return _image_index; - }; + TryAssert(in_flight.wait(), "Failed to wait in_flight fence"); + in_flight.reset(); - const auto image_index = in_flight.wait() - .transform([&in_flight](auto&&) noexcept { in_flight.reset(); }) - .and_then(acquire_next_image) - .transform(extract_index) - .transform_error(monadic::assert("Failed to acquire next swapchain image")) - .value(); + const auto&& [_, image_index] = TryAssert(m_swapchain->acquire_next_image(100ms, wait), + "Failed to acquire next swapchain image"); const auto& swapchain_image_resource = m_image_resources[image_index]; - const auto& framebuffer = swapchain_image_resource.framebuffer; const auto& signal = swapchain_image_resource.render_finished; // update viewer data and upload - const auto time = stdc::duration_cast(current_time - m_start_time).count(); + const auto time = stdc::duration_cast(current_time - m_start_time).count(); viewer_data.model = math::rotate(math::mat4f::identity(), time * math::radians(90.f), math::vec3f { 0.f, 1.f, 0.f }); auto& viewer_buffer = submission_resource.viewer_buffer; viewer_buffer.upload(viewer_data); + const auto rendering_info = gpu::RenderingInfo { + .render_area = { .x = 0, .y = 0, .width = window_extent.to().width, .height = window_extent.to().height }, + .color_attachments = { { .image_view = as_ref(swapchain_image_resource.view), + .layout = gpu::ImageLayout::ATTACHMENT_OPTIMAL, + .clear_value = gpu::ClearColor { .color = RGBColorDef::SILVER } } }, + .depth_attachment = { { .image_view = as_ref(swapchain_image_resource.depth_view), + .layout = gpu::ImageLayout::ATTACHMENT_OPTIMAL, + .clear_value = gpu::ClearDepthStencil {} } } + }; + // render in it auto& render_cmb = submission_resource.render_cmb; const auto& descriptor_set = submission_resource.descriptor_set; - static constexpr auto CLEAR_VALUES = std::array { - gpu::ClearColor { .color = RGBColorDef::SILVER }, - gpu::ClearDepthStencil {} - }; - static constexpr auto OFFSETS = std::array { 0_u64 }; - static constexpr auto PIPELINE_FLAGS = std::array { gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT }; - - render_cmb.reset() - .transform_error(monadic::assert("Failed to reset render command buffer")) - .value() - ->begin() - .transform_error(monadic::assert("Failed to begin render command buffer")) - .value() - ->begin_debug_region("Render textured cube") - .begin_render_pass(m_render_pass, framebuffer, CLEAR_VALUES) + TryAssertDiscard(render_cmb.reset(), "Failed to reset render command buffer"); + TryAssertDiscard(render_cmb.begin(), "Failed to begin render command buffer"); + + render_cmb + .transition_image_layout(swapchain_image_resource.image, + gpu::ImageLayout::PRESENT_SRC, + gpu::ImageLayout::ATTACHMENT_OPTIMAL) + .begin_debug_region("Render textured cube") + .begin_rendering(rendering_info) .bind_pipeline(m_pipeline) .bind_vertex_buffers(to_refs(m_vertex_buffer), OFFSETS) .bind_descriptor_sets(m_pipeline, m_pipeline_layout, as_refs(descriptor_set), {}) .draw(stdr::size(VERTICES)) - .end_render_pass() + .end_rendering() .end_debug_region() - .end() - .transform_error(monadic::assert("Failed to end render command buffer")) - .value() - ->submit(m_raster_queue, as_refs(wait), PIPELINE_FLAGS, as_refs(signal), as_ref(in_flight)) - .transform_error(monadic::assert("Failed to submit render command buffer")) - .value(); + .transition_image_layout(swapchain_image_resource.image, + gpu::ImageLayout::ATTACHMENT_OPTIMAL, + gpu::ImageLayout::PRESENT_SRC); - // present it - auto update_current_frame = [this](auto&&) mutable noexcept { - if (++m_current_frame >= BUFFERING_COUNT) m_current_frame = 0; - }; + TryAssertDiscard(render_cmb.end(), "Failed to end render command buffer"); + TryAssertDiscard(render_cmb.submit(m_raster_queue, as_refs(wait), PIPELINE_FLAGS, as_refs(signal), as_ref(in_flight)), + "Failed to submit render command buffer"); - auto _ = m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)) - .transform(update_current_frame) - .transform_error(monadic::assert("Failed to present swapchain image")); + // present it + TryAssert(m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)), + "Failed to present swapchain image"); - m_raster_queue->wait_idle(); - m_device->wait_idle(); + if (++m_current_frame >= BUFFERING_COUNT) m_current_frame = 0; } constexpr auto example_name() const noexcept -> std::string_view { return "Textured Cube"; } @@ -585,7 +506,6 @@ class Application: public base::Application { DeferInit m_fragment_shader; DeferInit m_descriptor_set_layout; DeferInit m_pipeline_layout; - DeferInit m_render_pass; DeferInit m_pipeline; DeferInit m_texture; DeferInit m_texture_view; diff --git a/examples/gpu/textured_cube/xmake.lua b/examples/gpu/textured_cube/xmake.lua index 93277400f..c3acc4dee 100644 --- a/examples/gpu/textured_cube/xmake.lua +++ b/examples/gpu/textured_cube/xmake.lua @@ -25,7 +25,11 @@ target("textured_cube", function() add_includedirs("$(builddir)/shaders") - if get_config("devmode") then set_rundir("$(builddir)") end + if get_config("devmode") then + add_defines('TEXTURE_DIR="examples/gpu/textured_cube/textures"') + add_defines('SHADER_DIR="$(builddir)/shaders"') + set_rundir("$(projectdir)") + end set_group("examples/stormkit-gpu") end) diff --git a/examples/gpu/triangle/src/main.cpp b/examples/gpu/triangle/src/main.cpp index 01176d0bb..13f5a7437 100644 --- a/examples/gpu/triangle/src/main.cpp +++ b/examples/gpu/triangle/src/main.cpp @@ -16,7 +16,7 @@ import gpu_app; LOGGER("stormkit.examples.gpu.triangle"); #ifndef SHADER_DIR - #define SHADER_DIR "." + #define SHADER_DIR "../share/stormkit/shaders/" #endif namespace stdr = std::ranges; @@ -37,21 +37,20 @@ struct SwapchainImageResource { gpu::Semaphore render_finished; }; -static constexpr auto BUFFERING_COUNT = 2; +namespace { + constexpr auto BUFFERING_COUNT = 2; + const auto SHADER = stdfs::path { SHADER_DIR } / "triangle.spv"; +} // namespace class Application: public base::Application { public: auto init_example() { // load shaders - m_vertex_shader = TryAssert(gpu::Shader::load_from_file(m_device, - SHADER_DIR "/shaders/triangle.spv", - gpu::ShaderStageFlag::VERTEX), - std::format("Failed to load vertex shader {}", SHADER_DIR "/shaders/triangle.spv")); + m_vertex_shader = TryAssert(gpu::Shader::load_from_file(m_device, SHADER, gpu::ShaderStageFlag::VERTEX), + std::format("Failed to load vertex shader {}", SHADER.string())); - m_fragment_shader = TryAssert(gpu::Shader::load_from_file(m_device, - SHADER_DIR "/shaders/triangle.spv", - gpu::ShaderStageFlag::FRAGMENT), - std::format("Failed to load fragment shader {}", SHADER_DIR "/shaders/triangle.spv")); + m_fragment_shader = TryAssert(gpu::Shader::load_from_file(m_device, SHADER, gpu::ShaderStageFlag::FRAGMENT), + std::format("Failed to load fragment shader {}", SHADER.string())); m_pipeline_layout = TryAssert(gpu::PipelineLayout::create(m_device, {}), "Failed to create pipeline layout"); @@ -171,11 +170,6 @@ class Application: public base::Application { static constexpr auto PIPELINE_FLAGS = std::array { gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT }; - // render in it - auto& render_cmb = submission_resource.render_cmb; - TryAssertDiscard(render_cmb.reset(), "Failed to reset render command buffer"); - TryAssertDiscard(render_cmb.begin(), "Failed to begin render command buffer"); - const auto window_extent = m_window->extent().to(); const auto rendering_info = gpu::RenderingInfo { .render_area = { .x = 0, .y = 0, .width = window_extent.width, .height = window_extent.height }, @@ -184,6 +178,11 @@ class Application: public base::Application { .clear_value = gpu::ClearColor { .color = RGBColorDef::SILVER } } } }; + // render in it + auto& render_cmb = submission_resource.render_cmb; + TryAssertDiscard(render_cmb.reset(), "Failed to reset render command buffer"); + TryAssertDiscard(render_cmb.begin(), "Failed to begin render command buffer"); + render_cmb .transition_image_layout(swapchain_image_resource.image, gpu::ImageLayout::PRESENT_SRC, @@ -203,8 +202,8 @@ class Application: public base::Application { "Failed to submit render command buffer"); // present it - TryAssert(m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)), - "Failed to present swapchain image"); + TryAssertDiscard(m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)), + "Failed to present swapchain image"); if (++m_current_frame >= BUFFERING_COUNT) m_current_frame = 0; } diff --git a/examples/gpu/triangle/xmake.lua b/examples/gpu/triangle/xmake.lua index 2e058eb9f..a50ca16c1 100644 --- a/examples/gpu/triangle/xmake.lua +++ b/examples/gpu/triangle/xmake.lua @@ -39,7 +39,10 @@ target("triangle", function() add_includedirs("$(builddir)/shaders") - if get_config("devmode") then set_rundir("$(builddir)") end + if get_config("devmode") then + add_defines('SHADER_DIR="$(builddir)/shaders"') + set_rundir("$(projectdir)") + end add_embeddirs("$(builddir)/shaders") diff --git a/examples/wsi/luau/src/main.cpp b/examples/wsi/luau/src/main.cpp index c01334c14..725bec20a 100644 --- a/examples/wsi/luau/src/main.cpp +++ b/examples/wsi/luau/src/main.cpp @@ -19,9 +19,13 @@ import stormkit.luau; LOGGER("Luau-Events"); #ifndef LUAU_DIR - #define LUAU_DIR "../luau" + #define LUAU_DIR "../share/luau" #endif +namespace stdfs = std::filesystem; + +static const auto LUAU_FILE = stdfs::path { LUAU_DIR } / "events.luau"; + using namespace stormkit; //////////////////////////////////////// @@ -30,7 +34,7 @@ auto main(std::span args) -> int { wsi::parse_args(args); auto logger = log::Logger::create_logger_instance(); - auto engine = luau::Engine::create(LUAU_DIR "/events.luau"); + auto engine = luau::Engine::create(LUAU_FILE); wsi::lua::init_lua(engine.global_namespace()); auto _ = engine.lua_main().transform_error(monadic::assert("lua runtime error!\n-------------------------------\n")); diff --git a/examples/wsi/luau/xmake.lua b/examples/wsi/luau/xmake.lua index 2f0c2b5dc..f8676ba80 100644 --- a/examples/wsi/luau/xmake.lua +++ b/examples/wsi/luau/xmake.lua @@ -25,9 +25,9 @@ if get_config("luau") then if get_config("devmode") then add_defines('LUAU_DIR="$(builddir)/luau"') set_rundir("$(projectdir)") - end - after_build(function(target) os.cp("examples/wsi/luau/luau", "$(builddir)") end) + after_build(function(target) os.cp("examples/wsi/luau/luau", "$(builddir)") end) + end set_group("examples/stormkit-wsi/luau") end) From a955d5f1cf9ac725b709927f7a87ab149f19ce38 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 1 Feb 2026 18:03:17 +0100 Subject: [PATCH 033/194] (gpu) fix some warnings --- src/gpu/core/device.cpp | 71 +++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/src/gpu/core/device.cpp b/src/gpu/core/device.cpp index d2099bb38..505b5d020 100644 --- a/src/gpu/core/device.cpp +++ b/src/gpu/core/device.cpp @@ -23,24 +23,24 @@ namespace stdr = std::ranges; namespace stdv = std::views; namespace { - constexpr auto RAYTRACING_EXTENSIONS = std::array { - VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, - VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, - VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, - VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME, - VK_KHR_SPIRV_1_4_EXTENSION_NAME, - VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME, - VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, - }; - - constexpr auto BASE_EXTENSIONS = std::array { - VK_KHR_MAINTENANCE_3_EXTENSION_NAME, - VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, - // "VK_KHR_maintenance4"sv, "VK_KHR_maintenance5"sv, "VK_KHR_maintenance6"sv - }; - constexpr auto SWAPCHAIN_EXTENSIONS = std::array { - VK_KHR_SWAPCHAIN_EXTENSION_NAME, - }; + constexpr auto RAYTRACING_EXTENSIONS = to_array({ + VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, + VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, + VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, + VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME, + VK_KHR_SPIRV_1_4_EXTENSION_NAME, + VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME, + VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, + }); + + constexpr auto BASE_EXTENSIONS = to_array({ + VK_KHR_MAINTENANCE_3_EXTENSION_NAME, + VK_KHR_MAINTENANCE_4_EXTENSION_NAME, + VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, + }); + constexpr auto SWAPCHAIN_EXTENSIONS = to_array({ + VK_KHR_SWAPCHAIN_EXTENSION_NAME, + }); auto vma_import_functions_from_volk(const VmaAllocatorCreateInfo* pAllocatorCreateInfo, VolkDeviceTable* device_table, @@ -269,22 +269,25 @@ namespace stormkit::gpu { }; }); - const auto& capabilities = m_physical_device->capabilities(); - const auto enabled_1_0_features = VkPhysicalDeviceFeatures { .multiDrawIndirect = true, .samplerAnisotropy = true }; - const auto enabled_1_2_features = VkPhysicalDeviceVulkan12Features { - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, - .pNext = nullptr, - .descriptorIndexing = true, - .descriptorBindingVariableDescriptorCount = true, - .runtimeDescriptorArray = true, - .bufferDeviceAddress = true - }; - const auto enabled_1_3_features = VkPhysicalDeviceVulkan13Features { - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES, - .pNext = std::bit_cast(&enabled_1_2_features), - .synchronization2 = true, - .dynamicRendering = true - }; + // const auto& capabilities = m_physical_device->capabilities(); + const auto enabled_1_0_features = init_by([](auto& out) static noexcept { + out.multiDrawIndirect = true; + out.samplerAnisotropy = true; + }); + const auto enabled_1_2_features = init_by([](auto& out) static noexcept { + out.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES; + out.pNext = nullptr; + out.descriptorIndexing = true; + out.descriptorBindingVariableDescriptorCount = true; + out.runtimeDescriptorArray = true; + out.bufferDeviceAddress = true; + }); + const auto enabled_1_3_features = init_by([&enabled_1_2_features](auto& out) noexcept { + out.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES; + out.pNext = std::bit_cast(&enabled_1_2_features); + out.synchronization2 = true; + out.dynamicRendering = true; + }); const auto device_extensions = m_physical_device->extensions(); From d9885d3bbd2be0271b29ce755ebb7e7155e15e19 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 2 Feb 2026 19:13:00 +0100 Subject: [PATCH 034/194] (core) improve threadpool --- .../stormkit/core/parallelism/threadpool.mpp | 43 ++++++++++--------- src/core/threadpool.cpp | 17 +++++--- 2 files changed, 33 insertions(+), 27 deletions(-) diff --git a/modules/stormkit/core/parallelism/threadpool.mpp b/modules/stormkit/core/parallelism/threadpool.mpp index 3062ea07b..9f8127d28 100644 --- a/modules/stormkit/core/parallelism/threadpool.mpp +++ b/modules/stormkit/core/parallelism/threadpool.mpp @@ -21,10 +21,11 @@ export namespace stormkit { inline namespace core { class STORMKIT_API ThreadPool { public: static constexpr struct NoFutureType { - } NoFuture = {}; + } NO_FUTURE = {}; template - using Callback = std::function; + using Closure = std::function; + // using Closure = std::move_only_function; explicit ThreadPool(u32 worker_count = std::thread::hardware_concurrency() / 2); ~ThreadPool(); @@ -35,15 +36,17 @@ export namespace stormkit { inline namespace core { ThreadPool(ThreadPool&&) noexcept; auto operator=(ThreadPool&&) noexcept -> ThreadPool&; - auto worker_count() const noexcept; + [[nodiscard]] + auto worker_count() const noexcept -> u32; template - auto post_task(Callback callback); + [[nodiscard]] + auto post_task(Closure task) noexcept -> decltype(auto); template - auto post_task(Callback callback, NoFutureType); + auto post_task(Closure task, NoFutureType) noexcept -> void; - auto join_all() -> void; + auto join_all() noexcept -> void; auto set_name(std::string_view name) noexcept -> void; @@ -66,16 +69,16 @@ export namespace stormkit { inline namespace core { }; template - auto post_task(Task::Type type, Callback callback); + auto post_task(Task::Type type, Closure task) noexcept -> decltype(auto); template - auto post_task(Task::Type type, Callback callback, NoFutureType); + auto post_task(Task::Type type, Closure task, NoFutureType) noexcept -> void; auto worker_main() noexcept -> void; u32 m_worker_count = 0; - std::vector m_workers; + std::vector m_workers; mutable std::mutex m_mutex; std::condition_variable m_work_signal; @@ -120,7 +123,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto ThreadPool::worker_count() const noexcept { + inline auto ThreadPool::worker_count() const noexcept -> u32 { return m_worker_count; } @@ -136,30 +139,30 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto ThreadPool::post_task(Callback callback) { - return post_task(Task::Type::Standard, std::move(callback)); + inline auto ThreadPool::post_task(Closure task) noexcept -> decltype(auto) { + return post_task(Task::Type::Standard, std::move(task)); } //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto ThreadPool::post_task(Callback callback, NoFutureType t) { - post_task(Task::Type::Standard, std::move(callback), t); + inline auto ThreadPool::post_task(Closure task, NoFutureType t) noexcept -> void { + auto _ = post_task(Task::Type::Standard, std::move(task), t); } //////////////////////////////////////// //////////////////////////////////////// template - inline auto ThreadPool::post_task(Task::Type type, Callback callback) { - auto packaged_task = std::make_shared>(std::move(callback)); + inline auto ThreadPool::post_task(Task::Type type, Closure closure) noexcept -> decltype(auto) { + auto packaged_task = std::make_shared>(std::move(closure)); auto future = packaged_task->get_future(); - auto task = Task { type, [callback = std::move(packaged_task)]() { (*callback)(); } }; + auto task = Task { type, [task = std::move(packaged_task)]() { (*task)(); } }; { - auto lock = std::unique_lock { m_mutex }; + auto _ = std::unique_lock { m_mutex }; m_tasks.emplace(std::move(task)); } @@ -172,8 +175,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - inline auto ThreadPool::post_task(Task::Type type, Callback callback, NoFutureType) { - auto task = Task { type, [callback = std::move(callback)]() { callback(); } }; + inline auto ThreadPool::post_task(Task::Type type, Closure closure, NoFutureType) noexcept -> void { + auto task = Task { type, [task = std::move(closure)]() { task(); } }; { auto lock = std::unique_lock { m_mutex }; diff --git a/src/core/threadpool.cpp b/src/core/threadpool.cpp index 8e90b2371..2e7bbc525 100644 --- a/src/core/threadpool.cpp +++ b/src/core/threadpool.cpp @@ -6,13 +6,15 @@ module stormkit.core; import std; +namespace stdr = std::ranges; + namespace stormkit { ///////////////////////////////////// ///////////////////////////////////// ThreadPool::ThreadPool(ThreadPool&& other) noexcept { auto lock = std::scoped_lock { other.m_mutex }; - m_worker_count = std::exchange(other.m_worker_count, 0u); + m_worker_count = other.m_worker_count; m_tasks = std::move(other.m_tasks); m_workers.reserve(m_worker_count); @@ -28,13 +30,13 @@ namespace stormkit { if (&other == this) [[unlikely]] return *this; - auto lock1 = std::unique_lock { other.m_mutex, std::defer_lock }; + auto lock1 = std::unique_lock { m_mutex, std::defer_lock }; auto lock2 = std::unique_lock { other.m_mutex, std::defer_lock }; std::lock(lock1, lock2); join_all(); - m_worker_count = std::exchange(other.m_worker_count, 0u); + m_worker_count = other.m_worker_count; m_tasks = std::move(other.m_tasks); m_workers.reserve(m_worker_count); @@ -48,11 +50,12 @@ namespace stormkit { ///////////////////////////////////// ///////////////////////////////////// - auto ThreadPool::join_all() -> void { - for (const auto _ : range(m_worker_count)) post_task(Task::Type::Terminate, [] {}, ThreadPool::NoFuture); + auto ThreadPool::join_all() noexcept -> void { + for (const auto _ : range(m_worker_count)) post_task(Task::Type::Terminate, [] {}, ThreadPool::NO_FUTURE); - for (auto& thread : m_workers) + for (auto& thread : m_workers) { if (thread.joinable()) thread.join(); + } } ///////////////////////////////////// @@ -63,7 +66,7 @@ namespace stormkit { { auto lock = std::unique_lock { m_mutex }; - if (std::empty(m_tasks)) m_work_signal.wait(lock, [this] { return not std::empty(m_tasks); }); + if (stdr::empty(m_tasks)) m_work_signal.wait(lock, [this] { return not std::empty(m_tasks); }); task = std::move(m_tasks.front()); m_tasks.pop(); From 118beed74788c2ce87c6bfec88d8731240ff2352 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 2 Feb 2026 19:13:10 +0100 Subject: [PATCH 035/194] (gpu) update enums.mpp --- modules/stormkit/gpu/core/vulkan/enums.mpp | 5392 ++++++++++---------- 1 file changed, 2740 insertions(+), 2652 deletions(-) diff --git a/modules/stormkit/gpu/core/vulkan/enums.mpp b/modules/stormkit/gpu/core/vulkan/enums.mpp index 00a2c2043..2d840048a 100644 --- a/modules/stormkit/gpu/core/vulkan/enums.mpp +++ b/modules/stormkit/gpu/core/vulkan/enums.mpp @@ -4,8 +4,8 @@ module; -#include #include +#include #include @@ -16,11 +16,10 @@ import stormkit.core; import :vulkan.volk; - export { namespace stormkit::gpu { namespace details { - template + template inline constexpr auto IS_VULKAN_ENUMERATION = false; } @@ -30,768 +29,724 @@ export { } inline constexpr auto QUEUE_FAMILY_IGNORED = std::numeric_limits::max(); - + enum class AccessFlag : u32 { - COLOR_ATTACHMENT_READ = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, - COLOR_ATTACHMENT_WRITE = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - DEPTH_STENCIL_ATTACHMENT_READ = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, - DEPTH_STENCIL_ATTACHMENT_WRITE = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - HOST_READ = VK_ACCESS_HOST_READ_BIT, - HOST_WRITE = VK_ACCESS_HOST_WRITE_BIT, - INDIRECT_COMMAND_READ = VK_ACCESS_INDIRECT_COMMAND_READ_BIT, - INPUT_ATTACHMENT_READ = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, - MEMORY_READ = VK_ACCESS_MEMORY_READ_BIT, - MEMORY_WRITE = VK_ACCESS_MEMORY_WRITE_BIT, - NONE = 0, - SHADER_READ = VK_ACCESS_SHADER_READ_BIT, - SHADER_WRITE = VK_ACCESS_SHADER_WRITE_BIT, - TRANSFER_READ = VK_ACCESS_TRANSFER_READ_BIT, - TRANSFER_WRITE = VK_ACCESS_TRANSFER_WRITE_BIT, - UNIFORM_READ = VK_ACCESS_UNIFORM_READ_BIT, - VERTEX_ATTRIBUTE_READ = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, - - }; - - template <> + COLOR_ATTACHMENT_READ = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, + COLOR_ATTACHMENT_WRITE = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + DEPTH_STENCIL_ATTACHMENT_READ = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, + DEPTH_STENCIL_ATTACHMENT_WRITE = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + HOST_READ = VK_ACCESS_HOST_READ_BIT, + HOST_WRITE = VK_ACCESS_HOST_WRITE_BIT, + INDIRECT_COMMAND_READ = VK_ACCESS_INDIRECT_COMMAND_READ_BIT, + INPUT_ATTACHMENT_READ = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, + MEMORY_READ = VK_ACCESS_MEMORY_READ_BIT, + MEMORY_WRITE = VK_ACCESS_MEMORY_WRITE_BIT, + NONE = 0, + SHADER_READ = VK_ACCESS_SHADER_READ_BIT, + SHADER_WRITE = VK_ACCESS_SHADER_WRITE_BIT, + TRANSFER_READ = VK_ACCESS_TRANSFER_READ_BIT, + TRANSFER_WRITE = VK_ACCESS_TRANSFER_WRITE_BIT, + UNIFORM_READ = VK_ACCESS_UNIFORM_READ_BIT, + VERTEX_ATTRIBUTE_READ = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class AttachmentLoadOperation : u8 { - CLEAR = VK_ATTACHMENT_LOAD_OP_CLEAR, - DONT_CARE = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - LOAD = VK_ATTACHMENT_LOAD_OP_LOAD, - + CLEAR = VK_ATTACHMENT_LOAD_OP_CLEAR, + DONT_CARE = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + LOAD = VK_ATTACHMENT_LOAD_OP_LOAD, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class AttachmentStoreOperation : u8 { - DONT_CARE = VK_ATTACHMENT_STORE_OP_DONT_CARE, - STORE = VK_ATTACHMENT_STORE_OP_STORE, - + DONT_CARE = VK_ATTACHMENT_STORE_OP_DONT_CARE, + STORE = VK_ATTACHMENT_STORE_OP_STORE, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class BlendFactor : u8 { - CONSTANT_ALPHA = VK_BLEND_FACTOR_CONSTANT_ALPHA, - CONSTANT_COLOR = VK_BLEND_FACTOR_CONSTANT_COLOR, - DST_ALPHA = VK_BLEND_FACTOR_DST_ALPHA, - DST_COLOR = VK_BLEND_FACTOR_DST_COLOR, - ONE = VK_BLEND_FACTOR_ONE, - ONE_MINUS_CONSTANT_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA, - ONE_MINUS_CONSTANT_COLOR = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, - ONE_MINUS_DST_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, - ONE_MINUS_DST_COLOR = VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, - ONE_MINUS_SRC1_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, - ONE_MINUS_SRC1_COLOR = VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, - ONE_MINUS_SRC_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, - ONE_MINUS_SRC_COLOR = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, - SRC1_ALPHA = VK_BLEND_FACTOR_SRC1_ALPHA, - SRC1_COLOR = VK_BLEND_FACTOR_SRC1_COLOR, - SRC_ALPHA = VK_BLEND_FACTOR_SRC_ALPHA, - SRC_ALPHA_SATURATE = VK_BLEND_FACTOR_SRC_ALPHA_SATURATE, - SRC_COLOR = VK_BLEND_FACTOR_SRC_COLOR, - ZERO = VK_BLEND_FACTOR_ZERO, - - }; - - template <> + CONSTANT_ALPHA = VK_BLEND_FACTOR_CONSTANT_ALPHA, + CONSTANT_COLOR = VK_BLEND_FACTOR_CONSTANT_COLOR, + DST_ALPHA = VK_BLEND_FACTOR_DST_ALPHA, + DST_COLOR = VK_BLEND_FACTOR_DST_COLOR, + ONE = VK_BLEND_FACTOR_ONE, + ONE_MINUS_CONSTANT_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA, + ONE_MINUS_CONSTANT_COLOR = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, + ONE_MINUS_DST_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, + ONE_MINUS_DST_COLOR = VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, + ONE_MINUS_SRC1_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, + ONE_MINUS_SRC1_COLOR = VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, + ONE_MINUS_SRC_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + ONE_MINUS_SRC_COLOR = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, + SRC1_ALPHA = VK_BLEND_FACTOR_SRC1_ALPHA, + SRC1_COLOR = VK_BLEND_FACTOR_SRC1_COLOR, + SRC_ALPHA = VK_BLEND_FACTOR_SRC_ALPHA, + SRC_ALPHA_SATURATE = VK_BLEND_FACTOR_SRC_ALPHA_SATURATE, + SRC_COLOR = VK_BLEND_FACTOR_SRC_COLOR, + ZERO = VK_BLEND_FACTOR_ZERO, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class BlendOperation : u8 { - ADD = VK_BLEND_OP_ADD, - MAX = VK_BLEND_OP_MAX, - MIN = VK_BLEND_OP_MIN, - REVERSE_SUBTRACT = VK_BLEND_OP_REVERSE_SUBTRACT, - SUBTRACT = VK_BLEND_OP_SUBTRACT, - + ADD = VK_BLEND_OP_ADD, + MAX = VK_BLEND_OP_MAX, + MIN = VK_BLEND_OP_MIN, + REVERSE_SUBTRACT = VK_BLEND_OP_REVERSE_SUBTRACT, + SUBTRACT = VK_BLEND_OP_SUBTRACT, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class BorderColor : u8 { - FLOAT_OPAQUE_BLACK = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK, - FLOAT_OPAQUE_WHITE = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE, - FLOAT_TRANSPARENT_BLACK = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, - INT_OPAQUE_BLACK = VK_BORDER_COLOR_INT_OPAQUE_BLACK, - INT_OPAQUE_WHITE = VK_BORDER_COLOR_INT_OPAQUE_WHITE, - INT_TRANSPARENT_BLACK = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK, - + FLOAT_OPAQUE_BLACK = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK, + FLOAT_OPAQUE_WHITE = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE, + FLOAT_TRANSPARENT_BLACK = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, + INT_OPAQUE_BLACK = VK_BORDER_COLOR_INT_OPAQUE_BLACK, + INT_OPAQUE_WHITE = VK_BORDER_COLOR_INT_OPAQUE_WHITE, + INT_TRANSPARENT_BLACK = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class BufferUsageFlag : u16 { - INDEX = VK_BUFFER_USAGE_INDEX_BUFFER_BIT, - INDIRECT = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, - STORAGE = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, - STORAGE_TEXEL = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, - TRANSFER_DST = VK_BUFFER_USAGE_TRANSFER_DST_BIT, - TRANSFER_SRC = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - UNIFORM = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, - UNIFORM_TEXEL = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, - VERTEX = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, - - }; - - template <> + INDEX = VK_BUFFER_USAGE_INDEX_BUFFER_BIT, + INDIRECT = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, + STORAGE = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, + STORAGE_TEXEL = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, + TRANSFER_DST = VK_BUFFER_USAGE_TRANSFER_DST_BIT, + TRANSFER_SRC = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + UNIFORM = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + UNIFORM_TEXEL = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, + VERTEX = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ColorComponentFlag : u8 { - A = VK_COLOR_COMPONENT_A_BIT, - B = VK_COLOR_COMPONENT_B_BIT, - G = VK_COLOR_COMPONENT_G_BIT, - NONE = 0, - R = VK_COLOR_COMPONENT_R_BIT, - RG = R | G, - RGB = RG | B, - RGBA = RGB | A, - - }; - - template <> + A = VK_COLOR_COMPONENT_A_BIT, + B = VK_COLOR_COMPONENT_B_BIT, + G = VK_COLOR_COMPONENT_G_BIT, + NONE = 0, + R = VK_COLOR_COMPONENT_R_BIT, + RG = R | G, + RGB = RG | B, + RGBA = RGB | A, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ColorSpace : u32 { - ADOBERGB_LINEAR = VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT, - ADOBERGB_NONLINEAR = VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT, - BT2020_LINEAR = VK_COLOR_SPACE_BT2020_LINEAR_EXT, - BT709_LINEAR = VK_COLOR_SPACE_BT709_LINEAR_EXT, - BT709_NONLINEAR = VK_COLOR_SPACE_BT709_NONLINEAR_EXT, - DCI_P3_NONLINEAR = VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT, - DISPLAY_NATIVE_AMD = VK_COLOR_SPACE_DISPLAY_NATIVE_AMD, - DISPLAY_P3_LINEAR = VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT, - DISPLAY_P3_NONLINEAR = VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT, - DOLBYVISION = VK_COLOR_SPACE_DOLBYVISION_EXT, - EXTENDED_SRGB_LINEAR = VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT, - EXTENDED_SRGB_NONLINEAR = VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT, - HDR10_HLG = VK_COLOR_SPACE_HDR10_HLG_EXT, - HDR10_ST2084 = VK_COLOR_SPACE_HDR10_ST2084_EXT, - PASS_THROUGH = VK_COLOR_SPACE_PASS_THROUGH_EXT, - SRGB_NONLINEAR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, - - }; - - template <> + ADOBERGB_LINEAR = VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT, + ADOBERGB_NONLINEAR = VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT, + BT2020_LINEAR = VK_COLOR_SPACE_BT2020_LINEAR_EXT, + BT709_LINEAR = VK_COLOR_SPACE_BT709_LINEAR_EXT, + BT709_NONLINEAR = VK_COLOR_SPACE_BT709_NONLINEAR_EXT, + DCI_P3_NONLINEAR = VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT, + DISPLAY_NATIVE_AMD = VK_COLOR_SPACE_DISPLAY_NATIVE_AMD, + DISPLAY_P3_LINEAR = VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT, + DISPLAY_P3_NONLINEAR = VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT, + DOLBYVISION = VK_COLOR_SPACE_DOLBYVISION_EXT, + EXTENDED_SRGB_LINEAR = VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT, + EXTENDED_SRGB_NONLINEAR = VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT, + HDR10_HLG = VK_COLOR_SPACE_HDR10_HLG_EXT, + HDR10_ST2084 = VK_COLOR_SPACE_HDR10_ST2084_EXT, + PASS_THROUGH = VK_COLOR_SPACE_PASS_THROUGH_EXT, + SRGB_NONLINEAR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class CommandBufferLevel : u8 { - PRIMARY = VK_COMMAND_BUFFER_LEVEL_PRIMARY, - SECONDARY = VK_COMMAND_BUFFER_LEVEL_SECONDARY, - + PRIMARY = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + SECONDARY = VK_COMMAND_BUFFER_LEVEL_SECONDARY, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class CompareOperation : u8 { - ALWAYS = VK_COMPARE_OP_ALWAYS, - EQUAL = VK_COMPARE_OP_EQUAL, - GREATER = VK_COMPARE_OP_GREATER, - GREATER_OR_EQUAL = VK_COMPARE_OP_GREATER_OR_EQUAL, - LESS = VK_COMPARE_OP_LESS, - LESS_OR_EQUAL = VK_COMPARE_OP_LESS_OR_EQUAL, - NEVER = VK_COMPARE_OP_NEVER, - NOT_EQUAL = VK_COMPARE_OP_NOT_EQUAL, - - }; - - template <> + ALWAYS = VK_COMPARE_OP_ALWAYS, + EQUAL = VK_COMPARE_OP_EQUAL, + GREATER = VK_COMPARE_OP_GREATER, + GREATER_OR_EQUAL = VK_COMPARE_OP_GREATER_OR_EQUAL, + LESS = VK_COMPARE_OP_LESS, + LESS_OR_EQUAL = VK_COMPARE_OP_LESS_OR_EQUAL, + NEVER = VK_COMPARE_OP_NEVER, + NOT_EQUAL = VK_COMPARE_OP_NOT_EQUAL, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class CullModeFlag : u8 { - BACK = VK_CULL_MODE_BACK_BIT, - FRONT = VK_CULL_MODE_FRONT_BIT, - FRONT_BACK = FRONT | BACK, - NONE = 0, - + BACK = VK_CULL_MODE_BACK_BIT, + FRONT = VK_CULL_MODE_FRONT_BIT, + FRONT_BACK = FRONT | BACK, + NONE = 0, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class DebugObjectType : u32 { - BUFFER = VK_OBJECT_TYPE_BUFFER, - BUFFER_VIEW = VK_OBJECT_TYPE_BUFFER_VIEW, - COMMAND_BUFFER = VK_OBJECT_TYPE_COMMAND_BUFFER, - COMMAND_POOL = VK_OBJECT_TYPE_COMMAND_POOL, - DEBUG_REPORT_CALLBACK = VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT, - DESCRIPTOR_POOL = VK_OBJECT_TYPE_DESCRIPTOR_POOL, - DESCRIPTOR_SET = VK_OBJECT_TYPE_DESCRIPTOR_SET, - DESCRIPTOR_SET_LAYOUT = VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, - DEVICE = VK_OBJECT_TYPE_DEVICE, - DEVICE_MEMORY = VK_OBJECT_TYPE_DEVICE_MEMORY, - DISPLAY = VK_OBJECT_TYPE_DISPLAY_KHR, - EVENT = VK_OBJECT_TYPE_EVENT, - FENCE = VK_OBJECT_TYPE_FENCE, - FRAMEBUFFER = VK_OBJECT_TYPE_FRAMEBUFFER, - IMAGE = VK_OBJECT_TYPE_IMAGE, - IMAGE_VIEW = VK_OBJECT_TYPE_IMAGE_VIEW, - INSTANCE = VK_OBJECT_TYPE_INSTANCE, - PHYSICAL_DEVICE = VK_OBJECT_TYPE_PHYSICAL_DEVICE, - PIPELINE = VK_OBJECT_TYPE_PIPELINE, - PIPELINE_CACHE = VK_OBJECT_TYPE_PIPELINE_CACHE, - PIPELINE_LAYOUT = VK_OBJECT_TYPE_PIPELINE_LAYOUT, - QUERY_POOL = VK_OBJECT_TYPE_QUERY_POOL, - QUEUE = VK_OBJECT_TYPE_QUEUE, - RENDER_PASS = VK_OBJECT_TYPE_RENDER_PASS, - SAMPLER = VK_OBJECT_TYPE_SAMPLER, - SEMAPHORE = VK_OBJECT_TYPE_SEMAPHORE, - SHADER_MODULE = VK_OBJECT_TYPE_SHADER_MODULE, - SURFACE = VK_OBJECT_TYPE_SURFACE_KHR, - SWAPCHAIN = VK_OBJECT_TYPE_SWAPCHAIN_KHR, - UNKNOWN = VK_OBJECT_TYPE_UNKNOWN, - - }; - - template <> + BUFFER = VK_OBJECT_TYPE_BUFFER, + BUFFER_VIEW = VK_OBJECT_TYPE_BUFFER_VIEW, + COMMAND_BUFFER = VK_OBJECT_TYPE_COMMAND_BUFFER, + COMMAND_POOL = VK_OBJECT_TYPE_COMMAND_POOL, + DEBUG_REPORT_CALLBACK = VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT, + DESCRIPTOR_POOL = VK_OBJECT_TYPE_DESCRIPTOR_POOL, + DESCRIPTOR_SET = VK_OBJECT_TYPE_DESCRIPTOR_SET, + DESCRIPTOR_SET_LAYOUT = VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, + DEVICE = VK_OBJECT_TYPE_DEVICE, + DEVICE_MEMORY = VK_OBJECT_TYPE_DEVICE_MEMORY, + DISPLAY = VK_OBJECT_TYPE_DISPLAY_KHR, + EVENT = VK_OBJECT_TYPE_EVENT, + FENCE = VK_OBJECT_TYPE_FENCE, + FRAMEBUFFER = VK_OBJECT_TYPE_FRAMEBUFFER, + IMAGE = VK_OBJECT_TYPE_IMAGE, + IMAGE_VIEW = VK_OBJECT_TYPE_IMAGE_VIEW, + INSTANCE = VK_OBJECT_TYPE_INSTANCE, + PHYSICAL_DEVICE = VK_OBJECT_TYPE_PHYSICAL_DEVICE, + PIPELINE = VK_OBJECT_TYPE_PIPELINE, + PIPELINE_CACHE = VK_OBJECT_TYPE_PIPELINE_CACHE, + PIPELINE_LAYOUT = VK_OBJECT_TYPE_PIPELINE_LAYOUT, + QUERY_POOL = VK_OBJECT_TYPE_QUERY_POOL, + QUEUE = VK_OBJECT_TYPE_QUEUE, + RENDER_PASS = VK_OBJECT_TYPE_RENDER_PASS, + SAMPLER = VK_OBJECT_TYPE_SAMPLER, + SEMAPHORE = VK_OBJECT_TYPE_SEMAPHORE, + SHADER_MODULE = VK_OBJECT_TYPE_SHADER_MODULE, + SURFACE = VK_OBJECT_TYPE_SURFACE_KHR, + SWAPCHAIN = VK_OBJECT_TYPE_SWAPCHAIN_KHR, + UNKNOWN = VK_OBJECT_TYPE_UNKNOWN, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class DependencyFlag : u8 { - BY_REGION = VK_DEPENDENCY_BY_REGION_BIT, - DEVICE_GROUP = VK_DEPENDENCY_DEVICE_GROUP_BIT, - NONE = 0, - VIEW_LOCAL = VK_DEPENDENCY_VIEW_LOCAL_BIT, - + BY_REGION = VK_DEPENDENCY_BY_REGION_BIT, + DEVICE_GROUP = VK_DEPENDENCY_DEVICE_GROUP_BIT, + NONE = 0, + VIEW_LOCAL = VK_DEPENDENCY_VIEW_LOCAL_BIT, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class DescriptorType : u8 { - COMBINED_IMAGE_SAMPLER = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - INPUT_ATTACHMENT = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, - SAMPLED_IMAGE = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - SAMPLER = VK_DESCRIPTOR_TYPE_SAMPLER, - STORAGE_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - STORAGE_BUFFER_DYNAMIC = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, - STORAGE_IMAGE = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - STORAGE_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, - UNIFORM_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - UNIFORM_BUFFER_DYNAMIC = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, - UNIFORM_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, - - }; - - template <> + COMBINED_IMAGE_SAMPLER = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + INPUT_ATTACHMENT = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, + SAMPLED_IMAGE = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + SAMPLER = VK_DESCRIPTOR_TYPE_SAMPLER, + STORAGE_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + STORAGE_BUFFER_DYNAMIC = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, + STORAGE_IMAGE = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + STORAGE_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, + UNIFORM_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + UNIFORM_BUFFER_DYNAMIC = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, + UNIFORM_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class DynamicState : u8 { - BLEND_CONSTANTS = VK_DYNAMIC_STATE_BLEND_CONSTANTS, - DEPTH_BIAS = VK_DYNAMIC_STATE_DEPTH_BIAS, - DEPTH_BOUNDS = VK_DYNAMIC_STATE_DEPTH_BOUNDS, - LINE_WIDTH = VK_DYNAMIC_STATE_LINE_WIDTH, - SCISSOR = VK_DYNAMIC_STATE_SCISSOR, - STENCIL_COMPARE_MASK = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, - STENCIL_REFERENCE = VK_DYNAMIC_STATE_STENCIL_REFERENCE, - STENCIL_WRITE_MASK = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, - VIEWPORT = VK_DYNAMIC_STATE_VIEWPORT, - - }; - - template <> + BLEND_CONSTANTS = VK_DYNAMIC_STATE_BLEND_CONSTANTS, + DEPTH_BIAS = VK_DYNAMIC_STATE_DEPTH_BIAS, + DEPTH_BOUNDS = VK_DYNAMIC_STATE_DEPTH_BOUNDS, + LINE_WIDTH = VK_DYNAMIC_STATE_LINE_WIDTH, + SCISSOR = VK_DYNAMIC_STATE_SCISSOR, + STENCIL_COMPARE_MASK = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, + STENCIL_REFERENCE = VK_DYNAMIC_STATE_STENCIL_REFERENCE, + STENCIL_WRITE_MASK = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, + VIEWPORT = VK_DYNAMIC_STATE_VIEWPORT, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class Filter : u32 { - CUBIC_IMG = VK_FILTER_CUBIC_IMG, - LINEAR = VK_FILTER_LINEAR, - NEAREST = VK_FILTER_NEAREST, - + CUBIC_IMG = VK_FILTER_CUBIC_IMG, + LINEAR = VK_FILTER_LINEAR, + NEAREST = VK_FILTER_NEAREST, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class FormatFeatureFlag : u32 { - BLIT_DST = VK_FORMAT_FEATURE_BLIT_DST_BIT, - BLIT_SRC = VK_FORMAT_FEATURE_BLIT_SRC_BIT, - COLOR_ATTACHMENT = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, - COLOR_ATTACHMENT_BLEND = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT, - COSITED_CHROMA_SAMPLES = VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT, - DEPTH_STENCIL_ATTACHMENT = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, - DISJOINT = VK_FORMAT_FEATURE_DISJOINT_BIT, - MIDPOINT_CHROMA_SAMPLES = VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT, - SAMPLED_IMAGE = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, - SAMPLED_IMAGE_FILTER_LINEAR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT, - SAMPLED_IMAGE_FILTER_MINMAX = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT, - SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT, - SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT, - SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT, - SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT, - STORAGE_IMAGE = VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT, - STORAGE_IMAGE_ATOMIC = VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT, - STORAGE_TEXEL_BUFFER = VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT, - STORAGE_TEXEL_BUFFER_ATOMIC = VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT, - TRANSFER_DST = VK_FORMAT_FEATURE_TRANSFER_DST_BIT, - TRANSFER_SRC = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT, - UNIFORM_TEXEL_BUFFER = VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT, - VERTEX_BUFFER = VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT, - - }; - - template <> + BLIT_DST = VK_FORMAT_FEATURE_BLIT_DST_BIT, + BLIT_SRC = VK_FORMAT_FEATURE_BLIT_SRC_BIT, + COLOR_ATTACHMENT = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, + COLOR_ATTACHMENT_BLEND = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT, + COSITED_CHROMA_SAMPLES = VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT, + DEPTH_STENCIL_ATTACHMENT = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, + DISJOINT = VK_FORMAT_FEATURE_DISJOINT_BIT, + MIDPOINT_CHROMA_SAMPLES = VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT, + SAMPLED_IMAGE = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, + SAMPLED_IMAGE_FILTER_LINEAR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT, + SAMPLED_IMAGE_FILTER_MINMAX = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT, + SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT + = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT, + SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE + = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT, + SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT, + SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER + = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT, + STORAGE_IMAGE = VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT, + STORAGE_IMAGE_ATOMIC = VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT, + STORAGE_TEXEL_BUFFER = VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT, + STORAGE_TEXEL_BUFFER_ATOMIC = VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT, + TRANSFER_DST = VK_FORMAT_FEATURE_TRANSFER_DST_BIT, + TRANSFER_SRC = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT, + UNIFORM_TEXEL_BUFFER = VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT, + VERTEX_BUFFER = VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class FrontFace : u8 { - CLOCKWISE = VK_FRONT_FACE_CLOCKWISE, - COUNTER_CLOCKWISE = VK_FRONT_FACE_COUNTER_CLOCKWISE, - + CLOCKWISE = VK_FRONT_FACE_CLOCKWISE, + COUNTER_CLOCKWISE = VK_FRONT_FACE_COUNTER_CLOCKWISE, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class GeometryFlag : u8 { - NO_DUPLICATE_ANY_HIT_INVOCATION = VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR, - OPAQUE = VK_GEOMETRY_OPAQUE_BIT_KHR, - + NO_DUPLICATE_ANY_HIT_INVOCATION = VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR, + OPAQUE = VK_GEOMETRY_OPAQUE_BIT_KHR, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class GeometryType : u8 { - AABBS = VK_GEOMETRY_TYPE_AABBS_KHR, - INSTANCES = VK_GEOMETRY_TYPE_INSTANCES_KHR, - TRIANGLES = VK_GEOMETRY_TYPE_TRIANGLES_KHR, - + AABBS = VK_GEOMETRY_TYPE_AABBS_KHR, + INSTANCES = VK_GEOMETRY_TYPE_INSTANCES_KHR, + TRIANGLES = VK_GEOMETRY_TYPE_TRIANGLES_KHR, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageAspectFlag : u8 { - COLOR = VK_IMAGE_ASPECT_COLOR_BIT, - DEPTH = VK_IMAGE_ASPECT_DEPTH_BIT, - NONE = VK_IMAGE_ASPECT_NONE_KHR, - STENCIL = VK_IMAGE_ASPECT_STENCIL_BIT, - + COLOR = VK_IMAGE_ASPECT_COLOR_BIT, + DEPTH = VK_IMAGE_ASPECT_DEPTH_BIT, + NONE = VK_IMAGE_ASPECT_NONE_KHR, + STENCIL = VK_IMAGE_ASPECT_STENCIL_BIT, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageCreateFlag : u16 { - ALIAS = VK_IMAGE_CREATE_ALIAS_BIT, - ARRAY_2D_COMPATIBLE = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, - BLOCK_TEXEL_VIEW_COMPATIBLE = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, - CUBE_COMPATIBLE = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, - DISJOINT = VK_IMAGE_CREATE_DISJOINT_BIT, - EXTENDED_USAGE = VK_IMAGE_CREATE_EXTENDED_USAGE_BIT, - MUTABLE_FORMAT = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, - NONE = 0, - PROTECTED = VK_IMAGE_CREATE_PROTECTED_BIT, - SPARSE_ALIASED = VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, - SPARSE_BINDING = VK_IMAGE_CREATE_SPARSE_BINDING_BIT, - SPARSE_RESIDENCY = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, - SPLIT_INSTANCE_BIND_REGIONS = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT, - - }; - - template <> + ALIAS = VK_IMAGE_CREATE_ALIAS_BIT, + ARRAY_2D_COMPATIBLE = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, + BLOCK_TEXEL_VIEW_COMPATIBLE = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, + CUBE_COMPATIBLE = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, + DISJOINT = VK_IMAGE_CREATE_DISJOINT_BIT, + EXTENDED_USAGE = VK_IMAGE_CREATE_EXTENDED_USAGE_BIT, + MUTABLE_FORMAT = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, + NONE = 0, + PROTECTED = VK_IMAGE_CREATE_PROTECTED_BIT, + SPARSE_ALIASED = VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, + SPARSE_BINDING = VK_IMAGE_CREATE_SPARSE_BINDING_BIT, + SPARSE_RESIDENCY = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, + SPLIT_INSTANCE_BIND_REGIONS = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageLayout : u32 { - ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, - COLOR_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, - DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, - DEPTH_STENCIL_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - DEPTH_STENCIL_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, - GENERAL = VK_IMAGE_LAYOUT_GENERAL, - PREINITIALIZED = VK_IMAGE_LAYOUT_PREINITIALIZED, - PRESENT_SRC = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - SHADER_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - SHARED_PRESENT = VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, - TRANSFER_DST_OPTIMAL = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - TRANSFER_SRC_OPTIMAL = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - UNDEFINED = VK_IMAGE_LAYOUT_UNDEFINED, - - }; - - template <> + ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, + COLOR_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, + DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, + DEPTH_STENCIL_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + DEPTH_STENCIL_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, + GENERAL = VK_IMAGE_LAYOUT_GENERAL, + PREINITIALIZED = VK_IMAGE_LAYOUT_PREINITIALIZED, + PRESENT_SRC = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + SHADER_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + SHARED_PRESENT = VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, + TRANSFER_DST_OPTIMAL = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + TRANSFER_SRC_OPTIMAL = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + UNDEFINED = VK_IMAGE_LAYOUT_UNDEFINED, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageTiling : u8 { - LINEAR = VK_IMAGE_TILING_LINEAR, - OPTIMAL = VK_IMAGE_TILING_OPTIMAL, - + LINEAR = VK_IMAGE_TILING_LINEAR, + OPTIMAL = VK_IMAGE_TILING_OPTIMAL, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageType : u8 { - T1D = VK_IMAGE_TYPE_1D, - T2D = VK_IMAGE_TYPE_2D, - T3D = VK_IMAGE_TYPE_3D, - + T1D = VK_IMAGE_TYPE_1D, + T2D = VK_IMAGE_TYPE_2D, + T3D = VK_IMAGE_TYPE_3D, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageUsageFlag : u16 { - COLOR_ATTACHMENT = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, - DEPTH_STENCIL_ATTACHMENT = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, - INPUT_ATTACHMENT = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, - SAMPLED = VK_IMAGE_USAGE_SAMPLED_BIT, - STORAGE = VK_IMAGE_USAGE_STORAGE_BIT, - TRANSFER_DST = VK_IMAGE_USAGE_TRANSFER_DST_BIT, - TRANSFER_SRC = VK_IMAGE_USAGE_TRANSFER_SRC_BIT, - TRANSIENT_ATTACHMENT = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, - - }; - - template <> + COLOR_ATTACHMENT = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + DEPTH_STENCIL_ATTACHMENT = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + INPUT_ATTACHMENT = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, + SAMPLED = VK_IMAGE_USAGE_SAMPLED_BIT, + STORAGE = VK_IMAGE_USAGE_STORAGE_BIT, + TRANSFER_DST = VK_IMAGE_USAGE_TRANSFER_DST_BIT, + TRANSFER_SRC = VK_IMAGE_USAGE_TRANSFER_SRC_BIT, + TRANSIENT_ATTACHMENT = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageViewType : u8 { - CUBE = VK_IMAGE_VIEW_TYPE_CUBE, - CUBE_ARRAY = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, - T1D = VK_IMAGE_VIEW_TYPE_1D, - T1D_ARRAY = VK_IMAGE_VIEW_TYPE_1D_ARRAY, - T2D = VK_IMAGE_VIEW_TYPE_2D, - T2D_ARRAY = VK_IMAGE_VIEW_TYPE_2D_ARRAY, - T3D = VK_IMAGE_VIEW_TYPE_3D, - + CUBE = VK_IMAGE_VIEW_TYPE_CUBE, + CUBE_ARRAY = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, + T1D = VK_IMAGE_VIEW_TYPE_1D, + T1D_ARRAY = VK_IMAGE_VIEW_TYPE_1D_ARRAY, + T2D = VK_IMAGE_VIEW_TYPE_2D, + T2D_ARRAY = VK_IMAGE_VIEW_TYPE_2D_ARRAY, + T3D = VK_IMAGE_VIEW_TYPE_3D, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class LogicOperation : u8 { - AND = VK_LOGIC_OP_AND, - AND_INVERTED = VK_LOGIC_OP_AND_INVERTED, - AND_REVERSE = VK_LOGIC_OP_AND_REVERSE, - CLEAR = VK_LOGIC_OP_CLEAR, - COPY = VK_LOGIC_OP_COPY, - COPY_INVERTED = VK_LOGIC_OP_COPY_INVERTED, - EQUIVALENT = VK_LOGIC_OP_EQUIVALENT, - INVERT = VK_LOGIC_OP_INVERT, - NAND = VK_LOGIC_OP_NAND, - NO_OP = VK_LOGIC_OP_NO_OP, - NOR = VK_LOGIC_OP_NOR, - OR = VK_LOGIC_OP_OR, - OR_INVERTED = VK_LOGIC_OP_OR_INVERTED, - OR_REVERSE = VK_LOGIC_OP_OR_REVERSE, - SET = VK_LOGIC_OP_SET, - XOR = VK_LOGIC_OP_XOR, - - }; - - template <> + AND = VK_LOGIC_OP_AND, + AND_INVERTED = VK_LOGIC_OP_AND_INVERTED, + AND_REVERSE = VK_LOGIC_OP_AND_REVERSE, + CLEAR = VK_LOGIC_OP_CLEAR, + COPY = VK_LOGIC_OP_COPY, + COPY_INVERTED = VK_LOGIC_OP_COPY_INVERTED, + EQUIVALENT = VK_LOGIC_OP_EQUIVALENT, + INVERT = VK_LOGIC_OP_INVERT, + NAND = VK_LOGIC_OP_NAND, + NO_OP = VK_LOGIC_OP_NO_OP, + NOR = VK_LOGIC_OP_NOR, + OR = VK_LOGIC_OP_OR, + OR_INVERTED = VK_LOGIC_OP_OR_INVERTED, + OR_REVERSE = VK_LOGIC_OP_OR_REVERSE, + SET = VK_LOGIC_OP_SET, + XOR = VK_LOGIC_OP_XOR, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class MemoryPropertyFlag : u8 { - DEVICE_LOCAL = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - HOST_CACHED = VK_MEMORY_PROPERTY_HOST_CACHED_BIT, - HOST_COHERENT = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - HOST_VISIBLE = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, - + DEVICE_LOCAL = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + HOST_CACHED = VK_MEMORY_PROPERTY_HOST_CACHED_BIT, + HOST_COHERENT = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + HOST_VISIBLE = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PhysicalDeviceType : u8 { - CPU = VK_PHYSICAL_DEVICE_TYPE_CPU, - DISCRETE_GPU = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, - INTEGRATED_GPU = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, - OTHER = VK_PHYSICAL_DEVICE_TYPE_OTHER, - VIRTUAL_GPU = VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, - + CPU = VK_PHYSICAL_DEVICE_TYPE_CPU, + DISCRETE_GPU = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, + INTEGRATED_GPU = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, + OTHER = VK_PHYSICAL_DEVICE_TYPE_OTHER, + VIRTUAL_GPU = VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PipelineBindPoint : u8 { - COMPUTE = VK_PIPELINE_BIND_POINT_COMPUTE, - GRAPHICS = VK_PIPELINE_BIND_POINT_GRAPHICS, - + COMPUTE = VK_PIPELINE_BIND_POINT_COMPUTE, + GRAPHICS = VK_PIPELINE_BIND_POINT_GRAPHICS, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PipelineStageFlag : u32 { - ALL_COMMANDS = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - ALL_GRAPHICS = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, - BOTTOM_OF_PIPE = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - COLOR_ATTACHMENT_OUTPUT = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - COMPUTE_SHADER = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - DRAW_INDIRECT = VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, - EARLY_FRAGMENT_TESTS = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, - FRAGMENT_SHADER = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - GEOMETRY_SHADER = VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, - HOST = VK_PIPELINE_STAGE_HOST_BIT, - LATE_FRAGMENT_TESTS = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - TESSELLATION_CONTROL_SHADER = VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, - TESSELLATION_EVALUATION_SHADER = VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, - TOP_OF_PIPE = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - TRANSFER = VK_PIPELINE_STAGE_TRANSFER_BIT, - VERTEX_INPUT = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, - VERTEX_SHADER = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, - - }; - - template <> + ALL_COMMANDS = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + ALL_GRAPHICS = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, + BOTTOM_OF_PIPE = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + COLOR_ATTACHMENT_OUTPUT = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + COMPUTE_SHADER = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + DRAW_INDIRECT = VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, + EARLY_FRAGMENT_TESTS = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, + FRAGMENT_SHADER = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + GEOMETRY_SHADER = VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, + HOST = VK_PIPELINE_STAGE_HOST_BIT, + LATE_FRAGMENT_TESTS = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + TESSELLATION_CONTROL_SHADER = VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, + TESSELLATION_EVALUATION_SHADER = VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, + TOP_OF_PIPE = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + TRANSFER = VK_PIPELINE_STAGE_TRANSFER_BIT, + VERTEX_INPUT = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, + VERTEX_SHADER = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PixelFormat : u32 { - A1_RGB5_UNORM_PACK16 = VK_FORMAT_A1R5G5B5_UNORM_PACK16, - A2_RGB10I_PACK32 = VK_FORMAT_A2R10G10B10_SINT_PACK32, - A2_RGB10_SNORM_PACK32 = VK_FORMAT_A2R10G10B10_SNORM_PACK32, - A2_RGB10_UNORM_PACK32 = VK_FORMAT_A2R10G10B10_UNORM_PACK32, - A2_RGB10U_PACK32 = VK_FORMAT_A2R10G10B10_UINT_PACK32, - B10_GR11UF_PACK32 = VK_FORMAT_B10G11R11_UFLOAT_PACK32, - BGR8_UNORM = VK_FORMAT_B8G8R8_UNORM, - BGRA8_UNORM = VK_FORMAT_B8G8R8A8_UNORM, - DEPTH16_UNORM = VK_FORMAT_D16_UNORM, - DEPTH16_UNORM_STENCIL8U = VK_FORMAT_D16_UNORM_S8_UINT, - DEPTH24_UNORM_PACK32 = VK_FORMAT_X8_D24_UNORM_PACK32, - DEPTH24_UNORM_STENCIL8U = VK_FORMAT_D24_UNORM_S8_UINT, - DEPTH32F = VK_FORMAT_D32_SFLOAT, - DEPTH32F_STENCIL8U = VK_FORMAT_D32_SFLOAT_S8_UINT, - R16F = VK_FORMAT_R16_SFLOAT, - R16I = VK_FORMAT_R16_SINT, - R16_SNORM = VK_FORMAT_R16_SNORM, - R16U = VK_FORMAT_R16_UINT, - R16_UNORM = VK_FORMAT_R16_UNORM, - R32F = VK_FORMAT_R32_SFLOAT, - R32I = VK_FORMAT_R32_SINT, - R32U = VK_FORMAT_R32_UINT, - R5_G6_B5_UNORM_PACK16 = VK_FORMAT_R5G6B5_UNORM_PACK16, - R8I = VK_FORMAT_R8_SINT, - R8_SNORM = VK_FORMAT_R8_SNORM, - R8U = VK_FORMAT_R8_UINT, - R8_UNORM = VK_FORMAT_R8_UNORM, - RG16F = VK_FORMAT_R16G16_SFLOAT, - RG16I = VK_FORMAT_R16G16_SINT, - RG16_SNORM = VK_FORMAT_R16G16_SNORM, - RG16U = VK_FORMAT_R16G16_UINT, - RG16_UNORM = VK_FORMAT_R16G16_UNORM, - RG32F = VK_FORMAT_R32G32_SFLOAT, - RG32I = VK_FORMAT_R32G32_SINT, - RG32U = VK_FORMAT_R32G32_UINT, - RG8I = VK_FORMAT_R8G8_SINT, - RG8_SNORM = VK_FORMAT_R8G8_SNORM, - RG8U = VK_FORMAT_R8G8_UINT, - RG8_UNORM = VK_FORMAT_R8G8_UNORM, - RGB16F = VK_FORMAT_R16G16B16_SFLOAT, - RGB16I = VK_FORMAT_R16G16B16_SINT, - RGB16_SNORM = VK_FORMAT_R16G16B16_SNORM, - RGB16U = VK_FORMAT_R16G16B16_UINT, - RGB16_UNORM = VK_FORMAT_R16G16B16_UNORM, - RGB32F = VK_FORMAT_R32G32B32_SFLOAT, - RGB32I = VK_FORMAT_R32G32B32_SINT, - RGB32U = VK_FORMAT_R32G32B32_UINT, - RGB8I = VK_FORMAT_R8G8B8_SINT, - RGB8_SNORM = VK_FORMAT_R8G8B8_SNORM, - RGB8U = VK_FORMAT_R8G8B8_UINT, - RGB8_UNORM = VK_FORMAT_R8G8B8_UNORM, - RGBA16F = VK_FORMAT_R16G16B16A16_SFLOAT, - RGBA16I = VK_FORMAT_R16G16B16A16_SINT, - RGBA16_SNORM = VK_FORMAT_R16G16B16A16_SNORM, - RGBA16U = VK_FORMAT_R16G16B16A16_UINT, - RGBA16_UNORM = VK_FORMAT_R16G16B16A16_UNORM, - RGBA32F = VK_FORMAT_R32G32B32A32_SFLOAT, - RGBA32I = VK_FORMAT_R32G32B32A32_SINT, - RGBA32U = VK_FORMAT_R32G32B32A32_UINT, - RGBA4_UNORM_PACK16 = VK_FORMAT_R4G4B4A4_UNORM_PACK16, - RGBA8I = VK_FORMAT_R8G8B8A8_SINT, - RGBA8_SNORM = VK_FORMAT_R8G8B8A8_SNORM, - RGBA8U = VK_FORMAT_R8G8B8A8_UINT, - RGBA8_UNORM = VK_FORMAT_R8G8B8A8_UNORM, - SBGR8 = VK_FORMAT_B8G8R8_SRGB, - SBGRA8 = VK_FORMAT_B8G8R8A8_SRGB, - SR8 = VK_FORMAT_R8_SRGB, - SRG8 = VK_FORMAT_R8G8_SRGB, - SRGB8 = VK_FORMAT_R8G8B8_SRGB, - SRGBA8 = VK_FORMAT_R8G8B8A8_SRGB, - UNDEFINED = VK_FORMAT_UNDEFINED, - - }; - - template <> + A1_RGB5_UNORM_PACK16 = VK_FORMAT_A1R5G5B5_UNORM_PACK16, + A2_RGB10I_PACK32 = VK_FORMAT_A2R10G10B10_SINT_PACK32, + A2_RGB10_SNORM_PACK32 = VK_FORMAT_A2R10G10B10_SNORM_PACK32, + A2_RGB10_UNORM_PACK32 = VK_FORMAT_A2R10G10B10_UNORM_PACK32, + A2_RGB10U_PACK32 = VK_FORMAT_A2R10G10B10_UINT_PACK32, + B10_GR11UF_PACK32 = VK_FORMAT_B10G11R11_UFLOAT_PACK32, + BGR8_UNORM = VK_FORMAT_B8G8R8_UNORM, + BGRA8_UNORM = VK_FORMAT_B8G8R8A8_UNORM, + DEPTH16_UNORM = VK_FORMAT_D16_UNORM, + DEPTH16_UNORM_STENCIL8U = VK_FORMAT_D16_UNORM_S8_UINT, + DEPTH24_UNORM_PACK32 = VK_FORMAT_X8_D24_UNORM_PACK32, + DEPTH24_UNORM_STENCIL8U = VK_FORMAT_D24_UNORM_S8_UINT, + DEPTH32F = VK_FORMAT_D32_SFLOAT, + DEPTH32F_STENCIL8U = VK_FORMAT_D32_SFLOAT_S8_UINT, + R16F = VK_FORMAT_R16_SFLOAT, + R16I = VK_FORMAT_R16_SINT, + R16_SNORM = VK_FORMAT_R16_SNORM, + R16U = VK_FORMAT_R16_UINT, + R16_UNORM = VK_FORMAT_R16_UNORM, + R32F = VK_FORMAT_R32_SFLOAT, + R32I = VK_FORMAT_R32_SINT, + R32U = VK_FORMAT_R32_UINT, + R5_G6_B5_UNORM_PACK16 = VK_FORMAT_R5G6B5_UNORM_PACK16, + R8I = VK_FORMAT_R8_SINT, + R8_SNORM = VK_FORMAT_R8_SNORM, + R8U = VK_FORMAT_R8_UINT, + R8_UNORM = VK_FORMAT_R8_UNORM, + RG16F = VK_FORMAT_R16G16_SFLOAT, + RG16I = VK_FORMAT_R16G16_SINT, + RG16_SNORM = VK_FORMAT_R16G16_SNORM, + RG16U = VK_FORMAT_R16G16_UINT, + RG16_UNORM = VK_FORMAT_R16G16_UNORM, + RG32F = VK_FORMAT_R32G32_SFLOAT, + RG32I = VK_FORMAT_R32G32_SINT, + RG32U = VK_FORMAT_R32G32_UINT, + RG8I = VK_FORMAT_R8G8_SINT, + RG8_SNORM = VK_FORMAT_R8G8_SNORM, + RG8U = VK_FORMAT_R8G8_UINT, + RG8_UNORM = VK_FORMAT_R8G8_UNORM, + RGB16F = VK_FORMAT_R16G16B16_SFLOAT, + RGB16I = VK_FORMAT_R16G16B16_SINT, + RGB16_SNORM = VK_FORMAT_R16G16B16_SNORM, + RGB16U = VK_FORMAT_R16G16B16_UINT, + RGB16_UNORM = VK_FORMAT_R16G16B16_UNORM, + RGB32F = VK_FORMAT_R32G32B32_SFLOAT, + RGB32I = VK_FORMAT_R32G32B32_SINT, + RGB32U = VK_FORMAT_R32G32B32_UINT, + RGB8I = VK_FORMAT_R8G8B8_SINT, + RGB8_SNORM = VK_FORMAT_R8G8B8_SNORM, + RGB8U = VK_FORMAT_R8G8B8_UINT, + RGB8_UNORM = VK_FORMAT_R8G8B8_UNORM, + RGBA16F = VK_FORMAT_R16G16B16A16_SFLOAT, + RGBA16I = VK_FORMAT_R16G16B16A16_SINT, + RGBA16_SNORM = VK_FORMAT_R16G16B16A16_SNORM, + RGBA16U = VK_FORMAT_R16G16B16A16_UINT, + RGBA16_UNORM = VK_FORMAT_R16G16B16A16_UNORM, + RGBA32F = VK_FORMAT_R32G32B32A32_SFLOAT, + RGBA32I = VK_FORMAT_R32G32B32A32_SINT, + RGBA32U = VK_FORMAT_R32G32B32A32_UINT, + RGBA4_UNORM_PACK16 = VK_FORMAT_R4G4B4A4_UNORM_PACK16, + RGBA8I = VK_FORMAT_R8G8B8A8_SINT, + RGBA8_SNORM = VK_FORMAT_R8G8B8A8_SNORM, + RGBA8U = VK_FORMAT_R8G8B8A8_UINT, + RGBA8_UNORM = VK_FORMAT_R8G8B8A8_UNORM, + SBGR8 = VK_FORMAT_B8G8R8_SRGB, + SBGRA8 = VK_FORMAT_B8G8R8A8_SRGB, + SR8 = VK_FORMAT_R8_SRGB, + SRG8 = VK_FORMAT_R8G8_SRGB, + SRGB8 = VK_FORMAT_R8G8B8_SRGB, + SRGBA8 = VK_FORMAT_R8G8B8A8_SRGB, + UNDEFINED = VK_FORMAT_UNDEFINED, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PolygonMode : u8 { - FILL = VK_POLYGON_MODE_FILL, - LINE = VK_POLYGON_MODE_LINE, - POINT = VK_POLYGON_MODE_POINT, - + FILL = VK_POLYGON_MODE_FILL, + LINE = VK_POLYGON_MODE_LINE, + POINT = VK_POLYGON_MODE_POINT, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PresentMode : u32 { - FIFO = VK_PRESENT_MODE_FIFO_KHR, - FIFO_RELAXED = VK_PRESENT_MODE_FIFO_RELAXED_KHR, - IMMEDIATE = VK_PRESENT_MODE_IMMEDIATE_KHR, - MAILBOX = VK_PRESENT_MODE_MAILBOX_KHR, - SHARED_CONTINUOUS_REFRESH = VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR, - SHARED_DEMAND_REFRESH = VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR, - + FIFO = VK_PRESENT_MODE_FIFO_KHR, + FIFO_RELAXED = VK_PRESENT_MODE_FIFO_RELAXED_KHR, + IMMEDIATE = VK_PRESENT_MODE_IMMEDIATE_KHR, + MAILBOX = VK_PRESENT_MODE_MAILBOX_KHR, + SHARED_CONTINUOUS_REFRESH = VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR, + SHARED_DEMAND_REFRESH = VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PrimitiveTopology : u8 { - LINE_LIST = VK_PRIMITIVE_TOPOLOGY_LINE_LIST, - LINE_STRIP = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, - POINT_LIST = VK_PRIMITIVE_TOPOLOGY_POINT_LIST, - TRIANGLE_FAN = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, - TRIANGLE_LIST = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, - TRIANGLE_STRIP = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, - + LINE_LIST = VK_PRIMITIVE_TOPOLOGY_LINE_LIST, + LINE_STRIP = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, + POINT_LIST = VK_PRIMITIVE_TOPOLOGY_POINT_LIST, + TRIANGLE_FAN = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, + TRIANGLE_LIST = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + TRIANGLE_STRIP = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class QueueFlag : u8 { - COMPUTE = VK_QUEUE_COMPUTE_BIT, - GRAPHICS = VK_QUEUE_GRAPHICS_BIT, - NONE = 0, - PROTECTED = VK_QUEUE_PROTECTED_BIT, - SPARSE_BINDING = VK_QUEUE_SPARSE_BINDING_BIT, - TRANSFER = VK_QUEUE_TRANSFER_BIT, - + COMPUTE = VK_QUEUE_COMPUTE_BIT, + GRAPHICS = VK_QUEUE_GRAPHICS_BIT, + NONE = 0, + PROTECTED = VK_QUEUE_PROTECTED_BIT, + SPARSE_BINDING = VK_QUEUE_SPARSE_BINDING_BIT, + TRANSFER = VK_QUEUE_TRANSFER_BIT, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ResolveModeFlag : u8 { - AVERAGE = VK_RESOLVE_MODE_AVERAGE_BIT, - EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID = VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID, - MAX = VK_RESOLVE_MODE_MAX_BIT, - MIN = VK_RESOLVE_MODE_MIN_BIT, - NONE = VK_RESOLVE_MODE_NONE, - SAMPLE_ZERO = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, - + AVERAGE = VK_RESOLVE_MODE_AVERAGE_BIT, + EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID = VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID, + MAX = VK_RESOLVE_MODE_MAX_BIT, + MIN = VK_RESOLVE_MODE_MIN_BIT, + NONE = VK_RESOLVE_MODE_NONE, + SAMPLE_ZERO = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class Result : i32 { - ERROR_DEVICE_LOST = VK_ERROR_DEVICE_LOST, - ERROR_EXTENSION_NOT_PRESENT = VK_ERROR_EXTENSION_NOT_PRESENT, - ERROR_FEATURE_NOT_PRESENT = VK_ERROR_FEATURE_NOT_PRESENT, - ERROR_FORMAT_NOT_SUPPORTED = VK_ERROR_FORMAT_NOT_SUPPORTED, - ERROR_FRAGMENTATION = VK_ERROR_FRAGMENTATION, - ERROR_FRAGMENTED_POOL = VK_ERROR_FRAGMENTED_POOL, - ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST = VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT, - ERROR_INCOMPATIBLE_DISPLAY = VK_ERROR_INCOMPATIBLE_DISPLAY_KHR, - ERROR_INCOMPATIBLE_DRIVER = VK_ERROR_INCOMPATIBLE_DRIVER, - ERROR_INITIALIZATION_FAILED = VK_ERROR_INITIALIZATION_FAILED, - ERROR_INVALID_EXTERNAL_HANDLE = VK_ERROR_INVALID_EXTERNAL_HANDLE, - ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, - ERROR_LAYER_NOT_PRESENT = VK_ERROR_LAYER_NOT_PRESENT, - ERROR_MEMORY_MAP_FAILED = VK_ERROR_MEMORY_MAP_FAILED, - ERROR_NATIVE_WINDOW_IN_USE = VK_ERROR_NATIVE_WINDOW_IN_USE_KHR, - ERROR_NOT_PERMITTED = VK_ERROR_NOT_PERMITTED, - ERROR_OUT_OF_DATE = VK_ERROR_OUT_OF_DATE_KHR, - ERROR_OUT_OF_DEVICE_MEMORY = VK_ERROR_OUT_OF_DEVICE_MEMORY, - ERROR_OUT_OF_HOST_MEMORY = VK_ERROR_OUT_OF_HOST_MEMORY, - ERROR_OUT_OF_POOL_MEMORY = VK_ERROR_OUT_OF_POOL_MEMORY, - ERROR_SURFACE_LOST = VK_ERROR_SURFACE_LOST_KHR, - ERROR_TOO_MANY_OBJECTS = VK_ERROR_TOO_MANY_OBJECTS, - ERROR_UNKNOWN = VK_ERROR_UNKNOWN, - ERROR_VALIDATION_FAILED = VK_ERROR_VALIDATION_FAILED_EXT, - EVENT_RESET = VK_EVENT_RESET, - EVENT_SET = VK_EVENT_SET, - INCOMPLETE = VK_INCOMPLETE, - NOT_READY = VK_NOT_READY, - OPERATION_DEFERRED = VK_OPERATION_DEFERRED_KHR, - OPERATION_NOT_DEFERRED = VK_OPERATION_NOT_DEFERRED_KHR, - PIPELINE_COMPILE_REQUIRED = VK_PIPELINE_COMPILE_REQUIRED, - SUBOPTIMAL = VK_SUBOPTIMAL_KHR, - SUCCESS = VK_SUCCESS, - THREAD_DONE = VK_THREAD_DONE_KHR, - THREAD_IDLE = VK_THREAD_IDLE_KHR, - TIMEOUT = VK_TIMEOUT, - - }; - - template <> + ERROR_DEVICE_LOST = VK_ERROR_DEVICE_LOST, + ERROR_EXTENSION_NOT_PRESENT = VK_ERROR_EXTENSION_NOT_PRESENT, + ERROR_FEATURE_NOT_PRESENT = VK_ERROR_FEATURE_NOT_PRESENT, + ERROR_FORMAT_NOT_SUPPORTED = VK_ERROR_FORMAT_NOT_SUPPORTED, + ERROR_FRAGMENTATION = VK_ERROR_FRAGMENTATION, + ERROR_FRAGMENTED_POOL = VK_ERROR_FRAGMENTED_POOL, + ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST = VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT, + ERROR_INCOMPATIBLE_DISPLAY = VK_ERROR_INCOMPATIBLE_DISPLAY_KHR, + ERROR_INCOMPATIBLE_DRIVER = VK_ERROR_INCOMPATIBLE_DRIVER, + ERROR_INITIALIZATION_FAILED = VK_ERROR_INITIALIZATION_FAILED, + ERROR_INVALID_EXTERNAL_HANDLE = VK_ERROR_INVALID_EXTERNAL_HANDLE, + ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, + ERROR_LAYER_NOT_PRESENT = VK_ERROR_LAYER_NOT_PRESENT, + ERROR_MEMORY_MAP_FAILED = VK_ERROR_MEMORY_MAP_FAILED, + ERROR_NATIVE_WINDOW_IN_USE = VK_ERROR_NATIVE_WINDOW_IN_USE_KHR, + ERROR_NOT_PERMITTED = VK_ERROR_NOT_PERMITTED, + ERROR_OUT_OF_DATE = VK_ERROR_OUT_OF_DATE_KHR, + ERROR_OUT_OF_DEVICE_MEMORY = VK_ERROR_OUT_OF_DEVICE_MEMORY, + ERROR_OUT_OF_HOST_MEMORY = VK_ERROR_OUT_OF_HOST_MEMORY, + ERROR_OUT_OF_POOL_MEMORY = VK_ERROR_OUT_OF_POOL_MEMORY, + ERROR_SURFACE_LOST = VK_ERROR_SURFACE_LOST_KHR, + ERROR_TOO_MANY_OBJECTS = VK_ERROR_TOO_MANY_OBJECTS, + ERROR_UNKNOWN = VK_ERROR_UNKNOWN, + ERROR_VALIDATION_FAILED = VK_ERROR_VALIDATION_FAILED_EXT, + EVENT_RESET = VK_EVENT_RESET, + EVENT_SET = VK_EVENT_SET, + INCOMPLETE = VK_INCOMPLETE, + NOT_READY = VK_NOT_READY, + OPERATION_DEFERRED = VK_OPERATION_DEFERRED_KHR, + OPERATION_NOT_DEFERRED = VK_OPERATION_NOT_DEFERRED_KHR, + PIPELINE_COMPILE_REQUIRED = VK_PIPELINE_COMPILE_REQUIRED, + SUBOPTIMAL = VK_SUBOPTIMAL_KHR, + SUCCESS = VK_SUCCESS, + THREAD_DONE = VK_THREAD_DONE_KHR, + THREAD_IDLE = VK_THREAD_IDLE_KHR, + TIMEOUT = VK_TIMEOUT, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class SampleCountFlag : u8 { - C1 = VK_SAMPLE_COUNT_1_BIT, - C16 = VK_SAMPLE_COUNT_16_BIT, - C2 = VK_SAMPLE_COUNT_2_BIT, - C32 = VK_SAMPLE_COUNT_32_BIT, - C4 = VK_SAMPLE_COUNT_4_BIT, - C64 = VK_SAMPLE_COUNT_64_BIT, - C8 = VK_SAMPLE_COUNT_8_BIT, - + C1 = VK_SAMPLE_COUNT_1_BIT, + C16 = VK_SAMPLE_COUNT_16_BIT, + C2 = VK_SAMPLE_COUNT_2_BIT, + C32 = VK_SAMPLE_COUNT_32_BIT, + C4 = VK_SAMPLE_COUNT_4_BIT, + C64 = VK_SAMPLE_COUNT_64_BIT, + C8 = VK_SAMPLE_COUNT_8_BIT, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class SamplerAddressMode : u8 { - CLAMP_TO_BORDER = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, - CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, - MIRROR_CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, - MIRRORED_REPEAT = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, - REPEAT = VK_SAMPLER_ADDRESS_MODE_REPEAT, - + CLAMP_TO_BORDER = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, + CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + MIRROR_CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, + MIRRORED_REPEAT = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, + REPEAT = VK_SAMPLER_ADDRESS_MODE_REPEAT, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class SamplerMipmapMode : u8 { - LINEAR = VK_SAMPLER_MIPMAP_MODE_LINEAR, - NEAREST = VK_SAMPLER_MIPMAP_MODE_NEAREST, - + LINEAR = VK_SAMPLER_MIPMAP_MODE_LINEAR, + NEAREST = VK_SAMPLER_MIPMAP_MODE_NEAREST, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ShaderStageFlag : u8 { - COMPUTE = VK_SHADER_STAGE_COMPUTE_BIT, - FRAGMENT = VK_SHADER_STAGE_FRAGMENT_BIT, - GEOMETRY = VK_SHADER_STAGE_GEOMETRY_BIT, - NONE = 0, - VERTEX = VK_SHADER_STAGE_VERTEX_BIT, - + COMPUTE = VK_SHADER_STAGE_COMPUTE_BIT, + FRAGMENT = VK_SHADER_STAGE_FRAGMENT_BIT, + GEOMETRY = VK_SHADER_STAGE_GEOMETRY_BIT, + NONE = 0, + VERTEX = VK_SHADER_STAGE_VERTEX_BIT, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class StencilFaceFlag : u8 { - BACK = VK_STENCIL_FACE_BACK_BIT, - FRONT = VK_STENCIL_FACE_FRONT_BIT, - FRONT_AND_BACK = FRONT | BACK, - + BACK = VK_STENCIL_FACE_BACK_BIT, + FRONT = VK_STENCIL_FACE_FRONT_BIT, + FRONT_AND_BACK = FRONT | BACK, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class VertexInputRate : u8 { - INSTANCE = VK_VERTEX_INPUT_RATE_INSTANCE, - VERTEX = VK_VERTEX_INPUT_RATE_VERTEX, - + INSTANCE = VK_VERTEX_INPUT_RATE_INSTANCE, + VERTEX = VK_VERTEX_INPUT_RATE_VERTEX, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - template requires(core::meta::IsPlainEnumeration or core::meta::Is) @@ -809,2665 +764,2777 @@ export { constexpr auto is_depth_stencil_format(PixelFormat format) noexcept -> bool; [[nodiscard]] constexpr auto is_depth_format(PixelFormat format) noexcept -> bool; + [[nodiscard]] + constexpr auto is_stencil_format(PixelFormat format) noexcept -> bool; [[nodiscard]] constexpr auto get_format_channel_count(PixelFormat format) noexcept -> u8; [[nodiscard]] constexpr auto get_format_element_count(PixelFormat format) noexcept -> u8; - } + } // namespace stormkit::gpu FLAG_ENUM(stormkit::gpu::AccessFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ, - stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE, - stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ, - stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE, - stormkit::gpu::AccessFlag::HOST_READ, - stormkit::gpu::AccessFlag::HOST_WRITE, - stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ, - stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ, - stormkit::gpu::AccessFlag::MEMORY_READ, - stormkit::gpu::AccessFlag::MEMORY_WRITE, - stormkit::gpu::AccessFlag::NONE, - stormkit::gpu::AccessFlag::SHADER_READ, - stormkit::gpu::AccessFlag::SHADER_WRITE, - stormkit::gpu::AccessFlag::TRANSFER_READ, - stormkit::gpu::AccessFlag::TRANSFER_WRITE, - stormkit::gpu::AccessFlag::UNIFORM_READ, - stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ, - - }; - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::AccessFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: return "AccessFlag::COLOR_ATTACHMENT_WRITE"; - case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE"; - case stormkit::gpu::AccessFlag::HOST_READ: return "AccessFlag::HOST_READ"; - case stormkit::gpu::AccessFlag::HOST_WRITE: return "AccessFlag::HOST_WRITE"; - case stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ: return "AccessFlag::INDIRECT_COMMAND_READ"; - case stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ: return "AccessFlag::INPUT_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::MEMORY_READ: return "AccessFlag::MEMORY_READ"; - case stormkit::gpu::AccessFlag::MEMORY_WRITE: return "AccessFlag::MEMORY_WRITE"; - case stormkit::gpu::AccessFlag::NONE: return "AccessFlag::NONE"; - case stormkit::gpu::AccessFlag::SHADER_READ: return "AccessFlag::SHADER_READ"; - case stormkit::gpu::AccessFlag::SHADER_WRITE: return "AccessFlag::SHADER_WRITE"; - case stormkit::gpu::AccessFlag::TRANSFER_READ: return "AccessFlag::TRANSFER_READ"; - case stormkit::gpu::AccessFlag::TRANSFER_WRITE: return "AccessFlag::TRANSFER_WRITE"; - case stormkit::gpu::AccessFlag::UNIFORM_READ: return "AccessFlag::UNIFORM_READ"; - case stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ: return "AccessFlag::VERTEX_ATTRIBUTE_READ"; - + stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ, + stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE, + stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ, + stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE, + stormkit::gpu::AccessFlag::HOST_READ, + stormkit::gpu::AccessFlag::HOST_WRITE, + stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ, + stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ, + stormkit::gpu::AccessFlag::MEMORY_READ, + stormkit::gpu::AccessFlag::MEMORY_WRITE, + stormkit::gpu::AccessFlag::NONE, + stormkit::gpu::AccessFlag::SHADER_READ, + stormkit::gpu::AccessFlag::SHADER_WRITE, + stormkit::gpu::AccessFlag::TRANSFER_READ, + stormkit::gpu::AccessFlag::TRANSFER_WRITE, + stormkit::gpu::AccessFlag::UNIFORM_READ, + stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ, + + }; + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::AccessFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: return "AccessFlag::COLOR_ATTACHMENT_WRITE"; + case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE"; + case stormkit::gpu::AccessFlag::HOST_READ: return "AccessFlag::HOST_READ"; + case stormkit::gpu::AccessFlag::HOST_WRITE: return "AccessFlag::HOST_WRITE"; + case stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ: return "AccessFlag::INDIRECT_COMMAND_READ"; + case stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ: return "AccessFlag::INPUT_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::MEMORY_READ: return "AccessFlag::MEMORY_READ"; + case stormkit::gpu::AccessFlag::MEMORY_WRITE: return "AccessFlag::MEMORY_WRITE"; + case stormkit::gpu::AccessFlag::NONE: return "AccessFlag::NONE"; + case stormkit::gpu::AccessFlag::SHADER_READ: return "AccessFlag::SHADER_READ"; + case stormkit::gpu::AccessFlag::SHADER_WRITE: return "AccessFlag::SHADER_WRITE"; + case stormkit::gpu::AccessFlag::TRANSFER_READ: return "AccessFlag::TRANSFER_READ"; + case stormkit::gpu::AccessFlag::TRANSFER_WRITE: return "AccessFlag::TRANSFER_WRITE"; + case stormkit::gpu::AccessFlag::UNIFORM_READ: return "AccessFlag::UNIFORM_READ"; + case stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ: return "AccessFlag::VERTEX_ATTRIBUTE_READ"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::AccessFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: return "AccessFlag::COLOR_ATTACHMENT_WRITE"; - case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE"; - case stormkit::gpu::AccessFlag::HOST_READ: return "AccessFlag::HOST_READ"; - case stormkit::gpu::AccessFlag::HOST_WRITE: return "AccessFlag::HOST_WRITE"; - case stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ: return "AccessFlag::INDIRECT_COMMAND_READ"; - case stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ: return "AccessFlag::INPUT_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::MEMORY_READ: return "AccessFlag::MEMORY_READ"; - case stormkit::gpu::AccessFlag::MEMORY_WRITE: return "AccessFlag::MEMORY_WRITE"; - case stormkit::gpu::AccessFlag::NONE: return "AccessFlag::NONE"; - case stormkit::gpu::AccessFlag::SHADER_READ: return "AccessFlag::SHADER_READ"; - case stormkit::gpu::AccessFlag::SHADER_WRITE: return "AccessFlag::SHADER_WRITE"; - case stormkit::gpu::AccessFlag::TRANSFER_READ: return "AccessFlag::TRANSFER_READ"; - case stormkit::gpu::AccessFlag::TRANSFER_WRITE: return "AccessFlag::TRANSFER_WRITE"; - case stormkit::gpu::AccessFlag::UNIFORM_READ: return "AccessFlag::UNIFORM_READ"; - case stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ: return "AccessFlag::VERTEX_ATTRIBUTE_READ"; - + switch (value) { + case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: return "AccessFlag::COLOR_ATTACHMENT_WRITE"; + case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE"; + case stormkit::gpu::AccessFlag::HOST_READ: return "AccessFlag::HOST_READ"; + case stormkit::gpu::AccessFlag::HOST_WRITE: return "AccessFlag::HOST_WRITE"; + case stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ: return "AccessFlag::INDIRECT_COMMAND_READ"; + case stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ: return "AccessFlag::INPUT_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::MEMORY_READ: return "AccessFlag::MEMORY_READ"; + case stormkit::gpu::AccessFlag::MEMORY_WRITE: return "AccessFlag::MEMORY_WRITE"; + case stormkit::gpu::AccessFlag::NONE: return "AccessFlag::NONE"; + case stormkit::gpu::AccessFlag::SHADER_READ: return "AccessFlag::SHADER_READ"; + case stormkit::gpu::AccessFlag::SHADER_WRITE: return "AccessFlag::SHADER_WRITE"; + case stormkit::gpu::AccessFlag::TRANSFER_READ: return "AccessFlag::TRANSFER_READ"; + case stormkit::gpu::AccessFlag::TRANSFER_WRITE: return "AccessFlag::TRANSFER_WRITE"; + case stormkit::gpu::AccessFlag::UNIFORM_READ: return "AccessFlag::UNIFORM_READ"; + case stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ: return "AccessFlag::VERTEX_ATTRIBUTE_READ"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::AttachmentLoadOperation) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::AttachmentLoadOperation::CLEAR, - stormkit::gpu::AttachmentLoadOperation::DONT_CARE, - stormkit::gpu::AttachmentLoadOperation::LOAD, - + stormkit::gpu::AttachmentLoadOperation::CLEAR, + stormkit::gpu::AttachmentLoadOperation::DONT_CARE, + stormkit::gpu::AttachmentLoadOperation::LOAD, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::AttachmentLoadOperation value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; - case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; - case stormkit::gpu::AttachmentLoadOperation::LOAD: return "AttachmentLoadOperation::LOAD"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::AttachmentLoadOperation + value) noexcept -> std::string_view { + switch (value) { + case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; + case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; + case stormkit::gpu::AttachmentLoadOperation::LOAD: return "AttachmentLoadOperation::LOAD"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentLoadOperation value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; - case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; - case stormkit::gpu::AttachmentLoadOperation::LOAD: return "AttachmentLoadOperation::LOAD"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentLoadOperation + value) noexcept -> std::string { + switch (value) { + case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; + case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; + case stormkit::gpu::AttachmentLoadOperation::LOAD: return "AttachmentLoadOperation::LOAD"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::AttachmentStoreOperation) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::AttachmentStoreOperation::DONT_CARE, - stormkit::gpu::AttachmentStoreOperation::STORE, - + stormkit::gpu::AttachmentStoreOperation::DONT_CARE, + stormkit::gpu::AttachmentStoreOperation::STORE, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::AttachmentStoreOperation value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; - case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::AttachmentStoreOperation + value) noexcept -> std::string_view { + switch (value) { + case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; + case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentStoreOperation value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; - case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentStoreOperation + value) noexcept -> std::string { + switch (value) { + case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; + case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::BlendFactor) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::BlendFactor::CONSTANT_ALPHA, - stormkit::gpu::BlendFactor::CONSTANT_COLOR, - stormkit::gpu::BlendFactor::DST_ALPHA, - stormkit::gpu::BlendFactor::DST_COLOR, - stormkit::gpu::BlendFactor::ONE, - stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA, - stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR, - stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA, - stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR, - stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA, - stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR, - stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA, - stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR, - stormkit::gpu::BlendFactor::SRC1_ALPHA, - stormkit::gpu::BlendFactor::SRC1_COLOR, - stormkit::gpu::BlendFactor::SRC_ALPHA, - stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE, - stormkit::gpu::BlendFactor::SRC_COLOR, - stormkit::gpu::BlendFactor::ZERO, - - }; - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::BlendFactor value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::BlendFactor::CONSTANT_ALPHA: return "BlendFactor::CONSTANT_ALPHA"; - case stormkit::gpu::BlendFactor::CONSTANT_COLOR: return "BlendFactor::CONSTANT_COLOR"; - case stormkit::gpu::BlendFactor::DST_ALPHA: return "BlendFactor::DST_ALPHA"; - case stormkit::gpu::BlendFactor::DST_COLOR: return "BlendFactor::DST_COLOR"; - case stormkit::gpu::BlendFactor::ONE: return "BlendFactor::ONE"; - case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: return "BlendFactor::ONE_MINUS_CONSTANT_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR: return "BlendFactor::ONE_MINUS_CONSTANT_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA: return "BlendFactor::ONE_MINUS_DST_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR: return "BlendFactor::ONE_MINUS_DST_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA: return "BlendFactor::ONE_MINUS_SRC1_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR: return "BlendFactor::ONE_MINUS_SRC1_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA: return "BlendFactor::ONE_MINUS_SRC_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR: return "BlendFactor::ONE_MINUS_SRC_COLOR"; - case stormkit::gpu::BlendFactor::SRC1_ALPHA: return "BlendFactor::SRC1_ALPHA"; - case stormkit::gpu::BlendFactor::SRC1_COLOR: return "BlendFactor::SRC1_COLOR"; - case stormkit::gpu::BlendFactor::SRC_ALPHA: return "BlendFactor::SRC_ALPHA"; - case stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE: return "BlendFactor::SRC_ALPHA_SATURATE"; - case stormkit::gpu::BlendFactor::SRC_COLOR: return "BlendFactor::SRC_COLOR"; - case stormkit::gpu::BlendFactor::ZERO: return "BlendFactor::ZERO"; - - } - std::unreachable(); - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::BlendFactor value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::BlendFactor::CONSTANT_ALPHA: return "BlendFactor::CONSTANT_ALPHA"; - case stormkit::gpu::BlendFactor::CONSTANT_COLOR: return "BlendFactor::CONSTANT_COLOR"; - case stormkit::gpu::BlendFactor::DST_ALPHA: return "BlendFactor::DST_ALPHA"; - case stormkit::gpu::BlendFactor::DST_COLOR: return "BlendFactor::DST_COLOR"; - case stormkit::gpu::BlendFactor::ONE: return "BlendFactor::ONE"; - case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: return "BlendFactor::ONE_MINUS_CONSTANT_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR: return "BlendFactor::ONE_MINUS_CONSTANT_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA: return "BlendFactor::ONE_MINUS_DST_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR: return "BlendFactor::ONE_MINUS_DST_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA: return "BlendFactor::ONE_MINUS_SRC1_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR: return "BlendFactor::ONE_MINUS_SRC1_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA: return "BlendFactor::ONE_MINUS_SRC_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR: return "BlendFactor::ONE_MINUS_SRC_COLOR"; - case stormkit::gpu::BlendFactor::SRC1_ALPHA: return "BlendFactor::SRC1_ALPHA"; - case stormkit::gpu::BlendFactor::SRC1_COLOR: return "BlendFactor::SRC1_COLOR"; - case stormkit::gpu::BlendFactor::SRC_ALPHA: return "BlendFactor::SRC_ALPHA"; - case stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE: return "BlendFactor::SRC_ALPHA_SATURATE"; - case stormkit::gpu::BlendFactor::SRC_COLOR: return "BlendFactor::SRC_COLOR"; - case stormkit::gpu::BlendFactor::ZERO: return "BlendFactor::ZERO"; - + stormkit::gpu::BlendFactor::CONSTANT_ALPHA, + stormkit::gpu::BlendFactor::CONSTANT_COLOR, + stormkit::gpu::BlendFactor::DST_ALPHA, + stormkit::gpu::BlendFactor::DST_COLOR, + stormkit::gpu::BlendFactor::ONE, + stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA, + stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR, + stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA, + stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR, + stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA, + stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR, + stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA, + stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR, + stormkit::gpu::BlendFactor::SRC1_ALPHA, + stormkit::gpu::BlendFactor::SRC1_COLOR, + stormkit::gpu::BlendFactor::SRC_ALPHA, + stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE, + stormkit::gpu::BlendFactor::SRC_COLOR, + stormkit::gpu::BlendFactor::ZERO, + + }; + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::BlendFactor value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::BlendFactor::CONSTANT_ALPHA: return "BlendFactor::CONSTANT_ALPHA"; + case stormkit::gpu::BlendFactor::CONSTANT_COLOR: return "BlendFactor::CONSTANT_COLOR"; + case stormkit::gpu::BlendFactor::DST_ALPHA: return "BlendFactor::DST_ALPHA"; + case stormkit::gpu::BlendFactor::DST_COLOR: return "BlendFactor::DST_COLOR"; + case stormkit::gpu::BlendFactor::ONE: return "BlendFactor::ONE"; + case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: return "BlendFactor::ONE_MINUS_CONSTANT_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR: return "BlendFactor::ONE_MINUS_CONSTANT_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA: return "BlendFactor::ONE_MINUS_DST_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR: return "BlendFactor::ONE_MINUS_DST_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA: return "BlendFactor::ONE_MINUS_SRC1_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR: return "BlendFactor::ONE_MINUS_SRC1_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA: return "BlendFactor::ONE_MINUS_SRC_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR: return "BlendFactor::ONE_MINUS_SRC_COLOR"; + case stormkit::gpu::BlendFactor::SRC1_ALPHA: return "BlendFactor::SRC1_ALPHA"; + case stormkit::gpu::BlendFactor::SRC1_COLOR: return "BlendFactor::SRC1_COLOR"; + case stormkit::gpu::BlendFactor::SRC_ALPHA: return "BlendFactor::SRC_ALPHA"; + case stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE: return "BlendFactor::SRC_ALPHA_SATURATE"; + case stormkit::gpu::BlendFactor::SRC_COLOR: return "BlendFactor::SRC_COLOR"; + case stormkit::gpu::BlendFactor::ZERO: return "BlendFactor::ZERO"; + } + std::unreachable(); + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::to_string(stormkit::gpu::BlendFactor value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::BlendFactor::CONSTANT_ALPHA: return "BlendFactor::CONSTANT_ALPHA"; + case stormkit::gpu::BlendFactor::CONSTANT_COLOR: return "BlendFactor::CONSTANT_COLOR"; + case stormkit::gpu::BlendFactor::DST_ALPHA: return "BlendFactor::DST_ALPHA"; + case stormkit::gpu::BlendFactor::DST_COLOR: return "BlendFactor::DST_COLOR"; + case stormkit::gpu::BlendFactor::ONE: return "BlendFactor::ONE"; + case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: return "BlendFactor::ONE_MINUS_CONSTANT_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR: return "BlendFactor::ONE_MINUS_CONSTANT_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA: return "BlendFactor::ONE_MINUS_DST_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR: return "BlendFactor::ONE_MINUS_DST_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA: return "BlendFactor::ONE_MINUS_SRC1_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR: return "BlendFactor::ONE_MINUS_SRC1_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA: return "BlendFactor::ONE_MINUS_SRC_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR: return "BlendFactor::ONE_MINUS_SRC_COLOR"; + case stormkit::gpu::BlendFactor::SRC1_ALPHA: return "BlendFactor::SRC1_ALPHA"; + case stormkit::gpu::BlendFactor::SRC1_COLOR: return "BlendFactor::SRC1_COLOR"; + case stormkit::gpu::BlendFactor::SRC_ALPHA: return "BlendFactor::SRC_ALPHA"; + case stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE: return "BlendFactor::SRC_ALPHA_SATURATE"; + case stormkit::gpu::BlendFactor::SRC_COLOR: return "BlendFactor::SRC_COLOR"; + case stormkit::gpu::BlendFactor::ZERO: return "BlendFactor::ZERO"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::BlendOperation) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::BlendOperation::ADD, - stormkit::gpu::BlendOperation::MAX, - stormkit::gpu::BlendOperation::MIN, - stormkit::gpu::BlendOperation::REVERSE_SUBTRACT, - stormkit::gpu::BlendOperation::SUBTRACT, - + stormkit::gpu::BlendOperation::ADD, stormkit::gpu::BlendOperation::MAX, + stormkit::gpu::BlendOperation::MIN, stormkit::gpu::BlendOperation::REVERSE_SUBTRACT, + stormkit::gpu::BlendOperation::SUBTRACT, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::BlendOperation value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::BlendOperation::ADD: return "BlendOperation::ADD"; - case stormkit::gpu::BlendOperation::MAX: return "BlendOperation::MAX"; - case stormkit::gpu::BlendOperation::MIN: return "BlendOperation::MIN"; - case stormkit::gpu::BlendOperation::REVERSE_SUBTRACT: return "BlendOperation::REVERSE_SUBTRACT"; - case stormkit::gpu::BlendOperation::SUBTRACT: return "BlendOperation::SUBTRACT"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::BlendOperation value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::BlendOperation::ADD: return "BlendOperation::ADD"; + case stormkit::gpu::BlendOperation::MAX: return "BlendOperation::MAX"; + case stormkit::gpu::BlendOperation::MIN: return "BlendOperation::MIN"; + case stormkit::gpu::BlendOperation::REVERSE_SUBTRACT: return "BlendOperation::REVERSE_SUBTRACT"; + case stormkit::gpu::BlendOperation::SUBTRACT: return "BlendOperation::SUBTRACT"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::BlendOperation value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::BlendOperation::ADD: return "BlendOperation::ADD"; - case stormkit::gpu::BlendOperation::MAX: return "BlendOperation::MAX"; - case stormkit::gpu::BlendOperation::MIN: return "BlendOperation::MIN"; - case stormkit::gpu::BlendOperation::REVERSE_SUBTRACT: return "BlendOperation::REVERSE_SUBTRACT"; - case stormkit::gpu::BlendOperation::SUBTRACT: return "BlendOperation::SUBTRACT"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::BlendOperation value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::BlendOperation::ADD: return "BlendOperation::ADD"; + case stormkit::gpu::BlendOperation::MAX: return "BlendOperation::MAX"; + case stormkit::gpu::BlendOperation::MIN: return "BlendOperation::MIN"; + case stormkit::gpu::BlendOperation::REVERSE_SUBTRACT: return "BlendOperation::REVERSE_SUBTRACT"; + case stormkit::gpu::BlendOperation::SUBTRACT: return "BlendOperation::SUBTRACT"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::BorderColor) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK, - stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE, - stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK, - stormkit::gpu::BorderColor::INT_OPAQUE_BLACK, - stormkit::gpu::BorderColor::INT_OPAQUE_WHITE, - stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK, - + stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK, stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE, + stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK, stormkit::gpu::BorderColor::INT_OPAQUE_BLACK, + stormkit::gpu::BorderColor::INT_OPAQUE_WHITE, stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::BorderColor value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: return "BorderColor::FLOAT_OPAQUE_BLACK"; - case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: return "BorderColor::FLOAT_OPAQUE_WHITE"; - case stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK: return "BorderColor::FLOAT_TRANSPARENT_BLACK"; - case stormkit::gpu::BorderColor::INT_OPAQUE_BLACK: return "BorderColor::INT_OPAQUE_BLACK"; - case stormkit::gpu::BorderColor::INT_OPAQUE_WHITE: return "BorderColor::INT_OPAQUE_WHITE"; - case stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK: return "BorderColor::INT_TRANSPARENT_BLACK"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::BorderColor value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: return "BorderColor::FLOAT_OPAQUE_BLACK"; + case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: return "BorderColor::FLOAT_OPAQUE_WHITE"; + case stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK: return "BorderColor::FLOAT_TRANSPARENT_BLACK"; + case stormkit::gpu::BorderColor::INT_OPAQUE_BLACK: return "BorderColor::INT_OPAQUE_BLACK"; + case stormkit::gpu::BorderColor::INT_OPAQUE_WHITE: return "BorderColor::INT_OPAQUE_WHITE"; + case stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK: return "BorderColor::INT_TRANSPARENT_BLACK"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::BorderColor value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: return "BorderColor::FLOAT_OPAQUE_BLACK"; - case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: return "BorderColor::FLOAT_OPAQUE_WHITE"; - case stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK: return "BorderColor::FLOAT_TRANSPARENT_BLACK"; - case stormkit::gpu::BorderColor::INT_OPAQUE_BLACK: return "BorderColor::INT_OPAQUE_BLACK"; - case stormkit::gpu::BorderColor::INT_OPAQUE_WHITE: return "BorderColor::INT_OPAQUE_WHITE"; - case stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK: return "BorderColor::INT_TRANSPARENT_BLACK"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::BorderColor value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: return "BorderColor::FLOAT_OPAQUE_BLACK"; + case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: return "BorderColor::FLOAT_OPAQUE_WHITE"; + case stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK: return "BorderColor::FLOAT_TRANSPARENT_BLACK"; + case stormkit::gpu::BorderColor::INT_OPAQUE_BLACK: return "BorderColor::INT_OPAQUE_BLACK"; + case stormkit::gpu::BorderColor::INT_OPAQUE_WHITE: return "BorderColor::INT_OPAQUE_WHITE"; + case stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK: return "BorderColor::INT_TRANSPARENT_BLACK"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::BufferUsageFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::BufferUsageFlag::INDEX, - stormkit::gpu::BufferUsageFlag::INDIRECT, - stormkit::gpu::BufferUsageFlag::STORAGE, - stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL, - stormkit::gpu::BufferUsageFlag::TRANSFER_DST, - stormkit::gpu::BufferUsageFlag::TRANSFER_SRC, - stormkit::gpu::BufferUsageFlag::UNIFORM, - stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL, - stormkit::gpu::BufferUsageFlag::VERTEX, - + stormkit::gpu::BufferUsageFlag::INDEX, stormkit::gpu::BufferUsageFlag::INDIRECT, + stormkit::gpu::BufferUsageFlag::STORAGE, stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL, + stormkit::gpu::BufferUsageFlag::TRANSFER_DST, stormkit::gpu::BufferUsageFlag::TRANSFER_SRC, + stormkit::gpu::BufferUsageFlag::UNIFORM, stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL, + stormkit::gpu::BufferUsageFlag::VERTEX, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::BufferUsageFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::BufferUsageFlag::INDEX: return "BufferUsageFlag::INDEX"; - case stormkit::gpu::BufferUsageFlag::INDIRECT: return "BufferUsageFlag::INDIRECT"; - case stormkit::gpu::BufferUsageFlag::STORAGE: return "BufferUsageFlag::STORAGE"; - case stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL: return "BufferUsageFlag::STORAGE_TEXEL"; - case stormkit::gpu::BufferUsageFlag::TRANSFER_DST: return "BufferUsageFlag::TRANSFER_DST"; - case stormkit::gpu::BufferUsageFlag::TRANSFER_SRC: return "BufferUsageFlag::TRANSFER_SRC"; - case stormkit::gpu::BufferUsageFlag::UNIFORM: return "BufferUsageFlag::UNIFORM"; - case stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL: return "BufferUsageFlag::UNIFORM_TEXEL"; - case stormkit::gpu::BufferUsageFlag::VERTEX: return "BufferUsageFlag::VERTEX"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::BufferUsageFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::BufferUsageFlag::INDEX: return "BufferUsageFlag::INDEX"; + case stormkit::gpu::BufferUsageFlag::INDIRECT: return "BufferUsageFlag::INDIRECT"; + case stormkit::gpu::BufferUsageFlag::STORAGE: return "BufferUsageFlag::STORAGE"; + case stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL: return "BufferUsageFlag::STORAGE_TEXEL"; + case stormkit::gpu::BufferUsageFlag::TRANSFER_DST: return "BufferUsageFlag::TRANSFER_DST"; + case stormkit::gpu::BufferUsageFlag::TRANSFER_SRC: return "BufferUsageFlag::TRANSFER_SRC"; + case stormkit::gpu::BufferUsageFlag::UNIFORM: return "BufferUsageFlag::UNIFORM"; + case stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL: return "BufferUsageFlag::UNIFORM_TEXEL"; + case stormkit::gpu::BufferUsageFlag::VERTEX: return "BufferUsageFlag::VERTEX"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::BufferUsageFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::BufferUsageFlag::INDEX: return "BufferUsageFlag::INDEX"; - case stormkit::gpu::BufferUsageFlag::INDIRECT: return "BufferUsageFlag::INDIRECT"; - case stormkit::gpu::BufferUsageFlag::STORAGE: return "BufferUsageFlag::STORAGE"; - case stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL: return "BufferUsageFlag::STORAGE_TEXEL"; - case stormkit::gpu::BufferUsageFlag::TRANSFER_DST: return "BufferUsageFlag::TRANSFER_DST"; - case stormkit::gpu::BufferUsageFlag::TRANSFER_SRC: return "BufferUsageFlag::TRANSFER_SRC"; - case stormkit::gpu::BufferUsageFlag::UNIFORM: return "BufferUsageFlag::UNIFORM"; - case stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL: return "BufferUsageFlag::UNIFORM_TEXEL"; - case stormkit::gpu::BufferUsageFlag::VERTEX: return "BufferUsageFlag::VERTEX"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::BufferUsageFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::BufferUsageFlag::INDEX: return "BufferUsageFlag::INDEX"; + case stormkit::gpu::BufferUsageFlag::INDIRECT: return "BufferUsageFlag::INDIRECT"; + case stormkit::gpu::BufferUsageFlag::STORAGE: return "BufferUsageFlag::STORAGE"; + case stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL: return "BufferUsageFlag::STORAGE_TEXEL"; + case stormkit::gpu::BufferUsageFlag::TRANSFER_DST: return "BufferUsageFlag::TRANSFER_DST"; + case stormkit::gpu::BufferUsageFlag::TRANSFER_SRC: return "BufferUsageFlag::TRANSFER_SRC"; + case stormkit::gpu::BufferUsageFlag::UNIFORM: return "BufferUsageFlag::UNIFORM"; + case stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL: return "BufferUsageFlag::UNIFORM_TEXEL"; + case stormkit::gpu::BufferUsageFlag::VERTEX: return "BufferUsageFlag::VERTEX"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ColorComponentFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ColorComponentFlag::A, - stormkit::gpu::ColorComponentFlag::B, - stormkit::gpu::ColorComponentFlag::G, - stormkit::gpu::ColorComponentFlag::NONE, - stormkit::gpu::ColorComponentFlag::R, - stormkit::gpu::ColorComponentFlag::RG, - stormkit::gpu::ColorComponentFlag::RGB, - stormkit::gpu::ColorComponentFlag::RGBA, - + stormkit::gpu::ColorComponentFlag::A, stormkit::gpu::ColorComponentFlag::B, + stormkit::gpu::ColorComponentFlag::G, stormkit::gpu::ColorComponentFlag::NONE, + stormkit::gpu::ColorComponentFlag::R, stormkit::gpu::ColorComponentFlag::RG, + stormkit::gpu::ColorComponentFlag::RGB, stormkit::gpu::ColorComponentFlag::RGBA, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ColorComponentFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ColorComponentFlag::A: return "ColorComponentFlag::A"; - case stormkit::gpu::ColorComponentFlag::B: return "ColorComponentFlag::B"; - case stormkit::gpu::ColorComponentFlag::G: return "ColorComponentFlag::G"; - case stormkit::gpu::ColorComponentFlag::NONE: return "ColorComponentFlag::NONE"; - case stormkit::gpu::ColorComponentFlag::R: return "ColorComponentFlag::R"; - case stormkit::gpu::ColorComponentFlag::RG: return "ColorComponentFlag::RG"; - case stormkit::gpu::ColorComponentFlag::RGB: return "ColorComponentFlag::RGB"; - case stormkit::gpu::ColorComponentFlag::RGBA: return "ColorComponentFlag::RGBA"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::ColorComponentFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ColorComponentFlag::A: return "ColorComponentFlag::A"; + case stormkit::gpu::ColorComponentFlag::B: return "ColorComponentFlag::B"; + case stormkit::gpu::ColorComponentFlag::G: return "ColorComponentFlag::G"; + case stormkit::gpu::ColorComponentFlag::NONE: return "ColorComponentFlag::NONE"; + case stormkit::gpu::ColorComponentFlag::R: return "ColorComponentFlag::R"; + case stormkit::gpu::ColorComponentFlag::RG: return "ColorComponentFlag::RG"; + case stormkit::gpu::ColorComponentFlag::RGB: return "ColorComponentFlag::RGB"; + case stormkit::gpu::ColorComponentFlag::RGBA: return "ColorComponentFlag::RGBA"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ColorComponentFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ColorComponentFlag::A: return "ColorComponentFlag::A"; - case stormkit::gpu::ColorComponentFlag::B: return "ColorComponentFlag::B"; - case stormkit::gpu::ColorComponentFlag::G: return "ColorComponentFlag::G"; - case stormkit::gpu::ColorComponentFlag::NONE: return "ColorComponentFlag::NONE"; - case stormkit::gpu::ColorComponentFlag::R: return "ColorComponentFlag::R"; - case stormkit::gpu::ColorComponentFlag::RG: return "ColorComponentFlag::RG"; - case stormkit::gpu::ColorComponentFlag::RGB: return "ColorComponentFlag::RGB"; - case stormkit::gpu::ColorComponentFlag::RGBA: return "ColorComponentFlag::RGBA"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::ColorComponentFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::ColorComponentFlag::A: return "ColorComponentFlag::A"; + case stormkit::gpu::ColorComponentFlag::B: return "ColorComponentFlag::B"; + case stormkit::gpu::ColorComponentFlag::G: return "ColorComponentFlag::G"; + case stormkit::gpu::ColorComponentFlag::NONE: return "ColorComponentFlag::NONE"; + case stormkit::gpu::ColorComponentFlag::R: return "ColorComponentFlag::R"; + case stormkit::gpu::ColorComponentFlag::RG: return "ColorComponentFlag::RG"; + case stormkit::gpu::ColorComponentFlag::RGB: return "ColorComponentFlag::RGB"; + case stormkit::gpu::ColorComponentFlag::RGBA: return "ColorComponentFlag::RGBA"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ColorSpace) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ColorSpace::ADOBERGB_LINEAR, - stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR, - stormkit::gpu::ColorSpace::BT2020_LINEAR, - stormkit::gpu::ColorSpace::BT709_LINEAR, - stormkit::gpu::ColorSpace::BT709_NONLINEAR, - stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR, - stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD, - stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR, - stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR, - stormkit::gpu::ColorSpace::DOLBYVISION, - stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR, - stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR, - stormkit::gpu::ColorSpace::HDR10_HLG, - stormkit::gpu::ColorSpace::HDR10_ST2084, - stormkit::gpu::ColorSpace::PASS_THROUGH, - stormkit::gpu::ColorSpace::SRGB_NONLINEAR, - + stormkit::gpu::ColorSpace::ADOBERGB_LINEAR, + stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR, + stormkit::gpu::ColorSpace::BT2020_LINEAR, + stormkit::gpu::ColorSpace::BT709_LINEAR, + stormkit::gpu::ColorSpace::BT709_NONLINEAR, + stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR, + stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD, + stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR, + stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR, + stormkit::gpu::ColorSpace::DOLBYVISION, + stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR, + stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR, + stormkit::gpu::ColorSpace::HDR10_HLG, + stormkit::gpu::ColorSpace::HDR10_ST2084, + stormkit::gpu::ColorSpace::PASS_THROUGH, + stormkit::gpu::ColorSpace::SRGB_NONLINEAR, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ColorSpace value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; - case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: return "ColorSpace::ADOBERGB_NONLINEAR"; - case stormkit::gpu::ColorSpace::BT2020_LINEAR: return "ColorSpace::BT2020_LINEAR"; - case stormkit::gpu::ColorSpace::BT709_LINEAR: return "ColorSpace::BT709_LINEAR"; - case stormkit::gpu::ColorSpace::BT709_NONLINEAR: return "ColorSpace::BT709_NONLINEAR"; - case stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR: return "ColorSpace::DCI_P3_NONLINEAR"; - case stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD: return "ColorSpace::DISPLAY_NATIVE_AMD"; - case stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR: return "ColorSpace::DISPLAY_P3_LINEAR"; - case stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR: return "ColorSpace::DISPLAY_P3_NONLINEAR"; - case stormkit::gpu::ColorSpace::DOLBYVISION: return "ColorSpace::DOLBYVISION"; - case stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR: return "ColorSpace::EXTENDED_SRGB_LINEAR"; - case stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR: return "ColorSpace::EXTENDED_SRGB_NONLINEAR"; - case stormkit::gpu::ColorSpace::HDR10_HLG: return "ColorSpace::HDR10_HLG"; - case stormkit::gpu::ColorSpace::HDR10_ST2084: return "ColorSpace::HDR10_ST2084"; - case stormkit::gpu::ColorSpace::PASS_THROUGH: return "ColorSpace::PASS_THROUGH"; - case stormkit::gpu::ColorSpace::SRGB_NONLINEAR: return "ColorSpace::SRGB_NONLINEAR"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::ColorSpace value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; + case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: return "ColorSpace::ADOBERGB_NONLINEAR"; + case stormkit::gpu::ColorSpace::BT2020_LINEAR: return "ColorSpace::BT2020_LINEAR"; + case stormkit::gpu::ColorSpace::BT709_LINEAR: return "ColorSpace::BT709_LINEAR"; + case stormkit::gpu::ColorSpace::BT709_NONLINEAR: return "ColorSpace::BT709_NONLINEAR"; + case stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR: return "ColorSpace::DCI_P3_NONLINEAR"; + case stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD: return "ColorSpace::DISPLAY_NATIVE_AMD"; + case stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR: return "ColorSpace::DISPLAY_P3_LINEAR"; + case stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR: return "ColorSpace::DISPLAY_P3_NONLINEAR"; + case stormkit::gpu::ColorSpace::DOLBYVISION: return "ColorSpace::DOLBYVISION"; + case stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR: return "ColorSpace::EXTENDED_SRGB_LINEAR"; + case stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR: return "ColorSpace::EXTENDED_SRGB_NONLINEAR"; + case stormkit::gpu::ColorSpace::HDR10_HLG: return "ColorSpace::HDR10_HLG"; + case stormkit::gpu::ColorSpace::HDR10_ST2084: return "ColorSpace::HDR10_ST2084"; + case stormkit::gpu::ColorSpace::PASS_THROUGH: return "ColorSpace::PASS_THROUGH"; + case stormkit::gpu::ColorSpace::SRGB_NONLINEAR: return "ColorSpace::SRGB_NONLINEAR"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::ColorSpace value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; - case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: return "ColorSpace::ADOBERGB_NONLINEAR"; - case stormkit::gpu::ColorSpace::BT2020_LINEAR: return "ColorSpace::BT2020_LINEAR"; - case stormkit::gpu::ColorSpace::BT709_LINEAR: return "ColorSpace::BT709_LINEAR"; - case stormkit::gpu::ColorSpace::BT709_NONLINEAR: return "ColorSpace::BT709_NONLINEAR"; - case stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR: return "ColorSpace::DCI_P3_NONLINEAR"; - case stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD: return "ColorSpace::DISPLAY_NATIVE_AMD"; - case stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR: return "ColorSpace::DISPLAY_P3_LINEAR"; - case stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR: return "ColorSpace::DISPLAY_P3_NONLINEAR"; - case stormkit::gpu::ColorSpace::DOLBYVISION: return "ColorSpace::DOLBYVISION"; - case stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR: return "ColorSpace::EXTENDED_SRGB_LINEAR"; - case stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR: return "ColorSpace::EXTENDED_SRGB_NONLINEAR"; - case stormkit::gpu::ColorSpace::HDR10_HLG: return "ColorSpace::HDR10_HLG"; - case stormkit::gpu::ColorSpace::HDR10_ST2084: return "ColorSpace::HDR10_ST2084"; - case stormkit::gpu::ColorSpace::PASS_THROUGH: return "ColorSpace::PASS_THROUGH"; - case stormkit::gpu::ColorSpace::SRGB_NONLINEAR: return "ColorSpace::SRGB_NONLINEAR"; - + switch (value) { + case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; + case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: return "ColorSpace::ADOBERGB_NONLINEAR"; + case stormkit::gpu::ColorSpace::BT2020_LINEAR: return "ColorSpace::BT2020_LINEAR"; + case stormkit::gpu::ColorSpace::BT709_LINEAR: return "ColorSpace::BT709_LINEAR"; + case stormkit::gpu::ColorSpace::BT709_NONLINEAR: return "ColorSpace::BT709_NONLINEAR"; + case stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR: return "ColorSpace::DCI_P3_NONLINEAR"; + case stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD: return "ColorSpace::DISPLAY_NATIVE_AMD"; + case stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR: return "ColorSpace::DISPLAY_P3_LINEAR"; + case stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR: return "ColorSpace::DISPLAY_P3_NONLINEAR"; + case stormkit::gpu::ColorSpace::DOLBYVISION: return "ColorSpace::DOLBYVISION"; + case stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR: return "ColorSpace::EXTENDED_SRGB_LINEAR"; + case stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR: return "ColorSpace::EXTENDED_SRGB_NONLINEAR"; + case stormkit::gpu::ColorSpace::HDR10_HLG: return "ColorSpace::HDR10_HLG"; + case stormkit::gpu::ColorSpace::HDR10_ST2084: return "ColorSpace::HDR10_ST2084"; + case stormkit::gpu::ColorSpace::PASS_THROUGH: return "ColorSpace::PASS_THROUGH"; + case stormkit::gpu::ColorSpace::SRGB_NONLINEAR: return "ColorSpace::SRGB_NONLINEAR"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::CommandBufferLevel) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::CommandBufferLevel::PRIMARY, - stormkit::gpu::CommandBufferLevel::SECONDARY, - + stormkit::gpu::CommandBufferLevel::PRIMARY, + stormkit::gpu::CommandBufferLevel::SECONDARY, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::CommandBufferLevel value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::CommandBufferLevel::PRIMARY: return "CommandBufferLevel::PRIMARY"; - case stormkit::gpu::CommandBufferLevel::SECONDARY: return "CommandBufferLevel::SECONDARY"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::CommandBufferLevel value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::CommandBufferLevel::PRIMARY: return "CommandBufferLevel::PRIMARY"; + case stormkit::gpu::CommandBufferLevel::SECONDARY: return "CommandBufferLevel::SECONDARY"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::CommandBufferLevel value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::CommandBufferLevel::PRIMARY: return "CommandBufferLevel::PRIMARY"; - case stormkit::gpu::CommandBufferLevel::SECONDARY: return "CommandBufferLevel::SECONDARY"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::CommandBufferLevel value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::CommandBufferLevel::PRIMARY: return "CommandBufferLevel::PRIMARY"; + case stormkit::gpu::CommandBufferLevel::SECONDARY: return "CommandBufferLevel::SECONDARY"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::CompareOperation) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::CompareOperation::ALWAYS, - stormkit::gpu::CompareOperation::EQUAL, - stormkit::gpu::CompareOperation::GREATER, - stormkit::gpu::CompareOperation::GREATER_OR_EQUAL, - stormkit::gpu::CompareOperation::LESS, - stormkit::gpu::CompareOperation::LESS_OR_EQUAL, - stormkit::gpu::CompareOperation::NEVER, - stormkit::gpu::CompareOperation::NOT_EQUAL, - + stormkit::gpu::CompareOperation::ALWAYS, stormkit::gpu::CompareOperation::EQUAL, + stormkit::gpu::CompareOperation::GREATER, stormkit::gpu::CompareOperation::GREATER_OR_EQUAL, + stormkit::gpu::CompareOperation::LESS, stormkit::gpu::CompareOperation::LESS_OR_EQUAL, + stormkit::gpu::CompareOperation::NEVER, stormkit::gpu::CompareOperation::NOT_EQUAL, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::CompareOperation value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::CompareOperation::ALWAYS: return "CompareOperation::ALWAYS"; - case stormkit::gpu::CompareOperation::EQUAL: return "CompareOperation::EQUAL"; - case stormkit::gpu::CompareOperation::GREATER: return "CompareOperation::GREATER"; - case stormkit::gpu::CompareOperation::GREATER_OR_EQUAL: return "CompareOperation::GREATER_OR_EQUAL"; - case stormkit::gpu::CompareOperation::LESS: return "CompareOperation::LESS"; - case stormkit::gpu::CompareOperation::LESS_OR_EQUAL: return "CompareOperation::LESS_OR_EQUAL"; - case stormkit::gpu::CompareOperation::NEVER: return "CompareOperation::NEVER"; - case stormkit::gpu::CompareOperation::NOT_EQUAL: return "CompareOperation::NOT_EQUAL"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::CompareOperation value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::CompareOperation::ALWAYS: return "CompareOperation::ALWAYS"; + case stormkit::gpu::CompareOperation::EQUAL: return "CompareOperation::EQUAL"; + case stormkit::gpu::CompareOperation::GREATER: return "CompareOperation::GREATER"; + case stormkit::gpu::CompareOperation::GREATER_OR_EQUAL: return "CompareOperation::GREATER_OR_EQUAL"; + case stormkit::gpu::CompareOperation::LESS: return "CompareOperation::LESS"; + case stormkit::gpu::CompareOperation::LESS_OR_EQUAL: return "CompareOperation::LESS_OR_EQUAL"; + case stormkit::gpu::CompareOperation::NEVER: return "CompareOperation::NEVER"; + case stormkit::gpu::CompareOperation::NOT_EQUAL: return "CompareOperation::NOT_EQUAL"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::CompareOperation value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::CompareOperation::ALWAYS: return "CompareOperation::ALWAYS"; - case stormkit::gpu::CompareOperation::EQUAL: return "CompareOperation::EQUAL"; - case stormkit::gpu::CompareOperation::GREATER: return "CompareOperation::GREATER"; - case stormkit::gpu::CompareOperation::GREATER_OR_EQUAL: return "CompareOperation::GREATER_OR_EQUAL"; - case stormkit::gpu::CompareOperation::LESS: return "CompareOperation::LESS"; - case stormkit::gpu::CompareOperation::LESS_OR_EQUAL: return "CompareOperation::LESS_OR_EQUAL"; - case stormkit::gpu::CompareOperation::NEVER: return "CompareOperation::NEVER"; - case stormkit::gpu::CompareOperation::NOT_EQUAL: return "CompareOperation::NOT_EQUAL"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::CompareOperation value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::CompareOperation::ALWAYS: return "CompareOperation::ALWAYS"; + case stormkit::gpu::CompareOperation::EQUAL: return "CompareOperation::EQUAL"; + case stormkit::gpu::CompareOperation::GREATER: return "CompareOperation::GREATER"; + case stormkit::gpu::CompareOperation::GREATER_OR_EQUAL: return "CompareOperation::GREATER_OR_EQUAL"; + case stormkit::gpu::CompareOperation::LESS: return "CompareOperation::LESS"; + case stormkit::gpu::CompareOperation::LESS_OR_EQUAL: return "CompareOperation::LESS_OR_EQUAL"; + case stormkit::gpu::CompareOperation::NEVER: return "CompareOperation::NEVER"; + case stormkit::gpu::CompareOperation::NOT_EQUAL: return "CompareOperation::NOT_EQUAL"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::CullModeFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::CullModeFlag::BACK, - stormkit::gpu::CullModeFlag::FRONT, - stormkit::gpu::CullModeFlag::FRONT_BACK, - stormkit::gpu::CullModeFlag::NONE, - + stormkit::gpu::CullModeFlag::BACK, + stormkit::gpu::CullModeFlag::FRONT, + stormkit::gpu::CullModeFlag::FRONT_BACK, + stormkit::gpu::CullModeFlag::NONE, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::CullModeFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::CullModeFlag::BACK: return "CullModeFlag::BACK"; - case stormkit::gpu::CullModeFlag::FRONT: return "CullModeFlag::FRONT"; - case stormkit::gpu::CullModeFlag::FRONT_BACK: return "CullModeFlag::FRONT_BACK"; - case stormkit::gpu::CullModeFlag::NONE: return "CullModeFlag::NONE"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::CullModeFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::CullModeFlag::BACK: return "CullModeFlag::BACK"; + case stormkit::gpu::CullModeFlag::FRONT: return "CullModeFlag::FRONT"; + case stormkit::gpu::CullModeFlag::FRONT_BACK: return "CullModeFlag::FRONT_BACK"; + case stormkit::gpu::CullModeFlag::NONE: return "CullModeFlag::NONE"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::CullModeFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::CullModeFlag::BACK: return "CullModeFlag::BACK"; - case stormkit::gpu::CullModeFlag::FRONT: return "CullModeFlag::FRONT"; - case stormkit::gpu::CullModeFlag::FRONT_BACK: return "CullModeFlag::FRONT_BACK"; - case stormkit::gpu::CullModeFlag::NONE: return "CullModeFlag::NONE"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::CullModeFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::CullModeFlag::BACK: return "CullModeFlag::BACK"; + case stormkit::gpu::CullModeFlag::FRONT: return "CullModeFlag::FRONT"; + case stormkit::gpu::CullModeFlag::FRONT_BACK: return "CullModeFlag::FRONT_BACK"; + case stormkit::gpu::CullModeFlag::NONE: return "CullModeFlag::NONE"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::DebugObjectType) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::DebugObjectType::BUFFER, - stormkit::gpu::DebugObjectType::BUFFER_VIEW, - stormkit::gpu::DebugObjectType::COMMAND_BUFFER, - stormkit::gpu::DebugObjectType::COMMAND_POOL, - stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK, - stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL, - stormkit::gpu::DebugObjectType::DESCRIPTOR_SET, - stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT, - stormkit::gpu::DebugObjectType::DEVICE, - stormkit::gpu::DebugObjectType::DEVICE_MEMORY, - stormkit::gpu::DebugObjectType::DISPLAY, - stormkit::gpu::DebugObjectType::EVENT, - stormkit::gpu::DebugObjectType::FENCE, - stormkit::gpu::DebugObjectType::FRAMEBUFFER, - stormkit::gpu::DebugObjectType::IMAGE, - stormkit::gpu::DebugObjectType::IMAGE_VIEW, - stormkit::gpu::DebugObjectType::INSTANCE, - stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE, - stormkit::gpu::DebugObjectType::PIPELINE, - stormkit::gpu::DebugObjectType::PIPELINE_CACHE, - stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT, - stormkit::gpu::DebugObjectType::QUERY_POOL, - stormkit::gpu::DebugObjectType::QUEUE, - stormkit::gpu::DebugObjectType::RENDER_PASS, - stormkit::gpu::DebugObjectType::SAMPLER, - stormkit::gpu::DebugObjectType::SEMAPHORE, - stormkit::gpu::DebugObjectType::SHADER_MODULE, - stormkit::gpu::DebugObjectType::SURFACE, - stormkit::gpu::DebugObjectType::SWAPCHAIN, - stormkit::gpu::DebugObjectType::UNKNOWN, - - }; - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::DebugObjectType value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::DebugObjectType::BUFFER: return "DebugObjectType::BUFFER"; - case stormkit::gpu::DebugObjectType::BUFFER_VIEW: return "DebugObjectType::BUFFER_VIEW"; - case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: return "DebugObjectType::COMMAND_BUFFER"; - case stormkit::gpu::DebugObjectType::COMMAND_POOL: return "DebugObjectType::COMMAND_POOL"; - case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: return "DebugObjectType::DEBUG_REPORT_CALLBACK"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: return "DebugObjectType::DESCRIPTOR_POOL"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: return "DebugObjectType::DESCRIPTOR_SET"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; - case stormkit::gpu::DebugObjectType::DEVICE: return "DebugObjectType::DEVICE"; - case stormkit::gpu::DebugObjectType::DEVICE_MEMORY: return "DebugObjectType::DEVICE_MEMORY"; - case stormkit::gpu::DebugObjectType::DISPLAY: return "DebugObjectType::DISPLAY"; - case stormkit::gpu::DebugObjectType::EVENT: return "DebugObjectType::EVENT"; - case stormkit::gpu::DebugObjectType::FENCE: return "DebugObjectType::FENCE"; - case stormkit::gpu::DebugObjectType::FRAMEBUFFER: return "DebugObjectType::FRAMEBUFFER"; - case stormkit::gpu::DebugObjectType::IMAGE: return "DebugObjectType::IMAGE"; - case stormkit::gpu::DebugObjectType::IMAGE_VIEW: return "DebugObjectType::IMAGE_VIEW"; - case stormkit::gpu::DebugObjectType::INSTANCE: return "DebugObjectType::INSTANCE"; - case stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE: return "DebugObjectType::PHYSICAL_DEVICE"; - case stormkit::gpu::DebugObjectType::PIPELINE: return "DebugObjectType::PIPELINE"; - case stormkit::gpu::DebugObjectType::PIPELINE_CACHE: return "DebugObjectType::PIPELINE_CACHE"; - case stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT: return "DebugObjectType::PIPELINE_LAYOUT"; - case stormkit::gpu::DebugObjectType::QUERY_POOL: return "DebugObjectType::QUERY_POOL"; - case stormkit::gpu::DebugObjectType::QUEUE: return "DebugObjectType::QUEUE"; - case stormkit::gpu::DebugObjectType::RENDER_PASS: return "DebugObjectType::RENDER_PASS"; - case stormkit::gpu::DebugObjectType::SAMPLER: return "DebugObjectType::SAMPLER"; - case stormkit::gpu::DebugObjectType::SEMAPHORE: return "DebugObjectType::SEMAPHORE"; - case stormkit::gpu::DebugObjectType::SHADER_MODULE: return "DebugObjectType::SHADER_MODULE"; - case stormkit::gpu::DebugObjectType::SURFACE: return "DebugObjectType::SURFACE"; - case stormkit::gpu::DebugObjectType::SWAPCHAIN: return "DebugObjectType::SWAPCHAIN"; - case stormkit::gpu::DebugObjectType::UNKNOWN: return "DebugObjectType::UNKNOWN"; - - } - std::unreachable(); - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::DebugObjectType value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::DebugObjectType::BUFFER: return "DebugObjectType::BUFFER"; - case stormkit::gpu::DebugObjectType::BUFFER_VIEW: return "DebugObjectType::BUFFER_VIEW"; - case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: return "DebugObjectType::COMMAND_BUFFER"; - case stormkit::gpu::DebugObjectType::COMMAND_POOL: return "DebugObjectType::COMMAND_POOL"; - case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: return "DebugObjectType::DEBUG_REPORT_CALLBACK"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: return "DebugObjectType::DESCRIPTOR_POOL"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: return "DebugObjectType::DESCRIPTOR_SET"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; - case stormkit::gpu::DebugObjectType::DEVICE: return "DebugObjectType::DEVICE"; - case stormkit::gpu::DebugObjectType::DEVICE_MEMORY: return "DebugObjectType::DEVICE_MEMORY"; - case stormkit::gpu::DebugObjectType::DISPLAY: return "DebugObjectType::DISPLAY"; - case stormkit::gpu::DebugObjectType::EVENT: return "DebugObjectType::EVENT"; - case stormkit::gpu::DebugObjectType::FENCE: return "DebugObjectType::FENCE"; - case stormkit::gpu::DebugObjectType::FRAMEBUFFER: return "DebugObjectType::FRAMEBUFFER"; - case stormkit::gpu::DebugObjectType::IMAGE: return "DebugObjectType::IMAGE"; - case stormkit::gpu::DebugObjectType::IMAGE_VIEW: return "DebugObjectType::IMAGE_VIEW"; - case stormkit::gpu::DebugObjectType::INSTANCE: return "DebugObjectType::INSTANCE"; - case stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE: return "DebugObjectType::PHYSICAL_DEVICE"; - case stormkit::gpu::DebugObjectType::PIPELINE: return "DebugObjectType::PIPELINE"; - case stormkit::gpu::DebugObjectType::PIPELINE_CACHE: return "DebugObjectType::PIPELINE_CACHE"; - case stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT: return "DebugObjectType::PIPELINE_LAYOUT"; - case stormkit::gpu::DebugObjectType::QUERY_POOL: return "DebugObjectType::QUERY_POOL"; - case stormkit::gpu::DebugObjectType::QUEUE: return "DebugObjectType::QUEUE"; - case stormkit::gpu::DebugObjectType::RENDER_PASS: return "DebugObjectType::RENDER_PASS"; - case stormkit::gpu::DebugObjectType::SAMPLER: return "DebugObjectType::SAMPLER"; - case stormkit::gpu::DebugObjectType::SEMAPHORE: return "DebugObjectType::SEMAPHORE"; - case stormkit::gpu::DebugObjectType::SHADER_MODULE: return "DebugObjectType::SHADER_MODULE"; - case stormkit::gpu::DebugObjectType::SURFACE: return "DebugObjectType::SURFACE"; - case stormkit::gpu::DebugObjectType::SWAPCHAIN: return "DebugObjectType::SWAPCHAIN"; - case stormkit::gpu::DebugObjectType::UNKNOWN: return "DebugObjectType::UNKNOWN"; - + stormkit::gpu::DebugObjectType::BUFFER, + stormkit::gpu::DebugObjectType::BUFFER_VIEW, + stormkit::gpu::DebugObjectType::COMMAND_BUFFER, + stormkit::gpu::DebugObjectType::COMMAND_POOL, + stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK, + stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL, + stormkit::gpu::DebugObjectType::DESCRIPTOR_SET, + stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT, + stormkit::gpu::DebugObjectType::DEVICE, + stormkit::gpu::DebugObjectType::DEVICE_MEMORY, + stormkit::gpu::DebugObjectType::DISPLAY, + stormkit::gpu::DebugObjectType::EVENT, + stormkit::gpu::DebugObjectType::FENCE, + stormkit::gpu::DebugObjectType::FRAMEBUFFER, + stormkit::gpu::DebugObjectType::IMAGE, + stormkit::gpu::DebugObjectType::IMAGE_VIEW, + stormkit::gpu::DebugObjectType::INSTANCE, + stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE, + stormkit::gpu::DebugObjectType::PIPELINE, + stormkit::gpu::DebugObjectType::PIPELINE_CACHE, + stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT, + stormkit::gpu::DebugObjectType::QUERY_POOL, + stormkit::gpu::DebugObjectType::QUEUE, + stormkit::gpu::DebugObjectType::RENDER_PASS, + stormkit::gpu::DebugObjectType::SAMPLER, + stormkit::gpu::DebugObjectType::SEMAPHORE, + stormkit::gpu::DebugObjectType::SHADER_MODULE, + stormkit::gpu::DebugObjectType::SURFACE, + stormkit::gpu::DebugObjectType::SWAPCHAIN, + stormkit::gpu::DebugObjectType::UNKNOWN, + + }; + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::DebugObjectType value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::DebugObjectType::BUFFER: return "DebugObjectType::BUFFER"; + case stormkit::gpu::DebugObjectType::BUFFER_VIEW: return "DebugObjectType::BUFFER_VIEW"; + case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: return "DebugObjectType::COMMAND_BUFFER"; + case stormkit::gpu::DebugObjectType::COMMAND_POOL: return "DebugObjectType::COMMAND_POOL"; + case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: return "DebugObjectType::DEBUG_REPORT_CALLBACK"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: return "DebugObjectType::DESCRIPTOR_POOL"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: return "DebugObjectType::DESCRIPTOR_SET"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; + case stormkit::gpu::DebugObjectType::DEVICE: return "DebugObjectType::DEVICE"; + case stormkit::gpu::DebugObjectType::DEVICE_MEMORY: return "DebugObjectType::DEVICE_MEMORY"; + case stormkit::gpu::DebugObjectType::DISPLAY: return "DebugObjectType::DISPLAY"; + case stormkit::gpu::DebugObjectType::EVENT: return "DebugObjectType::EVENT"; + case stormkit::gpu::DebugObjectType::FENCE: return "DebugObjectType::FENCE"; + case stormkit::gpu::DebugObjectType::FRAMEBUFFER: return "DebugObjectType::FRAMEBUFFER"; + case stormkit::gpu::DebugObjectType::IMAGE: return "DebugObjectType::IMAGE"; + case stormkit::gpu::DebugObjectType::IMAGE_VIEW: return "DebugObjectType::IMAGE_VIEW"; + case stormkit::gpu::DebugObjectType::INSTANCE: return "DebugObjectType::INSTANCE"; + case stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE: return "DebugObjectType::PHYSICAL_DEVICE"; + case stormkit::gpu::DebugObjectType::PIPELINE: return "DebugObjectType::PIPELINE"; + case stormkit::gpu::DebugObjectType::PIPELINE_CACHE: return "DebugObjectType::PIPELINE_CACHE"; + case stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT: return "DebugObjectType::PIPELINE_LAYOUT"; + case stormkit::gpu::DebugObjectType::QUERY_POOL: return "DebugObjectType::QUERY_POOL"; + case stormkit::gpu::DebugObjectType::QUEUE: return "DebugObjectType::QUEUE"; + case stormkit::gpu::DebugObjectType::RENDER_PASS: return "DebugObjectType::RENDER_PASS"; + case stormkit::gpu::DebugObjectType::SAMPLER: return "DebugObjectType::SAMPLER"; + case stormkit::gpu::DebugObjectType::SEMAPHORE: return "DebugObjectType::SEMAPHORE"; + case stormkit::gpu::DebugObjectType::SHADER_MODULE: return "DebugObjectType::SHADER_MODULE"; + case stormkit::gpu::DebugObjectType::SURFACE: return "DebugObjectType::SURFACE"; + case stormkit::gpu::DebugObjectType::SWAPCHAIN: return "DebugObjectType::SWAPCHAIN"; + case stormkit::gpu::DebugObjectType::UNKNOWN: return "DebugObjectType::UNKNOWN"; + } + std::unreachable(); + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::to_string(stormkit::gpu::DebugObjectType value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::DebugObjectType::BUFFER: return "DebugObjectType::BUFFER"; + case stormkit::gpu::DebugObjectType::BUFFER_VIEW: return "DebugObjectType::BUFFER_VIEW"; + case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: return "DebugObjectType::COMMAND_BUFFER"; + case stormkit::gpu::DebugObjectType::COMMAND_POOL: return "DebugObjectType::COMMAND_POOL"; + case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: return "DebugObjectType::DEBUG_REPORT_CALLBACK"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: return "DebugObjectType::DESCRIPTOR_POOL"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: return "DebugObjectType::DESCRIPTOR_SET"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; + case stormkit::gpu::DebugObjectType::DEVICE: return "DebugObjectType::DEVICE"; + case stormkit::gpu::DebugObjectType::DEVICE_MEMORY: return "DebugObjectType::DEVICE_MEMORY"; + case stormkit::gpu::DebugObjectType::DISPLAY: return "DebugObjectType::DISPLAY"; + case stormkit::gpu::DebugObjectType::EVENT: return "DebugObjectType::EVENT"; + case stormkit::gpu::DebugObjectType::FENCE: return "DebugObjectType::FENCE"; + case stormkit::gpu::DebugObjectType::FRAMEBUFFER: return "DebugObjectType::FRAMEBUFFER"; + case stormkit::gpu::DebugObjectType::IMAGE: return "DebugObjectType::IMAGE"; + case stormkit::gpu::DebugObjectType::IMAGE_VIEW: return "DebugObjectType::IMAGE_VIEW"; + case stormkit::gpu::DebugObjectType::INSTANCE: return "DebugObjectType::INSTANCE"; + case stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE: return "DebugObjectType::PHYSICAL_DEVICE"; + case stormkit::gpu::DebugObjectType::PIPELINE: return "DebugObjectType::PIPELINE"; + case stormkit::gpu::DebugObjectType::PIPELINE_CACHE: return "DebugObjectType::PIPELINE_CACHE"; + case stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT: return "DebugObjectType::PIPELINE_LAYOUT"; + case stormkit::gpu::DebugObjectType::QUERY_POOL: return "DebugObjectType::QUERY_POOL"; + case stormkit::gpu::DebugObjectType::QUEUE: return "DebugObjectType::QUEUE"; + case stormkit::gpu::DebugObjectType::RENDER_PASS: return "DebugObjectType::RENDER_PASS"; + case stormkit::gpu::DebugObjectType::SAMPLER: return "DebugObjectType::SAMPLER"; + case stormkit::gpu::DebugObjectType::SEMAPHORE: return "DebugObjectType::SEMAPHORE"; + case stormkit::gpu::DebugObjectType::SHADER_MODULE: return "DebugObjectType::SHADER_MODULE"; + case stormkit::gpu::DebugObjectType::SURFACE: return "DebugObjectType::SURFACE"; + case stormkit::gpu::DebugObjectType::SWAPCHAIN: return "DebugObjectType::SWAPCHAIN"; + case stormkit::gpu::DebugObjectType::UNKNOWN: return "DebugObjectType::UNKNOWN"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::DependencyFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::DependencyFlag::BY_REGION, - stormkit::gpu::DependencyFlag::DEVICE_GROUP, - stormkit::gpu::DependencyFlag::NONE, - stormkit::gpu::DependencyFlag::VIEW_LOCAL, - + stormkit::gpu::DependencyFlag::BY_REGION, + stormkit::gpu::DependencyFlag::DEVICE_GROUP, + stormkit::gpu::DependencyFlag::NONE, + stormkit::gpu::DependencyFlag::VIEW_LOCAL, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::DependencyFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::DependencyFlag::BY_REGION: return "DependencyFlag::BY_REGION"; - case stormkit::gpu::DependencyFlag::DEVICE_GROUP: return "DependencyFlag::DEVICE_GROUP"; - case stormkit::gpu::DependencyFlag::NONE: return "DependencyFlag::NONE"; - case stormkit::gpu::DependencyFlag::VIEW_LOCAL: return "DependencyFlag::VIEW_LOCAL"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::DependencyFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::DependencyFlag::BY_REGION: return "DependencyFlag::BY_REGION"; + case stormkit::gpu::DependencyFlag::DEVICE_GROUP: return "DependencyFlag::DEVICE_GROUP"; + case stormkit::gpu::DependencyFlag::NONE: return "DependencyFlag::NONE"; + case stormkit::gpu::DependencyFlag::VIEW_LOCAL: return "DependencyFlag::VIEW_LOCAL"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::DependencyFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::DependencyFlag::BY_REGION: return "DependencyFlag::BY_REGION"; - case stormkit::gpu::DependencyFlag::DEVICE_GROUP: return "DependencyFlag::DEVICE_GROUP"; - case stormkit::gpu::DependencyFlag::NONE: return "DependencyFlag::NONE"; - case stormkit::gpu::DependencyFlag::VIEW_LOCAL: return "DependencyFlag::VIEW_LOCAL"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::DependencyFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::DependencyFlag::BY_REGION: return "DependencyFlag::BY_REGION"; + case stormkit::gpu::DependencyFlag::DEVICE_GROUP: return "DependencyFlag::DEVICE_GROUP"; + case stormkit::gpu::DependencyFlag::NONE: return "DependencyFlag::NONE"; + case stormkit::gpu::DependencyFlag::VIEW_LOCAL: return "DependencyFlag::VIEW_LOCAL"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::DescriptorType) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, - stormkit::gpu::DescriptorType::INPUT_ATTACHMENT, - stormkit::gpu::DescriptorType::SAMPLED_IMAGE, - stormkit::gpu::DescriptorType::SAMPLER, - stormkit::gpu::DescriptorType::STORAGE_BUFFER, - stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC, - stormkit::gpu::DescriptorType::STORAGE_IMAGE, - stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER, - stormkit::gpu::DescriptorType::UNIFORM_BUFFER, - stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC, - stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER, - + stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, stormkit::gpu::DescriptorType::INPUT_ATTACHMENT, + stormkit::gpu::DescriptorType::SAMPLED_IMAGE, stormkit::gpu::DescriptorType::SAMPLER, + stormkit::gpu::DescriptorType::STORAGE_BUFFER, stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC, + stormkit::gpu::DescriptorType::STORAGE_IMAGE, stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER, + stormkit::gpu::DescriptorType::UNIFORM_BUFFER, stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC, + stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::DescriptorType value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: return "DescriptorType::COMBINED_IMAGE_SAMPLER"; - case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: return "DescriptorType::INPUT_ATTACHMENT"; - case stormkit::gpu::DescriptorType::SAMPLED_IMAGE: return "DescriptorType::SAMPLED_IMAGE"; - case stormkit::gpu::DescriptorType::SAMPLER: return "DescriptorType::SAMPLER"; - case stormkit::gpu::DescriptorType::STORAGE_BUFFER: return "DescriptorType::STORAGE_BUFFER"; - case stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC: return "DescriptorType::STORAGE_BUFFER_DYNAMIC"; - case stormkit::gpu::DescriptorType::STORAGE_IMAGE: return "DescriptorType::STORAGE_IMAGE"; - case stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER: return "DescriptorType::STORAGE_TEXEL_BUFFER"; - case stormkit::gpu::DescriptorType::UNIFORM_BUFFER: return "DescriptorType::UNIFORM_BUFFER"; - case stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC: return "DescriptorType::UNIFORM_BUFFER_DYNAMIC"; - case stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER: return "DescriptorType::UNIFORM_TEXEL_BUFFER"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::DescriptorType value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: return "DescriptorType::COMBINED_IMAGE_SAMPLER"; + case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: return "DescriptorType::INPUT_ATTACHMENT"; + case stormkit::gpu::DescriptorType::SAMPLED_IMAGE: return "DescriptorType::SAMPLED_IMAGE"; + case stormkit::gpu::DescriptorType::SAMPLER: return "DescriptorType::SAMPLER"; + case stormkit::gpu::DescriptorType::STORAGE_BUFFER: return "DescriptorType::STORAGE_BUFFER"; + case stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC: return "DescriptorType::STORAGE_BUFFER_DYNAMIC"; + case stormkit::gpu::DescriptorType::STORAGE_IMAGE: return "DescriptorType::STORAGE_IMAGE"; + case stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER: return "DescriptorType::STORAGE_TEXEL_BUFFER"; + case stormkit::gpu::DescriptorType::UNIFORM_BUFFER: return "DescriptorType::UNIFORM_BUFFER"; + case stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC: return "DescriptorType::UNIFORM_BUFFER_DYNAMIC"; + case stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER: return "DescriptorType::UNIFORM_TEXEL_BUFFER"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::DescriptorType value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: return "DescriptorType::COMBINED_IMAGE_SAMPLER"; - case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: return "DescriptorType::INPUT_ATTACHMENT"; - case stormkit::gpu::DescriptorType::SAMPLED_IMAGE: return "DescriptorType::SAMPLED_IMAGE"; - case stormkit::gpu::DescriptorType::SAMPLER: return "DescriptorType::SAMPLER"; - case stormkit::gpu::DescriptorType::STORAGE_BUFFER: return "DescriptorType::STORAGE_BUFFER"; - case stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC: return "DescriptorType::STORAGE_BUFFER_DYNAMIC"; - case stormkit::gpu::DescriptorType::STORAGE_IMAGE: return "DescriptorType::STORAGE_IMAGE"; - case stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER: return "DescriptorType::STORAGE_TEXEL_BUFFER"; - case stormkit::gpu::DescriptorType::UNIFORM_BUFFER: return "DescriptorType::UNIFORM_BUFFER"; - case stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC: return "DescriptorType::UNIFORM_BUFFER_DYNAMIC"; - case stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER: return "DescriptorType::UNIFORM_TEXEL_BUFFER"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::DescriptorType value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: return "DescriptorType::COMBINED_IMAGE_SAMPLER"; + case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: return "DescriptorType::INPUT_ATTACHMENT"; + case stormkit::gpu::DescriptorType::SAMPLED_IMAGE: return "DescriptorType::SAMPLED_IMAGE"; + case stormkit::gpu::DescriptorType::SAMPLER: return "DescriptorType::SAMPLER"; + case stormkit::gpu::DescriptorType::STORAGE_BUFFER: return "DescriptorType::STORAGE_BUFFER"; + case stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC: return "DescriptorType::STORAGE_BUFFER_DYNAMIC"; + case stormkit::gpu::DescriptorType::STORAGE_IMAGE: return "DescriptorType::STORAGE_IMAGE"; + case stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER: return "DescriptorType::STORAGE_TEXEL_BUFFER"; + case stormkit::gpu::DescriptorType::UNIFORM_BUFFER: return "DescriptorType::UNIFORM_BUFFER"; + case stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC: return "DescriptorType::UNIFORM_BUFFER_DYNAMIC"; + case stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER: return "DescriptorType::UNIFORM_TEXEL_BUFFER"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::DynamicState) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::DynamicState::BLEND_CONSTANTS, - stormkit::gpu::DynamicState::DEPTH_BIAS, - stormkit::gpu::DynamicState::DEPTH_BOUNDS, - stormkit::gpu::DynamicState::LINE_WIDTH, - stormkit::gpu::DynamicState::SCISSOR, - stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK, - stormkit::gpu::DynamicState::STENCIL_REFERENCE, - stormkit::gpu::DynamicState::STENCIL_WRITE_MASK, - stormkit::gpu::DynamicState::VIEWPORT, - + stormkit::gpu::DynamicState::BLEND_CONSTANTS, stormkit::gpu::DynamicState::DEPTH_BIAS, + stormkit::gpu::DynamicState::DEPTH_BOUNDS, stormkit::gpu::DynamicState::LINE_WIDTH, + stormkit::gpu::DynamicState::SCISSOR, stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK, + stormkit::gpu::DynamicState::STENCIL_REFERENCE, stormkit::gpu::DynamicState::STENCIL_WRITE_MASK, + stormkit::gpu::DynamicState::VIEWPORT, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::DynamicState value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::DynamicState::BLEND_CONSTANTS: return "DynamicState::BLEND_CONSTANTS"; - case stormkit::gpu::DynamicState::DEPTH_BIAS: return "DynamicState::DEPTH_BIAS"; - case stormkit::gpu::DynamicState::DEPTH_BOUNDS: return "DynamicState::DEPTH_BOUNDS"; - case stormkit::gpu::DynamicState::LINE_WIDTH: return "DynamicState::LINE_WIDTH"; - case stormkit::gpu::DynamicState::SCISSOR: return "DynamicState::SCISSOR"; - case stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK: return "DynamicState::STENCIL_COMPARE_MASK"; - case stormkit::gpu::DynamicState::STENCIL_REFERENCE: return "DynamicState::STENCIL_REFERENCE"; - case stormkit::gpu::DynamicState::STENCIL_WRITE_MASK: return "DynamicState::STENCIL_WRITE_MASK"; - case stormkit::gpu::DynamicState::VIEWPORT: return "DynamicState::VIEWPORT"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::DynamicState value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::DynamicState::BLEND_CONSTANTS: return "DynamicState::BLEND_CONSTANTS"; + case stormkit::gpu::DynamicState::DEPTH_BIAS: return "DynamicState::DEPTH_BIAS"; + case stormkit::gpu::DynamicState::DEPTH_BOUNDS: return "DynamicState::DEPTH_BOUNDS"; + case stormkit::gpu::DynamicState::LINE_WIDTH: return "DynamicState::LINE_WIDTH"; + case stormkit::gpu::DynamicState::SCISSOR: return "DynamicState::SCISSOR"; + case stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK: return "DynamicState::STENCIL_COMPARE_MASK"; + case stormkit::gpu::DynamicState::STENCIL_REFERENCE: return "DynamicState::STENCIL_REFERENCE"; + case stormkit::gpu::DynamicState::STENCIL_WRITE_MASK: return "DynamicState::STENCIL_WRITE_MASK"; + case stormkit::gpu::DynamicState::VIEWPORT: return "DynamicState::VIEWPORT"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::DynamicState value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::DynamicState::BLEND_CONSTANTS: return "DynamicState::BLEND_CONSTANTS"; - case stormkit::gpu::DynamicState::DEPTH_BIAS: return "DynamicState::DEPTH_BIAS"; - case stormkit::gpu::DynamicState::DEPTH_BOUNDS: return "DynamicState::DEPTH_BOUNDS"; - case stormkit::gpu::DynamicState::LINE_WIDTH: return "DynamicState::LINE_WIDTH"; - case stormkit::gpu::DynamicState::SCISSOR: return "DynamicState::SCISSOR"; - case stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK: return "DynamicState::STENCIL_COMPARE_MASK"; - case stormkit::gpu::DynamicState::STENCIL_REFERENCE: return "DynamicState::STENCIL_REFERENCE"; - case stormkit::gpu::DynamicState::STENCIL_WRITE_MASK: return "DynamicState::STENCIL_WRITE_MASK"; - case stormkit::gpu::DynamicState::VIEWPORT: return "DynamicState::VIEWPORT"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::DynamicState value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::DynamicState::BLEND_CONSTANTS: return "DynamicState::BLEND_CONSTANTS"; + case stormkit::gpu::DynamicState::DEPTH_BIAS: return "DynamicState::DEPTH_BIAS"; + case stormkit::gpu::DynamicState::DEPTH_BOUNDS: return "DynamicState::DEPTH_BOUNDS"; + case stormkit::gpu::DynamicState::LINE_WIDTH: return "DynamicState::LINE_WIDTH"; + case stormkit::gpu::DynamicState::SCISSOR: return "DynamicState::SCISSOR"; + case stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK: return "DynamicState::STENCIL_COMPARE_MASK"; + case stormkit::gpu::DynamicState::STENCIL_REFERENCE: return "DynamicState::STENCIL_REFERENCE"; + case stormkit::gpu::DynamicState::STENCIL_WRITE_MASK: return "DynamicState::STENCIL_WRITE_MASK"; + case stormkit::gpu::DynamicState::VIEWPORT: return "DynamicState::VIEWPORT"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::Filter) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::Filter::CUBIC_IMG, - stormkit::gpu::Filter::LINEAR, - stormkit::gpu::Filter::NEAREST, - + stormkit::gpu::Filter::CUBIC_IMG, + stormkit::gpu::Filter::LINEAR, + stormkit::gpu::Filter::NEAREST, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::Filter value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; - case stormkit::gpu::Filter::LINEAR: return "Filter::LINEAR"; - case stormkit::gpu::Filter::NEAREST: return "Filter::NEAREST"; - + switch (value) { + case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; + case stormkit::gpu::Filter::LINEAR: return "Filter::LINEAR"; + case stormkit::gpu::Filter::NEAREST: return "Filter::NEAREST"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::Filter value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; - case stormkit::gpu::Filter::LINEAR: return "Filter::LINEAR"; - case stormkit::gpu::Filter::NEAREST: return "Filter::NEAREST"; - + switch (value) { + case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; + case stormkit::gpu::Filter::LINEAR: return "Filter::LINEAR"; + case stormkit::gpu::Filter::NEAREST: return "Filter::NEAREST"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::FormatFeatureFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::FormatFeatureFlag::BLIT_DST, - stormkit::gpu::FormatFeatureFlag::BLIT_SRC, - stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT, - stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND, - stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES, - stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT, - stormkit::gpu::FormatFeatureFlag::DISJOINT, - stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER, - stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE, - stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC, - stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER, - stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC, - stormkit::gpu::FormatFeatureFlag::TRANSFER_DST, - stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC, - stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER, - stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER, - - }; - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::FormatFeatureFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::FormatFeatureFlag::BLIT_DST: return "FormatFeatureFlag::BLIT_DST"; - case stormkit::gpu::FormatFeatureFlag::BLIT_SRC: return "FormatFeatureFlag::BLIT_SRC"; - case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT: return "FormatFeatureFlag::COLOR_ATTACHMENT"; - case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND: return "FormatFeatureFlag::COLOR_ATTACHMENT_BLEND"; - case stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES: return "FormatFeatureFlag::COSITED_CHROMA_SAMPLES"; - case stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT: return "FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT"; - case stormkit::gpu::FormatFeatureFlag::DISJOINT: return "FormatFeatureFlag::DISJOINT"; - case stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES: return "FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE: return "FormatFeatureFlag::SAMPLED_IMAGE"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR: return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX: return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE: return "FormatFeatureFlag::STORAGE_IMAGE"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC: return "FormatFeatureFlag::STORAGE_IMAGE_ATOMIC"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC"; - case stormkit::gpu::FormatFeatureFlag::TRANSFER_DST: return "FormatFeatureFlag::TRANSFER_DST"; - case stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC: return "FormatFeatureFlag::TRANSFER_SRC"; - case stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER: return "FormatFeatureFlag::UNIFORM_TEXEL_BUFFER"; - case stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER: return "FormatFeatureFlag::VERTEX_BUFFER"; - - } - std::unreachable(); - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::FormatFeatureFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::FormatFeatureFlag::BLIT_DST: return "FormatFeatureFlag::BLIT_DST"; - case stormkit::gpu::FormatFeatureFlag::BLIT_SRC: return "FormatFeatureFlag::BLIT_SRC"; - case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT: return "FormatFeatureFlag::COLOR_ATTACHMENT"; - case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND: return "FormatFeatureFlag::COLOR_ATTACHMENT_BLEND"; - case stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES: return "FormatFeatureFlag::COSITED_CHROMA_SAMPLES"; - case stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT: return "FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT"; - case stormkit::gpu::FormatFeatureFlag::DISJOINT: return "FormatFeatureFlag::DISJOINT"; - case stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES: return "FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE: return "FormatFeatureFlag::SAMPLED_IMAGE"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR: return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX: return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE: return "FormatFeatureFlag::STORAGE_IMAGE"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC: return "FormatFeatureFlag::STORAGE_IMAGE_ATOMIC"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC"; - case stormkit::gpu::FormatFeatureFlag::TRANSFER_DST: return "FormatFeatureFlag::TRANSFER_DST"; - case stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC: return "FormatFeatureFlag::TRANSFER_SRC"; - case stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER: return "FormatFeatureFlag::UNIFORM_TEXEL_BUFFER"; - case stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER: return "FormatFeatureFlag::VERTEX_BUFFER"; - + stormkit::gpu::FormatFeatureFlag::BLIT_DST, + stormkit::gpu::FormatFeatureFlag::BLIT_SRC, + stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT, + stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND, + stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES, + stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT, + stormkit::gpu::FormatFeatureFlag::DISJOINT, + stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER, + stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE, + stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC, + stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER, + stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC, + stormkit::gpu::FormatFeatureFlag::TRANSFER_DST, + stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC, + stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER, + stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER, + + }; + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::FormatFeatureFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::FormatFeatureFlag::BLIT_DST: return "FormatFeatureFlag::BLIT_DST"; + case stormkit::gpu::FormatFeatureFlag::BLIT_SRC: return "FormatFeatureFlag::BLIT_SRC"; + case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT: return "FormatFeatureFlag::COLOR_ATTACHMENT"; + case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND: return "FormatFeatureFlag::COLOR_ATTACHMENT_BLEND"; + case stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES: return "FormatFeatureFlag::COSITED_CHROMA_SAMPLES"; + case stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT: return "FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT"; + case stormkit::gpu::FormatFeatureFlag::DISJOINT: return "FormatFeatureFlag::DISJOINT"; + case stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES: return "FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE: return "FormatFeatureFlag::SAMPLED_IMAGE"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR: + return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX: + return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT: + return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE: + return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER: + return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER: + return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE: return "FormatFeatureFlag::STORAGE_IMAGE"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC: return "FormatFeatureFlag::STORAGE_IMAGE_ATOMIC"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC: + return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC"; + case stormkit::gpu::FormatFeatureFlag::TRANSFER_DST: return "FormatFeatureFlag::TRANSFER_DST"; + case stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC: return "FormatFeatureFlag::TRANSFER_SRC"; + case stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER: return "FormatFeatureFlag::UNIFORM_TEXEL_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER: return "FormatFeatureFlag::VERTEX_BUFFER"; + } + std::unreachable(); + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::to_string(stormkit::gpu::FormatFeatureFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::FormatFeatureFlag::BLIT_DST: return "FormatFeatureFlag::BLIT_DST"; + case stormkit::gpu::FormatFeatureFlag::BLIT_SRC: return "FormatFeatureFlag::BLIT_SRC"; + case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT: return "FormatFeatureFlag::COLOR_ATTACHMENT"; + case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND: return "FormatFeatureFlag::COLOR_ATTACHMENT_BLEND"; + case stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES: return "FormatFeatureFlag::COSITED_CHROMA_SAMPLES"; + case stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT: return "FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT"; + case stormkit::gpu::FormatFeatureFlag::DISJOINT: return "FormatFeatureFlag::DISJOINT"; + case stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES: return "FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE: return "FormatFeatureFlag::SAMPLED_IMAGE"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR: + return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX: + return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT: + return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE: + return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER: + return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER: + return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE: return "FormatFeatureFlag::STORAGE_IMAGE"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC: return "FormatFeatureFlag::STORAGE_IMAGE_ATOMIC"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC: + return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC"; + case stormkit::gpu::FormatFeatureFlag::TRANSFER_DST: return "FormatFeatureFlag::TRANSFER_DST"; + case stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC: return "FormatFeatureFlag::TRANSFER_SRC"; + case stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER: return "FormatFeatureFlag::UNIFORM_TEXEL_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER: return "FormatFeatureFlag::VERTEX_BUFFER"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::FrontFace) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::FrontFace::CLOCKWISE, - stormkit::gpu::FrontFace::COUNTER_CLOCKWISE, - + stormkit::gpu::FrontFace::CLOCKWISE, + stormkit::gpu::FrontFace::COUNTER_CLOCKWISE, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::FrontFace value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; - case stormkit::gpu::FrontFace::COUNTER_CLOCKWISE: return "FrontFace::COUNTER_CLOCKWISE"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::FrontFace value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; + case stormkit::gpu::FrontFace::COUNTER_CLOCKWISE: return "FrontFace::COUNTER_CLOCKWISE"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::FrontFace value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; - case stormkit::gpu::FrontFace::COUNTER_CLOCKWISE: return "FrontFace::COUNTER_CLOCKWISE"; - + switch (value) { + case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; + case stormkit::gpu::FrontFace::COUNTER_CLOCKWISE: return "FrontFace::COUNTER_CLOCKWISE"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::GeometryFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION, - stormkit::gpu::GeometryFlag::OPAQUE, - + stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION, + stormkit::gpu::GeometryFlag::OPAQUE, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::GeometryFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION: return "GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION"; - case stormkit::gpu::GeometryFlag::OPAQUE: return "GeometryFlag::OPAQUE"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::GeometryFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION: + return "GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION"; + case stormkit::gpu::GeometryFlag::OPAQUE: return "GeometryFlag::OPAQUE"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION: return "GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION"; - case stormkit::gpu::GeometryFlag::OPAQUE: return "GeometryFlag::OPAQUE"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION: + return "GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION"; + case stormkit::gpu::GeometryFlag::OPAQUE: return "GeometryFlag::OPAQUE"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::GeometryType) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::GeometryType::AABBS, - stormkit::gpu::GeometryType::INSTANCES, - stormkit::gpu::GeometryType::TRIANGLES, - + stormkit::gpu::GeometryType::AABBS, + stormkit::gpu::GeometryType::INSTANCES, + stormkit::gpu::GeometryType::TRIANGLES, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::GeometryType value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::GeometryType::AABBS: return "GeometryType::AABBS"; - case stormkit::gpu::GeometryType::INSTANCES: return "GeometryType::INSTANCES"; - case stormkit::gpu::GeometryType::TRIANGLES: return "GeometryType::TRIANGLES"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::GeometryType value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::GeometryType::AABBS: return "GeometryType::AABBS"; + case stormkit::gpu::GeometryType::INSTANCES: return "GeometryType::INSTANCES"; + case stormkit::gpu::GeometryType::TRIANGLES: return "GeometryType::TRIANGLES"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryType value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::GeometryType::AABBS: return "GeometryType::AABBS"; - case stormkit::gpu::GeometryType::INSTANCES: return "GeometryType::INSTANCES"; - case stormkit::gpu::GeometryType::TRIANGLES: return "GeometryType::TRIANGLES"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryType value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::GeometryType::AABBS: return "GeometryType::AABBS"; + case stormkit::gpu::GeometryType::INSTANCES: return "GeometryType::INSTANCES"; + case stormkit::gpu::GeometryType::TRIANGLES: return "GeometryType::TRIANGLES"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageAspectFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageAspectFlag::COLOR, - stormkit::gpu::ImageAspectFlag::DEPTH, - stormkit::gpu::ImageAspectFlag::NONE, - stormkit::gpu::ImageAspectFlag::STENCIL, - + stormkit::gpu::ImageAspectFlag::COLOR, + stormkit::gpu::ImageAspectFlag::DEPTH, + stormkit::gpu::ImageAspectFlag::NONE, + stormkit::gpu::ImageAspectFlag::STENCIL, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageAspectFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ImageAspectFlag::COLOR: return "ImageAspectFlag::COLOR"; - case stormkit::gpu::ImageAspectFlag::DEPTH: return "ImageAspectFlag::DEPTH"; - case stormkit::gpu::ImageAspectFlag::NONE: return "ImageAspectFlag::NONE"; - case stormkit::gpu::ImageAspectFlag::STENCIL: return "ImageAspectFlag::STENCIL"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageAspectFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ImageAspectFlag::COLOR: return "ImageAspectFlag::COLOR"; + case stormkit::gpu::ImageAspectFlag::DEPTH: return "ImageAspectFlag::DEPTH"; + case stormkit::gpu::ImageAspectFlag::NONE: return "ImageAspectFlag::NONE"; + case stormkit::gpu::ImageAspectFlag::STENCIL: return "ImageAspectFlag::STENCIL"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageAspectFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ImageAspectFlag::COLOR: return "ImageAspectFlag::COLOR"; - case stormkit::gpu::ImageAspectFlag::DEPTH: return "ImageAspectFlag::DEPTH"; - case stormkit::gpu::ImageAspectFlag::NONE: return "ImageAspectFlag::NONE"; - case stormkit::gpu::ImageAspectFlag::STENCIL: return "ImageAspectFlag::STENCIL"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageAspectFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::ImageAspectFlag::COLOR: return "ImageAspectFlag::COLOR"; + case stormkit::gpu::ImageAspectFlag::DEPTH: return "ImageAspectFlag::DEPTH"; + case stormkit::gpu::ImageAspectFlag::NONE: return "ImageAspectFlag::NONE"; + case stormkit::gpu::ImageAspectFlag::STENCIL: return "ImageAspectFlag::STENCIL"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageCreateFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageCreateFlag::ALIAS, - stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE, - stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE, - stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE, - stormkit::gpu::ImageCreateFlag::DISJOINT, - stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE, - stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT, - stormkit::gpu::ImageCreateFlag::NONE, - stormkit::gpu::ImageCreateFlag::PROTECTED, - stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED, - stormkit::gpu::ImageCreateFlag::SPARSE_BINDING, - stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY, - stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS, - - }; - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageCreateFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ImageCreateFlag::ALIAS: return "ImageCreateFlag::ALIAS"; - case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE: return "ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE: return "ImageCreateFlag::CUBE_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::DISJOINT: return "ImageCreateFlag::DISJOINT"; - case stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE: return "ImageCreateFlag::EXTENDED_USAGE"; - case stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT: return "ImageCreateFlag::MUTABLE_FORMAT"; - case stormkit::gpu::ImageCreateFlag::NONE: return "ImageCreateFlag::NONE"; - case stormkit::gpu::ImageCreateFlag::PROTECTED: return "ImageCreateFlag::PROTECTED"; - case stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED: return "ImageCreateFlag::SPARSE_ALIASED"; - case stormkit::gpu::ImageCreateFlag::SPARSE_BINDING: return "ImageCreateFlag::SPARSE_BINDING"; - case stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY: return "ImageCreateFlag::SPARSE_RESIDENCY"; - case stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS: return "ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS"; - - } - std::unreachable(); - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageCreateFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ImageCreateFlag::ALIAS: return "ImageCreateFlag::ALIAS"; - case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE: return "ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE: return "ImageCreateFlag::CUBE_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::DISJOINT: return "ImageCreateFlag::DISJOINT"; - case stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE: return "ImageCreateFlag::EXTENDED_USAGE"; - case stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT: return "ImageCreateFlag::MUTABLE_FORMAT"; - case stormkit::gpu::ImageCreateFlag::NONE: return "ImageCreateFlag::NONE"; - case stormkit::gpu::ImageCreateFlag::PROTECTED: return "ImageCreateFlag::PROTECTED"; - case stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED: return "ImageCreateFlag::SPARSE_ALIASED"; - case stormkit::gpu::ImageCreateFlag::SPARSE_BINDING: return "ImageCreateFlag::SPARSE_BINDING"; - case stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY: return "ImageCreateFlag::SPARSE_RESIDENCY"; - case stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS: return "ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS"; - + stormkit::gpu::ImageCreateFlag::ALIAS, + stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE, + stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE, + stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE, + stormkit::gpu::ImageCreateFlag::DISJOINT, + stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE, + stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT, + stormkit::gpu::ImageCreateFlag::NONE, + stormkit::gpu::ImageCreateFlag::PROTECTED, + stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED, + stormkit::gpu::ImageCreateFlag::SPARSE_BINDING, + stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY, + stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS, + + }; + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageCreateFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ImageCreateFlag::ALIAS: return "ImageCreateFlag::ALIAS"; + case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE: + return "ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE: return "ImageCreateFlag::CUBE_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::DISJOINT: return "ImageCreateFlag::DISJOINT"; + case stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE: return "ImageCreateFlag::EXTENDED_USAGE"; + case stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT: return "ImageCreateFlag::MUTABLE_FORMAT"; + case stormkit::gpu::ImageCreateFlag::NONE: return "ImageCreateFlag::NONE"; + case stormkit::gpu::ImageCreateFlag::PROTECTED: return "ImageCreateFlag::PROTECTED"; + case stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED: return "ImageCreateFlag::SPARSE_ALIASED"; + case stormkit::gpu::ImageCreateFlag::SPARSE_BINDING: return "ImageCreateFlag::SPARSE_BINDING"; + case stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY: return "ImageCreateFlag::SPARSE_RESIDENCY"; + case stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS: + return "ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS"; + } + std::unreachable(); + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageCreateFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::ImageCreateFlag::ALIAS: return "ImageCreateFlag::ALIAS"; + case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE: + return "ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE: return "ImageCreateFlag::CUBE_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::DISJOINT: return "ImageCreateFlag::DISJOINT"; + case stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE: return "ImageCreateFlag::EXTENDED_USAGE"; + case stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT: return "ImageCreateFlag::MUTABLE_FORMAT"; + case stormkit::gpu::ImageCreateFlag::NONE: return "ImageCreateFlag::NONE"; + case stormkit::gpu::ImageCreateFlag::PROTECTED: return "ImageCreateFlag::PROTECTED"; + case stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED: return "ImageCreateFlag::SPARSE_ALIASED"; + case stormkit::gpu::ImageCreateFlag::SPARSE_BINDING: return "ImageCreateFlag::SPARSE_BINDING"; + case stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY: return "ImageCreateFlag::SPARSE_RESIDENCY"; + case stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS: + return "ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageLayout) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL, - stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL, - stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, - stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, - stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL, - stormkit::gpu::ImageLayout::GENERAL, - stormkit::gpu::ImageLayout::PREINITIALIZED, - stormkit::gpu::ImageLayout::PRESENT_SRC, - stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL, - stormkit::gpu::ImageLayout::SHARED_PRESENT, - stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL, - stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL, - stormkit::gpu::ImageLayout::UNDEFINED, - - }; - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageLayout value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL: return "ImageLayout::ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: return "ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: return "ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL: return "ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL: return "ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::GENERAL: return "ImageLayout::GENERAL"; - case stormkit::gpu::ImageLayout::PREINITIALIZED: return "ImageLayout::PREINITIALIZED"; - case stormkit::gpu::ImageLayout::PRESENT_SRC: return "ImageLayout::PRESENT_SRC"; - case stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL: return "ImageLayout::SHADER_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::SHARED_PRESENT: return "ImageLayout::SHARED_PRESENT"; - case stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL: return "ImageLayout::TRANSFER_DST_OPTIMAL"; - case stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL: return "ImageLayout::TRANSFER_SRC_OPTIMAL"; - case stormkit::gpu::ImageLayout::UNDEFINED: return "ImageLayout::UNDEFINED"; - - } - std::unreachable(); - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageLayout value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL: return "ImageLayout::ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: return "ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: return "ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL: return "ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL: return "ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::GENERAL: return "ImageLayout::GENERAL"; - case stormkit::gpu::ImageLayout::PREINITIALIZED: return "ImageLayout::PREINITIALIZED"; - case stormkit::gpu::ImageLayout::PRESENT_SRC: return "ImageLayout::PRESENT_SRC"; - case stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL: return "ImageLayout::SHADER_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::SHARED_PRESENT: return "ImageLayout::SHARED_PRESENT"; - case stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL: return "ImageLayout::TRANSFER_DST_OPTIMAL"; - case stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL: return "ImageLayout::TRANSFER_SRC_OPTIMAL"; - case stormkit::gpu::ImageLayout::UNDEFINED: return "ImageLayout::UNDEFINED"; - + stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL, + stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL, + stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, + stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, + stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL, + stormkit::gpu::ImageLayout::GENERAL, + stormkit::gpu::ImageLayout::PREINITIALIZED, + stormkit::gpu::ImageLayout::PRESENT_SRC, + stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL, + stormkit::gpu::ImageLayout::SHARED_PRESENT, + stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL, + stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL, + stormkit::gpu::ImageLayout::UNDEFINED, + + }; + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageLayout value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL: return "ImageLayout::ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: + return "ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: + return "ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL: + return "ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL: + return "ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::GENERAL: return "ImageLayout::GENERAL"; + case stormkit::gpu::ImageLayout::PREINITIALIZED: return "ImageLayout::PREINITIALIZED"; + case stormkit::gpu::ImageLayout::PRESENT_SRC: return "ImageLayout::PRESENT_SRC"; + case stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL: return "ImageLayout::SHADER_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::SHARED_PRESENT: return "ImageLayout::SHARED_PRESENT"; + case stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL: return "ImageLayout::TRANSFER_DST_OPTIMAL"; + case stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL: return "ImageLayout::TRANSFER_SRC_OPTIMAL"; + case stormkit::gpu::ImageLayout::UNDEFINED: return "ImageLayout::UNDEFINED"; + } + std::unreachable(); + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageLayout value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL: return "ImageLayout::ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: + return "ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: + return "ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL: + return "ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL: + return "ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::GENERAL: return "ImageLayout::GENERAL"; + case stormkit::gpu::ImageLayout::PREINITIALIZED: return "ImageLayout::PREINITIALIZED"; + case stormkit::gpu::ImageLayout::PRESENT_SRC: return "ImageLayout::PRESENT_SRC"; + case stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL: return "ImageLayout::SHADER_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::SHARED_PRESENT: return "ImageLayout::SHARED_PRESENT"; + case stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL: return "ImageLayout::TRANSFER_DST_OPTIMAL"; + case stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL: return "ImageLayout::TRANSFER_SRC_OPTIMAL"; + case stormkit::gpu::ImageLayout::UNDEFINED: return "ImageLayout::UNDEFINED"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageTiling) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageTiling::LINEAR, - stormkit::gpu::ImageTiling::OPTIMAL, - + stormkit::gpu::ImageTiling::LINEAR, + stormkit::gpu::ImageTiling::OPTIMAL, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageTiling value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ImageTiling::LINEAR: return "ImageTiling::LINEAR"; - case stormkit::gpu::ImageTiling::OPTIMAL: return "ImageTiling::OPTIMAL"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageTiling value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ImageTiling::LINEAR: return "ImageTiling::LINEAR"; + case stormkit::gpu::ImageTiling::OPTIMAL: return "ImageTiling::OPTIMAL"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageTiling value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ImageTiling::LINEAR: return "ImageTiling::LINEAR"; - case stormkit::gpu::ImageTiling::OPTIMAL: return "ImageTiling::OPTIMAL"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageTiling value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::ImageTiling::LINEAR: return "ImageTiling::LINEAR"; + case stormkit::gpu::ImageTiling::OPTIMAL: return "ImageTiling::OPTIMAL"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageType) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageType::T1D, - stormkit::gpu::ImageType::T2D, - stormkit::gpu::ImageType::T3D, - + stormkit::gpu::ImageType::T1D, + stormkit::gpu::ImageType::T2D, + stormkit::gpu::ImageType::T3D, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageType value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; - case stormkit::gpu::ImageType::T2D: return "ImageType::T2D"; - case stormkit::gpu::ImageType::T3D: return "ImageType::T3D"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageType value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; + case stormkit::gpu::ImageType::T2D: return "ImageType::T2D"; + case stormkit::gpu::ImageType::T3D: return "ImageType::T3D"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::ImageType value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; - case stormkit::gpu::ImageType::T2D: return "ImageType::T2D"; - case stormkit::gpu::ImageType::T3D: return "ImageType::T3D"; - + switch (value) { + case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; + case stormkit::gpu::ImageType::T2D: return "ImageType::T2D"; + case stormkit::gpu::ImageType::T3D: return "ImageType::T3D"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageUsageFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT, - stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT, - stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT, - stormkit::gpu::ImageUsageFlag::SAMPLED, - stormkit::gpu::ImageUsageFlag::STORAGE, - stormkit::gpu::ImageUsageFlag::TRANSFER_DST, - stormkit::gpu::ImageUsageFlag::TRANSFER_SRC, - stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT, - + stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT, stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT, + stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT, stormkit::gpu::ImageUsageFlag::SAMPLED, + stormkit::gpu::ImageUsageFlag::STORAGE, stormkit::gpu::ImageUsageFlag::TRANSFER_DST, + stormkit::gpu::ImageUsageFlag::TRANSFER_SRC, stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageUsageFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: return "ImageUsageFlag::COLOR_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT: return "ImageUsageFlag::INPUT_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::SAMPLED: return "ImageUsageFlag::SAMPLED"; - case stormkit::gpu::ImageUsageFlag::STORAGE: return "ImageUsageFlag::STORAGE"; - case stormkit::gpu::ImageUsageFlag::TRANSFER_DST: return "ImageUsageFlag::TRANSFER_DST"; - case stormkit::gpu::ImageUsageFlag::TRANSFER_SRC: return "ImageUsageFlag::TRANSFER_SRC"; - case stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT: return "ImageUsageFlag::TRANSIENT_ATTACHMENT"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageUsageFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: return "ImageUsageFlag::COLOR_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT: return "ImageUsageFlag::INPUT_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::SAMPLED: return "ImageUsageFlag::SAMPLED"; + case stormkit::gpu::ImageUsageFlag::STORAGE: return "ImageUsageFlag::STORAGE"; + case stormkit::gpu::ImageUsageFlag::TRANSFER_DST: return "ImageUsageFlag::TRANSFER_DST"; + case stormkit::gpu::ImageUsageFlag::TRANSFER_SRC: return "ImageUsageFlag::TRANSFER_SRC"; + case stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT: return "ImageUsageFlag::TRANSIENT_ATTACHMENT"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageUsageFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: return "ImageUsageFlag::COLOR_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT: return "ImageUsageFlag::INPUT_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::SAMPLED: return "ImageUsageFlag::SAMPLED"; - case stormkit::gpu::ImageUsageFlag::STORAGE: return "ImageUsageFlag::STORAGE"; - case stormkit::gpu::ImageUsageFlag::TRANSFER_DST: return "ImageUsageFlag::TRANSFER_DST"; - case stormkit::gpu::ImageUsageFlag::TRANSFER_SRC: return "ImageUsageFlag::TRANSFER_SRC"; - case stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT: return "ImageUsageFlag::TRANSIENT_ATTACHMENT"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageUsageFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: return "ImageUsageFlag::COLOR_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT: return "ImageUsageFlag::INPUT_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::SAMPLED: return "ImageUsageFlag::SAMPLED"; + case stormkit::gpu::ImageUsageFlag::STORAGE: return "ImageUsageFlag::STORAGE"; + case stormkit::gpu::ImageUsageFlag::TRANSFER_DST: return "ImageUsageFlag::TRANSFER_DST"; + case stormkit::gpu::ImageUsageFlag::TRANSFER_SRC: return "ImageUsageFlag::TRANSFER_SRC"; + case stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT: return "ImageUsageFlag::TRANSIENT_ATTACHMENT"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageViewType) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageViewType::CUBE, - stormkit::gpu::ImageViewType::CUBE_ARRAY, - stormkit::gpu::ImageViewType::T1D, - stormkit::gpu::ImageViewType::T1D_ARRAY, - stormkit::gpu::ImageViewType::T2D, - stormkit::gpu::ImageViewType::T2D_ARRAY, - stormkit::gpu::ImageViewType::T3D, - + stormkit::gpu::ImageViewType::CUBE, stormkit::gpu::ImageViewType::CUBE_ARRAY, + stormkit::gpu::ImageViewType::T1D, stormkit::gpu::ImageViewType::T1D_ARRAY, + stormkit::gpu::ImageViewType::T2D, stormkit::gpu::ImageViewType::T2D_ARRAY, + stormkit::gpu::ImageViewType::T3D, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageViewType value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ImageViewType::CUBE: return "ImageViewType::CUBE"; - case stormkit::gpu::ImageViewType::CUBE_ARRAY: return "ImageViewType::CUBE_ARRAY"; - case stormkit::gpu::ImageViewType::T1D: return "ImageViewType::T1D"; - case stormkit::gpu::ImageViewType::T1D_ARRAY: return "ImageViewType::T1D_ARRAY"; - case stormkit::gpu::ImageViewType::T2D: return "ImageViewType::T2D"; - case stormkit::gpu::ImageViewType::T2D_ARRAY: return "ImageViewType::T2D_ARRAY"; - case stormkit::gpu::ImageViewType::T3D: return "ImageViewType::T3D"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageViewType value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ImageViewType::CUBE: return "ImageViewType::CUBE"; + case stormkit::gpu::ImageViewType::CUBE_ARRAY: return "ImageViewType::CUBE_ARRAY"; + case stormkit::gpu::ImageViewType::T1D: return "ImageViewType::T1D"; + case stormkit::gpu::ImageViewType::T1D_ARRAY: return "ImageViewType::T1D_ARRAY"; + case stormkit::gpu::ImageViewType::T2D: return "ImageViewType::T2D"; + case stormkit::gpu::ImageViewType::T2D_ARRAY: return "ImageViewType::T2D_ARRAY"; + case stormkit::gpu::ImageViewType::T3D: return "ImageViewType::T3D"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageViewType value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ImageViewType::CUBE: return "ImageViewType::CUBE"; - case stormkit::gpu::ImageViewType::CUBE_ARRAY: return "ImageViewType::CUBE_ARRAY"; - case stormkit::gpu::ImageViewType::T1D: return "ImageViewType::T1D"; - case stormkit::gpu::ImageViewType::T1D_ARRAY: return "ImageViewType::T1D_ARRAY"; - case stormkit::gpu::ImageViewType::T2D: return "ImageViewType::T2D"; - case stormkit::gpu::ImageViewType::T2D_ARRAY: return "ImageViewType::T2D_ARRAY"; - case stormkit::gpu::ImageViewType::T3D: return "ImageViewType::T3D"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageViewType value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::ImageViewType::CUBE: return "ImageViewType::CUBE"; + case stormkit::gpu::ImageViewType::CUBE_ARRAY: return "ImageViewType::CUBE_ARRAY"; + case stormkit::gpu::ImageViewType::T1D: return "ImageViewType::T1D"; + case stormkit::gpu::ImageViewType::T1D_ARRAY: return "ImageViewType::T1D_ARRAY"; + case stormkit::gpu::ImageViewType::T2D: return "ImageViewType::T2D"; + case stormkit::gpu::ImageViewType::T2D_ARRAY: return "ImageViewType::T2D_ARRAY"; + case stormkit::gpu::ImageViewType::T3D: return "ImageViewType::T3D"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::LogicOperation) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::LogicOperation::AND, - stormkit::gpu::LogicOperation::AND_INVERTED, - stormkit::gpu::LogicOperation::AND_REVERSE, - stormkit::gpu::LogicOperation::CLEAR, - stormkit::gpu::LogicOperation::COPY, - stormkit::gpu::LogicOperation::COPY_INVERTED, - stormkit::gpu::LogicOperation::EQUIVALENT, - stormkit::gpu::LogicOperation::INVERT, - stormkit::gpu::LogicOperation::NAND, - stormkit::gpu::LogicOperation::NO_OP, - stormkit::gpu::LogicOperation::NOR, - stormkit::gpu::LogicOperation::OR, - stormkit::gpu::LogicOperation::OR_INVERTED, - stormkit::gpu::LogicOperation::OR_REVERSE, - stormkit::gpu::LogicOperation::SET, - stormkit::gpu::LogicOperation::XOR, - - }; - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::LogicOperation value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::LogicOperation::AND: return "LogicOperation::AND"; - case stormkit::gpu::LogicOperation::AND_INVERTED: return "LogicOperation::AND_INVERTED"; - case stormkit::gpu::LogicOperation::AND_REVERSE: return "LogicOperation::AND_REVERSE"; - case stormkit::gpu::LogicOperation::CLEAR: return "LogicOperation::CLEAR"; - case stormkit::gpu::LogicOperation::COPY: return "LogicOperation::COPY"; - case stormkit::gpu::LogicOperation::COPY_INVERTED: return "LogicOperation::COPY_INVERTED"; - case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; - case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; - case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; - case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; - case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; - case stormkit::gpu::LogicOperation::OR: return "LogicOperation::OR"; - case stormkit::gpu::LogicOperation::OR_INVERTED: return "LogicOperation::OR_INVERTED"; - case stormkit::gpu::LogicOperation::OR_REVERSE: return "LogicOperation::OR_REVERSE"; - case stormkit::gpu::LogicOperation::SET: return "LogicOperation::SET"; - case stormkit::gpu::LogicOperation::XOR: return "LogicOperation::XOR"; - - } - std::unreachable(); - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::LogicOperation value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::LogicOperation::AND: return "LogicOperation::AND"; - case stormkit::gpu::LogicOperation::AND_INVERTED: return "LogicOperation::AND_INVERTED"; - case stormkit::gpu::LogicOperation::AND_REVERSE: return "LogicOperation::AND_REVERSE"; - case stormkit::gpu::LogicOperation::CLEAR: return "LogicOperation::CLEAR"; - case stormkit::gpu::LogicOperation::COPY: return "LogicOperation::COPY"; - case stormkit::gpu::LogicOperation::COPY_INVERTED: return "LogicOperation::COPY_INVERTED"; - case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; - case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; - case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; - case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; - case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; - case stormkit::gpu::LogicOperation::OR: return "LogicOperation::OR"; - case stormkit::gpu::LogicOperation::OR_INVERTED: return "LogicOperation::OR_INVERTED"; - case stormkit::gpu::LogicOperation::OR_REVERSE: return "LogicOperation::OR_REVERSE"; - case stormkit::gpu::LogicOperation::SET: return "LogicOperation::SET"; - case stormkit::gpu::LogicOperation::XOR: return "LogicOperation::XOR"; - + stormkit::gpu::LogicOperation::AND, stormkit::gpu::LogicOperation::AND_INVERTED, + stormkit::gpu::LogicOperation::AND_REVERSE, stormkit::gpu::LogicOperation::CLEAR, + stormkit::gpu::LogicOperation::COPY, stormkit::gpu::LogicOperation::COPY_INVERTED, + stormkit::gpu::LogicOperation::EQUIVALENT, stormkit::gpu::LogicOperation::INVERT, + stormkit::gpu::LogicOperation::NAND, stormkit::gpu::LogicOperation::NO_OP, + stormkit::gpu::LogicOperation::NOR, stormkit::gpu::LogicOperation::OR, + stormkit::gpu::LogicOperation::OR_INVERTED, stormkit::gpu::LogicOperation::OR_REVERSE, + stormkit::gpu::LogicOperation::SET, stormkit::gpu::LogicOperation::XOR, + + }; + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::LogicOperation value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::LogicOperation::AND: return "LogicOperation::AND"; + case stormkit::gpu::LogicOperation::AND_INVERTED: return "LogicOperation::AND_INVERTED"; + case stormkit::gpu::LogicOperation::AND_REVERSE: return "LogicOperation::AND_REVERSE"; + case stormkit::gpu::LogicOperation::CLEAR: return "LogicOperation::CLEAR"; + case stormkit::gpu::LogicOperation::COPY: return "LogicOperation::COPY"; + case stormkit::gpu::LogicOperation::COPY_INVERTED: return "LogicOperation::COPY_INVERTED"; + case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; + case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; + case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; + case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; + case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; + case stormkit::gpu::LogicOperation::OR: return "LogicOperation::OR"; + case stormkit::gpu::LogicOperation::OR_INVERTED: return "LogicOperation::OR_INVERTED"; + case stormkit::gpu::LogicOperation::OR_REVERSE: return "LogicOperation::OR_REVERSE"; + case stormkit::gpu::LogicOperation::SET: return "LogicOperation::SET"; + case stormkit::gpu::LogicOperation::XOR: return "LogicOperation::XOR"; + } + std::unreachable(); + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::to_string(stormkit::gpu::LogicOperation value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::LogicOperation::AND: return "LogicOperation::AND"; + case stormkit::gpu::LogicOperation::AND_INVERTED: return "LogicOperation::AND_INVERTED"; + case stormkit::gpu::LogicOperation::AND_REVERSE: return "LogicOperation::AND_REVERSE"; + case stormkit::gpu::LogicOperation::CLEAR: return "LogicOperation::CLEAR"; + case stormkit::gpu::LogicOperation::COPY: return "LogicOperation::COPY"; + case stormkit::gpu::LogicOperation::COPY_INVERTED: return "LogicOperation::COPY_INVERTED"; + case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; + case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; + case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; + case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; + case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; + case stormkit::gpu::LogicOperation::OR: return "LogicOperation::OR"; + case stormkit::gpu::LogicOperation::OR_INVERTED: return "LogicOperation::OR_INVERTED"; + case stormkit::gpu::LogicOperation::OR_REVERSE: return "LogicOperation::OR_REVERSE"; + case stormkit::gpu::LogicOperation::SET: return "LogicOperation::SET"; + case stormkit::gpu::LogicOperation::XOR: return "LogicOperation::XOR"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::MemoryPropertyFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL, - stormkit::gpu::MemoryPropertyFlag::HOST_CACHED, - stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT, - stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE, - + stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL, + stormkit::gpu::MemoryPropertyFlag::HOST_CACHED, + stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT, + stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::MemoryPropertyFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: return "MemoryPropertyFlag::DEVICE_LOCAL"; - case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: return "MemoryPropertyFlag::HOST_CACHED"; - case stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT: return "MemoryPropertyFlag::HOST_COHERENT"; - case stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE: return "MemoryPropertyFlag::HOST_VISIBLE"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::MemoryPropertyFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: return "MemoryPropertyFlag::DEVICE_LOCAL"; + case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: return "MemoryPropertyFlag::HOST_CACHED"; + case stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT: return "MemoryPropertyFlag::HOST_COHERENT"; + case stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE: return "MemoryPropertyFlag::HOST_VISIBLE"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::MemoryPropertyFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: return "MemoryPropertyFlag::DEVICE_LOCAL"; - case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: return "MemoryPropertyFlag::HOST_CACHED"; - case stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT: return "MemoryPropertyFlag::HOST_COHERENT"; - case stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE: return "MemoryPropertyFlag::HOST_VISIBLE"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::MemoryPropertyFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: return "MemoryPropertyFlag::DEVICE_LOCAL"; + case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: return "MemoryPropertyFlag::HOST_CACHED"; + case stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT: return "MemoryPropertyFlag::HOST_COHERENT"; + case stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE: return "MemoryPropertyFlag::HOST_VISIBLE"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PhysicalDeviceType) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PhysicalDeviceType::CPU, - stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU, - stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU, - stormkit::gpu::PhysicalDeviceType::OTHER, - stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU, - + stormkit::gpu::PhysicalDeviceType::CPU, + stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU, + stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU, + stormkit::gpu::PhysicalDeviceType::OTHER, + stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PhysicalDeviceType value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::PhysicalDeviceType::CPU: return "PhysicalDeviceType::CPU"; - case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: return "PhysicalDeviceType::DISCRETE_GPU"; - case stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU: return "PhysicalDeviceType::INTEGRATED_GPU"; - case stormkit::gpu::PhysicalDeviceType::OTHER: return "PhysicalDeviceType::OTHER"; - case stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU: return "PhysicalDeviceType::VIRTUAL_GPU"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::PhysicalDeviceType value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::PhysicalDeviceType::CPU: return "PhysicalDeviceType::CPU"; + case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: return "PhysicalDeviceType::DISCRETE_GPU"; + case stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU: return "PhysicalDeviceType::INTEGRATED_GPU"; + case stormkit::gpu::PhysicalDeviceType::OTHER: return "PhysicalDeviceType::OTHER"; + case stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU: return "PhysicalDeviceType::VIRTUAL_GPU"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::PhysicalDeviceType value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::PhysicalDeviceType::CPU: return "PhysicalDeviceType::CPU"; - case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: return "PhysicalDeviceType::DISCRETE_GPU"; - case stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU: return "PhysicalDeviceType::INTEGRATED_GPU"; - case stormkit::gpu::PhysicalDeviceType::OTHER: return "PhysicalDeviceType::OTHER"; - case stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU: return "PhysicalDeviceType::VIRTUAL_GPU"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::PhysicalDeviceType value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::PhysicalDeviceType::CPU: return "PhysicalDeviceType::CPU"; + case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: return "PhysicalDeviceType::DISCRETE_GPU"; + case stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU: return "PhysicalDeviceType::INTEGRATED_GPU"; + case stormkit::gpu::PhysicalDeviceType::OTHER: return "PhysicalDeviceType::OTHER"; + case stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU: return "PhysicalDeviceType::VIRTUAL_GPU"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PipelineBindPoint) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PipelineBindPoint::COMPUTE, - stormkit::gpu::PipelineBindPoint::GRAPHICS, - + stormkit::gpu::PipelineBindPoint::COMPUTE, + stormkit::gpu::PipelineBindPoint::GRAPHICS, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PipelineBindPoint value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::PipelineBindPoint::COMPUTE: return "PipelineBindPoint::COMPUTE"; - case stormkit::gpu::PipelineBindPoint::GRAPHICS: return "PipelineBindPoint::GRAPHICS"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::PipelineBindPoint value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::PipelineBindPoint::COMPUTE: return "PipelineBindPoint::COMPUTE"; + case stormkit::gpu::PipelineBindPoint::GRAPHICS: return "PipelineBindPoint::GRAPHICS"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineBindPoint value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::PipelineBindPoint::COMPUTE: return "PipelineBindPoint::COMPUTE"; - case stormkit::gpu::PipelineBindPoint::GRAPHICS: return "PipelineBindPoint::GRAPHICS"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineBindPoint value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::PipelineBindPoint::COMPUTE: return "PipelineBindPoint::COMPUTE"; + case stormkit::gpu::PipelineBindPoint::GRAPHICS: return "PipelineBindPoint::GRAPHICS"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PipelineStageFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PipelineStageFlag::ALL_COMMANDS, - stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS, - stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE, - stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT, - stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER, - stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT, - stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS, - stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER, - stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER, - stormkit::gpu::PipelineStageFlag::HOST, - stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS, - stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER, - stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER, - stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE, - stormkit::gpu::PipelineStageFlag::TRANSFER, - stormkit::gpu::PipelineStageFlag::VERTEX_INPUT, - stormkit::gpu::PipelineStageFlag::VERTEX_SHADER, - - }; - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PipelineStageFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: return "PipelineStageFlag::ALL_COMMANDS"; - case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: return "PipelineStageFlag::ALL_GRAPHICS"; - case stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE: return "PipelineStageFlag::BOTTOM_OF_PIPE"; - case stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT: return "PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT"; - case stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER: return "PipelineStageFlag::COMPUTE_SHADER"; - case stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT: return "PipelineStageFlag::DRAW_INDIRECT"; - case stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS: return "PipelineStageFlag::EARLY_FRAGMENT_TESTS"; - case stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER: return "PipelineStageFlag::FRAGMENT_SHADER"; - case stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER: return "PipelineStageFlag::GEOMETRY_SHADER"; - case stormkit::gpu::PipelineStageFlag::HOST: return "PipelineStageFlag::HOST"; - case stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS: return "PipelineStageFlag::LATE_FRAGMENT_TESTS"; - case stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER: return "PipelineStageFlag::TESSELLATION_CONTROL_SHADER"; - case stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER: return "PipelineStageFlag::TESSELLATION_EVALUATION_SHADER"; - case stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE: return "PipelineStageFlag::TOP_OF_PIPE"; - case stormkit::gpu::PipelineStageFlag::TRANSFER: return "PipelineStageFlag::TRANSFER"; - case stormkit::gpu::PipelineStageFlag::VERTEX_INPUT: return "PipelineStageFlag::VERTEX_INPUT"; - case stormkit::gpu::PipelineStageFlag::VERTEX_SHADER: return "PipelineStageFlag::VERTEX_SHADER"; - - } - std::unreachable(); - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineStageFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: return "PipelineStageFlag::ALL_COMMANDS"; - case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: return "PipelineStageFlag::ALL_GRAPHICS"; - case stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE: return "PipelineStageFlag::BOTTOM_OF_PIPE"; - case stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT: return "PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT"; - case stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER: return "PipelineStageFlag::COMPUTE_SHADER"; - case stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT: return "PipelineStageFlag::DRAW_INDIRECT"; - case stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS: return "PipelineStageFlag::EARLY_FRAGMENT_TESTS"; - case stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER: return "PipelineStageFlag::FRAGMENT_SHADER"; - case stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER: return "PipelineStageFlag::GEOMETRY_SHADER"; - case stormkit::gpu::PipelineStageFlag::HOST: return "PipelineStageFlag::HOST"; - case stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS: return "PipelineStageFlag::LATE_FRAGMENT_TESTS"; - case stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER: return "PipelineStageFlag::TESSELLATION_CONTROL_SHADER"; - case stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER: return "PipelineStageFlag::TESSELLATION_EVALUATION_SHADER"; - case stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE: return "PipelineStageFlag::TOP_OF_PIPE"; - case stormkit::gpu::PipelineStageFlag::TRANSFER: return "PipelineStageFlag::TRANSFER"; - case stormkit::gpu::PipelineStageFlag::VERTEX_INPUT: return "PipelineStageFlag::VERTEX_INPUT"; - case stormkit::gpu::PipelineStageFlag::VERTEX_SHADER: return "PipelineStageFlag::VERTEX_SHADER"; - + stormkit::gpu::PipelineStageFlag::ALL_COMMANDS, + stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS, + stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE, + stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT, + stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER, + stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT, + stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS, + stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER, + stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER, + stormkit::gpu::PipelineStageFlag::HOST, + stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS, + stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER, + stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER, + stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE, + stormkit::gpu::PipelineStageFlag::TRANSFER, + stormkit::gpu::PipelineStageFlag::VERTEX_INPUT, + stormkit::gpu::PipelineStageFlag::VERTEX_SHADER, + + }; + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::PipelineStageFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: return "PipelineStageFlag::ALL_COMMANDS"; + case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: return "PipelineStageFlag::ALL_GRAPHICS"; + case stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE: return "PipelineStageFlag::BOTTOM_OF_PIPE"; + case stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT: return "PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT"; + case stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER: return "PipelineStageFlag::COMPUTE_SHADER"; + case stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT: return "PipelineStageFlag::DRAW_INDIRECT"; + case stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS: return "PipelineStageFlag::EARLY_FRAGMENT_TESTS"; + case stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER: return "PipelineStageFlag::FRAGMENT_SHADER"; + case stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER: return "PipelineStageFlag::GEOMETRY_SHADER"; + case stormkit::gpu::PipelineStageFlag::HOST: return "PipelineStageFlag::HOST"; + case stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS: return "PipelineStageFlag::LATE_FRAGMENT_TESTS"; + case stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER: + return "PipelineStageFlag::TESSELLATION_CONTROL_SHADER"; + case stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER: + return "PipelineStageFlag::TESSELLATION_EVALUATION_SHADER"; + case stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE: return "PipelineStageFlag::TOP_OF_PIPE"; + case stormkit::gpu::PipelineStageFlag::TRANSFER: return "PipelineStageFlag::TRANSFER"; + case stormkit::gpu::PipelineStageFlag::VERTEX_INPUT: return "PipelineStageFlag::VERTEX_INPUT"; + case stormkit::gpu::PipelineStageFlag::VERTEX_SHADER: return "PipelineStageFlag::VERTEX_SHADER"; + } + std::unreachable(); + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineStageFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: return "PipelineStageFlag::ALL_COMMANDS"; + case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: return "PipelineStageFlag::ALL_GRAPHICS"; + case stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE: return "PipelineStageFlag::BOTTOM_OF_PIPE"; + case stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT: return "PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT"; + case stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER: return "PipelineStageFlag::COMPUTE_SHADER"; + case stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT: return "PipelineStageFlag::DRAW_INDIRECT"; + case stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS: return "PipelineStageFlag::EARLY_FRAGMENT_TESTS"; + case stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER: return "PipelineStageFlag::FRAGMENT_SHADER"; + case stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER: return "PipelineStageFlag::GEOMETRY_SHADER"; + case stormkit::gpu::PipelineStageFlag::HOST: return "PipelineStageFlag::HOST"; + case stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS: return "PipelineStageFlag::LATE_FRAGMENT_TESTS"; + case stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER: + return "PipelineStageFlag::TESSELLATION_CONTROL_SHADER"; + case stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER: + return "PipelineStageFlag::TESSELLATION_EVALUATION_SHADER"; + case stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE: return "PipelineStageFlag::TOP_OF_PIPE"; + case stormkit::gpu::PipelineStageFlag::TRANSFER: return "PipelineStageFlag::TRANSFER"; + case stormkit::gpu::PipelineStageFlag::VERTEX_INPUT: return "PipelineStageFlag::VERTEX_INPUT"; + case stormkit::gpu::PipelineStageFlag::VERTEX_SHADER: return "PipelineStageFlag::VERTEX_SHADER"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PixelFormat) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16, - stormkit::gpu::PixelFormat::A2_RGB10I_PACK32, - stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32, - stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32, - stormkit::gpu::PixelFormat::A2_RGB10U_PACK32, - stormkit::gpu::PixelFormat::B10_GR11UF_PACK32, - stormkit::gpu::PixelFormat::BGR8_UNORM, - stormkit::gpu::PixelFormat::BGRA8_UNORM, - stormkit::gpu::PixelFormat::DEPTH16_UNORM, - stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U, - stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32, - stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U, - stormkit::gpu::PixelFormat::DEPTH32F, - stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U, - stormkit::gpu::PixelFormat::R16F, - stormkit::gpu::PixelFormat::R16I, - stormkit::gpu::PixelFormat::R16_SNORM, - stormkit::gpu::PixelFormat::R16U, - stormkit::gpu::PixelFormat::R16_UNORM, - stormkit::gpu::PixelFormat::R32F, - stormkit::gpu::PixelFormat::R32I, - stormkit::gpu::PixelFormat::R32U, - stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16, - stormkit::gpu::PixelFormat::R8I, - stormkit::gpu::PixelFormat::R8_SNORM, - stormkit::gpu::PixelFormat::R8U, - stormkit::gpu::PixelFormat::R8_UNORM, - stormkit::gpu::PixelFormat::RG16F, - stormkit::gpu::PixelFormat::RG16I, - stormkit::gpu::PixelFormat::RG16_SNORM, - stormkit::gpu::PixelFormat::RG16U, - stormkit::gpu::PixelFormat::RG16_UNORM, - stormkit::gpu::PixelFormat::RG32F, - stormkit::gpu::PixelFormat::RG32I, - stormkit::gpu::PixelFormat::RG32U, - stormkit::gpu::PixelFormat::RG8I, - stormkit::gpu::PixelFormat::RG8_SNORM, - stormkit::gpu::PixelFormat::RG8U, - stormkit::gpu::PixelFormat::RG8_UNORM, - stormkit::gpu::PixelFormat::RGB16F, - stormkit::gpu::PixelFormat::RGB16I, - stormkit::gpu::PixelFormat::RGB16_SNORM, - stormkit::gpu::PixelFormat::RGB16U, - stormkit::gpu::PixelFormat::RGB16_UNORM, - stormkit::gpu::PixelFormat::RGB32F, - stormkit::gpu::PixelFormat::RGB32I, - stormkit::gpu::PixelFormat::RGB32U, - stormkit::gpu::PixelFormat::RGB8I, - stormkit::gpu::PixelFormat::RGB8_SNORM, - stormkit::gpu::PixelFormat::RGB8U, - stormkit::gpu::PixelFormat::RGB8_UNORM, - stormkit::gpu::PixelFormat::RGBA16F, - stormkit::gpu::PixelFormat::RGBA16I, - stormkit::gpu::PixelFormat::RGBA16_SNORM, - stormkit::gpu::PixelFormat::RGBA16U, - stormkit::gpu::PixelFormat::RGBA16_UNORM, - stormkit::gpu::PixelFormat::RGBA32F, - stormkit::gpu::PixelFormat::RGBA32I, - stormkit::gpu::PixelFormat::RGBA32U, - stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16, - stormkit::gpu::PixelFormat::RGBA8I, - stormkit::gpu::PixelFormat::RGBA8_SNORM, - stormkit::gpu::PixelFormat::RGBA8U, - stormkit::gpu::PixelFormat::RGBA8_UNORM, - stormkit::gpu::PixelFormat::SBGR8, - stormkit::gpu::PixelFormat::SBGRA8, - stormkit::gpu::PixelFormat::SR8, - stormkit::gpu::PixelFormat::SRG8, - stormkit::gpu::PixelFormat::SRGB8, - stormkit::gpu::PixelFormat::SRGBA8, - stormkit::gpu::PixelFormat::UNDEFINED, - - }; - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PixelFormat value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; - case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; - case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; - case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; - case stormkit::gpu::PixelFormat::DEPTH16_UNORM: return "PixelFormat::DEPTH16_UNORM"; - case stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U: return "PixelFormat::DEPTH16_UNORM_STENCIL8U"; - case stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32: return "PixelFormat::DEPTH24_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U: return "PixelFormat::DEPTH24_UNORM_STENCIL8U"; - case stormkit::gpu::PixelFormat::DEPTH32F: return "PixelFormat::DEPTH32F"; - case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; - case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; - case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; - case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; - case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; - case stormkit::gpu::PixelFormat::R16_UNORM: return "PixelFormat::R16_UNORM"; - case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; - case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; - case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; - case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; - case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; - case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; - case stormkit::gpu::PixelFormat::R8_UNORM: return "PixelFormat::R8_UNORM"; - case stormkit::gpu::PixelFormat::RG16F: return "PixelFormat::RG16F"; - case stormkit::gpu::PixelFormat::RG16I: return "PixelFormat::RG16I"; - case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; - case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; - case stormkit::gpu::PixelFormat::RG16_UNORM: return "PixelFormat::RG16_UNORM"; - case stormkit::gpu::PixelFormat::RG32F: return "PixelFormat::RG32F"; - case stormkit::gpu::PixelFormat::RG32I: return "PixelFormat::RG32I"; - case stormkit::gpu::PixelFormat::RG32U: return "PixelFormat::RG32U"; - case stormkit::gpu::PixelFormat::RG8I: return "PixelFormat::RG8I"; - case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; - case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; - case stormkit::gpu::PixelFormat::RG8_UNORM: return "PixelFormat::RG8_UNORM"; - case stormkit::gpu::PixelFormat::RGB16F: return "PixelFormat::RGB16F"; - case stormkit::gpu::PixelFormat::RGB16I: return "PixelFormat::RGB16I"; - case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; - case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; - case stormkit::gpu::PixelFormat::RGB16_UNORM: return "PixelFormat::RGB16_UNORM"; - case stormkit::gpu::PixelFormat::RGB32F: return "PixelFormat::RGB32F"; - case stormkit::gpu::PixelFormat::RGB32I: return "PixelFormat::RGB32I"; - case stormkit::gpu::PixelFormat::RGB32U: return "PixelFormat::RGB32U"; - case stormkit::gpu::PixelFormat::RGB8I: return "PixelFormat::RGB8I"; - case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; - case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; - case stormkit::gpu::PixelFormat::RGB8_UNORM: return "PixelFormat::RGB8_UNORM"; - case stormkit::gpu::PixelFormat::RGBA16F: return "PixelFormat::RGBA16F"; - case stormkit::gpu::PixelFormat::RGBA16I: return "PixelFormat::RGBA16I"; - case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; - case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; - case stormkit::gpu::PixelFormat::RGBA16_UNORM: return "PixelFormat::RGBA16_UNORM"; - case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; - case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; - case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; - case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; - case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; - case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; - case stormkit::gpu::PixelFormat::RGBA8_UNORM: return "PixelFormat::RGBA8_UNORM"; - case stormkit::gpu::PixelFormat::SBGR8: return "PixelFormat::SBGR8"; - case stormkit::gpu::PixelFormat::SBGRA8: return "PixelFormat::SBGRA8"; - case stormkit::gpu::PixelFormat::SR8: return "PixelFormat::SR8"; - case stormkit::gpu::PixelFormat::SRG8: return "PixelFormat::SRG8"; - case stormkit::gpu::PixelFormat::SRGB8: return "PixelFormat::SRGB8"; - case stormkit::gpu::PixelFormat::SRGBA8: return "PixelFormat::SRGBA8"; - case stormkit::gpu::PixelFormat::UNDEFINED: return "PixelFormat::UNDEFINED"; - - } - std::unreachable(); - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::PixelFormat value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; - case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; - case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; - case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; - case stormkit::gpu::PixelFormat::DEPTH16_UNORM: return "PixelFormat::DEPTH16_UNORM"; - case stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U: return "PixelFormat::DEPTH16_UNORM_STENCIL8U"; - case stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32: return "PixelFormat::DEPTH24_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U: return "PixelFormat::DEPTH24_UNORM_STENCIL8U"; - case stormkit::gpu::PixelFormat::DEPTH32F: return "PixelFormat::DEPTH32F"; - case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; - case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; - case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; - case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; - case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; - case stormkit::gpu::PixelFormat::R16_UNORM: return "PixelFormat::R16_UNORM"; - case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; - case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; - case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; - case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; - case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; - case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; - case stormkit::gpu::PixelFormat::R8_UNORM: return "PixelFormat::R8_UNORM"; - case stormkit::gpu::PixelFormat::RG16F: return "PixelFormat::RG16F"; - case stormkit::gpu::PixelFormat::RG16I: return "PixelFormat::RG16I"; - case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; - case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; - case stormkit::gpu::PixelFormat::RG16_UNORM: return "PixelFormat::RG16_UNORM"; - case stormkit::gpu::PixelFormat::RG32F: return "PixelFormat::RG32F"; - case stormkit::gpu::PixelFormat::RG32I: return "PixelFormat::RG32I"; - case stormkit::gpu::PixelFormat::RG32U: return "PixelFormat::RG32U"; - case stormkit::gpu::PixelFormat::RG8I: return "PixelFormat::RG8I"; - case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; - case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; - case stormkit::gpu::PixelFormat::RG8_UNORM: return "PixelFormat::RG8_UNORM"; - case stormkit::gpu::PixelFormat::RGB16F: return "PixelFormat::RGB16F"; - case stormkit::gpu::PixelFormat::RGB16I: return "PixelFormat::RGB16I"; - case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; - case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; - case stormkit::gpu::PixelFormat::RGB16_UNORM: return "PixelFormat::RGB16_UNORM"; - case stormkit::gpu::PixelFormat::RGB32F: return "PixelFormat::RGB32F"; - case stormkit::gpu::PixelFormat::RGB32I: return "PixelFormat::RGB32I"; - case stormkit::gpu::PixelFormat::RGB32U: return "PixelFormat::RGB32U"; - case stormkit::gpu::PixelFormat::RGB8I: return "PixelFormat::RGB8I"; - case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; - case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; - case stormkit::gpu::PixelFormat::RGB8_UNORM: return "PixelFormat::RGB8_UNORM"; - case stormkit::gpu::PixelFormat::RGBA16F: return "PixelFormat::RGBA16F"; - case stormkit::gpu::PixelFormat::RGBA16I: return "PixelFormat::RGBA16I"; - case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; - case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; - case stormkit::gpu::PixelFormat::RGBA16_UNORM: return "PixelFormat::RGBA16_UNORM"; - case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; - case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; - case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; - case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; - case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; - case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; - case stormkit::gpu::PixelFormat::RGBA8_UNORM: return "PixelFormat::RGBA8_UNORM"; - case stormkit::gpu::PixelFormat::SBGR8: return "PixelFormat::SBGR8"; - case stormkit::gpu::PixelFormat::SBGRA8: return "PixelFormat::SBGRA8"; - case stormkit::gpu::PixelFormat::SR8: return "PixelFormat::SR8"; - case stormkit::gpu::PixelFormat::SRG8: return "PixelFormat::SRG8"; - case stormkit::gpu::PixelFormat::SRGB8: return "PixelFormat::SRGB8"; - case stormkit::gpu::PixelFormat::SRGBA8: return "PixelFormat::SRGBA8"; - case stormkit::gpu::PixelFormat::UNDEFINED: return "PixelFormat::UNDEFINED"; - + stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16, + stormkit::gpu::PixelFormat::A2_RGB10I_PACK32, + stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32, + stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32, + stormkit::gpu::PixelFormat::A2_RGB10U_PACK32, + stormkit::gpu::PixelFormat::B10_GR11UF_PACK32, + stormkit::gpu::PixelFormat::BGR8_UNORM, + stormkit::gpu::PixelFormat::BGRA8_UNORM, + stormkit::gpu::PixelFormat::DEPTH16_UNORM, + stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U, + stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32, + stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U, + stormkit::gpu::PixelFormat::DEPTH32F, + stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U, + stormkit::gpu::PixelFormat::R16F, + stormkit::gpu::PixelFormat::R16I, + stormkit::gpu::PixelFormat::R16_SNORM, + stormkit::gpu::PixelFormat::R16U, + stormkit::gpu::PixelFormat::R16_UNORM, + stormkit::gpu::PixelFormat::R32F, + stormkit::gpu::PixelFormat::R32I, + stormkit::gpu::PixelFormat::R32U, + stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16, + stormkit::gpu::PixelFormat::R8I, + stormkit::gpu::PixelFormat::R8_SNORM, + stormkit::gpu::PixelFormat::R8U, + stormkit::gpu::PixelFormat::R8_UNORM, + stormkit::gpu::PixelFormat::RG16F, + stormkit::gpu::PixelFormat::RG16I, + stormkit::gpu::PixelFormat::RG16_SNORM, + stormkit::gpu::PixelFormat::RG16U, + stormkit::gpu::PixelFormat::RG16_UNORM, + stormkit::gpu::PixelFormat::RG32F, + stormkit::gpu::PixelFormat::RG32I, + stormkit::gpu::PixelFormat::RG32U, + stormkit::gpu::PixelFormat::RG8I, + stormkit::gpu::PixelFormat::RG8_SNORM, + stormkit::gpu::PixelFormat::RG8U, + stormkit::gpu::PixelFormat::RG8_UNORM, + stormkit::gpu::PixelFormat::RGB16F, + stormkit::gpu::PixelFormat::RGB16I, + stormkit::gpu::PixelFormat::RGB16_SNORM, + stormkit::gpu::PixelFormat::RGB16U, + stormkit::gpu::PixelFormat::RGB16_UNORM, + stormkit::gpu::PixelFormat::RGB32F, + stormkit::gpu::PixelFormat::RGB32I, + stormkit::gpu::PixelFormat::RGB32U, + stormkit::gpu::PixelFormat::RGB8I, + stormkit::gpu::PixelFormat::RGB8_SNORM, + stormkit::gpu::PixelFormat::RGB8U, + stormkit::gpu::PixelFormat::RGB8_UNORM, + stormkit::gpu::PixelFormat::RGBA16F, + stormkit::gpu::PixelFormat::RGBA16I, + stormkit::gpu::PixelFormat::RGBA16_SNORM, + stormkit::gpu::PixelFormat::RGBA16U, + stormkit::gpu::PixelFormat::RGBA16_UNORM, + stormkit::gpu::PixelFormat::RGBA32F, + stormkit::gpu::PixelFormat::RGBA32I, + stormkit::gpu::PixelFormat::RGBA32U, + stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16, + stormkit::gpu::PixelFormat::RGBA8I, + stormkit::gpu::PixelFormat::RGBA8_SNORM, + stormkit::gpu::PixelFormat::RGBA8U, + stormkit::gpu::PixelFormat::RGBA8_UNORM, + stormkit::gpu::PixelFormat::SBGR8, + stormkit::gpu::PixelFormat::SBGRA8, + stormkit::gpu::PixelFormat::SR8, + stormkit::gpu::PixelFormat::SRG8, + stormkit::gpu::PixelFormat::SRGB8, + stormkit::gpu::PixelFormat::SRGBA8, + stormkit::gpu::PixelFormat::UNDEFINED, + + }; + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::PixelFormat value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; + case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; + case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; + case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; + case stormkit::gpu::PixelFormat::DEPTH16_UNORM: return "PixelFormat::DEPTH16_UNORM"; + case stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U: return "PixelFormat::DEPTH16_UNORM_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32: return "PixelFormat::DEPTH24_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U: return "PixelFormat::DEPTH24_UNORM_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH32F: return "PixelFormat::DEPTH32F"; + case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; + case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; + case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; + case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; + case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; + case stormkit::gpu::PixelFormat::R16_UNORM: return "PixelFormat::R16_UNORM"; + case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; + case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; + case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; + case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; + case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; + case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; + case stormkit::gpu::PixelFormat::R8_UNORM: return "PixelFormat::R8_UNORM"; + case stormkit::gpu::PixelFormat::RG16F: return "PixelFormat::RG16F"; + case stormkit::gpu::PixelFormat::RG16I: return "PixelFormat::RG16I"; + case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; + case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; + case stormkit::gpu::PixelFormat::RG16_UNORM: return "PixelFormat::RG16_UNORM"; + case stormkit::gpu::PixelFormat::RG32F: return "PixelFormat::RG32F"; + case stormkit::gpu::PixelFormat::RG32I: return "PixelFormat::RG32I"; + case stormkit::gpu::PixelFormat::RG32U: return "PixelFormat::RG32U"; + case stormkit::gpu::PixelFormat::RG8I: return "PixelFormat::RG8I"; + case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; + case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; + case stormkit::gpu::PixelFormat::RG8_UNORM: return "PixelFormat::RG8_UNORM"; + case stormkit::gpu::PixelFormat::RGB16F: return "PixelFormat::RGB16F"; + case stormkit::gpu::PixelFormat::RGB16I: return "PixelFormat::RGB16I"; + case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; + case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; + case stormkit::gpu::PixelFormat::RGB16_UNORM: return "PixelFormat::RGB16_UNORM"; + case stormkit::gpu::PixelFormat::RGB32F: return "PixelFormat::RGB32F"; + case stormkit::gpu::PixelFormat::RGB32I: return "PixelFormat::RGB32I"; + case stormkit::gpu::PixelFormat::RGB32U: return "PixelFormat::RGB32U"; + case stormkit::gpu::PixelFormat::RGB8I: return "PixelFormat::RGB8I"; + case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; + case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; + case stormkit::gpu::PixelFormat::RGB8_UNORM: return "PixelFormat::RGB8_UNORM"; + case stormkit::gpu::PixelFormat::RGBA16F: return "PixelFormat::RGBA16F"; + case stormkit::gpu::PixelFormat::RGBA16I: return "PixelFormat::RGBA16I"; + case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; + case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; + case stormkit::gpu::PixelFormat::RGBA16_UNORM: return "PixelFormat::RGBA16_UNORM"; + case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; + case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; + case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; + case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; + case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; + case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; + case stormkit::gpu::PixelFormat::RGBA8_UNORM: return "PixelFormat::RGBA8_UNORM"; + case stormkit::gpu::PixelFormat::SBGR8: return "PixelFormat::SBGR8"; + case stormkit::gpu::PixelFormat::SBGRA8: return "PixelFormat::SBGRA8"; + case stormkit::gpu::PixelFormat::SR8: return "PixelFormat::SR8"; + case stormkit::gpu::PixelFormat::SRG8: return "PixelFormat::SRG8"; + case stormkit::gpu::PixelFormat::SRGB8: return "PixelFormat::SRGB8"; + case stormkit::gpu::PixelFormat::SRGBA8: return "PixelFormat::SRGBA8"; + case stormkit::gpu::PixelFormat::UNDEFINED: return "PixelFormat::UNDEFINED"; + } + std::unreachable(); + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::to_string(stormkit::gpu::PixelFormat value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; + case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; + case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; + case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; + case stormkit::gpu::PixelFormat::DEPTH16_UNORM: return "PixelFormat::DEPTH16_UNORM"; + case stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U: return "PixelFormat::DEPTH16_UNORM_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32: return "PixelFormat::DEPTH24_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U: return "PixelFormat::DEPTH24_UNORM_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH32F: return "PixelFormat::DEPTH32F"; + case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; + case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; + case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; + case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; + case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; + case stormkit::gpu::PixelFormat::R16_UNORM: return "PixelFormat::R16_UNORM"; + case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; + case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; + case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; + case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; + case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; + case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; + case stormkit::gpu::PixelFormat::R8_UNORM: return "PixelFormat::R8_UNORM"; + case stormkit::gpu::PixelFormat::RG16F: return "PixelFormat::RG16F"; + case stormkit::gpu::PixelFormat::RG16I: return "PixelFormat::RG16I"; + case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; + case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; + case stormkit::gpu::PixelFormat::RG16_UNORM: return "PixelFormat::RG16_UNORM"; + case stormkit::gpu::PixelFormat::RG32F: return "PixelFormat::RG32F"; + case stormkit::gpu::PixelFormat::RG32I: return "PixelFormat::RG32I"; + case stormkit::gpu::PixelFormat::RG32U: return "PixelFormat::RG32U"; + case stormkit::gpu::PixelFormat::RG8I: return "PixelFormat::RG8I"; + case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; + case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; + case stormkit::gpu::PixelFormat::RG8_UNORM: return "PixelFormat::RG8_UNORM"; + case stormkit::gpu::PixelFormat::RGB16F: return "PixelFormat::RGB16F"; + case stormkit::gpu::PixelFormat::RGB16I: return "PixelFormat::RGB16I"; + case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; + case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; + case stormkit::gpu::PixelFormat::RGB16_UNORM: return "PixelFormat::RGB16_UNORM"; + case stormkit::gpu::PixelFormat::RGB32F: return "PixelFormat::RGB32F"; + case stormkit::gpu::PixelFormat::RGB32I: return "PixelFormat::RGB32I"; + case stormkit::gpu::PixelFormat::RGB32U: return "PixelFormat::RGB32U"; + case stormkit::gpu::PixelFormat::RGB8I: return "PixelFormat::RGB8I"; + case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; + case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; + case stormkit::gpu::PixelFormat::RGB8_UNORM: return "PixelFormat::RGB8_UNORM"; + case stormkit::gpu::PixelFormat::RGBA16F: return "PixelFormat::RGBA16F"; + case stormkit::gpu::PixelFormat::RGBA16I: return "PixelFormat::RGBA16I"; + case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; + case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; + case stormkit::gpu::PixelFormat::RGBA16_UNORM: return "PixelFormat::RGBA16_UNORM"; + case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; + case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; + case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; + case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; + case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; + case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; + case stormkit::gpu::PixelFormat::RGBA8_UNORM: return "PixelFormat::RGBA8_UNORM"; + case stormkit::gpu::PixelFormat::SBGR8: return "PixelFormat::SBGR8"; + case stormkit::gpu::PixelFormat::SBGRA8: return "PixelFormat::SBGRA8"; + case stormkit::gpu::PixelFormat::SR8: return "PixelFormat::SR8"; + case stormkit::gpu::PixelFormat::SRG8: return "PixelFormat::SRG8"; + case stormkit::gpu::PixelFormat::SRGB8: return "PixelFormat::SRGB8"; + case stormkit::gpu::PixelFormat::SRGBA8: return "PixelFormat::SRGBA8"; + case stormkit::gpu::PixelFormat::UNDEFINED: return "PixelFormat::UNDEFINED"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PolygonMode) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PolygonMode::FILL, - stormkit::gpu::PolygonMode::LINE, - stormkit::gpu::PolygonMode::POINT, - + stormkit::gpu::PolygonMode::FILL, + stormkit::gpu::PolygonMode::LINE, + stormkit::gpu::PolygonMode::POINT, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PolygonMode value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::PolygonMode::FILL: return "PolygonMode::FILL"; - case stormkit::gpu::PolygonMode::LINE: return "PolygonMode::LINE"; - case stormkit::gpu::PolygonMode::POINT: return "PolygonMode::POINT"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::PolygonMode value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::PolygonMode::FILL: return "PolygonMode::FILL"; + case stormkit::gpu::PolygonMode::LINE: return "PolygonMode::LINE"; + case stormkit::gpu::PolygonMode::POINT: return "PolygonMode::POINT"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::PolygonMode value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::PolygonMode::FILL: return "PolygonMode::FILL"; - case stormkit::gpu::PolygonMode::LINE: return "PolygonMode::LINE"; - case stormkit::gpu::PolygonMode::POINT: return "PolygonMode::POINT"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::PolygonMode value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::PolygonMode::FILL: return "PolygonMode::FILL"; + case stormkit::gpu::PolygonMode::LINE: return "PolygonMode::LINE"; + case stormkit::gpu::PolygonMode::POINT: return "PolygonMode::POINT"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PresentMode) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PresentMode::FIFO, - stormkit::gpu::PresentMode::FIFO_RELAXED, - stormkit::gpu::PresentMode::IMMEDIATE, - stormkit::gpu::PresentMode::MAILBOX, - stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH, - stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH, - + stormkit::gpu::PresentMode::FIFO, + stormkit::gpu::PresentMode::FIFO_RELAXED, + stormkit::gpu::PresentMode::IMMEDIATE, + stormkit::gpu::PresentMode::MAILBOX, + stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH, + stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PresentMode value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::PresentMode::FIFO: return "PresentMode::FIFO"; - case stormkit::gpu::PresentMode::FIFO_RELAXED: return "PresentMode::FIFO_RELAXED"; - case stormkit::gpu::PresentMode::IMMEDIATE: return "PresentMode::IMMEDIATE"; - case stormkit::gpu::PresentMode::MAILBOX: return "PresentMode::MAILBOX"; - case stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH: return "PresentMode::SHARED_CONTINUOUS_REFRESH"; - case stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH: return "PresentMode::SHARED_DEMAND_REFRESH"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::PresentMode value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::PresentMode::FIFO: return "PresentMode::FIFO"; + case stormkit::gpu::PresentMode::FIFO_RELAXED: return "PresentMode::FIFO_RELAXED"; + case stormkit::gpu::PresentMode::IMMEDIATE: return "PresentMode::IMMEDIATE"; + case stormkit::gpu::PresentMode::MAILBOX: return "PresentMode::MAILBOX"; + case stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH: return "PresentMode::SHARED_CONTINUOUS_REFRESH"; + case stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH: return "PresentMode::SHARED_DEMAND_REFRESH"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::PresentMode value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::PresentMode::FIFO: return "PresentMode::FIFO"; - case stormkit::gpu::PresentMode::FIFO_RELAXED: return "PresentMode::FIFO_RELAXED"; - case stormkit::gpu::PresentMode::IMMEDIATE: return "PresentMode::IMMEDIATE"; - case stormkit::gpu::PresentMode::MAILBOX: return "PresentMode::MAILBOX"; - case stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH: return "PresentMode::SHARED_CONTINUOUS_REFRESH"; - case stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH: return "PresentMode::SHARED_DEMAND_REFRESH"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::PresentMode value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::PresentMode::FIFO: return "PresentMode::FIFO"; + case stormkit::gpu::PresentMode::FIFO_RELAXED: return "PresentMode::FIFO_RELAXED"; + case stormkit::gpu::PresentMode::IMMEDIATE: return "PresentMode::IMMEDIATE"; + case stormkit::gpu::PresentMode::MAILBOX: return "PresentMode::MAILBOX"; + case stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH: return "PresentMode::SHARED_CONTINUOUS_REFRESH"; + case stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH: return "PresentMode::SHARED_DEMAND_REFRESH"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PrimitiveTopology) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PrimitiveTopology::LINE_LIST, - stormkit::gpu::PrimitiveTopology::LINE_STRIP, - stormkit::gpu::PrimitiveTopology::POINT_LIST, - stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN, - stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST, - stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP, - + stormkit::gpu::PrimitiveTopology::LINE_LIST, stormkit::gpu::PrimitiveTopology::LINE_STRIP, + stormkit::gpu::PrimitiveTopology::POINT_LIST, stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN, + stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST, stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PrimitiveTopology value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::PrimitiveTopology::LINE_LIST: return "PrimitiveTopology::LINE_LIST"; - case stormkit::gpu::PrimitiveTopology::LINE_STRIP: return "PrimitiveTopology::LINE_STRIP"; - case stormkit::gpu::PrimitiveTopology::POINT_LIST: return "PrimitiveTopology::POINT_LIST"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN: return "PrimitiveTopology::TRIANGLE_FAN"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST: return "PrimitiveTopology::TRIANGLE_LIST"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP: return "PrimitiveTopology::TRIANGLE_STRIP"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::PrimitiveTopology value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::PrimitiveTopology::LINE_LIST: return "PrimitiveTopology::LINE_LIST"; + case stormkit::gpu::PrimitiveTopology::LINE_STRIP: return "PrimitiveTopology::LINE_STRIP"; + case stormkit::gpu::PrimitiveTopology::POINT_LIST: return "PrimitiveTopology::POINT_LIST"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN: return "PrimitiveTopology::TRIANGLE_FAN"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST: return "PrimitiveTopology::TRIANGLE_LIST"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP: return "PrimitiveTopology::TRIANGLE_STRIP"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::PrimitiveTopology value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::PrimitiveTopology::LINE_LIST: return "PrimitiveTopology::LINE_LIST"; - case stormkit::gpu::PrimitiveTopology::LINE_STRIP: return "PrimitiveTopology::LINE_STRIP"; - case stormkit::gpu::PrimitiveTopology::POINT_LIST: return "PrimitiveTopology::POINT_LIST"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN: return "PrimitiveTopology::TRIANGLE_FAN"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST: return "PrimitiveTopology::TRIANGLE_LIST"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP: return "PrimitiveTopology::TRIANGLE_STRIP"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::PrimitiveTopology value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::PrimitiveTopology::LINE_LIST: return "PrimitiveTopology::LINE_LIST"; + case stormkit::gpu::PrimitiveTopology::LINE_STRIP: return "PrimitiveTopology::LINE_STRIP"; + case stormkit::gpu::PrimitiveTopology::POINT_LIST: return "PrimitiveTopology::POINT_LIST"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN: return "PrimitiveTopology::TRIANGLE_FAN"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST: return "PrimitiveTopology::TRIANGLE_LIST"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP: return "PrimitiveTopology::TRIANGLE_STRIP"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::QueueFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::QueueFlag::COMPUTE, - stormkit::gpu::QueueFlag::GRAPHICS, - stormkit::gpu::QueueFlag::NONE, - stormkit::gpu::QueueFlag::PROTECTED, - stormkit::gpu::QueueFlag::SPARSE_BINDING, - stormkit::gpu::QueueFlag::TRANSFER, - + stormkit::gpu::QueueFlag::COMPUTE, stormkit::gpu::QueueFlag::GRAPHICS, stormkit::gpu::QueueFlag::NONE, + stormkit::gpu::QueueFlag::PROTECTED, stormkit::gpu::QueueFlag::SPARSE_BINDING, stormkit::gpu::QueueFlag::TRANSFER, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::QueueFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; - case stormkit::gpu::QueueFlag::GRAPHICS: return "QueueFlag::GRAPHICS"; - case stormkit::gpu::QueueFlag::NONE: return "QueueFlag::NONE"; - case stormkit::gpu::QueueFlag::PROTECTED: return "QueueFlag::PROTECTED"; - case stormkit::gpu::QueueFlag::SPARSE_BINDING: return "QueueFlag::SPARSE_BINDING"; - case stormkit::gpu::QueueFlag::TRANSFER: return "QueueFlag::TRANSFER"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::QueueFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; + case stormkit::gpu::QueueFlag::GRAPHICS: return "QueueFlag::GRAPHICS"; + case stormkit::gpu::QueueFlag::NONE: return "QueueFlag::NONE"; + case stormkit::gpu::QueueFlag::PROTECTED: return "QueueFlag::PROTECTED"; + case stormkit::gpu::QueueFlag::SPARSE_BINDING: return "QueueFlag::SPARSE_BINDING"; + case stormkit::gpu::QueueFlag::TRANSFER: return "QueueFlag::TRANSFER"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::QueueFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; - case stormkit::gpu::QueueFlag::GRAPHICS: return "QueueFlag::GRAPHICS"; - case stormkit::gpu::QueueFlag::NONE: return "QueueFlag::NONE"; - case stormkit::gpu::QueueFlag::PROTECTED: return "QueueFlag::PROTECTED"; - case stormkit::gpu::QueueFlag::SPARSE_BINDING: return "QueueFlag::SPARSE_BINDING"; - case stormkit::gpu::QueueFlag::TRANSFER: return "QueueFlag::TRANSFER"; - + switch (value) { + case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; + case stormkit::gpu::QueueFlag::GRAPHICS: return "QueueFlag::GRAPHICS"; + case stormkit::gpu::QueueFlag::NONE: return "QueueFlag::NONE"; + case stormkit::gpu::QueueFlag::PROTECTED: return "QueueFlag::PROTECTED"; + case stormkit::gpu::QueueFlag::SPARSE_BINDING: return "QueueFlag::SPARSE_BINDING"; + case stormkit::gpu::QueueFlag::TRANSFER: return "QueueFlag::TRANSFER"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ResolveModeFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ResolveModeFlag::AVERAGE, - stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID, - stormkit::gpu::ResolveModeFlag::MAX, - stormkit::gpu::ResolveModeFlag::MIN, - stormkit::gpu::ResolveModeFlag::NONE, - stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO, - + stormkit::gpu::ResolveModeFlag::AVERAGE, stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID, + stormkit::gpu::ResolveModeFlag::MAX, stormkit::gpu::ResolveModeFlag::MIN, + stormkit::gpu::ResolveModeFlag::NONE, stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ResolveModeFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ResolveModeFlag::AVERAGE: return "ResolveModeFlag::AVERAGE"; - case stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID: return "ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID"; - case stormkit::gpu::ResolveModeFlag::MAX: return "ResolveModeFlag::MAX"; - case stormkit::gpu::ResolveModeFlag::MIN: return "ResolveModeFlag::MIN"; - case stormkit::gpu::ResolveModeFlag::NONE: return "ResolveModeFlag::NONE"; - case stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO: return "ResolveModeFlag::SAMPLE_ZERO"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::ResolveModeFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ResolveModeFlag::AVERAGE: return "ResolveModeFlag::AVERAGE"; + case stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID: + return "ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID"; + case stormkit::gpu::ResolveModeFlag::MAX: return "ResolveModeFlag::MAX"; + case stormkit::gpu::ResolveModeFlag::MIN: return "ResolveModeFlag::MIN"; + case stormkit::gpu::ResolveModeFlag::NONE: return "ResolveModeFlag::NONE"; + case stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO: return "ResolveModeFlag::SAMPLE_ZERO"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ResolveModeFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ResolveModeFlag::AVERAGE: return "ResolveModeFlag::AVERAGE"; - case stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID: return "ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID"; - case stormkit::gpu::ResolveModeFlag::MAX: return "ResolveModeFlag::MAX"; - case stormkit::gpu::ResolveModeFlag::MIN: return "ResolveModeFlag::MIN"; - case stormkit::gpu::ResolveModeFlag::NONE: return "ResolveModeFlag::NONE"; - case stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO: return "ResolveModeFlag::SAMPLE_ZERO"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::ResolveModeFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::ResolveModeFlag::AVERAGE: return "ResolveModeFlag::AVERAGE"; + case stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID: + return "ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID"; + case stormkit::gpu::ResolveModeFlag::MAX: return "ResolveModeFlag::MAX"; + case stormkit::gpu::ResolveModeFlag::MIN: return "ResolveModeFlag::MIN"; + case stormkit::gpu::ResolveModeFlag::NONE: return "ResolveModeFlag::NONE"; + case stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO: return "ResolveModeFlag::SAMPLE_ZERO"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::Result) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::Result::ERROR_DEVICE_LOST, - stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT, - stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT, - stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED, - stormkit::gpu::Result::ERROR_FRAGMENTATION, - stormkit::gpu::Result::ERROR_FRAGMENTED_POOL, - stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST, - stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY, - stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER, - stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED, - stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE, - stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, - stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT, - stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED, - stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE, - stormkit::gpu::Result::ERROR_NOT_PERMITTED, - stormkit::gpu::Result::ERROR_OUT_OF_DATE, - stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY, - stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY, - stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY, - stormkit::gpu::Result::ERROR_SURFACE_LOST, - stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS, - stormkit::gpu::Result::ERROR_UNKNOWN, - stormkit::gpu::Result::ERROR_VALIDATION_FAILED, - stormkit::gpu::Result::EVENT_RESET, - stormkit::gpu::Result::EVENT_SET, - stormkit::gpu::Result::INCOMPLETE, - stormkit::gpu::Result::NOT_READY, - stormkit::gpu::Result::OPERATION_DEFERRED, - stormkit::gpu::Result::OPERATION_NOT_DEFERRED, - stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED, - stormkit::gpu::Result::SUBOPTIMAL, - stormkit::gpu::Result::SUCCESS, - stormkit::gpu::Result::THREAD_DONE, - stormkit::gpu::Result::THREAD_IDLE, - stormkit::gpu::Result::TIMEOUT, - + stormkit::gpu::Result::ERROR_DEVICE_LOST, + stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT, + stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT, + stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED, + stormkit::gpu::Result::ERROR_FRAGMENTATION, + stormkit::gpu::Result::ERROR_FRAGMENTED_POOL, + stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST, + stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY, + stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER, + stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED, + stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE, + stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, + stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT, + stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED, + stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE, + stormkit::gpu::Result::ERROR_NOT_PERMITTED, + stormkit::gpu::Result::ERROR_OUT_OF_DATE, + stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY, + stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY, + stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY, + stormkit::gpu::Result::ERROR_SURFACE_LOST, + stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS, + stormkit::gpu::Result::ERROR_UNKNOWN, + stormkit::gpu::Result::ERROR_VALIDATION_FAILED, + stormkit::gpu::Result::EVENT_RESET, + stormkit::gpu::Result::EVENT_SET, + stormkit::gpu::Result::INCOMPLETE, + stormkit::gpu::Result::NOT_READY, + stormkit::gpu::Result::OPERATION_DEFERRED, + stormkit::gpu::Result::OPERATION_NOT_DEFERRED, + stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED, + stormkit::gpu::Result::SUBOPTIMAL, + stormkit::gpu::Result::SUCCESS, + stormkit::gpu::Result::THREAD_DONE, + stormkit::gpu::Result::THREAD_IDLE, + stormkit::gpu::Result::TIMEOUT, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::Result value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; - case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: return "Result::ERROR_EXTENSION_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT: return "Result::ERROR_FEATURE_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED: return "Result::ERROR_FORMAT_NOT_SUPPORTED"; - case stormkit::gpu::Result::ERROR_FRAGMENTATION: return "Result::ERROR_FRAGMENTATION"; - case stormkit::gpu::Result::ERROR_FRAGMENTED_POOL: return "Result::ERROR_FRAGMENTED_POOL"; - case stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST: return "Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST"; - case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY: return "Result::ERROR_INCOMPATIBLE_DISPLAY"; - case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER: return "Result::ERROR_INCOMPATIBLE_DRIVER"; - case stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED: return "Result::ERROR_INITIALIZATION_FAILED"; - case stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE: return "Result::ERROR_INVALID_EXTERNAL_HANDLE"; - case stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: return "Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; - case stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT: return "Result::ERROR_LAYER_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED: return "Result::ERROR_MEMORY_MAP_FAILED"; - case stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE: return "Result::ERROR_NATIVE_WINDOW_IN_USE"; - case stormkit::gpu::Result::ERROR_NOT_PERMITTED: return "Result::ERROR_NOT_PERMITTED"; - case stormkit::gpu::Result::ERROR_OUT_OF_DATE: return "Result::ERROR_OUT_OF_DATE"; - case stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY: return "Result::ERROR_OUT_OF_DEVICE_MEMORY"; - case stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY: return "Result::ERROR_OUT_OF_HOST_MEMORY"; - case stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY: return "Result::ERROR_OUT_OF_POOL_MEMORY"; - case stormkit::gpu::Result::ERROR_SURFACE_LOST: return "Result::ERROR_SURFACE_LOST"; - case stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS: return "Result::ERROR_TOO_MANY_OBJECTS"; - case stormkit::gpu::Result::ERROR_UNKNOWN: return "Result::ERROR_UNKNOWN"; - case stormkit::gpu::Result::ERROR_VALIDATION_FAILED: return "Result::ERROR_VALIDATION_FAILED"; - case stormkit::gpu::Result::EVENT_RESET: return "Result::EVENT_RESET"; - case stormkit::gpu::Result::EVENT_SET: return "Result::EVENT_SET"; - case stormkit::gpu::Result::INCOMPLETE: return "Result::INCOMPLETE"; - case stormkit::gpu::Result::NOT_READY: return "Result::NOT_READY"; - case stormkit::gpu::Result::OPERATION_DEFERRED: return "Result::OPERATION_DEFERRED"; - case stormkit::gpu::Result::OPERATION_NOT_DEFERRED: return "Result::OPERATION_NOT_DEFERRED"; - case stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED: return "Result::PIPELINE_COMPILE_REQUIRED"; - case stormkit::gpu::Result::SUBOPTIMAL: return "Result::SUBOPTIMAL"; - case stormkit::gpu::Result::SUCCESS: return "Result::SUCCESS"; - case stormkit::gpu::Result::THREAD_DONE: return "Result::THREAD_DONE"; - case stormkit::gpu::Result::THREAD_IDLE: return "Result::THREAD_IDLE"; - case stormkit::gpu::Result::TIMEOUT: return "Result::TIMEOUT"; - + switch (value) { + case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; + case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: return "Result::ERROR_EXTENSION_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT: return "Result::ERROR_FEATURE_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED: return "Result::ERROR_FORMAT_NOT_SUPPORTED"; + case stormkit::gpu::Result::ERROR_FRAGMENTATION: return "Result::ERROR_FRAGMENTATION"; + case stormkit::gpu::Result::ERROR_FRAGMENTED_POOL: return "Result::ERROR_FRAGMENTED_POOL"; + case stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST: + return "Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST"; + case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY: return "Result::ERROR_INCOMPATIBLE_DISPLAY"; + case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER: return "Result::ERROR_INCOMPATIBLE_DRIVER"; + case stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED: return "Result::ERROR_INITIALIZATION_FAILED"; + case stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE: return "Result::ERROR_INVALID_EXTERNAL_HANDLE"; + case stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: + return "Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; + case stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT: return "Result::ERROR_LAYER_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED: return "Result::ERROR_MEMORY_MAP_FAILED"; + case stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE: return "Result::ERROR_NATIVE_WINDOW_IN_USE"; + case stormkit::gpu::Result::ERROR_NOT_PERMITTED: return "Result::ERROR_NOT_PERMITTED"; + case stormkit::gpu::Result::ERROR_OUT_OF_DATE: return "Result::ERROR_OUT_OF_DATE"; + case stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY: return "Result::ERROR_OUT_OF_DEVICE_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY: return "Result::ERROR_OUT_OF_HOST_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY: return "Result::ERROR_OUT_OF_POOL_MEMORY"; + case stormkit::gpu::Result::ERROR_SURFACE_LOST: return "Result::ERROR_SURFACE_LOST"; + case stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS: return "Result::ERROR_TOO_MANY_OBJECTS"; + case stormkit::gpu::Result::ERROR_UNKNOWN: return "Result::ERROR_UNKNOWN"; + case stormkit::gpu::Result::ERROR_VALIDATION_FAILED: return "Result::ERROR_VALIDATION_FAILED"; + case stormkit::gpu::Result::EVENT_RESET: return "Result::EVENT_RESET"; + case stormkit::gpu::Result::EVENT_SET: return "Result::EVENT_SET"; + case stormkit::gpu::Result::INCOMPLETE: return "Result::INCOMPLETE"; + case stormkit::gpu::Result::NOT_READY: return "Result::NOT_READY"; + case stormkit::gpu::Result::OPERATION_DEFERRED: return "Result::OPERATION_DEFERRED"; + case stormkit::gpu::Result::OPERATION_NOT_DEFERRED: return "Result::OPERATION_NOT_DEFERRED"; + case stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED: return "Result::PIPELINE_COMPILE_REQUIRED"; + case stormkit::gpu::Result::SUBOPTIMAL: return "Result::SUBOPTIMAL"; + case stormkit::gpu::Result::SUCCESS: return "Result::SUCCESS"; + case stormkit::gpu::Result::THREAD_DONE: return "Result::THREAD_DONE"; + case stormkit::gpu::Result::THREAD_IDLE: return "Result::THREAD_IDLE"; + case stormkit::gpu::Result::TIMEOUT: return "Result::TIMEOUT"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::Result value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; - case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: return "Result::ERROR_EXTENSION_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT: return "Result::ERROR_FEATURE_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED: return "Result::ERROR_FORMAT_NOT_SUPPORTED"; - case stormkit::gpu::Result::ERROR_FRAGMENTATION: return "Result::ERROR_FRAGMENTATION"; - case stormkit::gpu::Result::ERROR_FRAGMENTED_POOL: return "Result::ERROR_FRAGMENTED_POOL"; - case stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST: return "Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST"; - case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY: return "Result::ERROR_INCOMPATIBLE_DISPLAY"; - case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER: return "Result::ERROR_INCOMPATIBLE_DRIVER"; - case stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED: return "Result::ERROR_INITIALIZATION_FAILED"; - case stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE: return "Result::ERROR_INVALID_EXTERNAL_HANDLE"; - case stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: return "Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; - case stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT: return "Result::ERROR_LAYER_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED: return "Result::ERROR_MEMORY_MAP_FAILED"; - case stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE: return "Result::ERROR_NATIVE_WINDOW_IN_USE"; - case stormkit::gpu::Result::ERROR_NOT_PERMITTED: return "Result::ERROR_NOT_PERMITTED"; - case stormkit::gpu::Result::ERROR_OUT_OF_DATE: return "Result::ERROR_OUT_OF_DATE"; - case stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY: return "Result::ERROR_OUT_OF_DEVICE_MEMORY"; - case stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY: return "Result::ERROR_OUT_OF_HOST_MEMORY"; - case stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY: return "Result::ERROR_OUT_OF_POOL_MEMORY"; - case stormkit::gpu::Result::ERROR_SURFACE_LOST: return "Result::ERROR_SURFACE_LOST"; - case stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS: return "Result::ERROR_TOO_MANY_OBJECTS"; - case stormkit::gpu::Result::ERROR_UNKNOWN: return "Result::ERROR_UNKNOWN"; - case stormkit::gpu::Result::ERROR_VALIDATION_FAILED: return "Result::ERROR_VALIDATION_FAILED"; - case stormkit::gpu::Result::EVENT_RESET: return "Result::EVENT_RESET"; - case stormkit::gpu::Result::EVENT_SET: return "Result::EVENT_SET"; - case stormkit::gpu::Result::INCOMPLETE: return "Result::INCOMPLETE"; - case stormkit::gpu::Result::NOT_READY: return "Result::NOT_READY"; - case stormkit::gpu::Result::OPERATION_DEFERRED: return "Result::OPERATION_DEFERRED"; - case stormkit::gpu::Result::OPERATION_NOT_DEFERRED: return "Result::OPERATION_NOT_DEFERRED"; - case stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED: return "Result::PIPELINE_COMPILE_REQUIRED"; - case stormkit::gpu::Result::SUBOPTIMAL: return "Result::SUBOPTIMAL"; - case stormkit::gpu::Result::SUCCESS: return "Result::SUCCESS"; - case stormkit::gpu::Result::THREAD_DONE: return "Result::THREAD_DONE"; - case stormkit::gpu::Result::THREAD_IDLE: return "Result::THREAD_IDLE"; - case stormkit::gpu::Result::TIMEOUT: return "Result::TIMEOUT"; - + switch (value) { + case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; + case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: return "Result::ERROR_EXTENSION_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT: return "Result::ERROR_FEATURE_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED: return "Result::ERROR_FORMAT_NOT_SUPPORTED"; + case stormkit::gpu::Result::ERROR_FRAGMENTATION: return "Result::ERROR_FRAGMENTATION"; + case stormkit::gpu::Result::ERROR_FRAGMENTED_POOL: return "Result::ERROR_FRAGMENTED_POOL"; + case stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST: + return "Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST"; + case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY: return "Result::ERROR_INCOMPATIBLE_DISPLAY"; + case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER: return "Result::ERROR_INCOMPATIBLE_DRIVER"; + case stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED: return "Result::ERROR_INITIALIZATION_FAILED"; + case stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE: return "Result::ERROR_INVALID_EXTERNAL_HANDLE"; + case stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: + return "Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; + case stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT: return "Result::ERROR_LAYER_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED: return "Result::ERROR_MEMORY_MAP_FAILED"; + case stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE: return "Result::ERROR_NATIVE_WINDOW_IN_USE"; + case stormkit::gpu::Result::ERROR_NOT_PERMITTED: return "Result::ERROR_NOT_PERMITTED"; + case stormkit::gpu::Result::ERROR_OUT_OF_DATE: return "Result::ERROR_OUT_OF_DATE"; + case stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY: return "Result::ERROR_OUT_OF_DEVICE_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY: return "Result::ERROR_OUT_OF_HOST_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY: return "Result::ERROR_OUT_OF_POOL_MEMORY"; + case stormkit::gpu::Result::ERROR_SURFACE_LOST: return "Result::ERROR_SURFACE_LOST"; + case stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS: return "Result::ERROR_TOO_MANY_OBJECTS"; + case stormkit::gpu::Result::ERROR_UNKNOWN: return "Result::ERROR_UNKNOWN"; + case stormkit::gpu::Result::ERROR_VALIDATION_FAILED: return "Result::ERROR_VALIDATION_FAILED"; + case stormkit::gpu::Result::EVENT_RESET: return "Result::EVENT_RESET"; + case stormkit::gpu::Result::EVENT_SET: return "Result::EVENT_SET"; + case stormkit::gpu::Result::INCOMPLETE: return "Result::INCOMPLETE"; + case stormkit::gpu::Result::NOT_READY: return "Result::NOT_READY"; + case stormkit::gpu::Result::OPERATION_DEFERRED: return "Result::OPERATION_DEFERRED"; + case stormkit::gpu::Result::OPERATION_NOT_DEFERRED: return "Result::OPERATION_NOT_DEFERRED"; + case stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED: return "Result::PIPELINE_COMPILE_REQUIRED"; + case stormkit::gpu::Result::SUBOPTIMAL: return "Result::SUBOPTIMAL"; + case stormkit::gpu::Result::SUCCESS: return "Result::SUCCESS"; + case stormkit::gpu::Result::THREAD_DONE: return "Result::THREAD_DONE"; + case stormkit::gpu::Result::THREAD_IDLE: return "Result::THREAD_IDLE"; + case stormkit::gpu::Result::TIMEOUT: return "Result::TIMEOUT"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::SampleCountFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::SampleCountFlag::C1, - stormkit::gpu::SampleCountFlag::C16, - stormkit::gpu::SampleCountFlag::C2, - stormkit::gpu::SampleCountFlag::C32, - stormkit::gpu::SampleCountFlag::C4, - stormkit::gpu::SampleCountFlag::C64, - stormkit::gpu::SampleCountFlag::C8, - + stormkit::gpu::SampleCountFlag::C1, stormkit::gpu::SampleCountFlag::C16, stormkit::gpu::SampleCountFlag::C2, + stormkit::gpu::SampleCountFlag::C32, stormkit::gpu::SampleCountFlag::C4, stormkit::gpu::SampleCountFlag::C64, + stormkit::gpu::SampleCountFlag::C8, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::SampleCountFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::SampleCountFlag::C1: return "SampleCountFlag::C1"; - case stormkit::gpu::SampleCountFlag::C16: return "SampleCountFlag::C16"; - case stormkit::gpu::SampleCountFlag::C2: return "SampleCountFlag::C2"; - case stormkit::gpu::SampleCountFlag::C32: return "SampleCountFlag::C32"; - case stormkit::gpu::SampleCountFlag::C4: return "SampleCountFlag::C4"; - case stormkit::gpu::SampleCountFlag::C64: return "SampleCountFlag::C64"; - case stormkit::gpu::SampleCountFlag::C8: return "SampleCountFlag::C8"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::SampleCountFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::SampleCountFlag::C1: return "SampleCountFlag::C1"; + case stormkit::gpu::SampleCountFlag::C16: return "SampleCountFlag::C16"; + case stormkit::gpu::SampleCountFlag::C2: return "SampleCountFlag::C2"; + case stormkit::gpu::SampleCountFlag::C32: return "SampleCountFlag::C32"; + case stormkit::gpu::SampleCountFlag::C4: return "SampleCountFlag::C4"; + case stormkit::gpu::SampleCountFlag::C64: return "SampleCountFlag::C64"; + case stormkit::gpu::SampleCountFlag::C8: return "SampleCountFlag::C8"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::SampleCountFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::SampleCountFlag::C1: return "SampleCountFlag::C1"; - case stormkit::gpu::SampleCountFlag::C16: return "SampleCountFlag::C16"; - case stormkit::gpu::SampleCountFlag::C2: return "SampleCountFlag::C2"; - case stormkit::gpu::SampleCountFlag::C32: return "SampleCountFlag::C32"; - case stormkit::gpu::SampleCountFlag::C4: return "SampleCountFlag::C4"; - case stormkit::gpu::SampleCountFlag::C64: return "SampleCountFlag::C64"; - case stormkit::gpu::SampleCountFlag::C8: return "SampleCountFlag::C8"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::SampleCountFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::SampleCountFlag::C1: return "SampleCountFlag::C1"; + case stormkit::gpu::SampleCountFlag::C16: return "SampleCountFlag::C16"; + case stormkit::gpu::SampleCountFlag::C2: return "SampleCountFlag::C2"; + case stormkit::gpu::SampleCountFlag::C32: return "SampleCountFlag::C32"; + case stormkit::gpu::SampleCountFlag::C4: return "SampleCountFlag::C4"; + case stormkit::gpu::SampleCountFlag::C64: return "SampleCountFlag::C64"; + case stormkit::gpu::SampleCountFlag::C8: return "SampleCountFlag::C8"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::SamplerAddressMode) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER, - stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE, - stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE, - stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT, - stormkit::gpu::SamplerAddressMode::REPEAT, - + stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER, + stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE, + stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE, + stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT, + stormkit::gpu::SamplerAddressMode::REPEAT, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::SamplerAddressMode value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; - case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; - case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::SamplerAddressMode value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; + case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; + case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerAddressMode value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; - case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; - case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerAddressMode value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; + case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; + case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::SamplerMipmapMode) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::SamplerMipmapMode::LINEAR, - stormkit::gpu::SamplerMipmapMode::NEAREST, - + stormkit::gpu::SamplerMipmapMode::LINEAR, + stormkit::gpu::SamplerMipmapMode::NEAREST, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::SamplerMipmapMode value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::SamplerMipmapMode::LINEAR: return "SamplerMipmapMode::LINEAR"; - case stormkit::gpu::SamplerMipmapMode::NEAREST: return "SamplerMipmapMode::NEAREST"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::SamplerMipmapMode value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::SamplerMipmapMode::LINEAR: return "SamplerMipmapMode::LINEAR"; + case stormkit::gpu::SamplerMipmapMode::NEAREST: return "SamplerMipmapMode::NEAREST"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerMipmapMode value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::SamplerMipmapMode::LINEAR: return "SamplerMipmapMode::LINEAR"; - case stormkit::gpu::SamplerMipmapMode::NEAREST: return "SamplerMipmapMode::NEAREST"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerMipmapMode value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::SamplerMipmapMode::LINEAR: return "SamplerMipmapMode::LINEAR"; + case stormkit::gpu::SamplerMipmapMode::NEAREST: return "SamplerMipmapMode::NEAREST"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ShaderStageFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ShaderStageFlag::COMPUTE, - stormkit::gpu::ShaderStageFlag::FRAGMENT, - stormkit::gpu::ShaderStageFlag::GEOMETRY, - stormkit::gpu::ShaderStageFlag::NONE, - stormkit::gpu::ShaderStageFlag::VERTEX, - + stormkit::gpu::ShaderStageFlag::COMPUTE, stormkit::gpu::ShaderStageFlag::FRAGMENT, + stormkit::gpu::ShaderStageFlag::GEOMETRY, stormkit::gpu::ShaderStageFlag::NONE, + stormkit::gpu::ShaderStageFlag::VERTEX, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ShaderStageFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ShaderStageFlag::COMPUTE: return "ShaderStageFlag::COMPUTE"; - case stormkit::gpu::ShaderStageFlag::FRAGMENT: return "ShaderStageFlag::FRAGMENT"; - case stormkit::gpu::ShaderStageFlag::GEOMETRY: return "ShaderStageFlag::GEOMETRY"; - case stormkit::gpu::ShaderStageFlag::NONE: return "ShaderStageFlag::NONE"; - case stormkit::gpu::ShaderStageFlag::VERTEX: return "ShaderStageFlag::VERTEX"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::ShaderStageFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ShaderStageFlag::COMPUTE: return "ShaderStageFlag::COMPUTE"; + case stormkit::gpu::ShaderStageFlag::FRAGMENT: return "ShaderStageFlag::FRAGMENT"; + case stormkit::gpu::ShaderStageFlag::GEOMETRY: return "ShaderStageFlag::GEOMETRY"; + case stormkit::gpu::ShaderStageFlag::NONE: return "ShaderStageFlag::NONE"; + case stormkit::gpu::ShaderStageFlag::VERTEX: return "ShaderStageFlag::VERTEX"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::ShaderStageFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ShaderStageFlag::COMPUTE: return "ShaderStageFlag::COMPUTE"; - case stormkit::gpu::ShaderStageFlag::FRAGMENT: return "ShaderStageFlag::FRAGMENT"; - case stormkit::gpu::ShaderStageFlag::GEOMETRY: return "ShaderStageFlag::GEOMETRY"; - case stormkit::gpu::ShaderStageFlag::NONE: return "ShaderStageFlag::NONE"; - case stormkit::gpu::ShaderStageFlag::VERTEX: return "ShaderStageFlag::VERTEX"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::ShaderStageFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::ShaderStageFlag::COMPUTE: return "ShaderStageFlag::COMPUTE"; + case stormkit::gpu::ShaderStageFlag::FRAGMENT: return "ShaderStageFlag::FRAGMENT"; + case stormkit::gpu::ShaderStageFlag::GEOMETRY: return "ShaderStageFlag::GEOMETRY"; + case stormkit::gpu::ShaderStageFlag::NONE: return "ShaderStageFlag::NONE"; + case stormkit::gpu::ShaderStageFlag::VERTEX: return "ShaderStageFlag::VERTEX"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::StencilFaceFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::StencilFaceFlag::BACK, - stormkit::gpu::StencilFaceFlag::FRONT, - stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK, - + stormkit::gpu::StencilFaceFlag::BACK, + stormkit::gpu::StencilFaceFlag::FRONT, + stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::StencilFaceFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::StencilFaceFlag::BACK: return "StencilFaceFlag::BACK"; - case stormkit::gpu::StencilFaceFlag::FRONT: return "StencilFaceFlag::FRONT"; - case stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK: return "StencilFaceFlag::FRONT_AND_BACK"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::StencilFaceFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::StencilFaceFlag::BACK: return "StencilFaceFlag::BACK"; + case stormkit::gpu::StencilFaceFlag::FRONT: return "StencilFaceFlag::FRONT"; + case stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK: return "StencilFaceFlag::FRONT_AND_BACK"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::StencilFaceFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::StencilFaceFlag::BACK: return "StencilFaceFlag::BACK"; - case stormkit::gpu::StencilFaceFlag::FRONT: return "StencilFaceFlag::FRONT"; - case stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK: return "StencilFaceFlag::FRONT_AND_BACK"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::StencilFaceFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::StencilFaceFlag::BACK: return "StencilFaceFlag::BACK"; + case stormkit::gpu::StencilFaceFlag::FRONT: return "StencilFaceFlag::FRONT"; + case stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK: return "StencilFaceFlag::FRONT_AND_BACK"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::VertexInputRate) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::VertexInputRate::INSTANCE, - stormkit::gpu::VertexInputRate::VERTEX, - + stormkit::gpu::VertexInputRate::INSTANCE, + stormkit::gpu::VertexInputRate::VERTEX, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::VertexInputRate value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::VertexInputRate::INSTANCE: return "VertexInputRate::INSTANCE"; - case stormkit::gpu::VertexInputRate::VERTEX: return "VertexInputRate::VERTEX"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::VertexInputRate value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::VertexInputRate::INSTANCE: return "VertexInputRate::INSTANCE"; + case stormkit::gpu::VertexInputRate::VERTEX: return "VertexInputRate::VERTEX"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::to_string(stormkit::gpu::VertexInputRate value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::VertexInputRate::INSTANCE: return "VertexInputRate::INSTANCE"; - case stormkit::gpu::VertexInputRate::VERTEX: return "VertexInputRate::VERTEX"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::VertexInputRate value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::VertexInputRate::INSTANCE: return "VertexInputRate::INSTANCE"; + case stormkit::gpu::VertexInputRate::VERTEX: return "VertexInputRate::VERTEX"; } std::unreachable(); } - - // enum class Format : u8 { - // BYTE, - // BYTE2, - // BYTE3, - // BYTE4, - // BYTE_NORM, - // BYTE2_NORM, - // BYTE3_NORM, - // BYTE4_NORM, + // enum class Format : u8 { + // BYTE, + // BYTE2, + // BYTE3, + // BYTE4, + + // BYTE_NORM, + // BYTE2_NORM, + // BYTE3_NORM, + // BYTE4_NORM, - // BYTE_SCALED, - // BYTE2_SCALED, - // BYTE3_SCALED, - // BYTE4_SCALED, + // BYTE_SCALED, + // BYTE2_SCALED, + // BYTE3_SCALED, + // BYTE4_SCALED, - // UBYTE, - // UBYTE2, - // UBYTE3, - // UBYTE4, + // UBYTE, + // UBYTE2, + // UBYTE3, + // UBYTE4, - // UBYTE_NORM, - // UBYTE2_NORM, - // UBYTE3_NORM, - // UBYTE4_NORM, + // UBYTE_NORM, + // UBYTE2_NORM, + // UBYTE3_NORM, + // UBYTE4_NORM, - // UBYTE_UCALED, - // UBYTE2_UCALED, - // UBYTE3_UCALED, - // UBYTE4_UCALED, + // UBYTE_UCALED, + // UBYTE2_UCALED, + // UBYTE3_UCALED, + // UBYTE4_UCALED, - // SHORT, - // SHORT2, - // SHORT3, - // SHORT4, + // SHORT, + // SHORT2, + // SHORT3, + // SHORT4, - // SHORT_NORM, - // SHORT2_NORM, - // SHORT3_NORM, - // SHORT4_NORM, + // SHORT_NORM, + // SHORT2_NORM, + // SHORT3_NORM, + // SHORT4_NORM, - // SHORT_SCALED, - // SHORT2_SCALED, - // SHORT3_SCALED, - // SHORT4_SCALED, + // SHORT_SCALED, + // SHORT2_SCALED, + // SHORT3_SCALED, + // SHORT4_SCALED, - // USHORT, - // USHORT2, - // USHORT3, - // USHORT4, + // USHORT, + // USHORT2, + // USHORT3, + // USHORT4, - // USHORT_NORM, - // USHORT2_NORM, - // USHORT3_NORM, - // USHORT4_NORM, + // USHORT_NORM, + // USHORT2_NORM, + // USHORT3_NORM, + // USHORT4_NORM, - // USHORT_UCALED, - // USHORT2_UCALED, - // USHORT3_UCALED, - // USHORT4_UCALED, + // USHORT_UCALED, + // USHORT2_UCALED, + // USHORT3_UCALED, + // USHORT4_UCALED, - // INT, - // INT2, - // INT3, - // INT4, + // INT, + // INT2, + // INT3, + // INT4, - // UINT, - // UINT2, - // UINT3, - // UINT4, + // UINT, + // UINT2, + // UINT3, + // UINT4, - // LONG, - // LONG2, - // LONG3, - // LONG4, + // LONG, + // LONG2, + // LONG3, + // LONG4, - // ULONG, - // ULONG2, - // ULONG3, - // ULONG4, - - // FLOAT, - // FLOAT2, - // FLOAT3, - // FLOAT4, + // ULONG, + // ULONG2, + // ULONG3, + // ULONG4, - // DOUBLE, - // DOUBLE2, - // DOUBLE3, - // DOUBLE4, - - // UNDEFINED, - // }; + // FLOAT, + // FLOAT2, + // FLOAT3, + // FLOAT4, + + // DOUBLE, + // DOUBLE2, + // DOUBLE3, + // DOUBLE4, + + // UNDEFINED, + // }; } //////////////////////////////////////////////////////////////////// @@ -3649,7 +3716,7 @@ namespace stormkit::gpu { requires(core::meta::IsPlainEnumeration or core::meta::Is) STORMKIT_FORCE_INLINE STORMKIT_INTRINSIC - constexpr auto to_vk(U value) noexcept -> T{ + constexpr auto to_vk(U value) noexcept -> T { return narrow(value); } @@ -3662,237 +3729,258 @@ namespace stormkit::gpu { constexpr auto from_vk(U value) noexcept -> T { return narrow(value); } -} - - - template stormkit::gpu::AccessFlag stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::AccessFlag stormkit::gpu::from_vk(VkAccessFlagBits); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); - template VkAccessFlagBits stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); - - template stormkit::gpu::AttachmentLoadOperation stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::AttachmentLoadOperation stormkit::gpu::from_vk(VkAttachmentLoadOp); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); - template VkAttachmentLoadOp stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); - - template stormkit::gpu::AttachmentStoreOperation stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::AttachmentStoreOperation stormkit::gpu::from_vk(VkAttachmentStoreOp); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); - template VkAttachmentStoreOp stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); - - template stormkit::gpu::BlendFactor stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::BlendFactor stormkit::gpu::from_vk(VkBlendFactor); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); - template VkBlendFactor stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); - - template stormkit::gpu::BlendOperation stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::BlendOperation stormkit::gpu::from_vk(VkBlendOp); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); - template VkBlendOp stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); - - template stormkit::gpu::BorderColor stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::BorderColor stormkit::gpu::from_vk(VkBorderColor); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BorderColor); - template VkBorderColor stormkit::gpu::to_vk(stormkit::gpu::BorderColor); - - template stormkit::gpu::BufferUsageFlag stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::BufferUsageFlag stormkit::gpu::from_vk(VkBufferUsageFlagBits); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); - template VkBufferUsageFlagBits stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); - - template stormkit::gpu::ColorComponentFlag stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::ColorComponentFlag stormkit::gpu::from_vk(VkColorComponentFlagBits); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); - template VkColorComponentFlagBits stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); - - template stormkit::gpu::ColorSpace stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::ColorSpace stormkit::gpu::from_vk(VkColorSpaceKHR); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); - template VkColorSpaceKHR stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); - - template stormkit::gpu::CommandBufferLevel stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::CommandBufferLevel stormkit::gpu::from_vk(VkCommandBufferLevel); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); - template VkCommandBufferLevel stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); - - template stormkit::gpu::CompareOperation stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::CompareOperation stormkit::gpu::from_vk(VkCompareOp); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); - template VkCompareOp stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); - - template stormkit::gpu::CullModeFlag stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::CullModeFlag stormkit::gpu::from_vk(VkCullModeFlagBits); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); - template VkCullModeFlagBits stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); - - template stormkit::gpu::DebugObjectType stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::DebugObjectType stormkit::gpu::from_vk(VkObjectType); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); - template VkObjectType stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); - - template stormkit::gpu::DependencyFlag stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::DependencyFlag stormkit::gpu::from_vk(VkDependencyFlagBits); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); - template VkDependencyFlagBits stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); - - template stormkit::gpu::DescriptorType stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::DescriptorType stormkit::gpu::from_vk(VkDescriptorType); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); - template VkDescriptorType stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); - - template stormkit::gpu::DynamicState stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::DynamicState stormkit::gpu::from_vk(VkDynamicState); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DynamicState); - template VkDynamicState stormkit::gpu::to_vk(stormkit::gpu::DynamicState); - - template stormkit::gpu::Filter stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::Filter stormkit::gpu::from_vk(VkFilter); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::Filter); - template VkFilter stormkit::gpu::to_vk(stormkit::gpu::Filter); - - template stormkit::gpu::FormatFeatureFlag stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::FormatFeatureFlag stormkit::gpu::from_vk(VkFormatFeatureFlagBits); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); - template VkFormatFeatureFlagBits stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); - - template stormkit::gpu::FrontFace stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::FrontFace stormkit::gpu::from_vk(VkFrontFace); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::FrontFace); - template VkFrontFace stormkit::gpu::to_vk(stormkit::gpu::FrontFace); - - template stormkit::gpu::GeometryFlag stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::GeometryFlag stormkit::gpu::from_vk(VkGeometryFlagBitsKHR); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); - template VkGeometryFlagBitsKHR stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); - - template stormkit::gpu::GeometryType stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::GeometryType stormkit::gpu::from_vk(VkGeometryTypeKHR); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::GeometryType); - template VkGeometryTypeKHR stormkit::gpu::to_vk(stormkit::gpu::GeometryType); - - template stormkit::gpu::ImageAspectFlag stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::ImageAspectFlag stormkit::gpu::from_vk(VkImageAspectFlagBits); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); - template VkImageAspectFlagBits stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); - - template stormkit::gpu::ImageCreateFlag stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::ImageCreateFlag stormkit::gpu::from_vk(VkImageCreateFlagBits); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); - template VkImageCreateFlagBits stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); - - template stormkit::gpu::ImageLayout stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::ImageLayout stormkit::gpu::from_vk(VkImageLayout); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); - template VkImageLayout stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); - - template stormkit::gpu::ImageTiling stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::ImageTiling stormkit::gpu::from_vk(VkImageTiling); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); - template VkImageTiling stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); - - template stormkit::gpu::ImageType stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::ImageType stormkit::gpu::from_vk(VkImageType); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageType); - template VkImageType stormkit::gpu::to_vk(stormkit::gpu::ImageType); - - template stormkit::gpu::ImageUsageFlag stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::ImageUsageFlag stormkit::gpu::from_vk(VkImageUsageFlagBits); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); - template VkImageUsageFlagBits stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); - - template stormkit::gpu::ImageViewType stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::ImageViewType stormkit::gpu::from_vk(VkImageViewType); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); - template VkImageViewType stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); - - template stormkit::gpu::LogicOperation stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::LogicOperation stormkit::gpu::from_vk(VkLogicOp); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); - template VkLogicOp stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); - - template stormkit::gpu::MemoryPropertyFlag stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::MemoryPropertyFlag stormkit::gpu::from_vk(VkMemoryPropertyFlagBits); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); - template VkMemoryPropertyFlagBits stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); - - template stormkit::gpu::PhysicalDeviceType stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::PhysicalDeviceType stormkit::gpu::from_vk(VkPhysicalDeviceType); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); - template VkPhysicalDeviceType stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); - - template stormkit::gpu::PipelineBindPoint stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::PipelineBindPoint stormkit::gpu::from_vk(VkPipelineBindPoint); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); - template VkPipelineBindPoint stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); - - template stormkit::gpu::PipelineStageFlag stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::PipelineStageFlag stormkit::gpu::from_vk(VkPipelineStageFlagBits); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); - template VkPipelineStageFlagBits stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); - - template stormkit::gpu::PixelFormat stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::PixelFormat stormkit::gpu::from_vk(VkFormat); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); - template VkFormat stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); - - template stormkit::gpu::PolygonMode stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::PolygonMode stormkit::gpu::from_vk(VkPolygonMode); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); - template VkPolygonMode stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); - - template stormkit::gpu::PresentMode stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::PresentMode stormkit::gpu::from_vk(VkPresentModeKHR); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PresentMode); - template VkPresentModeKHR stormkit::gpu::to_vk(stormkit::gpu::PresentMode); - - template stormkit::gpu::PrimitiveTopology stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::PrimitiveTopology stormkit::gpu::from_vk(VkPrimitiveTopology); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); - template VkPrimitiveTopology stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); - - template stormkit::gpu::QueueFlag stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::QueueFlag stormkit::gpu::from_vk(VkQueueFlagBits); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); - template VkQueueFlagBits stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); - - template stormkit::gpu::ResolveModeFlag stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::ResolveModeFlag stormkit::gpu::from_vk(VkResolveModeFlagBits); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ResolveModeFlag); - template VkResolveModeFlagBits stormkit::gpu::to_vk(stormkit::gpu::ResolveModeFlag); - - template stormkit::gpu::Result stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::Result stormkit::gpu::from_vk(VkResult); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::Result); - template VkResult stormkit::gpu::to_vk(stormkit::gpu::Result); - - template stormkit::gpu::SampleCountFlag stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::SampleCountFlag stormkit::gpu::from_vk(VkSampleCountFlagBits); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); - template VkSampleCountFlagBits stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); - - template stormkit::gpu::SamplerAddressMode stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::SamplerAddressMode stormkit::gpu::from_vk(VkSamplerAddressMode); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); - template VkSamplerAddressMode stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); - - template stormkit::gpu::SamplerMipmapMode stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::SamplerMipmapMode stormkit::gpu::from_vk(VkSamplerMipmapMode); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); - template VkSamplerMipmapMode stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); - - template stormkit::gpu::ShaderStageFlag stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::ShaderStageFlag stormkit::gpu::from_vk(VkShaderStageFlagBits); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); - template VkShaderStageFlagBits stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); - - template stormkit::gpu::StencilFaceFlag stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::StencilFaceFlag stormkit::gpu::from_vk(VkStencilFaceFlagBits); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); - template VkStencilFaceFlagBits stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); - - template stormkit::gpu::VertexInputRate stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::VertexInputRate stormkit::gpu::from_vk(VkVertexInputRate); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); - template VkVertexInputRate stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); - - +} // namespace stormkit::gpu + +template stormkit::gpu::AccessFlag stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::AccessFlag stormkit::gpu::from_vk(VkAccessFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); +template VkAccessFlagBits stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); + +template stormkit::gpu::AttachmentLoadOperation stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::AttachmentLoadOperation stormkit::gpu::from_vk(VkAttachmentLoadOp); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); +template VkAttachmentLoadOp stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); + +template stormkit::gpu::AttachmentStoreOperation stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::AttachmentStoreOperation stormkit::gpu::from_vk(VkAttachmentStoreOp); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); +template VkAttachmentStoreOp stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); + +template stormkit::gpu::BlendFactor stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::BlendFactor stormkit::gpu::from_vk(VkBlendFactor); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); +template VkBlendFactor stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); + +template stormkit::gpu::BlendOperation stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::BlendOperation stormkit::gpu::from_vk(VkBlendOp); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); +template VkBlendOp stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); + +template stormkit::gpu::BorderColor stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::BorderColor stormkit::gpu::from_vk(VkBorderColor); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BorderColor); +template VkBorderColor stormkit::gpu::to_vk(stormkit::gpu::BorderColor); + +template stormkit::gpu::BufferUsageFlag stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::BufferUsageFlag stormkit::gpu::from_vk(VkBufferUsageFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); +template VkBufferUsageFlagBits stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); + +template stormkit::gpu::ColorComponentFlag stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ColorComponentFlag stormkit::gpu::from_vk(VkColorComponentFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); +template VkColorComponentFlagBits stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); + +template stormkit::gpu::ColorSpace stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ColorSpace stormkit::gpu::from_vk(VkColorSpaceKHR); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); +template VkColorSpaceKHR stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); + +template stormkit::gpu::CommandBufferLevel stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::CommandBufferLevel stormkit::gpu::from_vk(VkCommandBufferLevel); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); +template VkCommandBufferLevel stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); + +template stormkit::gpu::CompareOperation stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::CompareOperation stormkit::gpu::from_vk(VkCompareOp); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); +template VkCompareOp stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); + +template stormkit::gpu::CullModeFlag stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::CullModeFlag stormkit::gpu::from_vk(VkCullModeFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); +template VkCullModeFlagBits stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); + +template stormkit::gpu::DebugObjectType stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::DebugObjectType stormkit::gpu::from_vk(VkObjectType); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); +template VkObjectType stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); + +template stormkit::gpu::DependencyFlag stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::DependencyFlag stormkit::gpu::from_vk(VkDependencyFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); +template VkDependencyFlagBits stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); + +template stormkit::gpu::DescriptorType stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::DescriptorType stormkit::gpu::from_vk(VkDescriptorType); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); +template VkDescriptorType stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); + +template stormkit::gpu::DynamicState stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::DynamicState stormkit::gpu::from_vk(VkDynamicState); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DynamicState); +template VkDynamicState stormkit::gpu::to_vk(stormkit::gpu::DynamicState); + +template stormkit::gpu::Filter stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::Filter stormkit::gpu::from_vk(VkFilter); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::Filter); +template VkFilter stormkit::gpu::to_vk(stormkit::gpu::Filter); + +template stormkit::gpu::FormatFeatureFlag stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::FormatFeatureFlag stormkit::gpu::from_vk(VkFormatFeatureFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); +template VkFormatFeatureFlagBits stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); + +template stormkit::gpu::FrontFace stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::FrontFace stormkit::gpu::from_vk(VkFrontFace); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::FrontFace); +template VkFrontFace stormkit::gpu::to_vk(stormkit::gpu::FrontFace); + +template stormkit::gpu::GeometryFlag stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::GeometryFlag stormkit::gpu::from_vk(VkGeometryFlagBitsKHR); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); +template VkGeometryFlagBitsKHR stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); + +template stormkit::gpu::GeometryType stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::GeometryType stormkit::gpu::from_vk(VkGeometryTypeKHR); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::GeometryType); +template VkGeometryTypeKHR stormkit::gpu::to_vk(stormkit::gpu::GeometryType); + +template stormkit::gpu::ImageAspectFlag stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageAspectFlag stormkit::gpu::from_vk(VkImageAspectFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); +template VkImageAspectFlagBits stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); + +template stormkit::gpu::ImageCreateFlag stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageCreateFlag stormkit::gpu::from_vk(VkImageCreateFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); +template VkImageCreateFlagBits stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); + +template stormkit::gpu::ImageLayout stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageLayout stormkit::gpu::from_vk(VkImageLayout); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); +template VkImageLayout stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); + +template stormkit::gpu::ImageTiling stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageTiling stormkit::gpu::from_vk(VkImageTiling); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); +template VkImageTiling stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); + +template stormkit::gpu::ImageType stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageType stormkit::gpu::from_vk(VkImageType); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageType); +template VkImageType stormkit::gpu::to_vk(stormkit::gpu::ImageType); + +template stormkit::gpu::ImageUsageFlag stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageUsageFlag stormkit::gpu::from_vk(VkImageUsageFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); +template VkImageUsageFlagBits stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); + +template stormkit::gpu::ImageViewType stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageViewType stormkit::gpu::from_vk(VkImageViewType); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); +template VkImageViewType stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); + +template stormkit::gpu::LogicOperation stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::LogicOperation stormkit::gpu::from_vk(VkLogicOp); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); +template VkLogicOp stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); + +template stormkit::gpu::MemoryPropertyFlag stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::MemoryPropertyFlag stormkit::gpu::from_vk(VkMemoryPropertyFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); +template VkMemoryPropertyFlagBits stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); + +template stormkit::gpu::PhysicalDeviceType stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PhysicalDeviceType stormkit::gpu::from_vk(VkPhysicalDeviceType); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); +template VkPhysicalDeviceType stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); + +template stormkit::gpu::PipelineBindPoint stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PipelineBindPoint stormkit::gpu::from_vk(VkPipelineBindPoint); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); +template VkPipelineBindPoint stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); + +template stormkit::gpu::PipelineStageFlag stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PipelineStageFlag stormkit::gpu::from_vk(VkPipelineStageFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); +template VkPipelineStageFlagBits stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); + +template stormkit::gpu::PixelFormat stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PixelFormat stormkit::gpu::from_vk(VkFormat); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); +template VkFormat stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); + +template stormkit::gpu::PolygonMode stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PolygonMode stormkit::gpu::from_vk(VkPolygonMode); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); +template VkPolygonMode stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); + +template stormkit::gpu::PresentMode stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PresentMode stormkit::gpu::from_vk(VkPresentModeKHR); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PresentMode); +template VkPresentModeKHR stormkit::gpu::to_vk(stormkit::gpu::PresentMode); + +template stormkit::gpu::PrimitiveTopology stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PrimitiveTopology stormkit::gpu::from_vk(VkPrimitiveTopology); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); +template VkPrimitiveTopology stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); + +template stormkit::gpu::QueueFlag stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::QueueFlag stormkit::gpu::from_vk(VkQueueFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); +template VkQueueFlagBits stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); + +template stormkit::gpu::ResolveModeFlag stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ResolveModeFlag stormkit::gpu::from_vk(VkResolveModeFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ResolveModeFlag); +template VkResolveModeFlagBits stormkit::gpu::to_vk(stormkit::gpu::ResolveModeFlag); + +template stormkit::gpu::Result stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::Result stormkit::gpu::from_vk(VkResult); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::Result); +template VkResult stormkit::gpu::to_vk(stormkit::gpu::Result); + +template stormkit::gpu::SampleCountFlag stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::SampleCountFlag stormkit::gpu::from_vk(VkSampleCountFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); +template VkSampleCountFlagBits stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); + +template stormkit::gpu::SamplerAddressMode stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::SamplerAddressMode stormkit::gpu::from_vk(VkSamplerAddressMode); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); +template VkSamplerAddressMode stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); + +template stormkit::gpu::SamplerMipmapMode stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::SamplerMipmapMode stormkit::gpu::from_vk(VkSamplerMipmapMode); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); +template VkSamplerMipmapMode stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); + +template stormkit::gpu::ShaderStageFlag stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ShaderStageFlag stormkit::gpu::from_vk(VkShaderStageFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); +template VkShaderStageFlagBits stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); + +template stormkit::gpu::StencilFaceFlag stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::StencilFaceFlag stormkit::gpu::from_vk(VkStencilFaceFlagBits); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); +template VkStencilFaceFlagBits stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); + +template stormkit::gpu::VertexInputRate stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::VertexInputRate stormkit::gpu::from_vk(VkVertexInputRate); +template VkFlags stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); +template VkVertexInputRate stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); From df2495b9c4497a97c158fce5931e68ab22e8a043 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 00:38:07 +0100 Subject: [PATCH 036/194] (wsi) fix window size on windows --- src/wsi/win32/window.cpp | 145 ++++++++++++++++----------------------- 1 file changed, 59 insertions(+), 86 deletions(-) diff --git a/src/wsi/win32/window.cpp b/src/wsi/win32/window.cpp index 100c2f443..ed17052eb 100644 --- a/src/wsi/win32/window.cpp +++ b/src/wsi/win32/window.cpp @@ -28,6 +28,8 @@ import :win32.mouse; namespace stdv = std::views; namespace stdr = std::ranges; +using namespace stormkit; + template constexpr auto format_as(const POINT& point, FormatContext& ctx) -> decltype(ctx.out()) { return std::format_to(ctx.out(), "{{ .x = {}, .y = {} }}", point.x, point.y); @@ -43,6 +45,14 @@ constexpr auto format_as(const RECT& rect, FormatContext& ctx) -> decltype(ctx.o rect.bottom); } +auto adjust_extent(const math::Extent2& extent, DWORD style, DWORD style_ex) noexcept -> math::Extent2 { + auto rect = RECT { .left = 0, .top = 0, .right = as(extent.width), .bottom = as(extent.height) }; + + AdjustWindowRectEx(&rect, style, FALSE, style_ex); + + return { rect.right - rect.left, rect.bottom - rect.top }; +} + namespace stormkit::wsi::win32 { using HBrush = RAIICapsule; @@ -53,9 +63,7 @@ namespace stormkit::wsi::win32 { // auto get_monitor_scale(HMONITOR monitor) -> math::vec2f; - auto CALLBACK - global_on_event(HWND handle, UINT message, WPARAM w_param, LPARAM l_param) noexcept - -> LRESULT; + auto CALLBACK global_on_event(HWND handle, UINT message, WPARAM w_param, LPARAM l_param) noexcept -> LRESULT; constinit auto g_window_count = std::atomic { 0 }; } // namespace @@ -97,9 +105,7 @@ namespace stormkit::wsi::win32 { ///////////////////////////////////// ///////////////////////////////////// - auto Window::open(std::string title, - const math::Extent2& extent, - WindowFlag flags) noexcept -> void { + auto Window::open(std::string title, const math::Extent2& extent, WindowFlag flags) noexcept -> void { auto style = DWORD { WS_SYSMENU | WS_BORDER }; auto style_ex = DWORD { 0 }; auto h_instance = GetModuleHandleA(nullptr); @@ -119,22 +125,24 @@ namespace stormkit::wsi::win32 { SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE); + const auto adjusted = adjust_extent(extent, style, style_ex); + std::println("{} => {}", extent, adjusted); m_window_handle = CreateWindowExA(style_ex, - CLASS_NAME, - std::data(title), - style, - CW_USEDEFAULT, - CW_USEDEFAULT, - as(extent.width), - as(extent.height), - nullptr, - nullptr, - h_instance, - this); + CLASS_NAME, + std::data(title), + style, + CW_USEDEFAULT, + CW_USEDEFAULT, + adjusted.width, + adjusted.height, + nullptr, + nullptr, + h_instance, + this); m_state.open = true; auto win32_monitor = MonitorFromWindow(m_window_handle, MONITOR_DEFAULTTONEAREST); const auto monitors = get_monitors(); - const auto& monitor = *stdr::find_if(monitors, [&win32_monitor](auto&& monitor) noexcept { + const auto& monitor = *stdr::find_if(monitors, [&win32_monitor](auto&& monitor) noexcept { return monitor.native_handle == win32_monitor; }); @@ -171,10 +179,7 @@ namespace stormkit::wsi::win32 { if (m_win32_state.external_context) return; auto hbrush = HBrush::create(RGB(color.r, color.g, color.b)); - const auto rect = RECT { 0, - 0, - as(m_state.extent.width), - as(m_state.extent.height) }; + const auto rect = RECT { 0, 0, as(m_state.extent.width), as(m_state.extent.height) }; FillRect(m_gdi_frame_data.context, &rect, hbrush); InvalidateRect(m_window_handle, nullptr, FALSE); @@ -188,11 +193,9 @@ namespace stormkit::wsi::win32 { const auto [width, height] = extent(); const auto count = std::min(as(stdr::size(pixels)), height * width); - stdr::copy(pixels - | stdv::take(count) - | stdv::transform([](const auto& col) static noexcept { - return as(col.r) << 16 | as(col.g) << 8 | col.b; - }), + stdr::copy(pixels | stdv::take(count) | stdv::transform([](const auto& col) static noexcept { + return as(col.r) << 16 | as(col.g) << 8 | col.b; + }), std::bit_cast(m_gdi_frame_data.pixels_ptr.load())); InvalidateRect(m_window_handle, nullptr, FALSE); @@ -222,12 +225,13 @@ namespace stormkit::wsi::win32 { ///////////////////////////////////// ///////////////////////////////////// auto Window::set_extent(const math::Extent2& extent) noexcept -> void { + const auto adjusted = adjust_extent(extent, m_win32_state.style, m_win32_state.style_ex); SetWindowPos(m_window_handle, HWND_TOP, 0, 0, - as(extent.width), - as(extent.height), + adjusted.width, + adjusted.height, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOOWNERZORDER); } @@ -240,10 +244,7 @@ namespace stormkit::wsi::win32 { auto style_ex = m_win32_state.style_ex; if (fullscreen) { style &= as(~(WS_CAPTION | WS_THICKFRAME)); - style_ex &= as(~(WS_EX_DLGMODALFRAME - | WS_EX_WINDOWEDGE - | WS_EX_CLIENTEDGE - | WS_EX_STATICEDGE)); + style_ex &= as(~(WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE)); x = 0; y = 0; @@ -456,13 +457,13 @@ namespace stormkit::wsi::win32 { auto ptr = core::ptr { nullptr }; m_gdi_frame_data.context = Hdc::create(hdesktop); - m_gdi_frame_data.bitmap = HBitmap:: - create(m_gdi_frame_data.context, - std::bit_cast(&frame_bitmap_info), - as(DIB_RGB_COLORS), - &ptr, - nullptr, - as(0)); + m_gdi_frame_data + .bitmap = HBitmap::create(m_gdi_frame_data.context, + std::bit_cast(&frame_bitmap_info), + as(DIB_RGB_COLORS), + &ptr, + nullptr, + as(0)); m_gdi_frame_data.pixels_ptr = ptr; m_gdi_frame_data.extent = { width, height }; SelectObject(m_gdi_frame_data.context, m_gdi_frame_data.bitmap); @@ -474,9 +475,7 @@ namespace stormkit::wsi::win32 { ///////////////////////////////////// ///////////////////////////////////// auto get_client_rect(HWND window_handle) noexcept -> RECT { - const auto client_rect = init_by([window_handle](auto& out) noexcept { - GetClientRect(window_handle, &out); - }); + const auto client_rect = init_by([window_handle](auto& out) noexcept { GetClientRect(window_handle, &out); }); const auto lefttop = init_by([window_handle, &client_rect](POINT& out) noexcept { out.x = client_rect.left; @@ -484,8 +483,7 @@ namespace stormkit::wsi::win32 { ClientToScreen(window_handle, &out); }); - const auto rightbottom = init_by([window_handle, - &client_rect](POINT& out) noexcept { + const auto rightbottom = init_by([window_handle, &client_rect](POINT& out) noexcept { out.x = client_rect.right; out.y = client_rect.bottom; ClientToScreen(window_handle, &out); @@ -524,10 +522,8 @@ namespace stormkit::wsi::win32 { ///////////////////////////////////// ///////////////////////////////////// - auto handle_window_events(Window& window, - UINT message, - WPARAM w_param, - LPARAM l_param) noexcept -> std::optional { + auto handle_window_events(Window& window, UINT message, WPARAM w_param, LPARAM l_param) noexcept + -> std::optional { const auto window_handle = std::bit_cast(window.native_handle()); if (message != WM_DESTROY and not window_handle) return 0; @@ -563,12 +559,9 @@ namespace stormkit::wsi::win32 { auto win32_monitor = MonitorFromWindow(window_handle, MONITOR_DEFAULTTONEAREST); if (window.current_monitor().native_handle != win32_monitor) { const auto monitors = get_monitors(); - const auto& _monitor = *stdr::find_if(monitors, - [&win32_monitor](auto&& - monitor) noexcept { - return monitor.native_handle - == win32_monitor; - }); + const auto& _monitor = *stdr::find_if(monitors, [&win32_monitor](auto&& monitor) noexcept { + return monitor.native_handle == win32_monitor; + }); window.set_current_monitor(_monitor); window.monitor_changed_event(std::move(_monitor)); @@ -623,10 +616,7 @@ namespace stormkit::wsi::win32 { ///////////////////////////////////// ///////////////////////////////////// - auto handle_input_events(Window& window, - UINT message, - WPARAM w_param, - LPARAM l_param) noexcept -> void { + auto handle_input_events(Window& window, UINT message, WPARAM w_param, LPARAM l_param) noexcept -> void { const auto window_handle = std::bit_cast(window.native_handle()); if (not window.state().active) return; @@ -635,10 +625,7 @@ namespace stormkit::wsi::win32 { case WM_RBUTTONDOWN: [[fallthrough]]; case WM_MBUTTONDOWN: [[fallthrough]]; case WM_XBUTTONDOWN: { - const auto [x, y] = extract_mouse_position(window_handle, - w_param, - l_param, - false); + const auto [x, y] = extract_mouse_position(window_handle, w_param, l_param, false); const auto button = extract_mouse_button(message, w_param, l_param); window.mouse_button_down_event(GLOBAL_MOUSE_ID, button, math::vec2i { x, y }); } break; @@ -646,10 +633,7 @@ namespace stormkit::wsi::win32 { case WM_RBUTTONUP: [[fallthrough]]; case WM_MBUTTONUP: [[fallthrough]]; case WM_XBUTTONUP: { - const auto [x, y] = extract_mouse_position(window_handle, - w_param, - l_param, - false); + const auto [x, y] = extract_mouse_position(window_handle, w_param, l_param, false); const auto button = extract_mouse_button(message, w_param, l_param); window.mouse_button_up_event(GLOBAL_MOUSE_ID, button, math::vec2i { x, y }); } break; @@ -688,25 +672,19 @@ namespace stormkit::wsi::win32 { track_mouse_event.dwFlags = TME_LEAVE; track_mouse_event.hwndTrack = window_handle; track_mouse_event.dwHoverTime = HOVER_DEFAULT; - if (TrackMouseEvent(&track_mouse_event) != FALSE) - window.win32_state().mouse_tracked = true; + if (TrackMouseEvent(&track_mouse_event) != FALSE) window.win32_state().mouse_tracked = true; } - const auto [x, y] = extract_mouse_position(window_handle, - w_param, - l_param, - false); + const auto [x, y] = extract_mouse_position(window_handle, w_param, l_param, false); if (state.locked and state.relative) { const auto relative_x = x - as(state.locked_at.x); const auto relative_y = y - as(state.locked_at.y); - window.mouse_moved_event(GLOBAL_MOUSE_ID, - math::vec2i { relative_x, relative_y }); + window.mouse_moved_event(GLOBAL_MOUSE_ID, math::vec2i { relative_x, relative_y }); } else if (state.relative) { const auto relative_x = x - as(state.last_position.x); const auto relative_y = y - as(state.last_position.y); - window.mouse_moved_event(GLOBAL_MOUSE_ID, - math::vec2i { relative_x, relative_y }); + window.mouse_moved_event(GLOBAL_MOUSE_ID, math::vec2i { relative_x, relative_y }); } else window.mouse_moved_event(GLOBAL_MOUSE_ID, math::vec2i { x, y }); } break; @@ -716,23 +694,18 @@ namespace stormkit::wsi::win32 { ///////////////////////////////////// ///////////////////////////////////// - auto global_on_event(HWND handle, UINT message, WPARAM w_param, LPARAM l_param) noexcept - -> LRESULT { + auto global_on_event(HWND handle, UINT message, WPARAM w_param, LPARAM l_param) noexcept -> LRESULT { if (message == WM_CREATE) { auto lp_create_params = std::bit_cast(l_param)->lpCreateParams; SetWindowLongPtrA(handle, GWLP_USERDATA, std::bit_cast(lp_create_params)); } - auto window = handle ? std::bit_cast(GetWindowLongPtrA(handle, GWLP_USERDATA)) - : nullptr; + auto window = handle ? std::bit_cast(GetWindowLongPtrA(handle, GWLP_USERDATA)) : nullptr; - if (auto result = handle_global_events(message, w_param, l_param); - result != std::nullopt) - return *result; + if (auto result = handle_global_events(message, w_param, l_param); result != std::nullopt) return *result; if (window) { - if (auto result = handle_window_events(*window, message, w_param, l_param); - result != std::nullopt) + if (auto result = handle_window_events(*window, message, w_param, l_param); result != std::nullopt) return *result; handle_input_events(*window, message, w_param, l_param); From b71c8e7369a4fdfa120a1176c65308dda83bb491 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 00:38:24 +0100 Subject: [PATCH 037/194] (xmake) fix luau on windows --- xmake.lua | 2 +- xmake/dependencies.xmake.lua | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/xmake.lua b/xmake.lua index 78fe5c484..e9448a963 100644 --- a/xmake.lua +++ b/xmake.lua @@ -167,7 +167,7 @@ namespace("stormkit", function() end end - if not get_config("luau") then remove_files(path.join(src_path, name, "lua.mpp")) end + if not get_config("luau") then remove_files(path.join(module_path, "lua.mpp")) end add_includedirs("$(projectdir)/include", { public = true }) diff --git a/xmake/dependencies.xmake.lua b/xmake/dependencies.xmake.lua index a96823188..0f54eba2a 100644 --- a/xmake/dependencies.xmake.lua +++ b/xmake/dependencies.xmake.lua @@ -32,11 +32,13 @@ local package_configs = { }, luau = { global = { + override = true, system = false, version = "master", configs = { + shared = false, extern_c = true, - cxflags = { cxx_runtime }, + build_cli = false, }, }, }, From 8c013f053464641e6333bac244503b5d92b64a6e Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 00:46:30 +0100 Subject: [PATCH 038/194] (core) fix STORMKIT_POP_WARNINGS macro on msvc --- include/stormkit/core/platform_macro.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/stormkit/core/platform_macro.hpp b/include/stormkit/core/platform_macro.hpp index d9068d4cf..19c4b63e6 100644 --- a/include/stormkit/core/platform_macro.hpp +++ b/include/stormkit/core/platform_macro.hpp @@ -34,7 +34,7 @@ #define STORMKIT_INTRINSIC [[msvc::intrinsic]] #define STORMKIT_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]] #define STORMKIT_PUSH_WARNINGS _Pragma("warning(push)") - #define STORMKIT_POP_WARNINGS _Pragma("warning(pop))") + #define STORMKIT_POP_WARNINGS _Pragma("warning(pop)") #define STORMKIT_ARRAY_IF_MSVC std::array #elif defined(_MSC_VER) and defined(__clang__) #if defined(_LIBCPP_VERSION) From 457e82c67cbe06f806a0c021067c12fa76ea446f Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 00:46:37 +0100 Subject: [PATCH 039/194] (gpu) fix some warnings --- examples/gpu/common/app.mpp | 2 +- examples/gpu/imgui/src/main.cpp | 2 +- examples/gpu/textured_cube/src/main.cpp | 4 ++-- examples/gpu/triangle/src/main.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/gpu/common/app.mpp b/examples/gpu/common/app.mpp index ed4a89e2b..7e1aa30c7 100644 --- a/examples/gpu/common/app.mpp +++ b/examples/gpu/common/app.mpp @@ -33,7 +33,7 @@ export namespace base { self.m_window->event_loop([&self] noexcept { self.run_example(); }); - self.m_raster_queue->wait_idle(); + TryAssertDiscard(self.m_raster_queue->wait_idle(), "Failed to wait for raster queue"); self.m_device->wait_idle(); if constexpr (requires { self.deinit(); }) self.deinit(); diff --git a/examples/gpu/imgui/src/main.cpp b/examples/gpu/imgui/src/main.cpp index 734601c1a..a8bf8956a 100644 --- a/examples/gpu/imgui/src/main.cpp +++ b/examples/gpu/imgui/src/main.cpp @@ -216,7 +216,7 @@ class Application: public base::Application { auto& in_flight = submission_resource.in_flight; TryAssert(in_flight.wait(), "Failed to wait in_flight fence"); - in_flight.reset(); + TryAssert(in_flight.reset(), "Failed to reset in_flight fence"); const auto&& [_, image_index] = TryAssert(m_swapchain->acquire_next_image(100ms, wait), "Failed to acquire next swapchain image"); diff --git a/examples/gpu/textured_cube/src/main.cpp b/examples/gpu/textured_cube/src/main.cpp index c4362737f..99a47f2c7 100644 --- a/examples/gpu/textured_cube/src/main.cpp +++ b/examples/gpu/textured_cube/src/main.cpp @@ -438,7 +438,7 @@ class Application: public base::Application { auto& in_flight = submission_resource.in_flight; TryAssert(in_flight.wait(), "Failed to wait in_flight fence"); - in_flight.reset(); + TryAssert(in_flight.reset(), "Failed to reset in_flight fence"); const auto&& [_, image_index] = TryAssert(m_swapchain->acquire_next_image(100ms, wait), "Failed to acquire next swapchain image"); @@ -451,7 +451,7 @@ class Application: public base::Application { viewer_data.model = math::rotate(math::mat4f::identity(), time * math::radians(90.f), math::vec3f { 0.f, 1.f, 0.f }); auto& viewer_buffer = submission_resource.viewer_buffer; - viewer_buffer.upload(viewer_data); + TryAssert(viewer_buffer.upload(viewer_data), "Failed to upload texture to gpu"); const auto rendering_info = gpu::RenderingInfo { .render_area = { .x = 0, .y = 0, .width = window_extent.to().width, .height = window_extent.to().height }, diff --git a/examples/gpu/triangle/src/main.cpp b/examples/gpu/triangle/src/main.cpp index 13f5a7437..1d14504d6 100644 --- a/examples/gpu/triangle/src/main.cpp +++ b/examples/gpu/triangle/src/main.cpp @@ -160,7 +160,7 @@ class Application: public base::Application { auto& in_flight = submission_resource.in_flight; TryAssert(in_flight.wait(), "Failed to wait in_flight fence"); - in_flight.reset(); + TryAssert(in_flight.reset(), "Failed to reset in_flight fence"); const auto&& [_, image_index] = TryAssert(m_swapchain->acquire_next_image(100ms, wait), "Failed to acquire next swapchain image"); From 1011781947fa6df6b15f8780d0cb58f5fc78ecc2 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 17:50:26 +0100 Subject: [PATCH 040/194] (core) finish refactoring color struct --- examples/gpu/imgui/src/main.cpp | 2 +- examples/gpu/textured_cube/src/main.cpp | 2 +- examples/gpu/triangle/src/main.cpp | 2 +- modules/stormkit/core/utils/color.mpp | 415 +++++++----------- modules/stormkit/gpu/core/structs.mpp | 2 +- .../stormkit/gpu/execution/command_buffer.mpp | 14 +- src/gpu/execution/command_buffer.cpp | 16 +- 7 files changed, 186 insertions(+), 267 deletions(-) diff --git a/examples/gpu/imgui/src/main.cpp b/examples/gpu/imgui/src/main.cpp index a8bf8956a..730d88a0a 100644 --- a/examples/gpu/imgui/src/main.cpp +++ b/examples/gpu/imgui/src/main.cpp @@ -231,7 +231,7 @@ class Application: public base::Application { .render_area = { .x = 0, .y = 0, .width = window_extent.width, .height = window_extent.height }, .color_attachments = { { .image_view = as_ref(swapchain_image_resource.view), .layout = gpu::ImageLayout::ATTACHMENT_OPTIMAL, - .clear_value = gpu::ClearColor { .color = RGBColorDef::SILVER } } } + .clear_value = gpu::ClearColor { .color = colors::SILVER } } } }; // render in it diff --git a/examples/gpu/textured_cube/src/main.cpp b/examples/gpu/textured_cube/src/main.cpp index 99a47f2c7..e8bbf99e1 100644 --- a/examples/gpu/textured_cube/src/main.cpp +++ b/examples/gpu/textured_cube/src/main.cpp @@ -457,7 +457,7 @@ class Application: public base::Application { .render_area = { .x = 0, .y = 0, .width = window_extent.to().width, .height = window_extent.to().height }, .color_attachments = { { .image_view = as_ref(swapchain_image_resource.view), .layout = gpu::ImageLayout::ATTACHMENT_OPTIMAL, - .clear_value = gpu::ClearColor { .color = RGBColorDef::SILVER } } }, + .clear_value = gpu::ClearColor { .color = colors::SILVER } } }, .depth_attachment = { { .image_view = as_ref(swapchain_image_resource.depth_view), .layout = gpu::ImageLayout::ATTACHMENT_OPTIMAL, .clear_value = gpu::ClearDepthStencil {} } } diff --git a/examples/gpu/triangle/src/main.cpp b/examples/gpu/triangle/src/main.cpp index 1d14504d6..48fd5f700 100644 --- a/examples/gpu/triangle/src/main.cpp +++ b/examples/gpu/triangle/src/main.cpp @@ -175,7 +175,7 @@ class Application: public base::Application { .render_area = { .x = 0, .y = 0, .width = window_extent.width, .height = window_extent.height }, .color_attachments = { { .image_view = as_ref(swapchain_image_resource.view), .layout = gpu::ImageLayout::ATTACHMENT_OPTIMAL, - .clear_value = gpu::ClearColor { .color = RGBColorDef::SILVER } } } + .clear_value = gpu::ClearColor { .color = colors::SILVER } } } }; // render in it diff --git a/modules/stormkit/core/utils/color.mpp b/modules/stormkit/core/utils/color.mpp index 81602d70b..5fcc0dd4a 100644 --- a/modules/stormkit/core/utils/color.mpp +++ b/modules/stormkit/core/utils/color.mpp @@ -5,7 +5,6 @@ module; #include -#include #include export module stormkit.core:utils.color; @@ -55,6 +54,8 @@ export namespace stormkit { inline namespace core { struct color { static constexpr auto COMPONENTS_COUNT = 1; T r; + + constexpr auto operator==(const color& other) const noexcept -> bool; }; template @@ -62,6 +63,8 @@ export namespace stormkit { inline namespace core { static constexpr auto COMPONENTS_COUNT = 2; T r; T g; + + constexpr auto operator==(const color& other) const noexcept -> bool; }; template @@ -70,6 +73,8 @@ export namespace stormkit { inline namespace core { T r; T g; T b; + + constexpr auto operator==(const color& other) const noexcept -> bool; }; template @@ -79,6 +84,8 @@ export namespace stormkit { inline namespace core { T g; T b; T a; + + constexpr auto operator==(const color& other) const noexcept -> bool; }; template @@ -88,6 +95,8 @@ export namespace stormkit { inline namespace core { T r; T g; T b; + + constexpr auto operator==(const color& other) const noexcept -> bool; }; template @@ -96,6 +105,8 @@ export namespace stormkit { inline namespace core { T b; T g; T r; + + constexpr auto operator==(const color& other) const noexcept -> bool; }; template @@ -105,6 +116,8 @@ export namespace stormkit { inline namespace core { T g; T r; T a; + + constexpr auto operator==(const color& other) const noexcept -> bool; }; template @@ -114,6 +127,8 @@ export namespace stormkit { inline namespace core { T b; T g; T r; + + constexpr auto operator==(const color& other) const noexcept -> bool; }; template @@ -133,54 +148,26 @@ export namespace stormkit { inline namespace core { template using abgrcolor = color; - constexpr auto color_component_as(u8 component) noexcept -> f32; - - constexpr auto color_component_as(f32 component) noexcept -> u8; - - template - constexpr auto max_color_component_value() noexcept -> T; - - template - struct RGBColor { - using ValueType = T; - using value_type = ValueType; - - constexpr RGBColor(ValueType red, - ValueType green, - ValueType blue, - ValueType alpha = max_color_component_value()) noexcept; - - constexpr explicit RGBColor(const math::vec3& vector) noexcept; - - constexpr explicit RGBColor(const math::vec4& vector) noexcept; - - constexpr RGBColor(const RGBColor& other) noexcept; - constexpr auto operator=(const RGBColor& other) noexcept -> RGBColor&; - - constexpr RGBColor(RGBColor&& other) noexcept; - constexpr auto operator=(RGBColor&& other) noexcept -> RGBColor&; - - template - constexpr RGBColor(const RGBColor& other) noexcept; - - template - constexpr auto operator=(const RGBColor& other) noexcept -> RGBColor&; - - constexpr auto to_vec3() const noexcept -> math::vec3; - constexpr auto to_vec4() const noexcept -> math::vec4; - - constexpr operator math::vec3() const noexcept; - constexpr operator math::vec4() const noexcept; - constexpr operator std::array() const noexcept; - - ValueType red; - ValueType green; - ValueType blue; - ValueType alpha; - }; - - using RGBColorU = RGBColor; - using RGBColorF = RGBColor; + using rcolor_f = rcolor; + using rgcolor_f = rgcolor; + using rgbcolor_f = rgbcolor; + using rgbacolor_f = rgbacolor; + using argbcolor_f = argbcolor; + using bgrcolor_f = bgrcolor; + using bgracolor_f = bgracolor; + using abgrcolor_f = abgrcolor; + + using rcolor_u = rcolor; + using rgcolor_u = rgcolor; + using rgbcolor_u = rgbcolor; + using rgbacolor_u = rgbacolor; + using argbcolor_u = argbcolor; + using bgrcolor_u = bgrcolor; + using bgracolor_u = bgracolor; + using abgrcolor_u = abgrcolor; + + template + constexpr auto format_as(const color& color, FormatContext& ctx) noexcept -> decltype(ctx.out()); }} // namespace stormkit::core namespace stormkit { inline namespace core { namespace details { @@ -225,155 +212,103 @@ export namespace stormkit { inline namespace core { }; template - inline constexpr auto WHITE = details::ImplicitConverter { - .c = { .r = ColorComponent::max(), - .g = ColorComponent::max(), - .b = ColorComponent::max(), + inline constexpr auto GRAY = details::ImplicitConverter { + .c = { .r = ColorComponent::max() / T { 2 }, + .g = ColorComponent::max() / T { 2 }, + .b = ColorComponent::max() / T { 2 }, .a = ColorComponent::max() } }; template - inline constexpr auto RED = details::ImplicitConverter { - .c = { .r = ColorComponent::max(), .g = 0, .b = 0, .a = ColorComponent::max() } + inline constexpr auto SILVER = details::ImplicitConverter { + .c = { .r = ColorComponent::max() / T { 2 } + ColorComponent::max() / T { 4 }, + .g = ColorComponent::max() / T { 2 } + ColorComponent::max() / T { 4 }, + .b = ColorComponent::max() / T { 2 } + ColorComponent::max() / T { 4 }, + .a = ColorComponent::max() } }; template - inline constexpr auto GREEN = details::ImplicitConverter { - .c = { .r = 0, .g = ColorComponent::max(), .b = 0, .a = ColorComponent::max() } + inline constexpr auto WHITE = details::ImplicitConverter { + .c = { .r = ColorComponent::max(), + .g = ColorComponent::max(), + .b = ColorComponent::max(), + .a = ColorComponent::max() } }; - template - inline constexpr auto BLUE = details::ImplicitConverter { - .c = { .r = 0, .g = 0, .b = ColorComponent::max(), .a = ColorComponent::max() } + template + inline constexpr auto MAROON = details::ImplicitConverter { + .c = { .r = ColorComponent::max() / T { 2 }, .g = T { 0 }, .b = T { 0 }, .a = ColorComponent::max() } }; template - inline constexpr auto YELLOW = details::ImplicitConverter { - .c = { .r = ColorComponent::max(), .g = ColorComponent::max(), .b = 0, .a = ColorComponent::max() } + inline constexpr auto RED = details::ImplicitConverter { + .c = { .r = ColorComponent::max(), .g = 0, .b = 0, .a = ColorComponent::max() } }; - } // namespace colors - - namespace RGBColorDef { - template - inline constexpr auto BLACK = RGBColor { T { 0 }, T { 0 }, T { 0 }, max_color_component_value() }; template - inline constexpr auto Gray = RGBColor { max_color_component_value() / T { 2 }, - max_color_component_value() / T { 2 }, - max_color_component_value() / T { 2 }, - max_color_component_value() }; - - template - inline constexpr auto SILVER = RGBColor { - (max_color_component_value() / T { 2 }) + (max_color_component_value() / T { 4 }), - (max_color_component_value() / T { 2 }) + (max_color_component_value() / T { 4 }), - (max_color_component_value() / T { 2 }) + (max_color_component_value() / T { 4 }), - max_color_component_value() + inline constexpr auto OLIVE = details::ImplicitConverter { + .c = { .r = ColorComponent::max() / T { 2 }, + .g = ColorComponent::max() / T { 2 }, + .b = T { 0 }, + .a = ColorComponent::max() } }; template - inline constexpr auto WHITE = RGBColor { - max_color_component_value(), - max_color_component_value(), - max_color_component_value(), - max_color_component_value() + inline constexpr auto YELLOW = details::ImplicitConverter { + .c = { .r = ColorComponent::max(), .g = ColorComponent::max(), .b = T { 0 }, .a = ColorComponent::max() } }; - template - inline constexpr auto Maroon = RGBColor { - max_color_component_value() / T { 2 }, - T { 0 }, - T { 0 }, - max_color_component_value() + template + inline constexpr auto GREEN = details::ImplicitConverter { + .c = { .r = 0, .g = ColorComponent::max() / T { 2 }, .b = 0, .a = ColorComponent::max() } }; - template - inline constexpr auto RED = RGBColor { max_color_component_value(), - T { 0 }, - T { 0 }, - max_color_component_value() }; - - template - inline constexpr auto Olive = RGBColor { - max_color_component_value() / T { 2 }, - max_color_component_value() / T { 2 }, - T { 0 }, - max_color_component_value() + template + inline constexpr auto LIME = details::ImplicitConverter { + .c = { .r = 0, .g = ColorComponent::max(), .b = 0, .a = ColorComponent::max() } }; - template - inline constexpr auto YELLOW = RGBColor { - max_color_component_value(), - max_color_component_value(), - T { 0 }, - max_color_component_value() - }; - template - inline constexpr auto GREEN = RGBColor { - T { 0 }, - max_color_component_value() / T { 2 }, - T { 0 }, - max_color_component_value() + template + inline constexpr auto TEAL = details::ImplicitConverter { + .c = { .r = 0, + .g = ColorComponent::max() / T { 2 }, + .b = ColorComponent::max() / T { 2 }, + .a = ColorComponent::max() } }; - template - inline constexpr auto LIME = RGBColor { T { 0 }, - max_color_component_value(), - T { 0 }, - max_color_component_value() }; - - template - inline constexpr auto TEAL = RGBColor { T { 0 }, - max_color_component_value() / T { 2 }, - max_color_component_value() / T { 2 }, - max_color_component_value() }; - - template - inline constexpr auto AQUA = RGBColor { T { 0 }, - max_color_component_value(), - max_color_component_value(), - max_color_component_value() }; - - template - inline constexpr auto NAVY = RGBColor { T { 0 }, - T { 0 }, - max_color_component_value() / T { 2 }, - max_color_component_value() }; + template + inline constexpr auto AQUA = details::ImplicitConverter { + .c = { .r = 0, .g = ColorComponent::max(), .b = ColorComponent::max(), .a = ColorComponent::max() } + }; - template - inline constexpr auto BLUE = RGBColor { T { 0 }, - T { 0 }, - max_color_component_value(), - max_color_component_value() }; + template + inline constexpr auto NAVY = details::ImplicitConverter { + .c = { .r = 0, .g = 0, .b = ColorComponent::max() / T { 2 }, .a = ColorComponent::max() } + }; - template - inline constexpr auto PURPLE = RGBColor { - max_color_component_value() / T { 2 }, - T { 0 }, - max_color_component_value() / T { 2 }, - max_color_component_value() + template + inline constexpr auto BLUE = details::ImplicitConverter { + .c = { .r = 0, .g = 0, .b = ColorComponent::max(), .a = ColorComponent::max() } }; - template - inline constexpr auto Fuchsia = RGBColor { - max_color_component_value(), - T { 0 }, - max_color_component_value(), - max_color_component_value() + template + inline constexpr auto PURPLE = details::ImplicitConverter { + .c = { .r = ColorComponent::max() / T { 2 }, + .g = 0, + .b = ColorComponent::max() / T { 2 }, + .a = ColorComponent::max() } }; - template - inline constexpr auto TRANSPARENT = RGBColor { T { 0 }, T { 0 }, T { 0 }, T { 0 } }; - } // namespace RGBColorDef + template + inline constexpr auto TRANSPARENT = details::ImplicitConverter { + .c = { .r = 0, .g = 0, .b = 0, .a = 0 } + }; + } // namespace colors - template - constexpr auto format_as(const RGBColor&, FormatContext& ctx) noexcept -> decltype(ctx.out()); + template + constexpr auto format_as(const color& color, FormatContext& ctx) noexcept -> decltype(ctx.out()); }} // namespace stormkit::core -export { - TEMPLATED_HASH_EQUAL_FUNC(stormkit::core::RGBColor, stormkit::meta::IsColorComponent, T, value.r, value.g, value.b, value.a) -} - //////////////////////////////////////////////////////////////////// /// IMPLEMENTATION /// //////////////////////////////////////////////////////////////////// @@ -474,122 +409,106 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template - constexpr RGBColor::RGBColor(ValueType _red, ValueType _green, ValueType _blue, ValueType _alpha) noexcept - : red { _red }, green { _green }, blue { _blue }, alpha { _alpha } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - constexpr RGBColor::RGBColor(const math::vec3& vector) noexcept - : red { vector.r }, green { vector.g }, blue { vector.b }, alpha(max_color_component_value()) { - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - constexpr RGBColor::RGBColor(const math::vec4& vector) noexcept - : red { vector.r }, green { vector.g }, blue { vector.b }, alpha { vector.a } { + template + constexpr auto format_as(const color& color, FormatContext& ctx) noexcept -> decltype(ctx.out()) { + if constexpr (LAYOUT == ColorLayout::R) return std::format_to(ctx.out(), "[color layout: R red: {}]", color.r); + else if constexpr (LAYOUT == ColorLayout::RG) + return std::format_to(ctx.out(), "[color layout: RG red: {}, green: {}]", color.r, color.g); + else if constexpr (LAYOUT == ColorLayout::RGB) + return std::format_to(ctx.out(), "[color layout: RGB red: {}, green: {}, blue: {}]", color.r, color.g, color.b); + else if constexpr (LAYOUT == ColorLayout::BGR) + return std::format_to(ctx.out(), "[color layout: BGR blue: {}, green: {}, red: {}]", color.r, color.g); + else if constexpr (LAYOUT == ColorLayout::RGBA) + return std::format_to(ctx.out(), + "[color layout: RGBA red: {}, green: {}, blue: {}, alpha: {}]", + color.r, + color.g, + color.b, + color.a); + else if constexpr (LAYOUT == ColorLayout::ARGB) + return std::format_to(ctx.out(), + "[color layout: ARGB alpha: {}, red: {}, green: {}, blue: {}]", + color.a, + color.r, + color.g, + color.b); + else if constexpr (LAYOUT == ColorLayout::BGRA) + return std::format_to(ctx.out(), + "[color layout: BGRA bue: {}, green: {}, red: {}, alpha: {}]", + color.b, + color.g, + color.r, + color.a); + else if constexpr (LAYOUT == ColorLayout::ABGR) + return std::format_to(ctx.out(), + "[color layout: ABGR alpha: {}, blue: {}, green: {}, red: {}]", + color.a, + color.b, + color.g, + color.r); } ///////////////////////////////////// ///////////////////////////////////// - template - constexpr RGBColor::RGBColor(const RGBColor& other) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - constexpr auto RGBColor::operator=(const RGBColor& other) noexcept -> RGBColor& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - constexpr RGBColor::RGBColor(RGBColor&& other) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - constexpr auto RGBColor::operator=(RGBColor&& other) noexcept -> RGBColor& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - template - constexpr RGBColor::RGBColor(const RGBColor& other) noexcept - : red { color_component_as(other.red) }, - green { color_component_as(other.green) }, - blue { color_component_as(other.blue) }, - alpha { color_component_as(other.alpha) } { + template + STORMKIT_FORCE_INLINE + constexpr auto color::operator==(const color& other) const noexcept -> bool { + return r == other.r; } ///////////////////////////////////// ///////////////////////////////////// - template - template - constexpr auto RGBColor::operator=(const RGBColor& other) noexcept -> RGBColor& { - red = color_component_as(other.red); - green = color_component_as(other.green); - blue = color_component_as(other.blue); - alpha = color_component_as(other.alpha); + template + STORMKIT_FORCE_INLINE + constexpr auto color::operator==(const color& other) const noexcept -> bool { + return r == other.r and g == other.g; } ///////////////////////////////////// ///////////////////////////////////// - template - constexpr auto RGBColor::to_vec3() const noexcept -> math::vec3 { - return { red, green, blue }; + template + STORMKIT_FORCE_INLINE + constexpr auto color::operator==(const color& other) const noexcept -> bool { + return r == other.r and g == other.g and b == other.b; } ///////////////////////////////////// ///////////////////////////////////// - template - constexpr auto RGBColor::to_vec4() const noexcept -> math::vec4 { - return { red, green, blue, alpha }; + template + STORMKIT_FORCE_INLINE + constexpr auto color::operator==(const color& other) const noexcept -> bool { + return r == other.r and g == other.g and b == other.b and a == other.a; } ///////////////////////////////////// ///////////////////////////////////// - template - constexpr RGBColor::operator math::vec3() const noexcept { - return to_vec3(); + template + STORMKIT_FORCE_INLINE + constexpr auto color::operator==(const color& other) const noexcept -> bool { + return r == other.r and g == other.g and b == other.b and a == other.a; } ///////////////////////////////////// ///////////////////////////////////// - template - constexpr RGBColor::operator math::vec4() const noexcept { - return to_vec4(); + template + STORMKIT_FORCE_INLINE + constexpr auto color::operator==(const color& other) const noexcept -> bool { + return r == other.r and g == other.g and b == other.b; } ///////////////////////////////////// ///////////////////////////////////// - template - constexpr RGBColor::operator std::array() const noexcept { - return { red, green, blue, alpha }; + template + STORMKIT_FORCE_INLINE + constexpr auto color::operator==(const color& other) const noexcept -> bool { + return r == other.r and g == other.g and b == other.b and a == other.a; } ///////////////////////////////////// ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto format_as(const RGBColor& color, FormatContext& ctx) noexcept -> decltype(ctx.out()) { - if constexpr (meta::Is) - return std::format_to(ctx.out(), - "{{red: {}, green: {}, blue: {}, alpha: {}}}", - color.red, - color.green, - color.blue, - color.alpha); - else { - const auto color_u8 = RGBColorU { color }; - return std::format_to(ctx.out(), - "{{red: {}, green: {}, blue: {}, alpha: {}}}", - color_u8.red, - color_u8.green, - color_u8.blue, - color_u8.alpha); - } + template + STORMKIT_FORCE_INLINE + constexpr auto color::operator==(const color& other) const noexcept -> bool { + return r == other.r and g == other.g and b == other.b and a == other.a; } }} // namespace stormkit::core diff --git a/modules/stormkit/gpu/core/structs.mpp b/modules/stormkit/gpu/core/structs.mpp index 2495938d5..bf5a734a4 100644 --- a/modules/stormkit/gpu/core/structs.mpp +++ b/modules/stormkit/gpu/core/structs.mpp @@ -237,7 +237,7 @@ export { }; struct ClearColor { - RGBColorF color = stormkit::RGBColorDef::SILVER; + rgbacolor_f color = stormkit::colors::SILVER; }; struct ClearDepthStencil { diff --git a/modules/stormkit/gpu/execution/command_buffer.mpp b/modules/stormkit/gpu/execution/command_buffer.mpp index 793181435..7b49a1b7c 100644 --- a/modules/stormkit/gpu/execution/command_buffer.mpp +++ b/modules/stormkit/gpu/execution/command_buffer.mpp @@ -153,9 +153,9 @@ export namespace stormkit::gpu { -> Expected>; auto end() noexcept -> Expected>; - auto begin_debug_region(std::string_view name, const RGBColorF& color = RGBColorDef::WHITE) noexcept + auto begin_debug_region(std::string_view name, const rgbcolor_f& color = colors::WHITE) noexcept -> CommandBuffer&; - auto insert_debug_label(std::string_view name, const RGBColorF& color = RGBColorDef::WHITE) noexcept + auto insert_debug_label(std::string_view name, const rgbcolor_f& color = colors::WHITE) noexcept -> CommandBuffer&; auto end_debug_region() noexcept -> CommandBuffer&; @@ -163,7 +163,7 @@ export namespace stormkit::gpu { auto begin_render_pass(const RenderPass& render_pass, const FrameBuffer& framebuffer, std::span clear_values = std::array { ClearValue { - ClearColor { .color = RGBColorDef::SILVER } } }, + ClearColor { .color = colors::SILVER } } }, bool secondary_commandbuffers = false) noexcept -> CommandBuffer&; auto next_sub_pass() noexcept -> CommandBuffer&; auto end_render_pass() noexcept -> CommandBuffer&; @@ -531,7 +531,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::begin_debug_region(std::string_view name, const RGBColorF& color) noexcept -> CommandBuffer& { + inline auto CommandBuffer::begin_debug_region(std::string_view name, const rgbcolor_f& color) noexcept -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); if (not vkCmdBeginDebugUtilsLabelEXT) [[unlikely]] @@ -541,7 +541,7 @@ namespace stormkit::gpu { .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, .pNext = nullptr, .pLabelName = stdr::data(name), - .color = { color.red, color.green, color.blue, color.alpha } + .color = { color.r, color.g, color.b, 1.f } }; vk_call(vkCmdBeginDebugUtilsLabelEXT, m_vk_handle, &info); @@ -551,7 +551,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::insert_debug_label(std::string_view name, const RGBColorF& color) noexcept -> CommandBuffer& { + inline auto CommandBuffer::insert_debug_label(std::string_view name, const rgbcolor_f& color) noexcept -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); if (not vkCmdInsertDebugUtilsLabelEXT) [[unlikely]] @@ -561,7 +561,7 @@ namespace stormkit::gpu { .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, .pNext = nullptr, .pLabelName = stdr::data(name), - .color = { color.red, color.green, color.blue, color.alpha } + .color = { color.r, color.g, color.b, 1.f } }; vk_call(vkCmdInsertDebugUtilsLabelEXT, m_vk_handle, &info); diff --git a/src/gpu/execution/command_buffer.cpp b/src/gpu/execution/command_buffer.cpp index 7855c9ffd..ae9c478ea 100644 --- a/src/gpu/execution/command_buffer.cpp +++ b/src/gpu/execution/command_buffer.cpp @@ -141,10 +141,10 @@ namespace stormkit::gpu { .clearValue = std::visit(Overloaded { [](const ClearColor& clear_color) static noexcept -> decltype(auto) { return VkClearValue { - .color = VkClearColorValue { .float32 = { clear_color.color.red, - clear_color.color.blue, - clear_color.color.green, - clear_color.color.alpha } }, + .color = VkClearColorValue { .float32 = { clear_color.color.r, + clear_color.color.b, + clear_color.color.g, + clear_color.color.a } }, }; }, [](const ClearDepthStencil& clear_depth_stencil) static noexcept -> decltype(auto) { @@ -196,10 +196,10 @@ namespace stormkit::gpu { | stdv::transform(core::monadic::either( [](const ClearColor& clear_color) static noexcept -> decltype(auto) { return VkClearValue { - .color = VkClearColorValue { .float32 = { clear_color.color.red, - clear_color.color.blue, - clear_color.color.green, - clear_color.color.alpha } }, + .color = VkClearColorValue { .float32 = { clear_color.color.r, + clear_color.color.b, + clear_color.color.g, + clear_color.color.a } }, }; }, [](const ClearDepthStencil& clear_depth_stencil) static noexcept -> decltype(auto) { From dfe168fee52c155b186fd3c47e42796e45e78edd Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 19:01:56 +0100 Subject: [PATCH 041/194] (core) remove hash_macro header and migrate all std::hash to hasher --- include/stormkit/core/hash_macro.hpp | 85 ---- modules/stormkit/core/hash/base.mpp | 60 ++- modules/stormkit/core/math/linear-matrix.mpp | 140 +++--- modules/stormkit/core/math/linear-vector.mpp | 397 ++++++++---------- modules/stormkit/core/math/linear.mpp | 44 +- modules/stormkit/core/meta/concepts.mpp | 10 + .../stormkit/core/string/constexpr_string.mpp | 8 +- modules/stormkit/core/typesafe/flags.mpp | 4 +- modules/stormkit/core/typesafe/ref.mpp | 42 +- .../stormkit/core/typesafe/strong_type.mpp | 117 +++--- modules/stormkit/core/utils/handle.mpp | 49 ++- modules/stormkit/gpu/core/structs.mpp | 21 +- .../stormkit/gpu/execution/command_buffer.mpp | 1 - .../stormkit/gpu/execution/descriptors.mpp | 70 ++- .../stormkit/gpu/execution/render_pass.mpp | 122 +++--- 15 files changed, 534 insertions(+), 636 deletions(-) delete mode 100644 include/stormkit/core/hash_macro.hpp diff --git a/include/stormkit/core/hash_macro.hpp b/include/stormkit/core/hash_macro.hpp deleted file mode 100644 index 412e70df6..000000000 --- a/include/stormkit/core/hash_macro.hpp +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (C) 2022 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -#ifndef STORMKIT_HASH_MACRO_HPP -#define STORMKIT_HASH_MACRO_HPP - -#include - -/// \brief `HASH_FUNC` declare hash func and define an operator== for a given `x` type -#define HASH_FUNC(x, ...) \ - template<> \ - struct std::hash { \ - [[nodiscard]] \ - auto operator()(const x& value) const noexcept -> stormkit::hash64 { \ - auto hash = stormkit::hash64 { 0 }; \ - stormkit::hash_combine(hash, __VA_ARGS__); \ - return hash; \ - } \ - }; - -#define CONSTRAINED_HASH_FUNC(x, ...) \ - template \ - struct std::hash { \ - [[nodiscard]] \ - auto operator()(const T& value) const noexcept -> stormkit::hash64 { \ - auto hash = stormkit::hash64 { 0 }; \ - stormkit::hash_combine(hash, __VA_ARGS__); \ - return hash; \ - } \ - }; - -#define TEMPLATED_HASH_FUNC(x, z, y, ...) \ - template \ - struct std::hash> { \ - [[nodiscard]] \ - auto operator()(const x& value) const noexcept -> stormkit::hash64 { \ - auto hash = stormkit::hash64 { 0 }; \ - stormkit::hash_combine(hash, __VA_ARGS__); \ - return hash; \ - } \ - }; - -#define EQUAL_FUNC(x) \ - template<> \ - struct std::equal_to { \ - [[nodiscard]] \ - constexpr auto operator()(const x& first, const x& second) const noexcept -> bool { \ - const auto hasher = std::hash {}; \ - return hasher(first) == hasher(second); \ - } \ - }; - -#define CONSTRAINED_EQUAL_FUNC(x) \ - template \ - struct std::equal_to { \ - [[nodiscard]] \ - constexpr auto operator()(const T& first, const T& second) const noexcept -> bool { \ - const auto hasher = std::hash {}; \ - return hasher(first) == hasher(second); \ - } \ - }; - -#define TEMPLATED_EQUAL_FUNC(x, z, y) \ - template \ - struct std::equal_to> { \ - [[nodiscard]] \ - constexpr auto operator()(const x& first, const x& second) const noexcept -> bool { \ - const auto hasher = std::hash> {}; \ - return hasher(first) == hasher(second); \ - } \ - }; - -#define HASH_EQUAL_FUNC(x, ...) \ - HASH_FUNC(x, __VA_ARGS__) \ - EQUAL_FUNC(x) - -#define CONSTRAINED_HASH_EQUAL_FUNC(x, ...) \ - CONSTRAINED_HASH_FUNC(x, __VA_ARGS__) \ - CONSTRAINED_EQUAL_FUNC(x) - -#define TEMPLATED_HASH_EQUAL_FUNC(x, z, y, ...) \ - TEMPLATED_HASH_FUNC(x, z, y, __VA_ARGS__) \ - TEMPLATED_EQUAL_FUNC(x, z, y) -#endif diff --git a/modules/stormkit/core/hash/base.mpp b/modules/stormkit/core/hash/base.mpp index bea9833d4..6d5574366 100644 --- a/modules/stormkit/core/hash/base.mpp +++ b/modules/stormkit/core/hash/base.mpp @@ -18,35 +18,39 @@ export namespace stormkit { inline namespace core { namespace meta { template - concept HashValue = meta::IsOneOf; + concept HashType = meta::IsOneOf; } - template + template constexpr auto hasher(const T& value) noexcept -> Ret = delete; namespace meta { template concept HasHasher = requires(T&& value) { - { hasher(std::forward(value)) } -> meta::HashValue; + { hasher(std::forward(value)) } -> meta::HashType; }; } // namespace meta - template + template + requires(sizeof...(Args) >= 2) + constexpr auto hash(Args&&... values) noexcept -> Ret; + + template constexpr auto hash(T&& value) noexcept -> Ret; - template + template requires(sizeof(T) <= sizeof(Ret)) constexpr auto hasher(T value) noexcept -> Ret; - template + template requires(sizeof(T) <= sizeof(Ret)) constexpr auto hasher(T value) noexcept -> Ret; - template - constexpr auto hash_combine(Ret& hash, T&& range) noexcept -> void; + template + constexpr auto hash_combine(Ret& hash, T&& value) noexcept -> void; - template - requires(sizeof...(Args) > 1) + template + requires(sizeof...(Args) >= 2) constexpr auto hash_combine(Ret& hash, Args&&... args) noexcept -> void; }} // namespace stormkit::core @@ -55,24 +59,34 @@ export namespace stormkit { inline namespace core { //////////////////////////////////////////////////////////////////// namespace stormkit { inline namespace core { + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(sizeof...(Args) >= 2) + STORMKIT_FORCE_INLINE STORMKIT_PURE + constexpr auto hash(Args&&... values) noexcept -> Ret { + auto out = Ret { 0 }; + stormkit::hash_combine(out, std::forward(values)...); + return out; + } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto hash(T&& value) noexcept -> Ret { static_assert(meta::HasHasher or meta::HasStdHashSpecialization, "No hasher or std::hash specialization!"); - if constexpr (meta::HasHasher) return hasher(std::forward(value)); + if constexpr (meta::HasHasher) return hasher(std::forward(value)); else { - const auto hasher = std::hash> {}; - return static_cast(hasher(std::forward(value))); + const auto _hasher = std::hash> {}; + return static_cast(_hasher(std::forward(value))); } } ///////////////////////////////////// ///////////////////////////////////// - template + template requires(sizeof(T) <= sizeof(Ret)) STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto hasher(T value) noexcept -> Ret { @@ -81,7 +95,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template + template requires(sizeof(T) <= sizeof(Ret)) STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto hasher(T value) noexcept -> Ret { @@ -90,25 +104,25 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE constexpr auto hash_combine(Ret& out, T&& value) noexcept -> void { if constexpr (std::ranges::range) - for (auto&& elem : value) hash_combine(out, elem); - else { out ^= hash(std::forward(value)) + 0x9e3779b9 + (out << 6) + (out >> 2); } + for (auto&& elem : value) stormkit::hash_combine(out, elem); + else { out ^= hash(std::forward(value)) + 0x9e3779b9 + (out << 6) + (out >> 2); } } ///////////////////////////////////// ///////////////////////////////////// - template - requires(sizeof...(Args) > 1) + template + requires(sizeof...(Args) >= 2) STORMKIT_FORCE_INLINE constexpr auto hash_combine(Ret& out, Args&&... args) noexcept -> void { #if defined(__cpp_expansion_statements) and __cpp_expansion_statements >= 202500L template for (constexpr auto elem : { std::forward(args)... }) - hash_combine(out, std::forward(elem)); + stormkit::hash_combine(out, std::forward(elem)); #else - (hash_combine(out, std::forward(args)), ...); + (stormkit::hash_combine(out, std::forward(args)), ...); #endif } }} // namespace stormkit::core diff --git a/modules/stormkit/core/math/linear-matrix.mpp b/modules/stormkit/core/math/linear-matrix.mpp index 6ae0e9ef8..12b9477f9 100644 --- a/modules/stormkit/core/math/linear-matrix.mpp +++ b/modules/stormkit/core/math/linear-matrix.mpp @@ -18,6 +18,10 @@ import :typesafe.floating_point; import :math.linear; import :math.linear.vector; +import :hash.base; + +import :string.format; + export { namespace stormkit { inline namespace core { namespace math { template @@ -277,7 +281,7 @@ export { template [[nodiscard]] - constexpr auto rotate(const mat4x4& mat, Radian angle, const vec3& axis) noexcept -> mat4x4; + constexpr auto rotate(const mat4x4& mat, angle::radian angle, const vec3& axis) noexcept -> mat4x4; template [[nodiscard]] @@ -289,7 +293,7 @@ export { template [[nodiscard]] - constexpr auto perspective(Radian fov_y, T aspect, T near, T far) noexcept -> mat4x4; + constexpr auto perspective(angle::radian fov_y, T aspect, T near, T far) noexcept -> mat4x4; template [[nodiscard]] @@ -309,25 +313,15 @@ export { requires(not core::meta::IsConst) [[nodiscard]] constexpr auto as_mdspan(T& value) noexcept -> MatrixSpan; - }}} // namespace stormkit::core::math - - namespace std { - template - struct hash { - [[nodiscard]] - auto operator()(const T&) const noexcept -> stormkit::u64; - }; - template - struct formatter { - template - constexpr auto parse(ParseContext& ctx) noexcept -> decltype(ctx.begin()); + template + constexpr auto hasher(const T& value) noexcept -> Ret; - template - [[nodiscard]] - auto format(const T&, FormatContext& ctx) const -> decltype(ctx.out()); - }; + template + auto format_as(const T& value, FormatContext& ctx) noexcept -> decltype(ctx.out); + }}} // namespace stormkit::core::math + namespace std { template constexpr range_format format_kind = range_format::disabled; } // namespace std @@ -575,7 +569,7 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto rotate(const mat4x4& mat, Radian angle, const vec3& axis) noexcept -> mat4x4 { + constexpr auto rotate(const mat4x4& mat, angle::radian angle, const vec3& axis) noexcept -> mat4x4 { auto out = mat4x4 {}; rotate(as_mdspan(mat), angle, as_mdspan(axis), as_mdspan_mut(out)); @@ -611,7 +605,7 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto perspective(Radian fov_y, T aspect, T near, T far) noexcept -> mat4x4 { + constexpr auto perspective(angle::radian fov_y, T aspect, T near, T far) noexcept -> mat4x4 { auto out = mat4x4 {}; perspective(fov_y, aspect, near, far, as_mdspan_mut(out)); @@ -659,71 +653,57 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto as_mdspan_mut(T& value) noexcept -> MatrixSpan { return MatrixSpan { stdr::data(value), T::EXTENTS }; } -}}} // namespace stormkit::core::math -//////////////////////////////////////// -//////////////////////////////////////// -template + //////////////////////////////////////// + //////////////////////////////////////// + template STORMKIT_PURE STORMKIT_FORCE_INLINE -auto std::hash::operator()(const T& mat) const noexcept -> stormkit::u64 { - const auto span = as_span(mat); + constexpr auto hasher(const T& value) noexcept -> Ret { + return hash(as_span(value)); + } - auto hash = stormkit::u64 { 0 }; - for (const auto v : span) stormkit::hash_combine(hash, v); + //////////////////////////////////////// + //////////////////////////////////////// + template + inline auto format_as(const T& mat, FormatContext& ctx) noexcept -> decltype(ctx.out) { + auto out = ctx.out(); - return hash; -} + auto i = 0; + auto check_by_extent = [&i](auto, auto) mutable { + const auto insert = i++ < (T::EXTENTS[0] - 1); + if (not insert) i = 0; -//////////////////////////////////////// -//////////////////////////////////////// -template -template -constexpr auto std::formatter::parse(ParseContext& ctx) noexcept -> decltype(ctx.begin()) { - return ctx.begin(); -} + return insert; + }; -//////////////////////////////////////// -//////////////////////////////////////// -template -template -inline auto std::formatter::format(const T& mat, FormatContext& ctx) const -> decltype(ctx.out()) { - auto out = ctx.out(); - - auto i = 0; - auto check_by_extent = [&i](auto, auto) mutable { - const auto insert = i++ < (T::EXTENTS[0] - 1); - if (not insert) i = 0; - - return insert; - }; - - format_to(out, "{ mat:"); - auto l = 0u; - if constexpr (stormkit::meta::IsIntegral) { - auto max_digit = 0u; - for (auto v : as_span(mat)) max_digit = std::max(max_digit, v == 0 ? 2 : narrow(std::log10(v) + 2)); - for (auto&& slice : mat | stdv::chunk_by(check_by_extent)) { - format_to(out, - "{}|{:n:>{}}|{}", - (l > 0) ? " "sv : " "sv, - slice, - max_digit, - (l != (T::EXTENTS[0] - 1)) ? "\n"sv : "}"sv); - ++l; + format_to(out, "[mat "); + auto l = 0u; + if constexpr (stormkit::meta::IsIntegral) { + auto max_digit = 0u; + for (auto v : as_span(mat)) max_digit = std::max(max_digit, v == 0 ? 2 : narrow(std::log10(v) + 2)); + for (auto&& slice : mat | stdv::chunk_by(check_by_extent)) { + format_to(out, + "{}|{:n:>{}}|{}", + (l > 0) ? " "sv : " "sv, + slice, + max_digit, + (l != (T::EXTENTS[0] - 1)) ? "\n"sv : "}"sv); + ++l; + } + } else { + auto max_digit = 0u; + for (auto v : as_span(mat)) max_digit = std::max(max_digit, narrow(v) == 0 ? 2 : narrow(std::log10(v) + 2)); + for (auto&& slice : mat | stdv::chunk_by(check_by_extent)) { + format_to(out, + "{}| {:n:>{}.5f}|{}", + (l > 0) ? " "sv : " "sv, + slice, + max_digit, + (l != (T::EXTENTS[0] - 1)) ? "\n"sv : "]"sv); + ++l; + } } - } else { - auto max_digit = 0u; - for (auto v : as_span(mat)) max_digit = std::max(max_digit, narrow(v) == 0 ? 2 : narrow(std::log10(v) + 2)); - for (auto&& slice : mat | stdv::chunk_by(check_by_extent)) { - format_to(out, - "{}| {:n:>{}.5f}|{}", - (l > 0) ? " "sv : " "sv, - slice, - max_digit, - (l != (T::EXTENTS[0] - 1)) ? "\n"sv : "}"sv); - ++l; - } - } - return out; -} + return out; + } +}}} // namespace stormkit::core::math diff --git a/modules/stormkit/core/math/linear-vector.mpp b/modules/stormkit/core/math/linear-vector.mpp index e7d12fa5e..e1a2990e4 100644 --- a/modules/stormkit/core/math/linear-vector.mpp +++ b/modules/stormkit/core/math/linear-vector.mpp @@ -11,201 +11,180 @@ export module stormkit.core:math.linear.vector; import std; import :meta; -import :typesafe; + +import :typesafe.integer; +import :typesafe.floating_point; import :math.linear; import :hash.base; -export { - namespace stormkit { inline namespace core { namespace math { - template - struct alignas(std::array) vec2 { - using value_type = T; - using size_type = usize; - using extent_type = u8; +import :string.format; - static constexpr auto EXTENT = std::array { 2uz }; +export namespace stormkit { inline namespace core { namespace math { + template + struct alignas(std::array) vec2 { + using value_type = T; + using size_type = usize; + using extent_type = u8; - T x; - T y; + static constexpr auto EXTENT = std::array { 2uz }; - template - constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst; + T x; + T y; - template - constexpr auto to() const noexcept -> vec2; - }; + template + constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst; - using vec2f32 = vec2; - using vec2f64 = vec2; - using vec2f = vec2f32; + template + constexpr auto to() const noexcept -> vec2; + }; - using vec2i32 = vec2; - using vec2i64 = vec2; - using vec2i = vec2i32; + using vec2f32 = vec2; + using vec2f64 = vec2; + using vec2f = vec2f32; - using vec2u32 = vec2; - using vec2u64 = vec2; - using vec2u = vec2u32; + using vec2i32 = vec2; + using vec2i64 = vec2; + using vec2i = vec2i32; - template - struct alignas(std::array) vec3 { - using value_type = T; - using size_type = usize; - using extent_type = u8; + using vec2u32 = vec2; + using vec2u64 = vec2; + using vec2u = vec2u32; - static constexpr auto EXTENT = std::array { 3uz }; + template + struct alignas(std::array) vec3 { + using value_type = T; + using size_type = usize; + using extent_type = u8; - T x; - T y; - T z; + static constexpr auto EXTENT = std::array { 3uz }; - template - constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst; + T x; + T y; + T z; - template - constexpr auto to() const noexcept -> vec3; - }; + template + constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst; - using vec3f32 = vec3; - using vec3f64 = vec3; - using vec3f = vec3f32; + template + constexpr auto to() const noexcept -> vec3; + }; - using vec3i32 = vec3; - using vec3i64 = vec3; - using vec3i = vec3i32; + using vec3f32 = vec3; + using vec3f64 = vec3; + using vec3f = vec3f32; - using vec3u32 = vec3; - using vec3u64 = vec3; - using vec3u = vec3u32; + using vec3i32 = vec3; + using vec3i64 = vec3; + using vec3i = vec3i32; - template - struct alignas(std::array) vec4 { - using value_type = T; - using size_type = usize; - using extent_type = u8; + using vec3u32 = vec3; + using vec3u64 = vec3; + using vec3u = vec3u32; - static constexpr auto EXTENT = std::array { 4uz }; + template + struct alignas(std::array) vec4 { + using value_type = T; + using size_type = usize; + using extent_type = u8; - T x; - T y; - T z; - T w; + static constexpr auto EXTENT = std::array { 4uz }; - template - constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst; + T x; + T y; + T z; + T w; - template - constexpr auto to() const noexcept -> vec4; - }; + template + constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst; - using vec4f32 = vec4; - using vec4f64 = vec4; - using vec4f = vec4f32; + template + constexpr auto to() const noexcept -> vec4; + }; - using vec4i32 = vec4; - using vec4i64 = vec4; - using vec4i = vec4i32; + using vec4f32 = vec4; + using vec4f64 = vec4; + using vec4f = vec4f32; - using vec4u32 = vec4; - using vec4u64 = vec4; - using vec4u = vec4u32; + using vec4i32 = vec4; + using vec4i64 = vec4; + using vec4i = vec4i32; - namespace meta { - template - concept IsVec2 = core::meta::IsSpecializationOf; - template - concept IsVec3 = core::meta::IsSpecializationOf; + using vec4u32 = vec4; + using vec4u64 = vec4; + using vec4u = vec4u32; - template - concept IsVec = IsVec2 || IsVec3; + namespace meta { + template + concept IsVec2 = core::meta::IsSpecializationOf; + template + concept IsVec3 = core::meta::IsSpecializationOf; - template - concept HasOneVecType = not(core::meta::IsMdspanType and core::meta::IsMdspanType) - or meta::IsVec - or meta::IsVec; - } // namespace meta + template + concept IsVec = IsVec2 || IsVec3; - template - [[nodiscard]] - constexpr auto add(const T& a, const T& b) noexcept -> T; + template + concept HasOneVecType = not(core::meta::IsMdspanType and core::meta::IsMdspanType) + or meta::IsVec + or meta::IsVec; + } // namespace meta - template - [[nodiscard]] - constexpr auto sub(const T& a, const T& b) noexcept -> T; + template + [[nodiscard]] + constexpr auto add(const T& a, const T& b) noexcept -> T; - template - [[nodiscard]] - constexpr auto mul(const T& a, typename T::value_type b) noexcept -> T; + template + [[nodiscard]] + constexpr auto sub(const T& a, const T& b) noexcept -> T; - template - [[nodiscard]] - constexpr auto div(const T& a, typename T::value_type b) noexcept -> T; + template + [[nodiscard]] + constexpr auto mul(const T& a, typename T::value_type b) noexcept -> T; - template - [[nodiscard]] - constexpr auto dot(const T& a, const T& b) noexcept -> typename T::value_type; + template + [[nodiscard]] + constexpr auto div(const T& a, typename T::value_type b) noexcept -> T; - template - [[nodiscard]] - constexpr auto cross(const vec3& a, const vec3& b) noexcept -> vec3; - - template - [[nodiscard]] - constexpr auto normalize(const T& a) noexcept -> T; - - template - [[nodiscard]] - constexpr auto as_mdspan(const T& value) noexcept -> VectorSpan; - - template - requires(not core::meta::IsConst) - [[nodiscard]] - constexpr auto as_mdspan_mut(T& value) noexcept -> VectorSpan; - }}} // namespace stormkit::core::math - - namespace std { - template - struct hash> { - [[nodiscard]] - auto operator()(const stormkit::math::vec2&) const noexcept -> stormkit::u64; - }; - - template - struct formatter, CharT>: formatter { - template - [[nodiscard]] - auto format(const stormkit::math::vec2&, FormatContext& ctx) const -> decltype(ctx.out()); - }; - - template - struct hash> { - [[nodiscard]] - auto operator()(const stormkit::math::vec3&) const noexcept -> stormkit::u64; - }; - - template - struct formatter, CharT>: formatter { - template - [[nodiscard]] - auto format(const stormkit::math::vec3&, FormatContext& ctx) const -> decltype(ctx.out()); - }; - - template - struct hash> { - [[nodiscard]] - auto operator()(const stormkit::math::vec4&) const noexcept -> stormkit::u64; - }; - - template - struct formatter, CharT>: formatter { - template - [[nodiscard]] - auto format(const stormkit::math::vec4&, FormatContext& ctx) const -> decltype(ctx.out()); - }; - } // namespace std -} // namespace stormkit::core::math + template + [[nodiscard]] + constexpr auto dot(const T& a, const T& b) noexcept -> typename T::value_type; + + template + [[nodiscard]] + constexpr auto cross(const vec3& a, const vec3& b) noexcept -> vec3; + + template + [[nodiscard]] + constexpr auto normalize(const T& a) noexcept -> T; + + template + [[nodiscard]] + constexpr auto as_mdspan(const T& value) noexcept -> VectorSpan; + + template + requires(not core::meta::IsConst) + [[nodiscard]] + constexpr auto as_mdspan_mut(T& value) noexcept -> VectorSpan; + + template + constexpr auto hasher(const vec2& value) noexcept -> Ret; + + template + constexpr auto hasher(const vec3& value) noexcept -> Ret; + + template + constexpr auto hasher(const vec4& value) noexcept -> Ret; + + template + auto format_as(const vec2& value, FormatContext& ctx) noexcept -> decltype(ctx.out); + + template + auto format_as(const vec3& value, FormatContext& ctx) noexcept -> decltype(ctx.out); + + template + auto format_as(const vec4& value, FormatContext& ctx) noexcept -> decltype(ctx.out); +}}} // namespace stormkit::core::math //////////////////////////////////////////////////////////////////// /// IMPLEMENTATION /// @@ -391,84 +370,52 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto as_mdspan_mut(T& value) noexcept -> VectorSpan { return VectorSpan { &value.x, T::EXTENT }; } -}}} // namespace stormkit::core::math -namespace std { - template + //////////////////////////////////////// + //////////////////////////////////////// + template STORMKIT_PURE STORMKIT_FORCE_INLINE - auto hash>::operator()(const stormkit::math::vec2& vec) const noexcept -> stormkit::u64 { - auto hash = stormkit::hash64 { 0 }; - - stormkit::hash_combine(hash, vec.x); - stormkit::hash_combine(hash, vec.y); - - return hash; + constexpr auto hasher(const vec2& value) noexcept -> Ret { + return hash(value.x, value.y); } - template - template - inline auto formatter, CharT>::format(const stormkit::math::vec2& vec, FormatContext& ctx) const - -> decltype(ctx.out()) { - auto out = ctx.out(); - - stdr::copy("{ vec2: .x = "sv, out); - formatter::format(vec.x, ctx); - stdr::copy(" .y = "sv, out); - formatter::format(vec.y, ctx); - stdr::copy(" }"sv, out); - - return std::move(out); + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_PURE STORMKIT_FORCE_INLINE + constexpr auto hasher(const vec3& value) noexcept -> Ret { + return hash(value.x, value.y, value.z); } - template + //////////////////////////////////////// + //////////////////////////////////////// + template STORMKIT_PURE STORMKIT_FORCE_INLINE - auto hash>::operator()(const stormkit::math::vec3& vec) const noexcept -> stormkit::u64 { - auto hash = stormkit::hash64 { 0 }; - stormkit::hash_combine(hash, vec.x, vec.y, vec.z); - return hash; + constexpr auto hasher(const vec4& value) noexcept -> Ret { + return hash(value.x, value.y, value.z, value.w); } - template - template - inline auto formatter, CharT>::format(const stormkit::math::vec3& vec, FormatContext& ctx) const - -> decltype(ctx.out()) { - auto out = ctx.out(); - - stdr::copy("{ vec3: .x = "sv, out); - formatter::format(vec.x, ctx); - stdr::copy(" .y = "sv, out); - formatter::format(vec.y, ctx); - stdr::copy(" .z = "sv, out); - formatter::format(vec.z, ctx); - stdr::copy(" }"sv, out); - - return std::move(out); + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto format_as(const vec2& value, FormatContext& ctx) noexcept -> decltype(ctx.out) { + return std::format_to(ctx.out(), "[vec2 x: {}, y: {}]", value.x, value.y); } - template - STORMKIT_PURE STORMKIT_FORCE_INLINE - auto hash>::operator()(const stormkit::math::vec4& vec) const noexcept -> stormkit::u64 { - auto hash = stormkit::hash64 { 0 }; - stormkit::hash_combine(hash, vec.x, vec.y, vec.z, vec.w); - return hash; + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto format_as(const vec3& value, FormatContext& ctx) noexcept -> decltype(ctx.out) { + return std::format_to(ctx.out(), "[vec2 x: {}, y: {}, z: {}]", value.x, value.y, value.z); } - template - template - inline auto formatter, CharT>::format(const stormkit::math::vec4& vec, FormatContext& ctx) const - -> decltype(ctx.out()) { - auto out = ctx.out(); - - stdr::copy("{ vec4: .x = "sv, out); - formatter::format(vec.x, ctx); - stdr::copy(" .y = "sv, out); - formatter::format(vec.y, ctx); - stdr::copy(" .z = "sv, out); - formatter::format(vec.z, ctx); - stdr::copy(" .w = "sv, out); - formatter::format(vec.w, ctx); - stdr::copy(" }"sv, out); - - return std::move(out); + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto format_as(const vec4& value, FormatContext& ctx) noexcept -> decltype(ctx.out) { + return std::format_to(ctx.out(), "[vec2 x: {}, y: {}, z: {}, w: {}]", value.x, value.y, value.z, value.w); } -} // namespace std +}}} // namespace stormkit::core::math diff --git a/modules/stormkit/core/math/linear.mpp b/modules/stormkit/core/math/linear.mpp index 9525a08ea..f979273cf 100644 --- a/modules/stormkit/core/math/linear.mpp +++ b/modules/stormkit/core/math/linear.mpp @@ -21,11 +21,17 @@ import :functional; // TODO improve template deduction export namespace stormkit { inline namespace core { namespace math { - template - using Euler = StrongType; + namespace angle { + template + using euler = StrongType; - template - using Radian = StrongType; + template + using radian = StrongType; + + template + [[nodiscard]] + constexpr auto radians(T degres) noexcept -> radian; + } // namespace angle template requires(sizeof...(Sizes) >= 1) @@ -73,10 +79,6 @@ export namespace stormkit { inline namespace core { namespace math { [[nodiscard]] constexpr auto as(const From& data) noexcept -> To; - template - [[nodiscard]] - constexpr auto radians(T degres) noexcept -> Radian; - template requires(not core::meta::IsConst) constexpr auto add(const TensorSpan& a, @@ -179,7 +181,7 @@ export namespace stormkit { inline namespace core { namespace math { template requires(std::is_signed_v and not core::meta::IsConst) - constexpr auto perspective(Radian fov_y, T aspect, T near, T far, SquareMatrixSpan out) noexcept -> void; + constexpr auto perspective(angle::radian fov_y, T aspect, T near, T far, SquareMatrixSpan out) noexcept -> void; template requires(std::is_signed_v and not core::meta::IsConst) @@ -196,6 +198,17 @@ export namespace stormkit { inline namespace core { namespace math { namespace stdr = std::ranges; namespace stormkit { inline namespace core { namespace math { + namespace angle { + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_PURE STORMKIT_FORCE_INLINE + constexpr auto radians(T degres) noexcept -> radian { + static constexpr auto one_rad = std::numbers::pi_v / T { 180 }; + return radian { degres * one_rad }; + } + } // namespace angle + template using MatData = std::array; template @@ -267,15 +280,6 @@ namespace stormkit { inline namespace core { namespace math { return To { data }; } - //////////////////////////////////////// - //////////////////////////////////////// - template - STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto radians(T degres) noexcept -> Radian { - static constexpr auto one_rad = std::numbers::pi_v / T { 180 }; - return Radian { degres * one_rad }; - } - //////////////////////////////////////// //////////////////////////////////////// template @@ -598,7 +602,7 @@ namespace stormkit { inline namespace core { namespace math { requires(std::is_signed_v and not core::meta::IsConst) STORMKIT_FORCE_INLINE constexpr auto rotate(const SquareMatrixSpan& a, - Radian angle, + angle::radian angle, const VectorSpan& axis, SquareMatrixSpan out) noexcept -> void { EXPECTS(a.data_handle() != out.data_handle()); @@ -679,7 +683,7 @@ namespace stormkit { inline namespace core { namespace math { template requires(std::is_signed_v and not core::meta::IsConst) STORMKIT_FORCE_INLINE - constexpr auto perspective(Radian fov_y, T aspect, T near, T far, SquareMatrixSpan out) noexcept -> void { + constexpr auto perspective(angle::radian fov_y, T aspect, T near, T far, SquareMatrixSpan out) noexcept -> void { EXPECTS(not is_equal(aspect, T { 0 })); EXPECTS(not is_equal(near, far)); diff --git a/modules/stormkit/core/meta/concepts.mpp b/modules/stormkit/core/meta/concepts.mpp index 3ac2ee44c..11f88cb73 100644 --- a/modules/stormkit/core/meta/concepts.mpp +++ b/modules/stormkit/core/meta/concepts.mpp @@ -29,6 +29,11 @@ namespace stormkit { inline namespace core { namespace meta::details { constexpr auto is_specialization_of_helper_nttp_ttv(const T&) noexcept -> std::true_type { return {}; } + + template typename T, typename T1, typename T2, auto Arg, typename... Ts> + constexpr auto is_specialization_of_helper_nttp_ttvts(const T&) noexcept -> std::true_type { + return {}; + } }}} // namespace stormkit::core::meta::details export namespace stormkit { inline namespace core { namespace meta { @@ -238,6 +243,11 @@ export namespace stormkit { inline namespace core { namespace meta { { details::is_specialization_of_helper_nttp_ttv(std::forward(s)) } -> IsStrict; }; + template typename T> + concept IsSpecializationOfNTTP_TTVTs = requires(S&& s) { + { details::is_specialization_of_helper_nttp_ttvts(std::forward(s)) } -> IsStrict; + }; + template class T> concept IsSpecializationWithNTTPOf = requires(S&& s) { { details::is_specialization_of_with_nttp_helper(std::forward(s)) } -> IsStrict; diff --git a/modules/stormkit/core/string/constexpr_string.mpp b/modules/stormkit/core/string/constexpr_string.mpp index 49a3aeedc..75f7fc718 100644 --- a/modules/stormkit/core/string/constexpr_string.mpp +++ b/modules/stormkit/core/string/constexpr_string.mpp @@ -12,7 +12,7 @@ import std; namespace stdr = std::ranges; -export namespace stormkit { inline namespace core { +export namespace stormkit { inline namespace core { namespace meta { template struct ConstexprString { consteval ConstexprString() noexcept = default; @@ -38,13 +38,13 @@ export namespace stormkit { inline namespace core { std::array data = {}; std::size_t m_size = 0; }; -}} // namespace stormkit::core +}}} // namespace stormkit::core::meta //////////////////////////////////////////////////////////////////// /// IMPLEMENTATION /// //////////////////////////////////////////////////////////////////// -namespace stormkit { inline namespace core { +namespace stormkit { inline namespace core { namespace meta { ///////////////////////////////////// ///////////////////////////////////// template @@ -101,4 +101,4 @@ namespace stormkit { inline namespace core { constexpr auto ConstexprString::update_size() noexcept -> void { m_size = std::char_traits::length(stdr::data(data)); } -}} // namespace stormkit::core +}}} // namespace stormkit::core::meta diff --git a/modules/stormkit/core/typesafe/flags.mpp b/modules/stormkit/core/typesafe/flags.mpp index 7813581c0..4db3b672c 100644 --- a/modules/stormkit/core/typesafe/flags.mpp +++ b/modules/stormkit/core/typesafe/flags.mpp @@ -128,7 +128,7 @@ namespace stormkit { inline namespace core { return res + 1; }(); - auto out = std::array>, OUT_SIZE> {}; + auto out = std::array>, OUT_SIZE> {}; auto queue = std::vector> {}; for (const auto& [k, v] : mapping) queue.emplace_back(k, std::string { v }, true); @@ -191,7 +191,7 @@ namespace stormkit { inline namespace core { return res; }(); - auto out = std::array>, OUT_SIZE> {}; + auto out = std::array>, OUT_SIZE> {}; auto queue = std::vector> {}; for (const auto& [k, v] : mapping) queue.emplace_back(k, std::string { v }, true); diff --git a/modules/stormkit/core/typesafe/ref.mpp b/modules/stormkit/core/typesafe/ref.mpp index 1a63a4776..69f80a65a 100644 --- a/modules/stormkit/core/typesafe/ref.mpp +++ b/modules/stormkit/core/typesafe/ref.mpp @@ -4,8 +4,6 @@ module; -#include - #include #include @@ -260,22 +258,17 @@ export { requires(std::ranges::range>) [[nodiscard]] constexpr auto to_mut_opt_refs(T& range) noexcept -> decltype(auto); - }} // namespace stormkit::core - namespace std { - template - struct pointer_traits> { - using pointer = typename stormkit::Ref::PointerType; - using element_type = typename stormkit::Ref::ElementType; - using difference_type = std::ptrdiff_t; - }; + template + constexpr auto hasher(const Ref& value) noexcept -> Ret; + }} // namespace stormkit::core - template - struct hash> { - [[nodiscard]] - auto operator()(const stormkit::Ref& ref) const noexcept -> stormkit::u64; - }; - } // namespace std + template + struct std::pointer_traits> { + using pointer = typename stormkit::Ref::PointerType; + using element_type = typename stormkit::Ref::ElementType; + using difference_type = std::ptrdiff_t; + }; } //////////////////////////////////////////////////////////////////// @@ -859,13 +852,12 @@ namespace stormkit { inline namespace core { }) | std::ranges::to(); } -}} // namespace stormkit::core - -using namespace stormkit; -template -inline auto std::hash>::operator()(const Ref& ref) const noexcept -> u64 { - auto hash = u64 { 0 }; - hash_combine(hash, ref.get()); - return hash; -} + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto hasher(const Ref& value) noexcept -> Ret { + return hash(value.get()); + } +}} // namespace stormkit::core diff --git a/modules/stormkit/core/typesafe/strong_type.mpp b/modules/stormkit/core/typesafe/strong_type.mpp index 78ea5f9d3..5fe4232cf 100644 --- a/modules/stormkit/core/typesafe/strong_type.mpp +++ b/modules/stormkit/core/typesafe/strong_type.mpp @@ -11,6 +11,8 @@ export module stormkit.core:typesafe.strong_type; import std; import :meta; +import :string.constexpr_string; +import :hash; export { namespace stormkit { inline namespace core { @@ -69,12 +71,12 @@ export { struct ImplicitConvertionTag {}; - template + template class StrongType; namespace meta { template - concept IsStrongType = IsSpecializationOf; + concept IsStrongType = IsSpecializationOfNTTP_TTVTs; template concept HasCapability = DerivedFrom; @@ -114,7 +116,7 @@ export { return meta::ToPlainType { std::forward(second).get() / std::forward(first) }; } - template + template class StrongType { public: using ValueType = T; @@ -182,19 +184,14 @@ export { // constexpr auto operator+=(First& first, Second&& second) { // first.get() += std::forward(second).get(); // } - }} // namespace stormkit::core - template - struct std::hash { - [[nodiscard]] - auto operator()(const T& value) const noexcept -> std::uint64_t; - }; - - template - struct std::formatter: std::formatter { - template - auto format(const T& data, FormatContext& ctx) const noexcept -> decltype(ctx.out()); - }; + template + constexpr auto hasher(const T& value) noexcept -> Ret; + + template + auto format_as(const StrongType& value, FormatContext& ctx) noexcept + -> decltype(ctx.out()); + }} // namespace stormkit::core } //////////////////////////////////////////////////////////////////// @@ -204,19 +201,19 @@ export { namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr StrongType::StrongType(ValueType value) noexcept(meta::IsNoexceptConstructible) + constexpr StrongType:: + StrongType(ValueType value) noexcept(meta::IsNoexceptConstructible) : m_value { value } { } //////////////////////////////////////// //////////////////////////////////////// - template + template template STORMKIT_FORCE_INLINE - constexpr StrongType:: + constexpr StrongType:: StrongType(std::in_place_t, Args&&... args) noexcept(meta::IsNoexceptConstructible) requires(meta::IsConstructible) : m_value { std::forward(args)... } { @@ -224,76 +221,77 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr StrongType::~StrongType() noexcept(meta::IsNoexceptDestructible) - = default; + constexpr StrongType::~StrongType() noexcept(meta::IsNoexceptDestructible< + ValueType>) = default; //////////////////////////////////////// //////////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr StrongType::StrongType(const StrongType&) noexcept(meta::IsNoexceptCopyConstructible< - ValueType>) + constexpr StrongType::StrongType(const StrongType&) noexcept(meta::IsNoexceptCopyConstructible< + ValueType>) requires(meta::IsCopyConstructible) = default; //////////////////////////////////////// //////////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr auto StrongType::operator=(const StrongType&) noexcept(meta::IsNoexceptCopyAssignable< - ValueType>) -> StrongType& + constexpr auto StrongType:: + operator=(const StrongType&) noexcept(meta::IsNoexceptCopyAssignable) -> StrongType& requires(meta::IsCopyAssignable) = default; //////////////////////////////////////// //////////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr StrongType::StrongType(StrongType&&) noexcept(meta::IsNoexceptMoveConstructible) + constexpr StrongType::StrongType(StrongType&&) noexcept(meta::IsNoexceptMoveConstructible< + ValueType>) requires(meta::IsMoveConstructible) = default; //////////////////////////////////////// //////////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr auto StrongType::operator=(StrongType&&) noexcept(meta::IsNoexceptMoveAssignable< - ValueType>) -> StrongType& + constexpr auto StrongType::operator=(StrongType&&) noexcept(meta::IsNoexceptMoveAssignable< + ValueType>) -> StrongType& requires(meta::IsMoveAssignable) = default; //////////////////////////////////////// //////////////////////////////////////// - template + template template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr StrongType::operator T(this Self&& self) noexcept { + constexpr StrongType::operator T(this Self&& self) noexcept { return std::forward_like(self.m_value); } //////////////////////////////////////// //////////////////////////////////////// - template + template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr StrongType::operator T&() & noexcept { + constexpr StrongType::operator T&() & noexcept { return get(); } //////////////////////////////////////// //////////////////////////////////////// - template + template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr StrongType::operator const T&() const & noexcept { + constexpr StrongType::operator const T&() const & noexcept { return get(); } //////////////////////////////////////// //////////////////////////////////////// - template + template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto StrongType::get(this auto&& self) noexcept -> decltype(auto) { + constexpr auto StrongType::get(this auto&& self) noexcept -> decltype(auto) { return std::forward_like(self.m_value); } @@ -306,24 +304,21 @@ namespace stormkit { inline namespace core { else return std::forward(value); } -}} // namespace stormkit::core -using namespace stormkit; - -//////////////////////////////////////// -//////////////////////////////////////// -template -STORMKIT_FORCE_INLINE -inline auto std::hash::operator()(const T& value) const noexcept -> std::uint64_t { - return std::hash {}(value.get()); -} + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto hasher(const T& value) noexcept -> Ret { + return hash(value.get()); + } -//////////////////////////////////////// -//////////////////////////////////////// -template -template -STORMKIT_FORCE_INLINE -auto std::formatter::format(const T& data, FormatContext& ctx) const noexcept -> decltype(ctx.out()) { - auto&& out = ctx.out(); - return std::format_to(out, "{}", data.get()); -} + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto format_as(const StrongType& value, FormatContext& ctx) noexcept + -> decltype(ctx.out()) { + return std::format_to(ctx.out(), "[{} value: {}]", Name, value.get()); + } +}} // namespace stormkit::core diff --git a/modules/stormkit/core/utils/handle.mpp b/modules/stormkit/core/utils/handle.mpp index be3232dec..6c9b170d3 100644 --- a/modules/stormkit/core/utils/handle.mpp +++ b/modules/stormkit/core/utils/handle.mpp @@ -19,15 +19,14 @@ import :meta; export { namespace stormkit { inline namespace core { - template + template struct Handle { using ID = _ID; static constexpr auto INVALID_HANDLE_VALUE = std::numeric_limits::max(); [[nodiscard]] - constexpr auto operator<=>(const Handle&) const noexcept -> std::strong_ordering - = default; + constexpr auto operator<=>(const Handle&) const noexcept -> std::strong_ordering = default; template U> constexpr operator Handle() const noexcept; @@ -53,9 +52,15 @@ export { template using Handle64 = Handle; + + template + constexpr auto hasher(const Handle& value) noexcept -> Ret; + + template + auto format_as(const Handle& value, FormatContext& ctx) noexcept -> decltype(ctx.out()); }} // namespace stormkit::core - template + template struct std::hash> { [[nodiscard]] constexpr auto operator()(stormkit::core::Handle handle) const noexcept -> stormkit::core::hash64; @@ -69,7 +74,7 @@ export { namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template + template template U> constexpr Handle::operator Handle() const noexcept { return Handle { id }; @@ -77,7 +82,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template + template constexpr auto& Handle::operator++() noexcept { ++id; return *this; @@ -85,7 +90,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template + template constexpr auto Handle::operator++(int) noexcept { auto old = *this; operator++(); @@ -94,7 +99,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template + template constexpr auto& Handle::operator--() noexcept { --id; return *this; @@ -102,7 +107,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template + template constexpr auto Handle::operator--(int) noexcept { auto old = *this; operator--(); @@ -111,23 +116,29 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template + template constexpr Handle::operator ID() const noexcept { return id; } ///////////////////////////////////// ///////////////////////////////////// - template + template constexpr auto Handle::invalid_handle() noexcept -> Handle { return Handle {}; } -}} // namespace stormkit::core -///////////////////////////////////// -///////////////////////////////////// -template -constexpr stormkit::core::hash64 std::hash>::operator()(stormkit::core::Handle handle) - const noexcept { - return stormkit::core::as(handle.id); -} + ///////////////////////////////////// + ///////////////////////////////////// + template + constexpr auto hasher(const Handle& value) noexcept -> Ret { + return hash(value.id); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto format_as(const Handle& value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { + return std::format_to(ctx.out(), "[handle id: {}]", value.id); + } +}} // namespace stormkit::core diff --git a/modules/stormkit/gpu/core/structs.mpp b/modules/stormkit/gpu/core/structs.mpp index bf5a734a4..55cc42c3d 100644 --- a/modules/stormkit/gpu/core/structs.mpp +++ b/modules/stormkit/gpu/core/structs.mpp @@ -4,9 +4,7 @@ module; -#include #include -#include #include #include @@ -316,10 +314,13 @@ export { [[nodiscard]] auto to_string(const PhysicalDeviceInfo& data) noexcept; - } // namespace stormkit::gpu - HASH_FUNC(stormkit::gpu::Viewport, value.position, value.extent, value.depth) - HASH_FUNC(stormkit::gpu::Scissor, value.offset, value.extent) + template + constexpr auto hasher(const Viewport& value) noexcept -> Ret; + + template + constexpr auto hasher(const Scissor& value) noexcept -> Ret; + } // namespace stormkit::gpu } //////////////////////////////////////////////////////////////////// @@ -369,4 +370,14 @@ namespace stormkit::gpu { data.driver_patch_version, data.type); } + + template + constexpr auto hasher(const Viewport& value) noexcept -> Ret { + return hash(value.position, value.extent, value.depth); + } + + template + constexpr auto hasher(const Scissor& value) noexcept -> Ret { + return hash(value.offset, value.extent); + } } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/execution/command_buffer.mpp b/modules/stormkit/gpu/execution/command_buffer.mpp index 7b49a1b7c..bae657868 100644 --- a/modules/stormkit/gpu/execution/command_buffer.mpp +++ b/modules/stormkit/gpu/execution/command_buffer.mpp @@ -5,7 +5,6 @@ module; #include -#include #include #include diff --git a/modules/stormkit/gpu/execution/descriptors.mpp b/modules/stormkit/gpu/execution/descriptors.mpp index ebf6a8b4d..a138ee59e 100644 --- a/modules/stormkit/gpu/execution/descriptors.mpp +++ b/modules/stormkit/gpu/execution/descriptors.mpp @@ -5,7 +5,6 @@ module; #include -#include #include #include @@ -21,8 +20,6 @@ import stormkit.gpu.resource; namespace stdr = std::ranges; namespace stdv = std::views; -export { - namespace stormkit::gpu { struct BufferDescriptor { DescriptorType type = DescriptorType::UNIFORM_BUFFER; u32 binding; @@ -30,6 +27,7 @@ export { u32 range; u32 offset = 0; }; +export namespace stormkit::gpu { struct ImageDescriptor { DescriptorType type = DescriptorType::COMBINED_IMAGE_SAMPLER; @@ -184,27 +182,25 @@ export { } }; - HASH_FUNC(stormkit::gpu::DescriptorSetLayoutBinding, value.binding, value.type, value.stages, value.descriptor_count) - HASH_FUNC(stormkit::gpu::BufferDescriptor, value.type, value.binding, value.buffer.get(), value.range, value.offset) - HASH_FUNC(stormkit::gpu::ImageDescriptor, - value.type, - value.binding, - value.layout, - value.image_view.get(), - value.sampler.get()) - template<> - struct STORMKIT_API std::hash { - [[nodiscard]] - auto operator()(const stormkit::gpu::Descriptor& value) const noexcept -> stormkit::hash64 { - auto hash = stormkit::hash64 { 0 }; std::visit([&hash](auto& descriptor) { stormkit::hash_combine(hash, descriptor); }, value); return hash; } }; -} + + template + constexpr auto hasher(const DescriptorSetLayout& value) noexcept -> Ret; + template + constexpr auto hasher(const DescriptorSetLayoutBinding& value) noexcept -> Ret; + template + constexpr auto hasher(const BufferDescriptor& value) noexcept -> Ret; + template + constexpr auto hasher(const ImageDescriptor& value) noexcept -> Ret; + template + constexpr auto hasher(const Descriptor& value) noexcept -> Ret; +} // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// /// IMPLEMENTATION /// @@ -584,4 +580,44 @@ namespace stormkit::gpu { ///////////////////////////////////// inline auto DescriptorPool::delete_vk_descriptor_set(VkDescriptorSet) -> void { } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto hasher(const DescriptorSetLayout& value) noexcept -> Ret { + return as(value.hash()); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto hasher(const DescriptorSetLayoutBinding& value) noexcept -> Ret { + return hash(value.binding, value.type, value.stages, value.descriptor_count); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto hasher(const BufferDescriptor& value) noexcept -> Ret { + return hash(value.type, value.binding, value.buffer, value.range, value.offset); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto hasher(const ImageDescriptor& value) noexcept -> Ret { + return hash(value.type, value.binding, value.layout, value.image_view, value.sampler); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto hasher(const Descriptor& value) noexcept -> Ret { + return std::visit([](const auto& descriptor) static noexcept { return hash(descriptor); }, value); + } } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/execution/render_pass.mpp b/modules/stormkit/gpu/execution/render_pass.mpp index 91649fa55..3bb92220c 100644 --- a/modules/stormkit/gpu/execution/render_pass.mpp +++ b/modules/stormkit/gpu/execution/render_pass.mpp @@ -5,7 +5,6 @@ module; #include -#include #include #include @@ -18,9 +17,7 @@ import stormkit.core; import stormkit.gpu.core; import stormkit.gpu.resource; -export { - namespace stormkit::gpu { - class RenderPass; +export namespace stormkit::gpu { class STORMKIT_API FrameBuffer { struct PrivateFuncTag {}; @@ -152,34 +149,19 @@ export { Ref m_vk_device_table; VkRAIIHandle m_vk_handle; }; - } // namespace stormkit::gpu - namespace std { - template<> - struct hash { - [[nodiscard]] - constexpr auto operator()(const stormkit::gpu::AttachmentDescription&) const noexcept -> stormkit::hash64; - }; - template<> - struct hash { - [[nodiscard]] - constexpr auto operator()(const stormkit::gpu::Subpass::Ref&) const noexcept -> stormkit::hash64; - }; - template<> - struct hash { - [[nodiscard]] - constexpr auto operator()(const stormkit::gpu::Subpass&) const noexcept -> stormkit::hash64; - }; - template<> - struct hash { - [[nodiscard]] - constexpr auto operator()(const stormkit::gpu::RenderPassDescription&) const noexcept -> stormkit::hash64; - }; - } // namespace std -} + template + constexpr auto hasher(const AttachmentDescription& value) noexcept -> Ret; + template + constexpr auto hasher(const Subpass::Ref& value) noexcept -> Ret; + template + constexpr auto hasher(const Subpass& value) noexcept -> Ret; + template + constexpr auto hasher(const RenderPassDescription& value) noexcept -> Ret; +} // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// /// IMPLEMENTATION /// @@ -376,45 +358,47 @@ namespace stormkit::gpu { inline auto RenderPass::native_handle() const noexcept -> VkRenderPass { return m_vk_handle; } -} // namespace stormkit::gpu -constexpr auto std::hash::operator()(const stormkit::gpu::AttachmentDescription& value) - const noexcept -> stormkit::hash64 { - auto hash = stormkit::hash64 { 0 }; - stormkit::hash_combine(hash, - value.format, - value.samples, - value.load_op, - value.store_op, - value.stencil_load_op, - value.stencil_store_op, - value.source_layout, - value.destination_layout, - value.resolve); - return hash; -} - -constexpr auto std::hash::operator()(const stormkit::gpu::Subpass::Ref& value) const noexcept - -> stormkit::hash64 { - auto hash = stormkit::hash64 { 0 }; - stormkit::hash_combine(hash, value.attachment_id, value.layout); - return hash; -} - -constexpr auto std::hash::operator()(const stormkit::gpu::Subpass& value) const noexcept - -> stormkit::hash64 { - auto hash = stormkit::hash64 { 0 }; - stormkit::hash_combine(hash, - value.bind_point, - value.color_attachment_refs, - value.depth_attachment_ref, - value.resolve_attachment_refs); - return hash; -} - -constexpr auto std::hash::operator()(const stormkit::gpu::RenderPassDescription& value) - const noexcept -> stormkit::hash64 { - auto hash = stormkit::hash64 { 0 }; - stormkit::hash_combine(hash, value.attachments, value.subpasses); - return hash; -} + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto hasher(const AttachmentDescription& value) noexcept -> Ret { + return hash(value.format, + value.samples, + value.load_op, + value.store_op, + value.stencil_load_op, + value.stencil_store_op, + value.source_layout, + value.destination_layout, + value.resolve); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto hasher(const Subpass::Ref& value) noexcept -> Ret { + return hash(value.attachment_id, value.layout); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto hasher(const Subpass& value) noexcept -> Ret { + return hash(value.bind_point, + value.color_attachment_refs, + value.depth_attachment_ref, + value.resolve_attachment_refs); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto hasher(const RenderPassDescription& value) noexcept -> Ret { + return hash(value.attachments, value.subpasses); + } +} // namespace stormkit::gpu From d887f7c203fd505ffc37c0a8f59397f82bdd9212 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 19:15:27 +0100 Subject: [PATCH 042/194] (core, wsi) update format_as implementation --- modules/stormkit/core/math/linear-vector.mpp | 12 ++-- modules/stormkit/core/string/format.mpp | 40 ++++++------- modules/stormkit/core/typesafe/ref.mpp | 15 +++++ modules/stormkit/core/utils/handle.mpp | 62 +++++++++----------- modules/stormkit/wsi/monitor.mpp | 17 +++--- 5 files changed, 76 insertions(+), 70 deletions(-) diff --git a/modules/stormkit/core/math/linear-vector.mpp b/modules/stormkit/core/math/linear-vector.mpp index e1a2990e4..19ab9164b 100644 --- a/modules/stormkit/core/math/linear-vector.mpp +++ b/modules/stormkit/core/math/linear-vector.mpp @@ -177,13 +177,13 @@ export namespace stormkit { inline namespace core { namespace math { constexpr auto hasher(const vec4& value) noexcept -> Ret; template - auto format_as(const vec2& value, FormatContext& ctx) noexcept -> decltype(ctx.out); + auto format_as(const vec2& value, FormatContext& ctx) noexcept -> decltype(ctx.out()); template - auto format_as(const vec3& value, FormatContext& ctx) noexcept -> decltype(ctx.out); + auto format_as(const vec3& value, FormatContext& ctx) noexcept -> decltype(ctx.out()); template - auto format_as(const vec4& value, FormatContext& ctx) noexcept -> decltype(ctx.out); + auto format_as(const vec4& value, FormatContext& ctx) noexcept -> decltype(ctx.out()); }}} // namespace stormkit::core::math //////////////////////////////////////////////////////////////////// @@ -399,7 +399,7 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto format_as(const vec2& value, FormatContext& ctx) noexcept -> decltype(ctx.out) { + inline auto format_as(const vec2& value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { return std::format_to(ctx.out(), "[vec2 x: {}, y: {}]", value.x, value.y); } @@ -407,7 +407,7 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto format_as(const vec3& value, FormatContext& ctx) noexcept -> decltype(ctx.out) { + inline auto format_as(const vec3& value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { return std::format_to(ctx.out(), "[vec2 x: {}, y: {}, z: {}]", value.x, value.y, value.z); } @@ -415,7 +415,7 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto format_as(const vec4& value, FormatContext& ctx) noexcept -> decltype(ctx.out) { + inline auto format_as(const vec4& value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { return std::format_to(ctx.out(), "[vec2 x: {}, y: {}, z: {}, w: {}]", value.x, value.y, value.z, value.w); } }}} // namespace stormkit::core::math diff --git a/modules/stormkit/core/string/format.mpp b/modules/stormkit/core/string/format.mpp index c25809b16..cab1de3f9 100644 --- a/modules/stormkit/core/string/format.mpp +++ b/modules/stormkit/core/string/format.mpp @@ -19,7 +19,7 @@ import :string.operations; export { namespace stormkit { inline namespace core { template - auto format_as(const T&, FormatContext&) noexcept -> FormatContext::iterator = delete; + auto format_as(const T&, FormatContext& ctx) noexcept -> decltype(ctx.out()) = delete; namespace meta { template @@ -36,59 +36,59 @@ export { inline constexpr struct FormatFN { template - static constexpr auto operator()(const T& value, FormatContext& ctx) noexcept -> FormatContext::iterator { + static constexpr auto operator()(const T& value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { return format_as(value, ctx); } } format_fn = {}; template - auto format_as(std::byte, FormatContext&) noexcept -> FormatContext::iterator; + auto format_as(std::byte, FormatContext& ctx) noexcept -> decltype(ctx.out()); template - auto format_as(stormkit::Secondf, FormatContext&) noexcept -> FormatContext::iterator; + auto format_as(stormkit::Secondf, FormatContext& ctx) noexcept -> decltype(ctx.out()); }} // namespace stormkit::core template struct std::formatter { template [[nodiscard]] - constexpr auto parse(ParseContext&) noexcept -> ParseContext::iterator; + constexpr auto parse(ParseContext& ctx) noexcept -> decltype(ctx.begin()); template [[nodiscard]] - auto format(const T&, FormatContext&) const noexcept -> FormatContext::iterator; + auto format(const T&, FormatContext& ctx) const noexcept -> decltype(ctx.out()); }; template struct std::formatter { template [[nodiscard]] - constexpr auto parse(ParseContext&) noexcept -> ParseContext::iterator; + constexpr auto parse(ParseContext& ctx) noexcept -> decltype(ctx.begin()); template [[nodiscard]] - auto format(const T&, FormatContext&) const -> FormatContext::iterator; + auto format(const T&, FormatContext& ctx) const -> decltype(ctx.out()); }; template struct std::formatter: public formatter { template [[nodiscard]] - auto format(const T&, FormatContext&) const -> FormatContext::iterator; + auto format(const T&, FormatContext& ctx) const -> decltype(ctx.out()); }; template struct std::formatter: public formatter, CharT> { template [[nodiscard]] - auto format(const std::error_code&, FormatContext&) const -> FormatContext::iterator; + auto format(const std::error_code&, FormatContext& ctx) const -> decltype(ctx.out()); }; template struct std::formatter: public formatter, CharT> { template [[nodiscard]] - auto format(const std::errc& code, FormatContext& ctx) const -> FormatContext::iterator; + auto format(const std::errc& code, FormatContext& ctx) const -> decltype(ctx.out()); }; } @@ -101,7 +101,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto format_as(std::byte value, FormatContext& ctx) noexcept -> FormatContext::iterator { + inline auto format_as(std::byte value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { auto&& out = ctx.out(); return std::format_to(out, "{}", narrow(value)); } @@ -110,7 +110,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto format_as(Secondf value, FormatContext& ctx) noexcept -> FormatContext::iterator { + inline auto format_as(Secondf value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { auto&& out = ctx.out(); return std::format_to(out, "{}", value.count()); } @@ -122,7 +122,7 @@ using namespace stormkit; ///////////////////////////////////// template template -constexpr auto std::formatter::parse(ParseContext& ctx) noexcept -> ParseContext::iterator { +constexpr auto std::formatter::parse(ParseContext& ctx) noexcept -> decltype(ctx.begin()) { return ctx.begin(); } @@ -130,7 +130,7 @@ constexpr auto std::formatter::parse(ParseContext& ctx) noexcept -> Pa ///////////////////////////////////// template template -auto std::formatter::format(const T& value, FormatContext& ctx) const noexcept -> FormatContext::iterator { +auto std::formatter::format(const T& value, FormatContext& ctx) const noexcept -> decltype(ctx.out()) { return core::format_fn(value, ctx); } @@ -138,7 +138,7 @@ auto std::formatter::format(const T& value, FormatContext& ctx) const ///////////////////////////////////// template template -constexpr auto std::formatter::parse(ParseContext& ctx) noexcept -> ParseContext::iterator { +constexpr auto std::formatter::parse(ParseContext& ctx) noexcept -> decltype(ctx.begin()) { return ctx.begin(); } @@ -146,7 +146,7 @@ constexpr auto std::formatter::parse(ParseContext& ctx) noexcept -> Pa ///////////////////////////////////// template template -auto std::formatter::format(const T& value, FormatContext& ctx) const -> FormatContext::iterator { +auto std::formatter::format(const T& value, FormatContext& ctx) const -> decltype(ctx.out()) { auto&& out = ctx.out(); if constexpr (requires { { as_string(value) } -> meta::Is; @@ -161,7 +161,7 @@ auto std::formatter::format(const T& value, FormatContext& ctx) const ///////////////////////////////////// template template -auto std::formatter::format(const T& value, FormatContext& ctx) const -> FormatContext::iterator { +auto std::formatter::format(const T& value, FormatContext& ctx) const -> decltype(ctx.out()) { auto&& out = ctx.out(); return format_to(out, "{:#0x}", std::bit_cast(std::to_address(value))); } @@ -171,7 +171,7 @@ auto std::formatter::format(const T& value, FormatContext& ctx) const template template auto std::formatter::format(const std::error_code& code, FormatContext& ctx) const - -> FormatContext::iterator { + -> decltype(ctx.out()) { auto&& out = ctx.out(); const auto message = code.message(); return format_to(out, "{}", message); @@ -181,7 +181,7 @@ auto std::formatter::format(const std::error_code& code, ///////////////////////////////////// template template -auto std::formatter::format(const std::errc& code, FormatContext& ctx) const -> FormatContext::iterator { +auto std::formatter::format(const std::errc& code, FormatContext& ctx) const -> decltype(ctx.out()) { auto&& out = ctx.out(); const auto message = make_error_code(code).message(); return format_to(out, "{}", message); diff --git a/modules/stormkit/core/typesafe/ref.mpp b/modules/stormkit/core/typesafe/ref.mpp index 69f80a65a..7d1129286 100644 --- a/modules/stormkit/core/typesafe/ref.mpp +++ b/modules/stormkit/core/typesafe/ref.mpp @@ -261,6 +261,9 @@ export { template constexpr auto hasher(const Ref& value) noexcept -> Ret; + + template + auto format_as(const Ref& value, FormatContext& ctx) noexcept -> decltype(ctx.out()); }} // namespace stormkit::core template @@ -860,4 +863,16 @@ namespace stormkit { inline namespace core { constexpr auto hasher(const Ref& value) noexcept -> Ret { return hash(value.get()); } + + ///////////////////////////////////// + ///////////////////////////////////// + template + inline auto format_as(const Ref& value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { + if constexpr (Optional) { + if (value == nullptr) return std::format_to(ctx.out(), "[ref value: null]"); + else + return std::format_to(ctx.out(), "[ref value: {}]", *value); + } else + return std::format_to(ctx.out(), "[ref value: {}]", *value); + } }} // namespace stormkit::core diff --git a/modules/stormkit/core/utils/handle.mpp b/modules/stormkit/core/utils/handle.mpp index 6c9b170d3..de8c988b6 100644 --- a/modules/stormkit/core/utils/handle.mpp +++ b/modules/stormkit/core/utils/handle.mpp @@ -17,55 +17,47 @@ import :typesafe.safecasts; import :typesafe.integer; import :meta; -export { - namespace stormkit { inline namespace core { - template - struct Handle { - using ID = _ID; - - static constexpr auto INVALID_HANDLE_VALUE = std::numeric_limits::max(); +export namespace stormkit { inline namespace core { + template + struct Handle { + using ID = _ID; - [[nodiscard]] - constexpr auto operator<=>(const Handle&) const noexcept -> std::strong_ordering = default; + static constexpr auto INVALID_HANDLE_VALUE = std::numeric_limits::max(); - template U> - constexpr operator Handle() const noexcept; + [[nodiscard]] + constexpr auto operator<=>(const Handle&) const noexcept -> std::strong_ordering = default; - constexpr auto& operator++() noexcept; + template U> + constexpr operator Handle() const noexcept; - constexpr auto operator++(int) noexcept; + constexpr auto& operator++() noexcept; - constexpr auto& operator--() noexcept; + constexpr auto operator++(int) noexcept; - constexpr auto operator--(int) noexcept; + constexpr auto& operator--() noexcept; - constexpr operator ID() const noexcept; + constexpr auto operator--(int) noexcept; - [[nodiscard]] - static constexpr auto invalid_handle() noexcept -> Handle; + constexpr operator ID() const noexcept; - ID id = INVALID_HANDLE_VALUE; - }; + [[nodiscard]] + static constexpr auto invalid_handle() noexcept -> Handle; - template - using Handle32 = Handle; + ID id = INVALID_HANDLE_VALUE; + }; - template - using Handle64 = Handle; + template + using Handle32 = Handle; - template - constexpr auto hasher(const Handle& value) noexcept -> Ret; + template + using Handle64 = Handle; - template - auto format_as(const Handle& value, FormatContext& ctx) noexcept -> decltype(ctx.out()); - }} // namespace stormkit::core + template + constexpr auto hasher(const Handle& value) noexcept -> Ret; - template - struct std::hash> { - [[nodiscard]] - constexpr auto operator()(stormkit::core::Handle handle) const noexcept -> stormkit::core::hash64; - }; -} + template + auto format_as(const Handle& value, FormatContext& ctx) noexcept -> decltype(ctx.out()); +}} // namespace stormkit::core //////////////////////////////////////////////////////////////////// /// IMPLEMENTATION /// diff --git a/modules/stormkit/wsi/monitor.mpp b/modules/stormkit/wsi/monitor.mpp index fb9ad379b..cc21a5907 100644 --- a/modules/stormkit/wsi/monitor.mpp +++ b/modules/stormkit/wsi/monitor.mpp @@ -36,7 +36,7 @@ export { constexpr auto as_string(Monitor::Flags flags) noexcept -> std::string_view; template - auto format_as(const Monitor&, FormatContext&) noexcept -> FormatContext::iterator; + auto format_as(const Monitor& monitor, FormatContext& ctx) noexcept -> decltype(ctx.out()); [[nodiscard]] STORMKIT_API @@ -98,13 +98,12 @@ namespace stormkit::wsi { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto format_as(const Monitor& monitor, FormatContext& ctx) noexcept -> FormatContext::iterator { - auto&& out = ctx.out(); - return format_to(out, - "{{ Monitor: .name = {}, .flags = {}, .extents = {}, .scale_factor = {} }}", - monitor.name, - monitor.flags, - monitor.extents, - monitor.scale_factor); + inline auto format_as(const Monitor& monitor, FormatContext& ctx) noexcept -> decltype(ctx.out()) { + return std::format_to(ctx.out(), + "{{ Monitor: .name = {}, .flags = {}, .extents = {}, .scale_factor = {} }}", + monitor.name, + monitor.flags, + monitor.extents, + monitor.scale_factor); } } // namespace stormkit::wsi From c186c8d6daea0bd12bc5f82d0c6ece3e32d7a9af Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 19:19:22 +0100 Subject: [PATCH 043/194] (core, gpu, image, wsi) update extent naming --- examples/entities/gameoflife/src/App.cpp | 2 +- examples/entities/gameoflife/src/Renderer.cpp | 6 +- examples/gpu/textured_cube/src/main.cpp | 10 +- examples/wsi/events/src/main.cpp | 2 +- examples/wsi/framebuffer/src/main.cpp | 2 +- modules/stormkit/core/math/extent.mpp | 212 +++++++-------- modules/stormkit/core/math/geometry.mpp | 4 +- modules/stormkit/gpu/core/structs.mpp | 14 +- modules/stormkit/gpu/core/vulkan/structs.mpp | 24 +- .../stormkit/gpu/execution/command_buffer.mpp | 18 +- .../stormkit/gpu/execution/descriptors.mpp | 246 ++++++++---------- .../stormkit/gpu/execution/render_pass.mpp | 215 ++++++++------- modules/stormkit/gpu/execution/swapchain.mpp | 12 +- modules/stormkit/gpu/resource/image.mpp | 8 +- modules/stormkit/image.mpp | 12 +- modules/stormkit/luau/core.mpp | 8 +- modules/stormkit/wsi/lua.mpp | 2 +- modules/stormkit/wsi/monitor.mpp | 2 +- modules/stormkit/wsi/window.mpp | 10 +- src/gpu/core/physical_device.cpp | 214 +++++++-------- src/gpu/execution/command_buffer.cpp | 2 +- src/gpu/execution/swapchain.cpp | 12 +- src/image/image.cpp | 6 +- src/image/jpg.mpp | 2 +- src/image/ktx.mpp | 2 +- src/image/png.mpp | 2 +- src/image/qoi.mpp | 2 +- src/wsi/common/window_base.mpp | 10 +- src/wsi/ios/window_impl.hpp | 2 +- src/wsi/linux/wayland/window.cpp | 4 +- src/wsi/linux/wayland/window.mpp | 6 +- src/wsi/linux/window.mpp | 12 +- src/wsi/linux/x11/monitor.mpp | 4 +- src/wsi/linux/x11/window.cpp | 6 +- src/wsi/linux/x11/window.mpp | 4 +- src/wsi/macos/swift/CppBridge.cpp | 2 +- src/wsi/macos/window.mpp | 4 +- src/wsi/win32/window.cpp | 6 +- src/wsi/win32/window.mpp | 14 +- src/wsi/window.cpp | 6 +- 40 files changed, 544 insertions(+), 587 deletions(-) diff --git a/examples/entities/gameoflife/src/App.cpp b/examples/entities/gameoflife/src/App.cpp index 97f47c4b6..dcc595646 100644 --- a/examples/entities/gameoflife/src/App.cpp +++ b/examples/entities/gameoflife/src/App.cpp @@ -83,7 +83,7 @@ auto App::run([[maybe_unused]] const int argc, [[maybe_unused]] CZString argv[]) auto App::do_initWindow() -> void { const auto window_style = wsi::WindowStyle::ALL; - m_window = allocate(WINDOW_TITLE, math::ExtentU { 800u, 600u }, window_style); + m_window = allocate(WINDOW_TITLE, math::uextent2 { 800u, 600u }, window_style); m_renderer = allocate(*m_window); } diff --git a/examples/entities/gameoflife/src/Renderer.cpp b/examples/entities/gameoflife/src/Renderer.cpp index 27b849145..c2f88aa74 100644 --- a/examples/entities/gameoflife/src/Renderer.cpp +++ b/examples/entities/gameoflife/src/Renderer.cpp @@ -28,7 +28,7 @@ auto Renderer::operator=(Renderer&&) noexcept -> Renderer& = default; auto Renderer::renderFrame() -> void { const auto& surface_extent = m_surface->extent(); - const auto surface_extentf = math::ExtentF { surface_extent }; + const auto surface_extentf = math::fextent2 { surface_extent }; if (m_surface->needRecreate()) { m_surface->recreate(); @@ -136,7 +136,7 @@ auto Renderer::do_initBaseRenderObjects() -> void { auto Renderer::do_initMeshRenderObjects() -> void { const auto& surface_extent = m_surface->extent(); - const auto surface_extentf = math::ExtentF { surface_extent }; + const auto surface_extentf = math::fextent2 { surface_extent }; m_board.vertex_shader = m_device->allocateShader(SHADER_DATA, gpu::ShaderStageFlag::Vertex); m_board.fragment_shader = m_device->allocateShader(SHADER_DATA, gpu::ShaderStageFlag::Fragment); @@ -212,7 +212,7 @@ auto Renderer::do_initMeshRenderObjects() -> void { auto Renderer::do_initPerFrameObjects() -> void { const auto& surface_extent = m_surface->extent(); - const auto surface_extentf = math::ExtentF { surface_extent }; + const auto surface_extentf = math::fextent2 { surface_extent }; const auto buffering_count = m_surface->bufferingCount(); m_surface_views.clear(); diff --git a/examples/gpu/textured_cube/src/main.cpp b/examples/gpu/textured_cube/src/main.cpp index e8bbf99e1..fe2356c22 100644 --- a/examples/gpu/textured_cube/src/main.cpp +++ b/examples/gpu/textured_cube/src/main.cpp @@ -426,7 +426,10 @@ class Application: public base::Application { const auto window_extent = m_window->extent(); const auto window_extent_f32 = window_extent.to(); auto viewer_data = ViewerData { - .proj = math::perspective(math::radians(45.f), window_extent_f32.width / window_extent_f32.height, 0.1f, 100.f), + .proj = math::perspective(math::angle::radians(45.f), + window_extent_f32.width / window_extent_f32.height, + 0.1f, + 100.f), .view = math::look_at(math::vec3f { 0.f, 3.f, 5.f }, { 0.f, 0.f, 0.f }, { 0.f, 1.f, 0.f }), .model = math::mat4f::identity(), }; @@ -447,8 +450,9 @@ class Application: public base::Application { const auto& signal = swapchain_image_resource.render_finished; // update viewer data and upload - const auto time = stdc::duration_cast(current_time - m_start_time).count(); - viewer_data.model = math::rotate(math::mat4f::identity(), time * math::radians(90.f), math::vec3f { 0.f, 1.f, 0.f }); + const auto time = stdc::duration_cast(current_time - m_start_time).count(); + viewer_data + .model = math::rotate(math::mat4f::identity(), time * math::angle::radians(90.f), math::vec3f { 0.f, 1.f, 0.f }); auto& viewer_buffer = submission_resource.viewer_buffer; TryAssert(viewer_buffer.upload(viewer_data), "Failed to upload texture to gpu"); diff --git a/examples/wsi/events/src/main.cpp b/examples/wsi/events/src/main.cpp index 1557b1191..ef6c316d8 100644 --- a/examples/wsi/events/src/main.cpp +++ b/examples/wsi/events/src/main.cpp @@ -41,7 +41,7 @@ auto main(std::span args) -> int { auto foo = 0; window - .on(wsi::ResizedEventFunc { [](const math::Extent2& extent) static noexcept { ilog("Resize event: {}", extent); } }, + .on(wsi::ResizedEventFunc { [](const math::uextent2& extent) static noexcept { ilog("Resize event: {}", extent); } }, wsi::MonitorChangedEventFunc { [](const wsi::Monitor& monitor) noexcept { ilog("Monitor changed event: {}", monitor); } }, diff --git a/examples/wsi/framebuffer/src/main.cpp b/examples/wsi/framebuffer/src/main.cpp index 92ddd0487..06defffe9 100644 --- a/examples/wsi/framebuffer/src/main.cpp +++ b/examples/wsi/framebuffer/src/main.cpp @@ -68,7 +68,7 @@ auto main(std::span args) -> int { auto pixels = std::vector> {}; update_pixels(pool, pixels, window.extent()); auto active = true; - window.on(wsi::ResizedEventFunc { [&](const math::Extent2& extent) mutable noexcept { + window.on(wsi::ResizedEventFunc { [&](const math::uextent2& extent) mutable noexcept { update_pixels(pool, pixels, extent); window.fill_framebuffer(pixels); } }, diff --git a/modules/stormkit/core/math/extent.mpp b/modules/stormkit/core/math/extent.mpp index 73c2efebf..3340564be 100644 --- a/modules/stormkit/core/math/extent.mpp +++ b/modules/stormkit/core/math/extent.mpp @@ -23,22 +23,22 @@ namespace stdr = std::ranges; export { namespace stormkit { inline namespace core { namespace math { template - struct Extent; + struct extent; template - struct alignas(std::array) Extent { + struct alignas(std::array) extent { static constexpr auto RANK = 2uz; using ElementType = T; using OrderingType = meta::ArithmeticOrderingType; template - constexpr auto narrow_to() const noexcept -> Extent; + constexpr auto narrow_to() const noexcept -> extent; template - constexpr auto to(const std::source_location& = std::source_location::current()) const noexcept -> Extent; + constexpr auto to(const std::source_location& = std::source_location::current()) const noexcept -> extent; template - constexpr auto to() const noexcept -> Extent; + constexpr auto to() const noexcept -> extent; /// @brief The extent width ElementType width = 0; @@ -48,22 +48,26 @@ export { }; template - using Extent2 = Extent; + using extent2 = extent; + + using fextent2 = extent2; + using uextent2 = extent2; + using iextent2 = extent2; template - struct alignas(std::array) Extent { + struct alignas(std::array) extent { static constexpr auto RANK = 3uz; using ElementType = T; using OrderingType = meta::ArithmeticOrderingType; template - constexpr auto narrow_to() const noexcept -> Extent; + constexpr auto narrow_to() const noexcept -> extent; template - constexpr auto to(const std::source_location& = std::source_location::current()) const noexcept -> Extent; + constexpr auto to(const std::source_location& = std::source_location::current()) const noexcept -> extent; template - constexpr auto to() const noexcept -> Extent; + constexpr auto to() const noexcept -> extent; /// @brief The extent width ElementType width = 0; @@ -76,13 +80,17 @@ export { }; template - using Extent3 = Extent; + using extent3 = extent; + + using fextent3 = extent3; + using uextent3 = extent3; + using iextent3 = extent3; template - Extent(T, T) -> Extent; + extent(T, T) -> extent; template - Extent(T, T, T) -> Extent; + extent(T, T, T) -> extent; namespace meta { template @@ -121,7 +129,7 @@ export { /// `factor` template [[nodiscard]] - constexpr auto operator*(Extent&& event, typename Extent::ElemenType factor) noexcept + constexpr auto operator*(Extent&& extent, typename Extent::ElemenType factor) noexcept -> core::meta::CanonicalType; /// @brief Divide an extent with a factor. @@ -129,7 +137,7 @@ export { /// @returns A newly constructed extent equal to this extent Divided with `factor` template [[nodiscard]] - constexpr auto operator/(Extent&& event, typename Extent::ElemenType factor) noexcept + constexpr auto operator/(Extent&& extent, typename Extent::ElemenType factor) noexcept -> core::meta::CanonicalType; /// @brief Multiply this extent with a factor. @@ -148,29 +156,19 @@ export { template auto to_string(Extent&& extent) noexcept -> std::string; - }}} // namespace stormkit::core::math - template - struct std::formatter>: std::formatter { - template - auto format(const math::Extent& extent, FormatContext& ctx) const noexcept -> decltype(ctx.out()); - }; - - template - struct std::formatter>: std::formatter { - template - auto format(const math::Extent& extent, FormatContext& ctx) const noexcept -> decltype(ctx.out()); - }; - - template - struct std::hash> { - static constexpr auto operator()(const math::Extent& extent) noexcept; - }; - - template - struct std::hash> { - static constexpr auto operator()(const math::Extent& extent) noexcept; - }; + template + auto format_as(const extent& extent, FormatContext& ctx) noexcept -> decltype(ctx.out()); + + template + auto format_as(const extent& extent, FormatContext& ctx) noexcept -> decltype(ctx.out()); + + template + constexpr auto hasher(const extent& extent) noexcept -> Ret; + + template + constexpr auto hasher(const extent& extent) noexcept -> Ret; + }}} // namespace stormkit::core::math } //////////////////////////////////////////////////////////////////// @@ -183,7 +181,7 @@ namespace stormkit { inline namespace core { namespace math { template template STORMKIT_PURE - constexpr auto Extent::narrow_to() const noexcept -> Extent { + constexpr auto extent::narrow_to() const noexcept -> extent { return { .width = narrow(width), .height = narrow(height) }; } @@ -192,7 +190,7 @@ namespace stormkit { inline namespace core { namespace math { template template STORMKIT_PURE - constexpr auto Extent::to(const std::source_location& location) const noexcept -> Extent { + constexpr auto extent::to(const std::source_location& location) const noexcept -> extent { return { .width = as(width, location), .height = as(height, location) }; } @@ -201,8 +199,8 @@ namespace stormkit { inline namespace core { namespace math { template template STORMKIT_PURE - constexpr auto Extent::to() const noexcept -> Extent { - using Out = Extent; + constexpr auto extent::to() const noexcept -> extent { + using Out = extent; using Array = std::array; using OtherArray = std::array; @@ -224,7 +222,7 @@ namespace stormkit { inline namespace core { namespace math { template template STORMKIT_PURE - constexpr auto Extent::narrow_to() const noexcept -> Extent { + constexpr auto extent::narrow_to() const noexcept -> extent { return { .width = narrow(width), .height = narrow(height), .depth = narrow(depth) }; } @@ -233,7 +231,7 @@ namespace stormkit { inline namespace core { namespace math { template template STORMKIT_PURE - constexpr auto Extent::to(const std::source_location& location) const noexcept -> Extent { + constexpr auto extent::to(const std::source_location& location) const noexcept -> extent { return { .width = as(width, location), .height = as(height, location), .depth = as(depth, location) }; } @@ -242,8 +240,8 @@ namespace stormkit { inline namespace core { namespace math { template template STORMKIT_PURE - constexpr auto Extent::to() const noexcept -> Extent { - using Out = Extent; + constexpr auto extent::to() const noexcept -> extent { + using Out = extent; using Array = std::array; using OtherArray = std::array; @@ -299,16 +297,16 @@ namespace stormkit { inline namespace core { namespace math { ///////////////////////////////////// template STORMKIT_PURE - constexpr auto operator*(Extent&& event, typename Extent::ElemenType factor) noexcept -> core::meta::CanonicalType { - return core::meta::CanonicalType { std::forward(event) } *= factor; + constexpr auto operator*(Extent&& extent, typename Extent::ElemenType factor) noexcept -> core::meta::CanonicalType { + return core::meta::CanonicalType { std::forward(extent) } *= factor; } ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_PURE - constexpr auto operator/(Extent&& event, typename Extent::ElemenType factor) noexcept -> core::meta::CanonicalType { - return core::meta::CanonicalType { std::forward(event) } /= factor; + constexpr auto operator/(Extent&& extent, typename Extent::ElemenType factor) noexcept -> core::meta::CanonicalType { + return core::meta::CanonicalType { std::forward(extent) } /= factor; } ///////////////////////////////////// @@ -338,89 +336,71 @@ namespace stormkit { inline namespace core { namespace math { ///////////////////////////////////// ///////////////////////////////////// template - auto to_string(Extent&& extent) noexcept -> std::string { + STORMKIT_FORCE_INLINE + inline auto to_string(Extent&& extent) noexcept -> std::string { return std::format("{}", extent); } ///////////////////////////////////// ///////////////////////////////////// template - auto to_string(Extent&& extent) noexcept -> std::string { + STORMKIT_FORCE_INLINE + inline auto to_string(Extent&& extent) noexcept -> std::string { return std::format("{}", extent); } -}}} // namespace stormkit::core::math -///////////////////////////////////// -///////////////////////////////////// -template -template -auto std::formatter>::format(const math::Extent& extent, FormatContext& ctx) const noexcept - -> decltype(ctx.out()) { - auto&& out = ctx.out(); - format_to(out, "{{ .width = "); - formatter::format(extent.width, ctx); - format_to(out, ", .height = "); - formatter::format(extent.height, ctx); - return format_to(out, " }}"); -} + ///////////////////////////////////// + ///////////////////////////////////// + template + inline auto format_as(const extent& extent, FormatContext& ctx) noexcept -> decltype(ctx.out()) { + return format_to(ctx.out(), "[extent2 width: {}, height: {}]", extent.width, extent.height); + } -///////////////////////////////////// -///////////////////////////////////// -template -template -auto std::formatter>::format(const math::Extent& extent, FormatContext& ctx) const noexcept - -> decltype(ctx.out()) { - auto&& out = ctx.out(); - format_to(out, "{{ .width = "); - formatter::format(extent.width, ctx); - format_to(out, ", .height = "); - formatter::format(extent.height, ctx); - format_to(out, ", .depth = "); - formatter::format(extent.depth, ctx); - return format_to(out, " }}"); -} + ///////////////////////////////////// + ///////////////////////////////////// + template + inline auto format_as(const extent& extent, FormatContext& ctx) noexcept -> decltype(ctx.out()) { + return format_to(ctx.out(), "[extent3 width: {}, height: {}, depth: {}]", extent.width, extent.height, extent.depth); + } -///////////////////////////////////// -///////////////////////////////////// -template -constexpr auto std::hash>::operator()(const math::Extent& extent) noexcept { - auto hash = hash64 { 0 }; - hash_combine(hash, extent.width, extent.height); - return hash; -} + ///////////////////////////////////// + ///////////////////////////////////// + template + constexpr auto hasher(const extent& extent) noexcept -> Ret { + return hash(extent.width, extent.height); + } -///////////////////////////////////// -///////////////////////////////////// -template -constexpr auto std::hash>::operator()(const math::Extent& extent) noexcept { - auto hash = hash64 { 0 }; - hash_combine(hash, extent.width, extent.height, extent.depth); - return hash; -} + ///////////////////////////////////// + ///////////////////////////////////// + template + constexpr auto hasher(const extent& extent) noexcept -> Ret { + return hash(extent.width, extent.height, extent.depth); + } +}}} // namespace stormkit::core::math -static_assert(sizeof(math::Extent2) == sizeof(std::array)); -static_assert(sizeof(math::Extent3) == sizeof(std::array)); +static_assert(sizeof(math::uextent2) == sizeof(std::array)); +static_assert(sizeof(math::uextent3) == sizeof(std::array)); -static_assert(sizeof(math::Extent2) == sizeof(std::array)); -static_assert(sizeof(math::Extent3) == sizeof(std::array)); +static_assert(sizeof(math::iextent2) == sizeof(std::array)); +static_assert(sizeof(math::extent3_i) == sizeof(std::array)); -static_assert(sizeof(math::Extent2) == sizeof(std::array)); -static_assert(sizeof(math::Extent3) == sizeof(std::array)); +static_assert(sizeof(math::extent2) == sizeof(std::array)); +static_assert(sizeof(math::extent3) == sizeof(std::array)); -static_assert(sizeof(math::Extent2) == sizeof(std::array)); -static_assert(sizeof(math::Extent3) == sizeof(std::array)); +static_assert(sizeof(math::extent2) == sizeof(std::array)); +static_assert(sizeof(math::extent3) == sizeof(std::array)); -static_assert(sizeof(math::Extent2) == sizeof(std::array)); -static_assert(sizeof(math::Extent3) == sizeof(std::array)); +static_assert(sizeof(math::fextent2) == sizeof(std::array)); +static_assert(sizeof(math::fextent3) == sizeof(std::array)); -static_assert(math::Extent2::RANK == 2); -static_assert(math::Extent3::RANK == 3); -static_assert(math::Extent3::RANK != 2); -static_assert(math::Extent2::RANK != 3); +static_assert(math::fextent2::RANK == 2); +static_assert(math::fextent3::RANK == 3); +static_assert(math::fextent3::RANK != 2); +static_assert(math::fextent2::RANK != 3); -static_assert(math::meta::IsExtent>); -static_assert(math::meta::IsExtent>); -static_assert(math::meta::IsExtent2>); -static_assert(not math::meta::IsExtent2>); -static_assert(math::meta::IsExtent3>); -static_assert(not math::meta::IsExtent3>); +static_assert(math::meta::IsExtent); +static_assert(math::meta::IsExtent); +static_assert(math::meta::IsExtent2); +static_assert(not math::meta::IsExtent2); +static_assert(math::meta::IsExtent3); +static_assert(not math::meta::IsExtent3); diff --git a/modules/stormkit/core/math/geometry.mpp b/modules/stormkit/core/math/geometry.mpp index 9327625d3..078f64f4e 100644 --- a/modules/stormkit/core/math/geometry.mpp +++ b/modules/stormkit/core/math/geometry.mpp @@ -26,7 +26,7 @@ export namespace stormkit { inline namespace core { namespace math { Positive height; constexpr auto position() const noexcept -> vec2; - constexpr auto extent() const noexcept -> Extent2; + constexpr auto extent() const noexcept -> extent2; template constexpr auto to() const noexcept -> rect; @@ -88,7 +88,7 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto rect::extent() const noexcept -> Extent2 { + constexpr auto rect::extent() const noexcept -> extent2 { return { width.value, height.value }; } diff --git a/modules/stormkit/gpu/core/structs.mpp b/modules/stormkit/gpu/core/structs.mpp index 55cc42c3d..c6e9451f7 100644 --- a/modules/stormkit/gpu/core/structs.mpp +++ b/modules/stormkit/gpu/core/structs.mpp @@ -225,13 +225,13 @@ export { struct Viewport { math::vec2f position; - math::Extent2 extent; + math::extent2 extent; math::vec2f depth; }; struct Scissor { math::vec2i offset; - math::Extent2 extent; + math::uextent2 extent; }; struct ClearColor { @@ -253,7 +253,7 @@ export { ImageSubresourceLayers subresource_layers; math::vec3i offset; - math::Extent3 extent; + math::uextent3 extent; }; struct BlitRegion { @@ -262,12 +262,12 @@ export { struct { math::vec3i position; - math::Extent3 extent; + math::iextent3 extent; } src_offset; struct { math::vec3i position; - math::Extent3 extent; + math::iextent3 extent; } dst_offset; }; @@ -308,7 +308,7 @@ export { using Expected = std::expected; [[nodiscard]] - constexpr auto compute_mip_level(const math::Extent2& extent) noexcept -> u32; + constexpr auto compute_mip_level(const math::uextent2& extent) noexcept -> u32; [[nodiscard]] constexpr auto compute_uniform_buffer_offset_align(usize size, const RenderCapabilities& capabilities) noexcept -> usize; @@ -331,7 +331,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto compute_mip_level(const math::Extent2& extent) noexcept -> u32 { + constexpr auto compute_mip_level(const math::uextent2& extent) noexcept -> u32 { const auto as_float = extent.to(); return as(math::floor(math::log2(math::max(as_float.width, as_float.height)))) + 1; } diff --git a/modules/stormkit/gpu/core/vulkan/structs.mpp b/modules/stormkit/gpu/core/vulkan/structs.mpp index ec77da84d..4ade52be5 100644 --- a/modules/stormkit/gpu/core/vulkan/structs.mpp +++ b/modules/stormkit/gpu/core/vulkan/structs.mpp @@ -65,13 +65,13 @@ export namespace stormkit::gpu { [[nodiscard]] constexpr auto to_vk(const Extent& extent) noexcept -> Out; - template> + template [[nodiscard]] - constexpr auto from_vk(const VkExtent2D& viewport) noexcept -> Extent; + constexpr auto from_vk(const VkExtent2D& viewport) noexcept -> Out; - template> + template [[nodiscard]] - constexpr auto from_vk(const VkExtent3D& viewport) noexcept -> Extent; + constexpr auto from_vk(const VkExtent3D& viewport) noexcept -> Out; } // namespace stormkit::gpu namespace stormkit::gpu { @@ -204,21 +204,21 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto from_vk(const VkExtent2D& extent) noexcept -> Extent { - using T = typename Extent::ElementType; - return Extent { .width = as(extent.width), .height = as(extent.height) }; + constexpr auto from_vk(const VkExtent2D& extent) noexcept -> Out { + using T = typename Out::ElementType; + return Out { .width = as(extent.width), .height = as(extent.height) }; } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto from_vk(const VkExtent3D& extent) noexcept -> Extent { - using T = typename Extent::ElementType; - return Extent { .width = as(extent.width), .height = as(extent.height) }; + constexpr auto from_vk(const VkExtent3D& extent) noexcept -> Out { + using T = typename Out::ElementType; + return Out { .width = as(extent.width), .height = as(extent.height) }; } } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/execution/command_buffer.mpp b/modules/stormkit/gpu/execution/command_buffer.mpp index bae657868..61a341c61 100644 --- a/modules/stormkit/gpu/execution/command_buffer.mpp +++ b/modules/stormkit/gpu/execution/command_buffer.mpp @@ -171,10 +171,10 @@ export namespace stormkit::gpu { auto bind_pipeline(const Pipeline& pipeline) noexcept -> CommandBuffer&; auto set_viewport(u32 first_viewport, std::span viewports) noexcept -> CommandBuffer&; auto set_scissor(u32 first_scissor, std::span scissors) noexcept -> CommandBuffer&; - auto set_line_width(float width) noexcept -> CommandBuffer&; - auto set_depth_bias(float constant_factor, float clamp, float slope_factor) noexcept -> CommandBuffer&; - auto set_blend_constants(std::span constants) noexcept -> CommandBuffer&; - auto set_depth_bounds(float min, float max) noexcept -> CommandBuffer&; + auto set_line_width(f32 width) noexcept -> CommandBuffer&; + auto set_depth_bias(f32 constant_factor, f32 clamp, f32 slope_factor) noexcept -> CommandBuffer&; + auto set_blend_constants(std::span constants) noexcept -> CommandBuffer&; + auto set_depth_bounds(f32 min, f32 max) noexcept -> CommandBuffer&; auto set_stencil_compare_mask(StencilFaceFlag face, u32 mask) noexcept -> CommandBuffer&; auto set_stencil_write_mask(StencilFaceFlag face, u32 mask) noexcept -> CommandBuffer&; auto set_stencil_reference(StencilFaceFlag face, u32 reference) noexcept -> CommandBuffer&; @@ -213,7 +213,7 @@ export namespace stormkit::gpu { ImageLayout dst_layout, const ImageSubresourceLayers& src_subresource_layers, const ImageSubresourceLayers& dst_subresource_layers, - const math::Extent3& extent) noexcept -> CommandBuffer&; + const math::uextent3& extent) noexcept -> CommandBuffer&; auto resolve_image(const Image& src, const Image& dst, @@ -626,7 +626,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::set_line_width(float width) noexcept -> CommandBuffer& { + inline auto CommandBuffer::set_line_width(f32 width) noexcept -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); vk_call(m_vk_device_table->vkCmdSetLineWidth, m_vk_handle, width); @@ -636,7 +636,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::set_depth_bias(float constant_factor, float clamp, float slope_factor) noexcept -> CommandBuffer& { + inline auto CommandBuffer::set_depth_bias(f32 constant_factor, f32 clamp, f32 slope_factor) noexcept -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); vk_call(m_vk_device_table->vkCmdSetDepthBias, m_vk_handle, constant_factor, clamp, slope_factor); @@ -646,7 +646,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::set_blend_constants(std::span constants) noexcept -> CommandBuffer& { + inline auto CommandBuffer::set_blend_constants(std::span constants) noexcept -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); f32 data[] = { constants[0], constants[1], constants[2], constants[3] }; @@ -658,7 +658,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::set_depth_bounds(float min, float max) noexcept -> CommandBuffer& { + inline auto CommandBuffer::set_depth_bounds(f32 min, f32 max) noexcept -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); vk_call(m_vk_device_table->vkCmdSetDepthBounds, m_vk_handle, min, max); diff --git a/modules/stormkit/gpu/execution/descriptors.mpp b/modules/stormkit/gpu/execution/descriptors.mpp index a138ee59e..129674cbc 100644 --- a/modules/stormkit/gpu/execution/descriptors.mpp +++ b/modules/stormkit/gpu/execution/descriptors.mpp @@ -20,174 +20,155 @@ import stormkit.gpu.resource; namespace stdr = std::ranges; namespace stdv = std::views; - struct BufferDescriptor { - DescriptorType type = DescriptorType::UNIFORM_BUFFER; - u32 binding; - Ref buffer; - u32 range; - u32 offset = 0; - }; export namespace stormkit::gpu { + struct BufferDescriptor { + DescriptorType type = DescriptorType::UNIFORM_BUFFER; + u32 binding; + Ref buffer; + u32 range; + u32 offset = 0; + }; - struct ImageDescriptor { - DescriptorType type = DescriptorType::COMBINED_IMAGE_SAMPLER; - u32 binding; - ImageLayout layout; - Ref image_view; - Ref sampler; - }; - - using Descriptor = std::variant; - class DescriptorPool; - - class STORMKIT_API DescriptorSet { - struct PrivateFuncTag {}; - - using Deleter = std::function; - - public: - static constexpr auto DEBUG_TYPE = DebugObjectType::DESCRIPTOR_SET; - - ~DescriptorSet() noexcept; + struct ImageDescriptor { + DescriptorType type = DescriptorType::COMBINED_IMAGE_SAMPLER; + u32 binding; + ImageLayout layout; + Ref image_view; + Ref sampler; + }; - DescriptorSet(const DescriptorSet&) = delete; - auto operator=(const DescriptorSet&) -> DescriptorSet& = delete; + using Descriptor = std::variant; + class DescriptorPool; - DescriptorSet(DescriptorSet&&) noexcept; - auto operator=(DescriptorSet&&) noexcept -> DescriptorSet&; + class STORMKIT_API DescriptorSet { + struct PrivateFuncTag {}; - auto update(std::span descriptors) -> void; + using Deleter = std::function; - [[nodiscard]] - auto types() const noexcept -> const std::vector&; + public: + static constexpr auto DEBUG_TYPE = DebugObjectType::DESCRIPTOR_SET; - [[nodiscard]] - auto native_handle() const noexcept -> VkDescriptorSet; + ~DescriptorSet() noexcept; - DescriptorSet(VkDevice, const VolkDeviceTable&, VkDescriptorSet&&, Deleter&&, PrivateFuncTag) noexcept; + DescriptorSet(const DescriptorSet&) = delete; + auto operator=(const DescriptorSet&) -> DescriptorSet& = delete; - private: - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; + DescriptorSet(DescriptorSet&&) noexcept; + auto operator=(DescriptorSet&&) noexcept -> DescriptorSet&; - VkDescriptorSet m_vk_handle; + auto update(std::span descriptors) -> void; - Deleter m_deleter; - friend class DescriptorPool; - }; + [[nodiscard]] + auto types() const noexcept -> const std::vector&; - struct DescriptorSetLayoutBinding { - u32 binding; - DescriptorType type; - ShaderStageFlag stages; - usize descriptor_count; - }; + [[nodiscard]] + auto native_handle() const noexcept -> VkDescriptorSet; - class STORMKIT_API DescriptorSetLayout { - struct PrivateFuncTag {}; + DescriptorSet(VkDevice, const VolkDeviceTable&, VkDescriptorSet&&, Deleter&&, PrivateFuncTag) noexcept; - public: - static constexpr auto DEBUG_TYPE = DebugObjectType::DESCRIPTOR_SET_LAYOUT; + private: + VkDevice m_vk_device = nullptr; + Ref m_vk_device_table; - static auto create(const Device& device, std::vector bindings) noexcept - -> Expected; - static auto allocate(const Device& device, std::vector bindings) noexcept - -> Expected>; - ~DescriptorSetLayout() noexcept; + VkDescriptorSet m_vk_handle; - DescriptorSetLayout(const DescriptorSetLayout&) = delete; - auto operator=(const DescriptorSetLayout&) -> DescriptorSetLayout& = delete; + Deleter m_deleter; + friend class DescriptorPool; + }; - DescriptorSetLayout(DescriptorSetLayout&&) noexcept; - auto operator=(DescriptorSetLayout&&) noexcept -> DescriptorSetLayout&; + struct DescriptorSetLayoutBinding { + u32 binding; + DescriptorType type; + ShaderStageFlag stages; + usize descriptor_count; + }; - [[nodiscard]] - auto hash() const noexcept -> hash64; - [[nodiscard]] - auto bindings() const noexcept -> const std::vector&; + class STORMKIT_API DescriptorSetLayout { + struct PrivateFuncTag {}; - [[nodiscard]] - auto native_handle() const noexcept -> VkDescriptorSetLayout; + public: + static constexpr auto DEBUG_TYPE = DebugObjectType::DESCRIPTOR_SET_LAYOUT; - [[nodiscard]] - auto operator==(const DescriptorSetLayout& second) const noexcept -> bool; + static auto create(const Device& device, std::vector bindings) noexcept + -> Expected; + static auto allocate(const Device& device, std::vector bindings) noexcept + -> Expected>; + ~DescriptorSetLayout() noexcept; - DescriptorSetLayout(const Device&, std::vector&&, PrivateFuncTag) noexcept; + DescriptorSetLayout(const DescriptorSetLayout&) = delete; + auto operator=(const DescriptorSetLayout&) -> DescriptorSetLayout& = delete; - private: - auto do_init() noexcept -> Expected; + DescriptorSetLayout(DescriptorSetLayout&&) noexcept; + auto operator=(DescriptorSetLayout&&) noexcept -> DescriptorSetLayout&; - std::vector m_bindings; + [[nodiscard]] + auto hash() const noexcept -> hash64; + [[nodiscard]] + auto bindings() const noexcept -> const std::vector&; - hash64 m_hash = 0; - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; - }; + [[nodiscard]] + auto native_handle() const noexcept -> VkDescriptorSetLayout; - class STORMKIT_API DescriptorPool { - struct PrivateFuncTag {}; + [[nodiscard]] + auto operator==(const DescriptorSetLayout& second) const noexcept -> bool; - public: - static constexpr auto DEBUG_TYPE = DebugObjectType::DESCRIPTOR_POOL; + DescriptorSetLayout(const Device&, std::vector&&, PrivateFuncTag) noexcept; - struct Size { - DescriptorType type; - u32 descriptor_count; - }; + private: + auto do_init() noexcept -> Expected; - static auto create(const Device& device, std::span sizes, u32 max_sets) noexcept - -> Expected; - static auto allocate(const Device& device, std::span sizes, u32 max_sets) noexcept - -> Expected>; - ~DescriptorPool() noexcept; + std::vector m_bindings; - DescriptorPool(const DescriptorPool&) = delete; - auto operator=(const DescriptorPool&) -> DescriptorPool& = delete; + hash64 m_hash = 0; + VkDevice m_vk_device = nullptr; + Ref m_vk_device_table; + VkRAIIHandle m_vk_handle; + }; - DescriptorPool(DescriptorPool&&) noexcept; - auto operator=(DescriptorPool&&) noexcept -> DescriptorPool&; + class STORMKIT_API DescriptorPool { + struct PrivateFuncTag {}; - auto create_descriptor_set(const DescriptorSetLayout& layout) const noexcept -> Expected; - auto create_descriptor_sets(usize count, const DescriptorSetLayout& layout) const noexcept - -> Expected>; + public: + static constexpr auto DEBUG_TYPE = DebugObjectType::DESCRIPTOR_POOL; - auto allocate_descriptor_set(const DescriptorSetLayout& layout) const noexcept -> Expected>; - auto allocate_descriptor_sets(usize count, const DescriptorSetLayout& layout) const noexcept - -> Expected>>; + struct Size { + DescriptorType type; + u32 descriptor_count; + }; - [[nodiscard]] - auto native_handle() const noexcept -> VkDescriptorPool; + static auto create(const Device& device, std::span sizes, u32 max_sets) noexcept -> Expected; + static auto allocate(const Device& device, std::span sizes, u32 max_sets) noexcept + -> Expected>; + ~DescriptorPool() noexcept; - DescriptorPool(const Device&, PrivateFuncTag) noexcept; + DescriptorPool(const DescriptorPool&) = delete; + auto operator=(const DescriptorPool&) -> DescriptorPool& = delete; - private: - auto do_init(std::span, u32) noexcept -> Expected; + DescriptorPool(DescriptorPool&&) noexcept; + auto operator=(DescriptorPool&&) noexcept -> DescriptorPool&; - auto create_vk_descriptor_sets(usize, const DescriptorSetLayout&) const - -> VulkanExpected>; - static auto delete_vk_descriptor_set(VkDescriptorSet) -> void; + auto create_descriptor_set(const DescriptorSetLayout& layout) const noexcept -> Expected; + auto create_descriptor_sets(usize count, const DescriptorSetLayout& layout) const noexcept + -> Expected>; - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; - }; - } // namespace stormkit::gpu + auto allocate_descriptor_set(const DescriptorSetLayout& layout) const noexcept -> Expected>; + auto allocate_descriptor_sets(usize count, const DescriptorSetLayout& layout) const noexcept + -> Expected>>; - template<> - struct STORMKIT_API std::hash { [[nodiscard]] - auto operator()(const stormkit::gpu::DescriptorSetLayout& value) const noexcept -> stormkit::hash64 { - return value.hash(); - } - }; + auto native_handle() const noexcept -> VkDescriptorPool; + DescriptorPool(const Device&, PrivateFuncTag) noexcept; + private: + auto do_init(std::span, u32) noexcept -> Expected; - std::visit([&hash](auto& descriptor) { stormkit::hash_combine(hash, descriptor); }, value); + auto create_vk_descriptor_sets(usize, const DescriptorSetLayout&) const -> VulkanExpected>; + static auto delete_vk_descriptor_set(VkDescriptorSet) -> void; - return hash; - } + VkDevice m_vk_device = nullptr; + Ref m_vk_device_table; + VkRAIIHandle m_vk_handle; }; template @@ -231,8 +212,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorSet::DescriptorSet(DescriptorSet&&) noexcept - = default; + inline DescriptorSet::DescriptorSet(DescriptorSet&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// @@ -350,14 +330,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorSetLayout::~DescriptorSetLayout() noexcept - = default; + inline DescriptorSetLayout::~DescriptorSetLayout() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorSetLayout::DescriptorSetLayout(DescriptorSetLayout&& other) noexcept - = default; + inline DescriptorSetLayout::DescriptorSetLayout(DescriptorSetLayout&& other) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// @@ -453,14 +431,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorPool::~DescriptorPool() noexcept - = default; + inline DescriptorPool::~DescriptorPool() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorPool::DescriptorPool(DescriptorPool&& other) noexcept - = default; + inline DescriptorPool::DescriptorPool(DescriptorPool&& other) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// diff --git a/modules/stormkit/gpu/execution/render_pass.mpp b/modules/stormkit/gpu/execution/render_pass.mpp index 3bb92220c..87ccd7538 100644 --- a/modules/stormkit/gpu/execution/render_pass.mpp +++ b/modules/stormkit/gpu/execution/render_pass.mpp @@ -18,140 +18,137 @@ import stormkit.gpu.core; import stormkit.gpu.resource; export namespace stormkit::gpu { + class RenderPass; - class STORMKIT_API FrameBuffer { - struct PrivateFuncTag {}; + class STORMKIT_API FrameBuffer { + struct PrivateFuncTag {}; - public: - static constexpr auto DEBUG_TYPE = DebugObjectType::FRAMEBUFFER; + public: + static constexpr auto DEBUG_TYPE = DebugObjectType::FRAMEBUFFER; - static auto create(const Device& device, - const RenderPass& render_pass, - const math::Extent2& extent, - std::vector> attachments) noexcept -> Expected; - static auto allocate(const Device& device, - const RenderPass& render_pass, - const math::Extent2& extent, - std::vector> attachments) noexcept -> Expected>; - ~FrameBuffer() noexcept; + static auto create(const Device& device, + const RenderPass& render_pass, + const math::uextent2& extent, + std::vector> attachments) noexcept -> Expected; + static auto allocate(const Device& device, + const RenderPass& render_pass, + const math::uextent2& extent, + std::vector> attachments) noexcept -> Expected>; + ~FrameBuffer() noexcept; - FrameBuffer(const FrameBuffer&) = delete; - auto operator=(const FrameBuffer&) -> FrameBuffer& = delete; + FrameBuffer(const FrameBuffer&) = delete; + auto operator=(const FrameBuffer&) -> FrameBuffer& = delete; - FrameBuffer(FrameBuffer&&) noexcept; - auto operator=(FrameBuffer&&) noexcept -> FrameBuffer&; + FrameBuffer(FrameBuffer&&) noexcept; + auto operator=(FrameBuffer&&) noexcept -> FrameBuffer&; - [[nodiscard]] - auto extent() const noexcept -> const math::Extent2&; - [[nodiscard]] - auto attachments() const noexcept -> const std::vector>&; + [[nodiscard]] + auto extent() const noexcept -> const math::uextent2&; + [[nodiscard]] + auto attachments() const noexcept -> const std::vector>&; - [[nodiscard]] - auto native_handle() const noexcept -> VkFramebuffer; + [[nodiscard]] + auto native_handle() const noexcept -> VkFramebuffer; - FrameBuffer(const Device&, const math::Extent2&, std::vector>, PrivateFuncTag) noexcept; + FrameBuffer(const Device&, const math::uextent2&, std::vector>, PrivateFuncTag) noexcept; - private: - auto do_init(const RenderPass&) noexcept -> Expected; + private: + auto do_init(const RenderPass&) noexcept -> Expected; - math::Extent2 m_extent = { 0, 0 }; - std::vector> m_attachments; + math::uextent2 m_extent = { 0, 0 }; + std::vector> m_attachments; - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; - }; - - struct AttachmentDescription { - PixelFormat format; - SampleCountFlag samples = SampleCountFlag::C1; + VkDevice m_vk_device = nullptr; + Ref m_vk_device_table; + VkRAIIHandle m_vk_handle; + }; - AttachmentLoadOperation load_op = AttachmentLoadOperation::CLEAR; - AttachmentStoreOperation store_op = AttachmentStoreOperation::STORE; + struct AttachmentDescription { + PixelFormat format; + SampleCountFlag samples = SampleCountFlag::C1; - AttachmentLoadOperation stencil_load_op = AttachmentLoadOperation::DONT_CARE; - AttachmentStoreOperation stencil_store_op = AttachmentStoreOperation::DONT_CARE; + AttachmentLoadOperation load_op = AttachmentLoadOperation::CLEAR; + AttachmentStoreOperation store_op = AttachmentStoreOperation::STORE; - ImageLayout source_layout = ImageLayout::UNDEFINED; - ImageLayout destination_layout = ImageLayout::PRESENT_SRC; + AttachmentLoadOperation stencil_load_op = AttachmentLoadOperation::DONT_CARE; + AttachmentStoreOperation stencil_store_op = AttachmentStoreOperation::DONT_CARE; - bool resolve = false; - }; + ImageLayout source_layout = ImageLayout::UNDEFINED; + ImageLayout destination_layout = ImageLayout::PRESENT_SRC; - using AttachmentDescriptions = std::vector; + bool resolve = false; + }; - struct Subpass { - struct Ref { - u32 attachment_id; + using AttachmentDescriptions = std::vector; - ImageLayout layout = ImageLayout::COLOR_ATTACHMENT_OPTIMAL; - }; + struct Subpass { + struct Ref { + u32 attachment_id; - PipelineBindPoint bind_point; - std::vector color_attachment_refs = {}; - std::vector resolve_attachment_refs = {}; - std::optional depth_attachment_ref = {}; + ImageLayout layout = ImageLayout::COLOR_ATTACHMENT_OPTIMAL; }; - using Subpasses = std::vector; + PipelineBindPoint bind_point; + std::vector color_attachment_refs = {}; + std::vector resolve_attachment_refs = {}; + std::optional depth_attachment_ref = {}; + }; - struct RenderPassDescription { - AttachmentDescriptions attachments; - Subpasses subpasses; + using Subpasses = std::vector; - auto is_compatible(const RenderPassDescription& description) const noexcept -> bool; - }; + struct RenderPassDescription { + AttachmentDescriptions attachments; + Subpasses subpasses; - class STORMKIT_API RenderPass { - struct PrivateFuncTag {}; + auto is_compatible(const RenderPassDescription& description) const noexcept -> bool; + }; - public: - static constexpr auto DEBUG_TYPE = DebugObjectType::RENDER_PASS; + class STORMKIT_API RenderPass { + struct PrivateFuncTag {}; - static auto create(const Device& device, const RenderPassDescription& description) noexcept -> Expected; - static auto allocate(const Device& device, const RenderPassDescription& description) noexcept - -> Expected>; - ~RenderPass() noexcept; + public: + static constexpr auto DEBUG_TYPE = DebugObjectType::RENDER_PASS; - RenderPass(const RenderPass&) = delete; - auto operator=(const RenderPass&) -> RenderPass& = delete; + static auto create(const Device& device, const RenderPassDescription& description) noexcept -> Expected; + static auto allocate(const Device& device, const RenderPassDescription& description) noexcept + -> Expected>; + ~RenderPass() noexcept; - RenderPass(RenderPass&&) noexcept; - auto operator=(RenderPass&&) noexcept -> RenderPass&; + RenderPass(const RenderPass&) = delete; + auto operator=(const RenderPass&) -> RenderPass& = delete; - auto create_frame_buffer(const Device& device, - const math::Extent2& extent, - std::vector> attachments) const noexcept -> Expected; - auto allocate_frame_buffer(const Device& device, - const math::Extent2& extent, - std::vector> attachments) const noexcept - -> Expected>; + RenderPass(RenderPass&&) noexcept; + auto operator=(RenderPass&&) noexcept -> RenderPass&; - [[nodiscard]] - auto is_compatible(const RenderPass& render_pass) const noexcept -> bool; - [[nodiscard]] - auto is_compatible(const RenderPassDescription& description) const noexcept -> bool; + auto create_frame_buffer(const Device& device, + const math::uextent2& extent, + std::vector> attachments) const noexcept -> Expected; + auto allocate_frame_buffer(const Device& device, + const math::uextent2& extent, + std::vector> attachments) const noexcept -> Expected>; - [[nodiscard]] - auto description() const noexcept -> const RenderPassDescription&; + [[nodiscard]] + auto is_compatible(const RenderPass& render_pass) const noexcept -> bool; + [[nodiscard]] + auto is_compatible(const RenderPassDescription& description) const noexcept -> bool; - [[nodiscard]] - auto native_handle() const noexcept -> VkRenderPass; + [[nodiscard]] + auto description() const noexcept -> const RenderPassDescription&; - RenderPass(const Device& device, const RenderPassDescription& description, PrivateFuncTag) noexcept; + [[nodiscard]] + auto native_handle() const noexcept -> VkRenderPass; - private: - auto do_init() noexcept -> Expected; - - RenderPassDescription m_description = {}; - - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; - }; + RenderPass(const Device& device, const RenderPassDescription& description, PrivateFuncTag) noexcept; + private: + auto do_init() noexcept -> Expected; + RenderPassDescription m_description = {}; + VkDevice m_vk_device = nullptr; + Ref m_vk_device_table; + VkRAIIHandle m_vk_handle; + }; template constexpr auto hasher(const AttachmentDescription& value) noexcept -> Ret; @@ -172,7 +169,7 @@ namespace stormkit::gpu { ///////////////////////////////////// STORMKIT_FORCE_INLINE inline FrameBuffer::FrameBuffer(const Device& device, - const math::Extent2& extent, + const math::uextent2& extent, std::vector> attachments, PrivateFuncTag) noexcept : m_extent { extent }, @@ -189,7 +186,7 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto FrameBuffer::create(const Device& device, const RenderPass& render_pass, - const math::Extent2& extent, + const math::uextent2& extent, std::vector> attachments) noexcept -> Expected { auto frame_buffer = FrameBuffer { device, extent, std::move(attachments), PrivateFuncTag {} }; return frame_buffer.do_init(render_pass).transform(core::monadic::consume(frame_buffer)); @@ -200,7 +197,7 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto FrameBuffer::allocate(const Device& device, const RenderPass& render_pass, - const math::Extent2& extent, + const math::uextent2& extent, std::vector> attachments) noexcept -> Expected> { auto frame_buffer = allocate_unsafe(device, extent, std::move(attachments), PrivateFuncTag {}); return frame_buffer->do_init(render_pass).transform(core::monadic::consume(frame_buffer)); @@ -209,14 +206,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline FrameBuffer::~FrameBuffer() noexcept - = default; + inline FrameBuffer::~FrameBuffer() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline FrameBuffer::FrameBuffer(FrameBuffer&& other) noexcept - = default; + inline FrameBuffer::FrameBuffer(FrameBuffer&& other) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// @@ -226,7 +221,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto FrameBuffer::extent() const noexcept -> const math::Extent2& { + inline auto FrameBuffer::extent() const noexcept -> const math::uextent2& { return m_extent; } @@ -301,14 +296,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline RenderPass::~RenderPass() noexcept - = default; + inline RenderPass::~RenderPass() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline RenderPass::RenderPass(RenderPass&& other) noexcept - = default; + inline RenderPass::RenderPass(RenderPass&& other) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// @@ -319,7 +312,7 @@ namespace stormkit::gpu { ///////////////////////////////////// STORMKIT_FORCE_INLINE inline auto RenderPass::create_frame_buffer(const Device& device, - const math::Extent2& extent, + const math::uextent2& extent, std::vector> attachments) const noexcept -> Expected { return FrameBuffer::create(device, *this, extent, std::move(attachments)); @@ -329,7 +322,7 @@ namespace stormkit::gpu { ///////////////////////////////////// STORMKIT_FORCE_INLINE inline auto RenderPass::allocate_frame_buffer(const Device& device, - const math::Extent2& extent, + const math::uextent2& extent, std::vector> attachments) const noexcept -> Expected> { return FrameBuffer::allocate(device, *this, extent, std::move(attachments)); diff --git a/modules/stormkit/gpu/execution/swapchain.mpp b/modules/stormkit/gpu/execution/swapchain.mpp index 46284e2cb..68356962c 100644 --- a/modules/stormkit/gpu/execution/swapchain.mpp +++ b/modules/stormkit/gpu/execution/swapchain.mpp @@ -32,11 +32,11 @@ export namespace stormkit::gpu { static auto create(const Device& device, const Surface& surface, - const math::Extent2& extent, + const math::uextent2& extent, OptionalRef old_swapchain = std::nullopt) noexcept -> Expected; static auto allocate(const Device& device, const Surface& surface, - const math::Extent2& extent, + const math::uextent2& extent, OptionalRef old_swapchain = std::nullopt) noexcept -> Expected>; ~SwapChain(); @@ -59,9 +59,9 @@ export namespace stormkit::gpu { SwapChain(const Device&, PrivateFuncTag) noexcept; private: - auto do_init(const Device&, const Surface&, const math::Extent2&, VkSwapchainKHR) noexcept -> Expected; + auto do_init(const Device&, const Surface&, const math::uextent2&, VkSwapchainKHR) noexcept -> Expected; - math::Extent2 m_extent; + math::uextent2 m_extent; PixelFormat m_pixel_format; u32 m_image_count; @@ -108,7 +108,7 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto SwapChain::create(const Device& device, const Surface& surface, - const math::Extent2& extent, + const math::uextent2& extent, OptionalRef old_swapchain) noexcept -> Expected { auto swapchain = SwapChain { device, PrivateFuncTag {} }; return swapchain.do_init(device, surface, extent, old_swapchain ? old_swapchain->native_handle() : nullptr) @@ -120,7 +120,7 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto SwapChain::allocate(const Device& device, const Surface& surface, - const math::Extent2& extent, + const math::uextent2& extent, OptionalRef old_swapchain) noexcept -> Expected> { auto swapchain = std::make_unique(device, PrivateFuncTag {}); return swapchain->do_init(device, surface, extent, old_swapchain ? old_swapchain->native_handle() : nullptr) diff --git a/modules/stormkit/gpu/resource/image.mpp b/modules/stormkit/gpu/resource/image.mpp index 7beb2dd3d..b5f7436c5 100644 --- a/modules/stormkit/gpu/resource/image.mpp +++ b/modules/stormkit/gpu/resource/image.mpp @@ -127,7 +127,7 @@ export namespace stormkit::gpu { public: struct CreateInfo { - math::Extent3 extent; + math::uextent3 extent; PixelFormat format = PixelFormat::RGBA8_UNORM; u32 layers = 1u; u32 mip_levels = 1u; @@ -152,7 +152,7 @@ export namespace stormkit::gpu { auto operator=(Image&&) noexcept -> Image&; [[nodiscard]] - auto extent() const noexcept -> const math::Extent3&; + auto extent() const noexcept -> const math::uextent3&; [[nodiscard]] auto format() const noexcept -> PixelFormat; [[nodiscard]] @@ -180,7 +180,7 @@ export namespace stormkit::gpu { auto do_init(const CreateInfo&) noexcept -> Expected; auto do_init(const VkImageCreateInfo&, MemoryPropertyFlag) noexcept -> Expected; - math::Extent3 m_extent = { 0, 0, 0 }; + math::uextent3 m_extent = { 0, 0, 0 }; PixelFormat m_format = {}; u32 m_layers = 0; u32 m_faces = 0; @@ -471,7 +471,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Image::extent() const noexcept -> const math::Extent3& { + inline auto Image::extent() const noexcept -> const math::uextent3& { return m_extent; } diff --git a/modules/stormkit/image.mpp b/modules/stormkit/image.mpp index 950279c5a..157f75177 100644 --- a/modules/stormkit/image.mpp +++ b/modules/stormkit/image.mpp @@ -111,7 +111,7 @@ export namespace stormkit::image { }; struct ImageData { - math::Extent3 extent = { .width = 0u, .height = 0u }; + math::uextent3 extent = { .width = 0u, .height = 0u }; u32 channel_count = 0u; u32 bytes_per_channel = 0u; u32 layers = 1u; @@ -124,7 +124,7 @@ export namespace stormkit::image { Image() noexcept; explicit Image(ImageData&& data) noexcept; - Image(const math::Extent3& extent, Format format) noexcept; + Image(const math::uextent3& extent, Format format) noexcept; Image(const std::filesystem::path& filepath, Codec codec = Codec::AUTODETECT) noexcept; Image(std::span data, Codec codec = Codec::AUTODETECT) noexcept; ~Image() noexcept; @@ -148,12 +148,12 @@ export namespace stormkit::image { auto save_to_memory(Codec codec, CodecArgs args = CodecArgs::BINARY) const noexcept -> std::expected, Error>; - auto create(math::Extent3 extent, Format format) noexcept -> void; + auto create(math::uextent3 extent, Format format) noexcept -> void; [[nodiscard]] auto convert_to(Format format) const noexcept -> Image; [[nodiscard]] - auto scale(const math::Extent3& scale_to) const noexcept -> Image; + auto scale(const math::uextent3& scale_to) const noexcept -> Image; [[nodiscard]] auto flip_x() const noexcept -> Image; [[nodiscard]] @@ -177,7 +177,7 @@ export namespace stormkit::image { auto pixel(math::vec3u position, u32 layer = 0u, u32 face = 0u, u32 level = 0u) const noexcept -> std::span; [[nodiscard]] - auto extent(u32 level = 0u) const noexcept -> math::Extent3; + auto extent(u32 level = 0u) const noexcept -> math::uextent3; [[nodiscard]] auto channelCount() const noexcept -> u32; @@ -324,7 +324,7 @@ namespace stormkit::image { ///////////////////////////////////// ///////////////////////////////////// - inline auto Image::extent(u32 level) const noexcept -> math::Extent3 { + inline auto Image::extent(u32 level) const noexcept -> math::uextent3 { EXPECTS(m_data.mip_levels > level); return { .width = std::max(1u, m_data.extent.width >> level), diff --git a/modules/stormkit/luau/core.mpp b/modules/stormkit/luau/core.mpp index 171c8c1fc..55097da26 100644 --- a/modules/stormkit/luau/core.mpp +++ b/modules/stormkit/luau/core.mpp @@ -29,13 +29,13 @@ namespace stormkit::luau::core { //////////////////////////////////////// inline auto bind_extent(lb::Namespace& global_namespace) noexcept -> lb::Namespace { return global_namespace.beginNamespace("math") - .beginClass>("uextent2") + .beginClass("uextent2") .endClass() - .beginClass>("uextent3") + .beginClass("uextent3") .endClass() - .beginClass>("fextent2") + .beginClass>("fextent2") .endClass() - .beginClass>("fextent3") + .beginClass>("fextent3") .endClass() .endNamespace(); } diff --git a/modules/stormkit/wsi/lua.mpp b/modules/stormkit/wsi/lua.mpp index 67e8b981f..2da42af9a 100644 --- a/modules/stormkit/wsi/lua.mpp +++ b/modules/stormkit/wsi/lua.mpp @@ -168,7 +168,7 @@ namespace stormkit::wsi::lua { return return_value.cast().value(); }); }) - .addFunction("on_resized", +(make_lua_closure&>())) + .addFunction("on_resized", +(make_lua_closure())) .addFunction("on_restored", +(make_lua_closure())) .addFunction("on_minimized", +(make_lua_closure())) .addFunction("on_activate", +(make_lua_closure())) diff --git a/modules/stormkit/wsi/monitor.mpp b/modules/stormkit/wsi/monitor.mpp index cc21a5907..8c463afc3 100644 --- a/modules/stormkit/wsi/monitor.mpp +++ b/modules/stormkit/wsi/monitor.mpp @@ -24,7 +24,7 @@ export { Flags flags = Flags::NONE; std::string name; - std::vector> extents; + std::vector extents; u32 scale_factor = 1; [[nodiscard]] diff --git a/modules/stormkit/wsi/window.mpp b/modules/stormkit/wsi/window.mpp index c0f6c254d..0edc31da6 100644 --- a/modules/stormkit/wsi/window.mpp +++ b/modules/stormkit/wsi/window.mpp @@ -65,8 +65,8 @@ export { using std::function::function; }; - struct ResizedEventFunc: std::function&)> { - using std::function&)>::function; + struct ResizedEventFunc: std::function { + using std::function::function; }; struct RestoredEventFunc: std::function { @@ -128,7 +128,7 @@ export { Window(Window&&) noexcept; auto operator=(Window&&) noexcept -> Window&; - static auto open(std::string title, const math::Extent2& size, WindowFlag flags) noexcept -> Window; + static auto open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> Window; auto close() noexcept -> void; [[nodiscard]] @@ -158,10 +158,10 @@ export { auto title() const noexcept -> const std::string&; auto set_title(std::string title) noexcept -> void; - auto set_extent(const math::Extent2& extent) noexcept -> void; + auto set_extent(const math::uextent2& extent) noexcept -> void; [[nodiscard]] - auto extent() const noexcept -> const math::Extent2&; + auto extent() const noexcept -> const math::uextent2&; auto set_fullscreen(bool fullscreen) noexcept -> void; auto toggle_fullscreen() noexcept -> void; diff --git a/src/gpu/core/physical_device.cpp b/src/gpu/core/physical_device.cpp index 6e3a1f382..32a01e46e 100644 --- a/src/gpu/core/physical_device.cpp +++ b/src/gpu/core/physical_device.cpp @@ -14,6 +14,9 @@ import stormkit.core; using namespace std::literals; +namespace stdr = std::ranges; +namespace stdv = std::views; + namespace stormkit::gpu { namespace { constexpr auto RAYTRACING_EXTENSIONS = std::array { @@ -99,39 +102,39 @@ namespace stormkit::gpu { m_device_info.driver_major_version = vk_version_major(properties.driverVersion); m_device_info.driver_minor_version = vk_version_minor(properties.driverVersion); m_device_info.driver_patch_version = vk_version_patch(properties.driverVersion); - std::ranges::copy(properties.pipelineCacheUUID, std::ranges::begin(m_device_info.pipeline_cache_uuid)); + stdr::copy(properties.pipelineCacheUUID, stdr::begin(m_device_info.pipeline_cache_uuid)); m_device_info.type = from_vk(properties.deviceType); - m_capabilities.limits.max_image_dimension_1D = properties.limits.maxImageDimension1D; - m_capabilities.limits.max_image_dimension_2D = properties.limits.maxImageDimension2D; - m_capabilities.limits.max_image_dimension_3D = properties.limits.maxImageDimension3D; - m_capabilities.limits.max_image_dimension_cube = properties.limits.maxImageDimensionCube; - m_capabilities.limits.max_image_array_layers = properties.limits.maxImageArrayLayers; - m_capabilities.limits.max_texel_buffer_elements = properties.limits.maxTexelBufferElements; - m_capabilities.limits.max_uniform_buffer_range = properties.limits.maxUniformBufferRange; - m_capabilities.limits.max_storage_buffer_range = properties.limits.maxStorageBufferRange; - m_capabilities.limits.max_push_constants_size = properties.limits.maxPushConstantsSize; - m_capabilities.limits.max_memory_allocation_count = properties.limits.maxMemoryAllocationCount; - m_capabilities.limits.max_sampler_allocation_count = properties.limits.maxSamplerAllocationCount; - m_capabilities.limits.buffer_image_granularity = properties.limits.bufferImageGranularity; - m_capabilities.limits.sparse_address_space_size = properties.limits.sparseAddressSpaceSize; - m_capabilities.limits.max_bound_descriptor_sets = properties.limits.maxBoundDescriptorSets; - m_capabilities.limits.max_per_stage_descriptor_samplers = properties.limits.maxPerStageDescriptorSamplers; - m_capabilities.limits.max_per_stage_descriptor_uniform_buffers = properties.limits.maxPerStageDescriptorUniformBuffers; - m_capabilities.limits.max_per_stage_descriptor_storage_buffers = properties.limits.maxPerStageDescriptorStorageBuffers; - m_capabilities.limits.max_per_stage_descriptor_sampled_images = properties.limits.maxPerStageDescriptorSampledImages; - m_capabilities.limits.max_per_stage_descriptor_storage_images = properties.limits.maxPerStageDescriptorStorageImages; - m_capabilities.limits.max_per_stage_descriptor_input_attachments = properties.limits - .maxPerStageDescriptorInputAttachments; - m_capabilities.limits.max_per_stage_resources = properties.limits.maxPerStageResources; - m_capabilities.limits.max_descriptor_set_samplers = properties.limits.maxDescriptorSetSamplers; - m_capabilities.limits.max_descriptor_set_uniform_buffers = properties.limits.maxDescriptorSetUniformBuffers; - m_capabilities.limits.max_descriptor_set_uniform_buffers_dynamic = properties.limits - .maxDescriptorSetUniformBuffersDynamic; - m_capabilities.limits.max_descriptor_set_storage_buffers = properties.limits.maxDescriptorSetStorageBuffers; - m_capabilities.limits.max_descriptor_set_storage_buffers_dynamic = properties.limits - .maxDescriptorSetStorageBuffersDynamic; + m_capabilities.limits.max_image_dimension_1D = properties.limits.maxImageDimension1D; + m_capabilities.limits.max_image_dimension_2D = properties.limits.maxImageDimension2D; + m_capabilities.limits.max_image_dimension_3D = properties.limits.maxImageDimension3D; + m_capabilities.limits.max_image_dimension_cube = properties.limits.maxImageDimensionCube; + m_capabilities.limits.max_image_array_layers = properties.limits.maxImageArrayLayers; + m_capabilities.limits.max_texel_buffer_elements = properties.limits.maxTexelBufferElements; + m_capabilities.limits.max_uniform_buffer_range = properties.limits.maxUniformBufferRange; + m_capabilities.limits.max_storage_buffer_range = properties.limits.maxStorageBufferRange; + m_capabilities.limits.max_push_constants_size = properties.limits.maxPushConstantsSize; + m_capabilities.limits.max_memory_allocation_count = properties.limits.maxMemoryAllocationCount; + m_capabilities.limits.max_sampler_allocation_count = properties.limits.maxSamplerAllocationCount; + m_capabilities.limits.buffer_image_granularity = properties.limits.bufferImageGranularity; + m_capabilities.limits.sparse_address_space_size = properties.limits.sparseAddressSpaceSize; + m_capabilities.limits.max_bound_descriptor_sets = properties.limits.maxBoundDescriptorSets; + m_capabilities.limits.max_per_stage_descriptor_samplers = properties.limits.maxPerStageDescriptorSamplers; + m_capabilities.limits.max_per_stage_descriptor_uniform_buffers = properties.limits.maxPerStageDescriptorUniformBuffers; + m_capabilities.limits.max_per_stage_descriptor_storage_buffers = properties.limits.maxPerStageDescriptorStorageBuffers; + m_capabilities.limits.max_per_stage_descriptor_sampled_images = properties.limits.maxPerStageDescriptorSampledImages; + m_capabilities.limits.max_per_stage_descriptor_storage_images = properties.limits.maxPerStageDescriptorStorageImages; + m_capabilities.limits + .max_per_stage_descriptor_input_attachments = properties.limits.maxPerStageDescriptorInputAttachments; + m_capabilities.limits.max_per_stage_resources = properties.limits.maxPerStageResources; + m_capabilities.limits.max_descriptor_set_samplers = properties.limits.maxDescriptorSetSamplers; + m_capabilities.limits.max_descriptor_set_uniform_buffers = properties.limits.maxDescriptorSetUniformBuffers; + m_capabilities.limits + .max_descriptor_set_uniform_buffers_dynamic = properties.limits.maxDescriptorSetUniformBuffersDynamic; + m_capabilities.limits.max_descriptor_set_storage_buffers = properties.limits.maxDescriptorSetStorageBuffers; + m_capabilities.limits + .max_descriptor_set_storage_buffers_dynamic = properties.limits.maxDescriptorSetStorageBuffersDynamic; m_capabilities.limits.max_descriptor_set_sampled_images = properties.limits.maxDescriptorSetSampledImages; m_capabilities.limits.max_descriptor_set_storage_images = properties.limits.maxDescriptorSetStorageImages; m_capabilities.limits.max_descriptor_set_input_attachments = properties.limits.maxDescriptorSetInputAttachments; @@ -142,33 +145,34 @@ namespace stormkit::gpu { m_capabilities.limits.max_vertex_output_components = properties.limits.maxVertexOutputComponents; m_capabilities.limits.max_tessellation_generation_level = properties.limits.maxTessellationGenerationLevel; m_capabilities.limits.max_tessellation_patch_size = properties.limits.maxTessellationPatchSize; - m_capabilities.limits.max_tessellation_control_per_vertex_input_components - = properties.limits.maxTessellationControlPerVertexInputComponents; - m_capabilities.limits.max_tessellation_control_per_vertex_output_components - = properties.limits.maxTessellationControlPerVertexOutputComponents; - m_capabilities.limits.max_tessellation_control_per_patch_output_components - = properties.limits.maxTessellationControlPerPatchOutputComponents; - m_capabilities.limits.max_tessellation_control_total_output_components = properties.limits - .maxTessellationControlTotalOutputComponents; - m_capabilities.limits.max_tessellation_evaluation_input_components = properties.limits - .maxTessellationEvaluationInputComponents; - m_capabilities.limits.max_tessellation_evaluation_output_components = properties.limits - .maxTessellationEvaluationOutputComponents; - m_capabilities.limits.max_geometry_shader_invocations = properties.limits.maxGeometryShaderInvocations; - m_capabilities.limits.max_geometry_input_components = properties.limits.maxGeometryInputComponents; - m_capabilities.limits.max_geometry_output_components = properties.limits.maxGeometryOutputComponents; - m_capabilities.limits.max_geometry_output_vertices = properties.limits.maxGeometryOutputVertices; - m_capabilities.limits.max_geometry_total_output_components = properties.limits.maxGeometryTotalOutputComponents; - m_capabilities.limits.max_fragment_input_components = properties.limits.maxFragmentInputComponents; - m_capabilities.limits.max_fragment_output_attachments = properties.limits.maxFragmentOutputAttachments; - m_capabilities.limits.max_fragment_dual_src_attachments = properties.limits.maxFragmentDualSrcAttachments; + m_capabilities.limits + .max_tessellation_control_per_vertex_input_components = properties.limits + .maxTessellationControlPerVertexInputComponents; + m_capabilities.limits + .max_tessellation_control_per_vertex_output_components = properties.limits + .maxTessellationControlPerVertexOutputComponents; + m_capabilities.limits + .max_tessellation_control_per_patch_output_components = properties.limits + .maxTessellationControlPerPatchOutputComponents; + m_capabilities.limits + .max_tessellation_control_total_output_components = properties.limits.maxTessellationControlTotalOutputComponents; + m_capabilities.limits + .max_tessellation_evaluation_input_components = properties.limits.maxTessellationEvaluationInputComponents; + m_capabilities.limits + .max_tessellation_evaluation_output_components = properties.limits.maxTessellationEvaluationOutputComponents; + m_capabilities.limits.max_geometry_shader_invocations = properties.limits.maxGeometryShaderInvocations; + m_capabilities.limits.max_geometry_input_components = properties.limits.maxGeometryInputComponents; + m_capabilities.limits.max_geometry_output_components = properties.limits.maxGeometryOutputComponents; + m_capabilities.limits.max_geometry_output_vertices = properties.limits.maxGeometryOutputVertices; + m_capabilities.limits.max_geometry_total_output_components = properties.limits.maxGeometryTotalOutputComponents; + m_capabilities.limits.max_fragment_input_components = properties.limits.maxFragmentInputComponents; + m_capabilities.limits.max_fragment_output_attachments = properties.limits.maxFragmentOutputAttachments; + m_capabilities.limits.max_fragment_dual_src_attachments = properties.limits.maxFragmentDualSrcAttachments; m_capabilities.limits.max_fragment_combined_output_resources = properties.limits.maxFragmentCombinedOutputResources; m_capabilities.limits.max_compute_shared_memory_size = properties.limits.maxComputeSharedMemorySize; - std::ranges::copy(properties.limits.maxComputeWorkGroupCount, - std::ranges::begin(m_capabilities.limits.max_compute_work_group_count)); + stdr::copy(properties.limits.maxComputeWorkGroupCount, stdr::begin(m_capabilities.limits.max_compute_work_group_count)); m_capabilities.limits.max_compute_work_group_invocations = properties.limits.maxComputeWorkGroupInvocations; - std::ranges::copy(properties.limits.maxComputeWorkGroupSize, - std::ranges::begin(m_capabilities.limits.max_compute_work_group_size)); + stdr::copy(properties.limits.maxComputeWorkGroupSize, stdr::begin(m_capabilities.limits.max_compute_work_group_size)); m_capabilities.limits.sub_pixel_precision_bits = properties.limits.subPixelPrecisionBits; m_capabilities.limits.sub_texel_precision_bits = properties.limits.subTexelPrecisionBits; m_capabilities.limits.mipmap_precision_bits = properties.limits.mipmapPrecisionBits; @@ -177,41 +181,41 @@ namespace stormkit::gpu { m_capabilities.limits.max_sampler_lod_bias = properties.limits.maxSamplerLodBias; m_capabilities.limits.max_sampler_anisotropy = properties.limits.maxSamplerAnisotropy; m_capabilities.limits.max_viewports = properties.limits.maxViewports; - std::ranges::copy(properties.limits.maxViewportDimensions, - std::ranges::begin(m_capabilities.limits.max_viewport_dimensions)); - std::ranges::copy(properties.limits.viewportBoundsRange, std::ranges::begin(m_capabilities.limits.viewport_bounds_range)); - m_capabilities.limits.viewport_sub_pixel_bits = properties.limits.viewportSubPixelBits; - m_capabilities.limits.min_memory_map_alignment = properties.limits.minMemoryMapAlignment; - m_capabilities.limits.min_texel_buffer_offset_alignment = properties.limits.minTexelBufferOffsetAlignment; - m_capabilities.limits.min_uniform_buffer_offset_alignment = properties.limits.minUniformBufferOffsetAlignment; - m_capabilities.limits.min_storage_buffer_offset_alignment = properties.limits.minStorageBufferOffsetAlignment; - m_capabilities.limits.min_texel_offset = properties.limits.minTexelOffset; - m_capabilities.limits.max_texel_offset = properties.limits.maxTexelOffset; - m_capabilities.limits.min_texel_gather_offset = properties.limits.minTexelGatherOffset; - m_capabilities.limits.max_texel_gather_offset = properties.limits.maxTexelGatherOffset; - m_capabilities.limits.min_interpolation_offset = properties.limits.minInterpolationOffset; - m_capabilities.limits.max_interpolation_offset = properties.limits.maxInterpolationOffset; - m_capabilities.limits.sub_pixel_interpolation_offset_bits = properties.limits.subPixelInterpolationOffsetBits; - m_capabilities.limits.max_framebuffer_width = properties.limits.maxFramebufferWidth; - m_capabilities.limits.max_framebuffer_height = properties.limits.maxFramebufferHeight; - m_capabilities.limits.max_framebuffer_layers = properties.limits.maxFramebufferLayers; - m_capabilities.limits.framebuffer_color_sample_counts = narrow(properties.limits - .framebufferColorSampleCounts); - m_capabilities.limits.framebuffer_depth_sample_counts = narrow(properties.limits - .framebufferDepthSampleCounts); - m_capabilities.limits.framebuffer_stencil_sample_counts = narrow(properties.limits - .framebufferStencilSampleCounts); - m_capabilities.limits.framebuffer_no_attachments_sample_counts = narrow< - SampleCountFlag>(properties.limits.framebufferNoAttachmentsSampleCounts); - m_capabilities.limits.max_color_attachments = properties.limits.maxColorAttachments; - m_capabilities.limits.sampled_image_color_sample_counts = narrow(properties.limits - .sampledImageColorSampleCounts); - m_capabilities.limits.sampled_image_integer_sample_counts = narrow(properties.limits - .sampledImageIntegerSampleCounts); - m_capabilities.limits.sampled_image_depth_sample_counts = narrow(properties.limits - .sampledImageDepthSampleCounts); - m_capabilities.limits.sampled_image_stencil_sample_counts = narrow(properties.limits - .sampledImageStencilSampleCounts); + stdr::copy(properties.limits.maxViewportDimensions, stdr::begin(m_capabilities.limits.max_viewport_dimensions)); + stdr::copy(properties.limits.viewportBoundsRange, stdr::begin(m_capabilities.limits.viewport_bounds_range)); + m_capabilities.limits.viewport_sub_pixel_bits = properties.limits.viewportSubPixelBits; + m_capabilities.limits.min_memory_map_alignment = properties.limits.minMemoryMapAlignment; + m_capabilities.limits.min_texel_buffer_offset_alignment = properties.limits.minTexelBufferOffsetAlignment; + m_capabilities.limits.min_uniform_buffer_offset_alignment = properties.limits.minUniformBufferOffsetAlignment; + m_capabilities.limits.min_storage_buffer_offset_alignment = properties.limits.minStorageBufferOffsetAlignment; + m_capabilities.limits.min_texel_offset = properties.limits.minTexelOffset; + m_capabilities.limits.max_texel_offset = properties.limits.maxTexelOffset; + m_capabilities.limits.min_texel_gather_offset = properties.limits.minTexelGatherOffset; + m_capabilities.limits.max_texel_gather_offset = properties.limits.maxTexelGatherOffset; + m_capabilities.limits.min_interpolation_offset = properties.limits.minInterpolationOffset; + m_capabilities.limits.max_interpolation_offset = properties.limits.maxInterpolationOffset; + m_capabilities.limits.sub_pixel_interpolation_offset_bits = properties.limits.subPixelInterpolationOffsetBits; + m_capabilities.limits.max_framebuffer_width = properties.limits.maxFramebufferWidth; + m_capabilities.limits.max_framebuffer_height = properties.limits.maxFramebufferHeight; + m_capabilities.limits.max_framebuffer_layers = properties.limits.maxFramebufferLayers; + m_capabilities.limits + .framebuffer_color_sample_counts = narrow(properties.limits.framebufferColorSampleCounts); + m_capabilities.limits + .framebuffer_depth_sample_counts = narrow(properties.limits.framebufferDepthSampleCounts); + m_capabilities.limits + .framebuffer_stencil_sample_counts = narrow(properties.limits.framebufferStencilSampleCounts); + m_capabilities.limits + .framebuffer_no_attachments_sample_counts = narrow(properties.limits + .framebufferNoAttachmentsSampleCounts); + m_capabilities.limits.max_color_attachments = properties.limits.maxColorAttachments; + m_capabilities.limits + .sampled_image_color_sample_counts = narrow(properties.limits.sampledImageColorSampleCounts); + m_capabilities.limits + .sampled_image_integer_sample_counts = narrow(properties.limits.sampledImageIntegerSampleCounts); + m_capabilities.limits + .sampled_image_depth_sample_counts = narrow(properties.limits.sampledImageDepthSampleCounts); + m_capabilities.limits + .sampled_image_stencil_sample_counts = narrow(properties.limits.sampledImageStencilSampleCounts); m_capabilities.limits.storage_image_sample_counts = narrow(properties.limits.storageImageSampleCounts); m_capabilities.limits.max_sample_mask_words = properties.limits.maxSampleMaskWords; m_capabilities.limits.timestamp_compute_and_engine = properties.limits.timestampComputeAndGraphics; @@ -220,8 +224,8 @@ namespace stormkit::gpu { m_capabilities.limits.max_cull_distances = properties.limits.maxCullDistances; m_capabilities.limits.max_combined_clip_and_cull_distances = properties.limits.maxCombinedClipAndCullDistances; m_capabilities.limits.discrete_queue_priorities = properties.limits.discreteQueuePriorities; - std::ranges::copy(properties.limits.pointSizeRange, std::ranges::begin(m_capabilities.limits.point_size_range)); - std::ranges::copy(properties.limits.lineWidthRange, std::ranges::begin(m_capabilities.limits.line_width_range)); + stdr::copy(properties.limits.pointSizeRange, stdr::begin(m_capabilities.limits.point_size_range)); + stdr::copy(properties.limits.lineWidthRange, stdr::begin(m_capabilities.limits.line_width_range)); m_capabilities.limits.point_size_granularity = properties.limits.pointSizeGranularity; m_capabilities.limits.line_width_granularity = properties.limits.lineWidthGranularity; m_capabilities.limits.strict_lines = properties.limits.strictLines; @@ -289,7 +293,7 @@ namespace stormkit::gpu { m_extensions = *vk_enumerate(vkEnumerateDeviceExtensionProperties, m_vk_handle, nullptr) .transform_error(core::monadic::assert(format("Failed to enumerate device {} extensions properties", m_device_info.device_name))) - | std::views::transform([](auto&& extension) noexcept { + | stdv::transform([](auto&& extension) noexcept { const auto string_size = std::char_traits::length(extension.extensionName); auto string = std::string {}; @@ -297,21 +301,21 @@ namespace stormkit::gpu { stdr::copy(std::string_view { extension.extensionName, string_size }, std::begin(string)); return string; }) - | std::ranges::to(); + | stdr::to(); const auto vk_memory_properties = vk_call(vkGetPhysicalDeviceMemoryProperties, m_vk_handle); m_memory_types = vk_memory_properties.memoryTypes - | std::views::transform([](auto&& type) static noexcept { + | stdv::transform([](auto&& type) static noexcept { return core::narrow(type.propertyFlags); - }) - | std::ranges::to(); + }) + | stdr::to(); m_queue_families = vk_enumerate(vkGetPhysicalDeviceQueueFamilyProperties, m_vk_handle) - | std::views::transform([](auto&& family) static noexcept { + | stdv::transform([](auto&& family) static noexcept { return QueueFamily { .flags = narrow(family.queueFlags), .count = family.queueCount }; }) - | std::ranges::to(); + | stdr::to(); const auto format_values = core::meta::enumerate(); for (const auto val : format_values) { @@ -338,28 +342,28 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// auto PhysicalDevice::check_extension_support(std::string_view extension) const noexcept -> bool { - return std::ranges::any_of(m_extensions, [extension](const auto& e) { return e == extension; }); + return stdr::any_of(m_extensions, [extension](const auto& e) { return e == extension; }); } ///////////////////////////////////// ///////////////////////////////////// auto PhysicalDevice::check_extension_support(std::span extensions) const noexcept -> bool { - auto required_extensions = HashSet { std::ranges::begin(extensions), std::ranges::end(extensions) }; - // HashSet { std::ranges::begin(extensions), - // std::ranges::end(extensions) }; + auto required_extensions = HashSet { stdr::begin(extensions), stdr::end(extensions) }; + // HashSet { stdr::begin(extensions), + // stdr::end(extensions) }; for (const auto& extension : m_extensions) required_extensions.erase(extension); - return std::ranges::empty(required_extensions); + return stdr::empty(required_extensions); } ///////////////////////////////////// ///////////////////////////////////// auto PhysicalDevice::check_extension_support(std::span extensions) const noexcept -> bool { - auto required_extensions = HashSet { std::ranges::begin(extensions), std::ranges::end(extensions) }; + auto required_extensions = HashSet { stdr::begin(extensions), stdr::end(extensions) }; for (const auto& extension : m_extensions) required_extensions.erase(extension); - return std::ranges::empty(required_extensions); + return stdr::empty(required_extensions); } } // namespace stormkit::gpu diff --git a/src/gpu/execution/command_buffer.cpp b/src/gpu/execution/command_buffer.cpp index ae9c478ea..07932be2b 100644 --- a/src/gpu/execution/command_buffer.cpp +++ b/src/gpu/execution/command_buffer.cpp @@ -407,7 +407,7 @@ namespace stormkit::gpu { ImageLayout dst_layout, const ImageSubresourceLayers& src_subresource_layers, const ImageSubresourceLayers& dst_subresource_layers, - const math::Extent3& extent) noexcept -> CommandBuffer& { + const math::uextent3& extent) noexcept -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); const auto vk_src_subresource_layers = VkImageSubresourceLayers { diff --git a/src/gpu/execution/swapchain.cpp b/src/gpu/execution/swapchain.cpp index 111e792f0..f3966a648 100644 --- a/src/gpu/execution/swapchain.cpp +++ b/src/gpu/execution/swapchain.cpp @@ -42,7 +42,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto choose_swap_extent(const VkSurfaceCapabilitiesKHR& capabilities, const math::Extent2& extent) noexcept + auto choose_swap_extent(const VkSurfaceCapabilitiesKHR& capabilities, const math::uextent2& extent) noexcept -> VkExtent2D { static constexpr auto int_max = std::numeric_limits::max(); @@ -51,7 +51,7 @@ namespace stormkit::gpu { auto actual_extent = to_vk(extent); actual_extent.width = std::max(capabilities.minImageExtent.width, - std::min(capabilities.maxImageExtent.width, actual_extent.width)); + std::min(capabilities.maxImageExtent.width, actual_extent.width)); actual_extent.height = std::max(capabilities.minImageExtent.height, std::min(capabilities.maxImageExtent.height, actual_extent.height)); @@ -74,7 +74,7 @@ namespace stormkit::gpu { ///////////////////////////////////// auto SwapChain::do_init(const Device& device, const Surface& surface, - const math::Extent2& extent, + const math::uextent2& extent, VkSwapchainKHR old_swapchain) noexcept -> Expected { const auto& physical_device = device.physical_device(); @@ -139,14 +139,14 @@ namespace stormkit::gpu { .transform([this, &device](auto&& vk_images) noexcept { m_image_count = as(std::ranges::size(vk_images)); m_images = vk_images - | std::views::transform([this, &device](auto&& image) noexcept { + | std::views::transform([this, &device](auto&& image) noexcept { const auto create_info = Image::CreateInfo { .extent = { m_extent.width, m_extent.height, 1_u32 }, .format = m_pixel_format }; return Image::create(device, create_info, std::move(image)); - }) - | std::ranges::to(); + }) + | std::ranges::to(); }) .transform_error(monadic::from_vk()); } diff --git a/src/image/image.cpp b/src/image/image.cpp index b90f5c564..b6c2e834a 100644 --- a/src/image/image.cpp +++ b/src/image/image.cpp @@ -138,7 +138,7 @@ namespace stormkit::image { ///////////////////////////////////// ///////////////////////////////////// - Image::Image(const math::Extent3& extent, Format format) noexcept : Image {} { + Image::Image(const math::uextent3& extent, Format format) noexcept : Image {} { create(extent, format); } @@ -402,7 +402,7 @@ namespace stormkit::image { ///////////////////////////////////// ///////////////////////////////////// - auto Image::create(math::Extent3 extent, Format format) noexcept -> void { + auto Image::create(math::uextent3 extent, Format format) noexcept -> void { EXPECTS(extent.width > 0u and extent.height > 0u and extent.depth > 0u and format != Format::UNDEFINED); m_data.data.clear(); @@ -469,7 +469,7 @@ namespace stormkit::image { ///////////////////////////////////// ///////////////////////////////////// - auto Image::scale(const math::Extent3&) const noexcept -> Image { + auto Image::scale(const math::uextent3&) const noexcept -> Image { return *this; } diff --git a/src/image/jpg.mpp b/src/image/jpg.mpp index cdda6ce84..39736ac2a 100644 --- a/src/image/jpg.mpp +++ b/src/image/jpg.mpp @@ -73,7 +73,7 @@ namespace stormkit::image::details { auto image_memory = std::vector {}; volatile auto format = Format {}; // NOTE volatile for error: variable ‘format’ might be // clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered] - auto extent = math::Extent3 {}; + auto extent = math::uextent3 {}; auto info = jpeg_decompress_struct {}; auto error_mgr = jpeg_error_mgr {}; diff --git a/src/image/ktx.mpp b/src/image/ktx.mpp index c65f01633..7e320f838 100644 --- a/src/image/ktx.mpp +++ b/src/image/ktx.mpp @@ -120,7 +120,7 @@ namespace stormkit::image::details { /**/ /*auto image_data = image::Image::ImageData {};*/ /**/ - /*image_data.extent = math::ExtentI { image.extent().x, image.extent().y, image.extent().z + /*image_data.extent = math::extentI { image.extent().x, image.extent().y, image.extent().z * };*/ /*image_data.channel_count = get_format_channel_count(format);*/ /*image_data.bytes_per_channel = getSizeof(format);*/ diff --git a/src/image/png.mpp b/src/image/png.mpp index 0f85e89ea..08ca567a6 100644 --- a/src/image/png.mpp +++ b/src/image/png.mpp @@ -77,7 +77,7 @@ namespace stormkit::image::details { auto load_png(std::span data) noexcept -> std::expected { auto image_memory = std::vector {}; auto format = Format {}; - auto extent = math::Extent3 {}; + auto extent = math::uextent3 {}; auto read_param = png::ReadParam { 8u, data }; diff --git a/src/image/qoi.mpp b/src/image/qoi.mpp index ae315b265..df023038f 100644 --- a/src/image/qoi.mpp +++ b/src/image/qoi.mpp @@ -90,7 +90,7 @@ namespace stormkit::image::details { const auto raw_header = data.subspan(SIZE_OF_HEADER); const auto* header = std::bit_cast(stdr::data(raw_header)); - const auto extent = math::Extent3 { .width = byte_swap(header->width), .height = byte_swap(header->height) }; + const auto extent = math::uextent3 { .width = byte_swap(header->width), .height = byte_swap(header->height) }; const auto channels = header->channels; const auto format = CHANNELS_TO_FORMAT.at(header->channels)[header->colorspace]; diff --git a/src/wsi/common/window_base.mpp b/src/wsi/common/window_base.mpp index 66bca81e4..7b584848f 100644 --- a/src/wsi/common/window_base.mpp +++ b/src/wsi/common/window_base.mpp @@ -53,9 +53,9 @@ export namespace stormkit::wsi::common { [[nodiscard]] auto title() const noexcept -> const std::string&; - auto set_extent(const math::Extent2& extent) noexcept -> bool; + auto set_extent(const math::uextent2& extent) noexcept -> bool; [[nodiscard]] - auto extent() const noexcept -> const math::Extent2&; + auto extent() const noexcept -> const math::uextent2&; auto set_fullscreen(bool fullscreen) noexcept -> bool; [[nodiscard]] @@ -100,7 +100,7 @@ export namespace stormkit::wsi::common { bool active = false; bool fullscreen = false; bool visible = false; - math::Extent2 extent; + math::uextent2 extent; OptionalRef current_monitor; std::string title; @@ -174,7 +174,7 @@ namespace stormkit::wsi::common { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto WindowBase::set_extent(const math::Extent2& extent) noexcept -> bool { + inline auto WindowBase::set_extent(const math::uextent2& extent) noexcept -> bool { if (not m_state.open) return false; m_state.extent = extent; @@ -184,7 +184,7 @@ namespace stormkit::wsi::common { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto WindowBase::extent() const noexcept -> const math::Extent2& { + inline auto WindowBase::extent() const noexcept -> const math::uextent2& { return m_state.extent; } diff --git a/src/wsi/ios/window_impl.hpp b/src/wsi/ios/window_impl.hpp index 0bf114f56..3a25a3cf6 100644 --- a/src/wsi/ios/window_impl.hpp +++ b/src/wsi/ios/window_impl.hpp @@ -44,7 +44,7 @@ namespace storm::window { void set_title(const std::string& title) noexcept override; void setVideoSettings(const storm::window::VideoSettings& settings) noexcept override; - storm::core::Extentu size() const noexcept override; + storm::core::extentu size() const noexcept override; bool is_open() const noexcept override; bool isVisible() const noexcept override; diff --git a/src/wsi/linux/wayland/window.cpp b/src/wsi/linux/wayland/window.cpp index 3db828e74..b830d2fca 100644 --- a/src/wsi/linux/wayland/window.cpp +++ b/src/wsi/linux/wayland/window.cpp @@ -114,7 +114,7 @@ namespace stormkit::wsi::linux::wayland { ///////////////////////////////////// ///////////////////////////////////// - auto Window::open(std::string title, const math::Extent2& extent, WindowFlag flags) noexcept -> void { + auto Window::open(std::string title, const math::uextent2& extent, WindowFlag flags) noexcept -> void { auto& globals = wl::get_globals(); m_surface = wl::Surface::create(globals.compositor); @@ -230,7 +230,7 @@ namespace stormkit::wsi::linux::wayland { ///////////////////////////////////// ///////////////////////////////////// - auto Window::set_extent(const math::Extent2&) noexcept -> void { + auto Window::set_extent(const math::uextent2&) noexcept -> void { } ///////////////////////////////////// diff --git a/src/wsi/linux/wayland/window.mpp b/src/wsi/linux/wayland/window.mpp index d315ee29d..0493b0c2a 100644 --- a/src/wsi/linux/wayland/window.mpp +++ b/src/wsi/linux/wayland/window.mpp @@ -43,7 +43,7 @@ export { Window(Window&&) noexcept; auto operator=(Window&&) noexcept -> Window&; - auto open(std::string title, const math::Extent2& size, WindowFlag flags) noexcept -> void; + auto open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> void; auto close() noexcept -> void; auto handle_events() noexcept -> void; @@ -52,7 +52,7 @@ export { auto fill_framebuffer(std::span> colors) noexcept -> void; auto set_title(std::string title) noexcept -> void; - auto set_extent(const math::Extent2& extent) noexcept -> void; + auto set_extent(const math::uextent2& extent) noexcept -> void; auto set_fullscreen(bool fullscreen) noexcept -> void; auto confine_mouse(bool confined, u8 id) noexcept -> void; @@ -133,7 +133,7 @@ export { bool suspended = false; bool fullscreen = false; - std::optional> resizing; + std::optional resizing; } m_pending_state; }; } // namespace stormkit::wsi::linux::wayland diff --git a/src/wsi/linux/window.mpp b/src/wsi/linux/window.mpp index efaa291fc..e359669aa 100644 --- a/src/wsi/linux/window.mpp +++ b/src/wsi/linux/window.mpp @@ -35,7 +35,7 @@ export namespace stormkit::wsi::linux { Window(Window&&) noexcept; auto operator=(Window&&) noexcept -> Window&; - auto open(std::string title, const math::Extent2& size, WindowFlag flags) noexcept -> void; + auto open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> void; auto close() noexcept -> void; [[nodiscard]] @@ -56,9 +56,9 @@ export namespace stormkit::wsi::linux { [[nodiscard]] auto title() const noexcept -> const std::string&; - auto set_extent(const math::Extent2& extent) noexcept -> void; + auto set_extent(const math::uextent2& extent) noexcept -> void; [[nodiscard]] - auto extent() const noexcept -> const math::Extent2&; + auto extent() const noexcept -> const math::uextent2&; auto set_fullscreen(bool fullscreen) noexcept -> void; [[nodiscard]] @@ -143,7 +143,7 @@ namespace stormkit::wsi::linux { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Window::open(std::string title, const math::Extent2& extent, WindowFlag flags) noexcept -> void { + inline auto Window::open(std::string title, const math::uextent2& extent, WindowFlag flags) noexcept -> void { switch (m_wm) { case WM::X11: as(m_impl).open(std::move(title), extent, flags); break; case WM::WAYLAND: as(m_impl).open(std::move(title), extent, flags); break; @@ -271,7 +271,7 @@ namespace stormkit::wsi::linux { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Window::set_extent(const math::Extent2& extent) noexcept -> void { + inline auto Window::set_extent(const math::uextent2& extent) noexcept -> void { switch (m_wm) { case WM::X11: as(m_impl).set_extent(extent); break; case WM::WAYLAND: as(m_impl).set_extent(extent); break; @@ -283,7 +283,7 @@ namespace stormkit::wsi::linux { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto Window::extent() const noexcept -> const math::Extent2& { + inline auto Window::extent() const noexcept -> const math::uextent2& { switch (m_wm) { case WM::X11: return as(m_impl).extent(); case WM::WAYLAND: return as(m_impl).extent(); diff --git a/src/wsi/linux/x11/monitor.mpp b/src/wsi/linux/x11/monitor.mpp index 788fd333d..545e8bada 100644 --- a/src/wsi/linux/x11/monitor.mpp +++ b/src/wsi/linux/x11/monitor.mpp @@ -77,11 +77,11 @@ namespace stormkit::wsi::linux::x11 { if (crtc == nullptr) {} - monitor.extents.emplace_back(math::Extent2 { as(crtc.handle()->width), as(crtc.handle()->height) }); + monitor.extents.emplace_back(math::extent2 { as(crtc.handle()->width), as(crtc.handle()->height) }); } if (stdr::empty(monitor.extents)) - monitor.extents.emplace_back(math::Extent2 { as(xcb_monitor_iter.data->width), + monitor.extents.emplace_back(math::extent2 { as(xcb_monitor_iter.data->width), as(xcb_monitor_iter.data->height) }); } } diff --git a/src/wsi/linux/x11/window.cpp b/src/wsi/linux/x11/window.cpp index 41ecf7370..6eb1ee2c9 100644 --- a/src/wsi/linux/x11/window.cpp +++ b/src/wsi/linux/x11/window.cpp @@ -132,7 +132,7 @@ namespace stormkit::wsi::linux::x11 { ///////////////////////////////////// ///////////////////////////////////// - auto Window::open(std::string title, const math::Extent2& extent, WindowFlag flags) noexcept -> void { + auto Window::open(std::string title, const math::uextent2& extent, WindowFlag flags) noexcept -> void { const auto& connection = xcb::get_globals().connection; const auto screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data; @@ -460,7 +460,7 @@ namespace stormkit::wsi::linux::x11 { ///////////////////////////////////// ///////////////////////////////////// - auto Window::set_extent(const math::Extent2& extent) noexcept -> void { + auto Window::set_extent(const math::uextent2& extent) noexcept -> void { auto& globals = xcb::get_globals(); const auto mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; @@ -683,7 +683,7 @@ namespace stormkit::wsi::linux::x11 { auto configure_event = std::bit_cast(xevent); if ((configure_event->width != m_state.extent.width) || (configure_event->height != m_state.extent.height)) { - m_state.extent = math::Extent2 { configure_event->width, configure_event->height }.narrow_to(); + m_state.extent = math::extent2 { configure_event->width, configure_event->height }.narrow_to(); if (m_graphics_context) update_framebuffer(); diff --git a/src/wsi/linux/x11/window.mpp b/src/wsi/linux/x11/window.mpp index 4d2b5ea91..cb35efd11 100644 --- a/src/wsi/linux/x11/window.mpp +++ b/src/wsi/linux/x11/window.mpp @@ -72,7 +72,7 @@ export namespace stormkit::wsi::linux::x11 { Window(Window&&) noexcept; auto operator=(Window&&) noexcept -> Window&; - auto open(std::string title, const math::Extent2& size, WindowFlag flags) noexcept -> void; + auto open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> void; auto close() noexcept -> void; auto handle_events() noexcept -> void; @@ -81,7 +81,7 @@ export namespace stormkit::wsi::linux::x11 { auto fill_framebuffer(std::span> colors) noexcept -> void; auto set_title(std::string title) noexcept -> void; - auto set_extent(const math::Extent2& extent) noexcept -> void; + auto set_extent(const math::uextent2& extent) noexcept -> void; auto set_fullscreen(bool fullscreen) noexcept -> void; auto confine_mouse(bool confined, u8 mouse_id) noexcept -> void; diff --git a/src/wsi/macos/swift/CppBridge.cpp b/src/wsi/macos/swift/CppBridge.cpp index 336111155..c933c01b1 100644 --- a/src/wsi/macos/swift/CppBridge.cpp +++ b/src/wsi/macos/swift/CppBridge.cpp @@ -202,7 +202,7 @@ extern "C" { EXPECTS(ptr != 0); auto& window = *std::bit_cast(ptr); - window.WindowBase::set_extent(math::Extent2 { width, height }.to()); + window.WindowBase::set_extent(math::extent2 { width, height }.to()); window.resized_event(window.extent()); } diff --git a/src/wsi/macos/window.mpp b/src/wsi/macos/window.mpp index abb538f20..824ff620d 100644 --- a/src/wsi/macos/window.mpp +++ b/src/wsi/macos/window.mpp @@ -56,7 +56,7 @@ export namespace stormkit::wsi::macos { return *this; } - auto open(std::string title, const math::Extent2& size, WindowFlag flags) noexcept + auto open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> void { const auto resizeable = check_flag_bit(flags, WindowFlag::RESIZEABLE); const auto borderless = check_flag_bit(flags, WindowFlag::BORDERLESS); @@ -108,7 +108,7 @@ export namespace stormkit::wsi::macos { } } - auto set_extent([[maybe_unused]] const math::Extent2& extent) noexcept -> void {} + auto set_extent([[maybe_unused]] const math::uextent2& extent) noexcept -> void {} auto set_fullscreen(bool fullscreen) noexcept -> void { if (WindowBase::set_fullscreen(fullscreen)) {} diff --git a/src/wsi/win32/window.cpp b/src/wsi/win32/window.cpp index ed17052eb..34d4124a2 100644 --- a/src/wsi/win32/window.cpp +++ b/src/wsi/win32/window.cpp @@ -45,7 +45,7 @@ constexpr auto format_as(const RECT& rect, FormatContext& ctx) -> decltype(ctx.o rect.bottom); } -auto adjust_extent(const math::Extent2& extent, DWORD style, DWORD style_ex) noexcept -> math::Extent2 { +auto adjust_extent(const math::uextent2& extent, DWORD style, DWORD style_ex) noexcept -> math::extent2 { auto rect = RECT { .left = 0, .top = 0, .right = as(extent.width), .bottom = as(extent.height) }; AdjustWindowRectEx(&rect, style, FALSE, style_ex); @@ -105,7 +105,7 @@ namespace stormkit::wsi::win32 { ///////////////////////////////////// ///////////////////////////////////// - auto Window::open(std::string title, const math::Extent2& extent, WindowFlag flags) noexcept -> void { + auto Window::open(std::string title, const math::uextent2& extent, WindowFlag flags) noexcept -> void { auto style = DWORD { WS_SYSMENU | WS_BORDER }; auto style_ex = DWORD { 0 }; auto h_instance = GetModuleHandleA(nullptr); @@ -224,7 +224,7 @@ namespace stormkit::wsi::win32 { ///////////////////////////////////// ///////////////////////////////////// - auto Window::set_extent(const math::Extent2& extent) noexcept -> void { + auto Window::set_extent(const math::uextent2& extent) noexcept -> void { const auto adjusted = adjust_extent(extent, m_win32_state.style, m_win32_state.style_ex); SetWindowPos(m_window_handle, HWND_TOP, diff --git a/src/wsi/win32/window.mpp b/src/wsi/win32/window.mpp index 6c2543812..adb9b1022 100644 --- a/src/wsi/win32/window.mpp +++ b/src/wsi/win32/window.mpp @@ -34,7 +34,7 @@ export namespace stormkit::wsi::win32 { Window(Window&&) noexcept; auto operator=(Window&&) noexcept -> Window&; - auto open(std::string title, const math::Extent2& size, WindowFlag flags) noexcept + auto open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> void; auto close() noexcept -> void; @@ -44,7 +44,7 @@ export namespace stormkit::wsi::win32 { auto fill_framebuffer(std::span> colors) noexcept -> void; auto set_title(std::string title) noexcept -> void; - auto set_extent(const math::Extent2& extent) noexcept -> void; + auto set_extent(const math::uextent2& extent) noexcept -> void; auto set_fullscreen(bool fullscreen) noexcept -> void; auto confine_mouse(bool confined, u8 mouse_id) noexcept -> void; @@ -84,7 +84,7 @@ export namespace stormkit::wsi::win32 { [[nodiscard]] auto native_handle() const noexcept -> NativeHandle; - auto update_geometry(const math::Extent2& extent) noexcept -> void; + auto update_geometry(const math::uextent2& extent) noexcept -> void; auto win32_state(this auto& self) noexcept -> decltype(auto); auto state(this auto& self) noexcept -> decltype(auto); @@ -102,8 +102,8 @@ export namespace stormkit::wsi::win32 { bool mouse_inside = false; bool resizing = false; - math::Extent2 extent; - math::Extent2 last_extent; + math::uextent2 extent; + math::uextent2 last_extent; DWORD tls_index = 0; @@ -131,7 +131,7 @@ export namespace stormkit::wsi::win32 { HBitmap bitmap = HBitmap::empty(); std::atomic pixels_ptr = nullptr; - math::Extent2 extent; + math::extent2 extent; } m_gdi_frame_data; }; } // namespace stormkit::wsi::win32 @@ -165,7 +165,7 @@ namespace stormkit::wsi::win32 { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Window::update_geometry(const math::Extent2& extent) noexcept -> void { + inline auto Window::update_geometry(const math::uextent2& extent) noexcept -> void { m_state.extent = extent; m_win32_state.extent = extent; } diff --git a/src/wsi/window.cpp b/src/wsi/window.cpp index 534ee90c9..992a54017 100644 --- a/src/wsi/window.cpp +++ b/src/wsi/window.cpp @@ -63,7 +63,7 @@ namespace stormkit::wsi { ///////////////////////////////////// ///////////////////////////////////// - auto Window::open(std::string title, const math::Extent2& size, WindowFlag flags) noexcept -> Window { + auto Window::open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> Window { auto window = Window {}; window.m_impl->open(std::move(title), size, flags); return window; @@ -125,13 +125,13 @@ namespace stormkit::wsi { ///////////////////////////////////// ///////////////////////////////////// - auto Window::set_extent(const math::Extent2& extent) noexcept -> void { + auto Window::set_extent(const math::uextent2& extent) noexcept -> void { m_impl->set_extent(extent); } ///////////////////////////////////// ///////////////////////////////////// - auto Window::extent() const noexcept -> const math::Extent2& { + auto Window::extent() const noexcept -> const math::uextent2& { return m_impl->extent(); } From ee1bc54e3b79f34eb1b018f07ba071cdfde1bc12 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 19:19:36 +0100 Subject: [PATCH 044/194] (log) fix ConstexprString now in namespace meta --- modules/stormkit/log.mpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/modules/stormkit/log.mpp b/modules/stormkit/log.mpp index cfee13822..9b139ac81 100644 --- a/modules/stormkit/log.mpp +++ b/modules/stormkit/log.mpp @@ -116,7 +116,7 @@ export { std::string_view name = ""; }; - template + template [[nodiscard]] constexpr auto operator""_module() noexcept -> stormkit::log::Module; @@ -257,8 +257,7 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline ConsoleLogger::ConsoleLogger(const ConsoleLogger&) noexcept - = default; + inline ConsoleLogger::ConsoleLogger(const ConsoleLogger&) noexcept = default; //////////////////////////////////////// //////////////////////////////////////// @@ -268,8 +267,7 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline ConsoleLogger::ConsoleLogger(ConsoleLogger&&) noexcept - = default; + inline ConsoleLogger::ConsoleLogger(ConsoleLogger&&) noexcept = default; //////////////////////////////////////// //////////////////////////////////////// @@ -279,14 +277,12 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline ConsoleLogger::~ConsoleLogger() noexcept - = default; + inline ConsoleLogger::~ConsoleLogger() noexcept = default; //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline FileLogger::FileLogger(FileLogger&&) noexcept - = default; + inline FileLogger::FileLogger(FileLogger&&) noexcept = default; //////////////////////////////////////// //////////////////////////////////////// @@ -296,8 +292,7 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline FileLogger::~FileLogger() noexcept - = default; + inline FileLogger::~FileLogger() noexcept = default; //////////////////////////////////////// //////////////////////////////////////// @@ -396,7 +391,7 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// - template + template STORMKIT_FORCE_INLINE STORMKIT_CONST inline constexpr auto operator""_module() noexcept -> stormkit::log::Module { From 5b62416dfd4770125dca8c37172373cdc49edb45 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 19:31:58 +0100 Subject: [PATCH 045/194] (core, gpu, wsi, image) rename vector types --- .../entities/gameoflife/src/Constants.mpp | 4 +- examples/gpu/imgui/src/main.cpp | 6 +- examples/gpu/textured_cube/src/main.cpp | 8 +- examples/wsi/events/src/main.cpp | 6 +- modules/stormkit/core/math/extent.mpp | 2 +- modules/stormkit/core/math/linear-vector.mpp | 82 +++++++------------ modules/stormkit/core/math/linear.mpp | 22 ++--- modules/stormkit/gpu/core/structs.mpp | 12 +-- modules/stormkit/gpu/core/vulkan/structs.mpp | 22 ++--- modules/stormkit/image.mpp | 8 +- modules/stormkit/wsi/window.mpp | 14 ++-- src/wsi/common/input_base.mpp | 4 +- src/wsi/common/window_base.mpp | 2 +- src/wsi/ios/input_handler_impl.hpp | 8 +- src/wsi/linux/wayland/window.cpp | 2 +- src/wsi/linux/wayland/window.mpp | 2 +- src/wsi/linux/window.mpp | 4 +- src/wsi/linux/x11/window.cpp | 6 +- src/wsi/linux/x11/window.mpp | 2 +- src/wsi/macos/window.mpp | 2 +- src/wsi/win32/mouse.mpp | 4 +- src/wsi/win32/window.cpp | 18 ++-- src/wsi/win32/window.mpp | 2 +- src/wsi/window.cpp | 2 +- tests/core/math/linear-matrix.cpp | 4 +- tests/core/math/linear-vector.cpp | 22 ++--- 26 files changed, 123 insertions(+), 147 deletions(-) diff --git a/examples/entities/gameoflife/src/Constants.mpp b/examples/entities/gameoflife/src/Constants.mpp index 1b5a5fad4..8772b0bee 100644 --- a/examples/entities/gameoflife/src/Constants.mpp +++ b/examples/entities/gameoflife/src/Constants.mpp @@ -21,7 +21,7 @@ export { #endif inline constexpr auto VERTEX_SIZE - = sizeof(stormkit::math::vec2f) + sizeof(stormkit::vec3f); + = sizeof(stormkit::math::fvec2) + sizeof(stormkit::fvec3); inline constexpr auto WINDOW_TITLE = "StormKit GameOfLife Example"; inline constexpr auto MESH_VERTEX_BUFFER_SIZE = VERTEX_SIZE * 3; inline constexpr auto MESH_VERTEX_BINDING_DESCRIPTIONS = std::array { @@ -36,7 +36,7 @@ export { .binding = 0, .format = stormkit::gpu::format::f322, .offset - = sizeof(stormkit::math::vec2f) } + = sizeof(stormkit::math::fvec2) } }; inline constexpr auto BOARD_SIZE = 100u; diff --git a/examples/gpu/imgui/src/main.cpp b/examples/gpu/imgui/src/main.cpp index 730d88a0a..2b2c45518 100644 --- a/examples/gpu/imgui/src/main.cpp +++ b/examples/gpu/imgui/src/main.cpp @@ -171,13 +171,13 @@ class Application: public base::Application { if (key == wsi::Key::ESCAPE) m_window->close(); io.AddInputCharactersUTF8(&c); } }, - wsi::MouseMovedEventFunc { [&io](u8 /*id*/, const math::vec2i& position) mutable noexcept { + wsi::MouseMovedEventFunc { [&io](u8 /*id*/, const math::ivec2& position) mutable noexcept { const auto _position = position.to(); io.AddMouseSourceEvent(ImGuiMouseSource_Mouse); io.AddMousePosEvent(_position.x, _position.y); } }, - wsi::MouseButtonDownEventFunc { [&io](u8 /*id*/, wsi::MouseButton button, const math::vec2i&) mutable noexcept { + wsi::MouseButtonDownEventFunc { [&io](u8 /*id*/, wsi::MouseButton button, const math::ivec2&) mutable noexcept { auto mouse_button = -1; if (button == wsi::MouseButton::LEFT) mouse_button = 0; if (button == wsi::MouseButton::RIGHT) mouse_button = 1; @@ -188,7 +188,7 @@ class Application: public base::Application { io.AddMouseSourceEvent(ImGuiMouseSource_Mouse); io.AddMouseButtonEvent(mouse_button, true); } }, - wsi::MouseButtonUpEventFunc { [&io](u8 /*id*/, wsi::MouseButton button, const math::vec2i&) mutable noexcept { + wsi::MouseButtonUpEventFunc { [&io](u8 /*id*/, wsi::MouseButton button, const math::ivec2&) mutable noexcept { auto mouse_button = -1; if (button == wsi::MouseButton::LEFT) mouse_button = 0; if (button == wsi::MouseButton::RIGHT) mouse_button = 1; diff --git a/examples/gpu/textured_cube/src/main.cpp b/examples/gpu/textured_cube/src/main.cpp index fe2356c22..1eb2fd8ff 100644 --- a/examples/gpu/textured_cube/src/main.cpp +++ b/examples/gpu/textured_cube/src/main.cpp @@ -51,8 +51,8 @@ struct SwapchainImageResource { }; struct Vertex { - math::vec3f position; - math::vec2f uv; + math::fvec3 position; + math::fvec2 uv; static constexpr auto attribute_descriptions() noexcept -> std::array { return to_array({ @@ -430,7 +430,7 @@ class Application: public base::Application { window_extent_f32.width / window_extent_f32.height, 0.1f, 100.f), - .view = math::look_at(math::vec3f { 0.f, 3.f, 5.f }, { 0.f, 0.f, 0.f }, { 0.f, 1.f, 0.f }), + .view = math::look_at(math::fvec3 { 0.f, 3.f, 5.f }, { 0.f, 0.f, 0.f }, { 0.f, 1.f, 0.f }), .model = math::mat4f::identity(), }; @@ -452,7 +452,7 @@ class Application: public base::Application { // update viewer data and upload const auto time = stdc::duration_cast(current_time - m_start_time).count(); viewer_data - .model = math::rotate(math::mat4f::identity(), time * math::angle::radians(90.f), math::vec3f { 0.f, 1.f, 0.f }); + .model = math::rotate(math::mat4f::identity(), time * math::angle::radians(90.f), math::fvec3 { 0.f, 1.f, 0.f }); auto& viewer_buffer = submission_resource.viewer_buffer; TryAssert(viewer_buffer.upload(viewer_data), "Failed to upload texture to gpu"); diff --git a/examples/wsi/events/src/main.cpp b/examples/wsi/events/src/main.cpp index ef6c316d8..bcfe3b4e5 100644 --- a/examples/wsi/events/src/main.cpp +++ b/examples/wsi/events/src/main.cpp @@ -45,13 +45,13 @@ auto main(std::span args) -> int { wsi::MonitorChangedEventFunc { [](const wsi::Monitor& monitor) noexcept { ilog("Monitor changed event: {}", monitor); } }, - wsi::MouseMovedEventFunc { [](u8 /*id*/, const math::vec2i& position) noexcept { + wsi::MouseMovedEventFunc { [](u8 /*id*/, const math::ivec2& position) noexcept { ilog("Mouse move event: {}", position); } }, - wsi::MouseButtonDownEventFunc { [](u8 /*id*/, wsi::MouseButton button, const math::vec2i& position) noexcept { + wsi::MouseButtonDownEventFunc { [](u8 /*id*/, wsi::MouseButton button, const math::ivec2& position) noexcept { ilog("Mouse button down event: {} {}", button, position); } }, - wsi::MouseButtonUpEventFunc { [](u8 /*id*/, wsi::MouseButton button, const math::vec2i& position) noexcept { + wsi::MouseButtonUpEventFunc { [](u8 /*id*/, wsi::MouseButton button, const math::ivec2& position) noexcept { ilog("Mouse button up event: {} {}", button, position); } }, wsi::RestoredEventFunc { [] noexcept { ilog("Restored event"); } }, diff --git a/modules/stormkit/core/math/extent.mpp b/modules/stormkit/core/math/extent.mpp index 3340564be..337dc019c 100644 --- a/modules/stormkit/core/math/extent.mpp +++ b/modules/stormkit/core/math/extent.mpp @@ -382,7 +382,7 @@ static_assert(sizeof(math::uextent2) == sizeof(std::array)); static_assert(sizeof(math::uextent3) == sizeof(std::array)); static_assert(sizeof(math::iextent2) == sizeof(std::array)); -static_assert(sizeof(math::extent3_i) == sizeof(std::array)); +static_assert(sizeof(math::iextent3) == sizeof(std::array)); static_assert(sizeof(math::extent2) == sizeof(std::array)); static_assert(sizeof(math::extent3) == sizeof(std::array)); diff --git a/modules/stormkit/core/math/linear-vector.mpp b/modules/stormkit/core/math/linear-vector.mpp index 19ab9164b..dddc43bd4 100644 --- a/modules/stormkit/core/math/linear-vector.mpp +++ b/modules/stormkit/core/math/linear-vector.mpp @@ -40,17 +40,9 @@ export namespace stormkit { inline namespace core { namespace math { constexpr auto to() const noexcept -> vec2; }; - using vec2f32 = vec2; - using vec2f64 = vec2; - using vec2f = vec2f32; - - using vec2i32 = vec2; - using vec2i64 = vec2; - using vec2i = vec2i32; - - using vec2u32 = vec2; - using vec2u64 = vec2; - using vec2u = vec2u32; + using fvec2 = vec2; + using ivec2 = vec2; + using uvec2 = vec2; template struct alignas(std::array) vec3 { @@ -71,17 +63,9 @@ export namespace stormkit { inline namespace core { namespace math { constexpr auto to() const noexcept -> vec3; }; - using vec3f32 = vec3; - using vec3f64 = vec3; - using vec3f = vec3f32; - - using vec3i32 = vec3; - using vec3i64 = vec3; - using vec3i = vec3i32; - - using vec3u32 = vec3; - using vec3u64 = vec3; - using vec3u = vec3u32; + using fvec3 = vec3; + using ivec3 = vec3; + using uvec3 = vec3; template struct alignas(std::array) vec4 { @@ -103,17 +87,9 @@ export namespace stormkit { inline namespace core { namespace math { constexpr auto to() const noexcept -> vec4; }; - using vec4f32 = vec4; - using vec4f64 = vec4; - using vec4f = vec4f32; - - using vec4i32 = vec4; - using vec4i64 = vec4; - using vec4i = vec4i32; - - using vec4u32 = vec4; - using vec4u64 = vec4; - using vec4u = vec4u32; + using fvec4 = vec4; + using ivec4 = vec4; + using uvec4 = vec4; namespace meta { template @@ -193,26 +169,26 @@ export namespace stormkit { inline namespace core { namespace math { namespace stdr = std::ranges; namespace stormkit { inline namespace core { namespace math { - static_assert(sizeof(vec2u32) == sizeof(u32) * 2); - static_assert(sizeof(vec2u64) == sizeof(u64) * 2); - static_assert(sizeof(vec2i32) == sizeof(i32) * 2); - static_assert(sizeof(vec2i64) == sizeof(i64) * 2); - static_assert(sizeof(vec2f32) == sizeof(f32) * 2); - static_assert(sizeof(vec2f64) == sizeof(f64) * 2); - - static_assert(sizeof(vec3u32) == sizeof(u32) * 3); - static_assert(sizeof(vec3u64) == sizeof(u64) * 3); - static_assert(sizeof(vec3i32) == sizeof(i32) * 3); - static_assert(sizeof(vec3i64) == sizeof(i64) * 3); - static_assert(sizeof(vec3f32) == sizeof(f32) * 3); - static_assert(sizeof(vec3f64) == sizeof(f64) * 3); - - static_assert(sizeof(vec4u32) == sizeof(u32) * 4); - static_assert(sizeof(vec4u64) == sizeof(u64) * 4); - static_assert(sizeof(vec4i32) == sizeof(i32) * 4); - static_assert(sizeof(vec4i64) == sizeof(i64) * 4); - static_assert(sizeof(vec4f32) == sizeof(f32) * 4); - static_assert(sizeof(vec4f64) == sizeof(f64) * 4); + static_assert(sizeof(uvec2) == sizeof(u32) * 2); + static_assert(sizeof(vec2) == sizeof(u64) * 2); + static_assert(sizeof(ivec2) == sizeof(i32) * 2); + static_assert(sizeof(vec2) == sizeof(i64) * 2); + static_assert(sizeof(fvec2) == sizeof(f32) * 2); + static_assert(sizeof(vec2) == sizeof(f64) * 2); + + static_assert(sizeof(uvec3) == sizeof(u32) * 3); + static_assert(sizeof(vec3) == sizeof(u64) * 3); + static_assert(sizeof(ivec3) == sizeof(i32) * 3); + static_assert(sizeof(vec3) == sizeof(i64) * 3); + static_assert(sizeof(fvec3) == sizeof(f32) * 3); + static_assert(sizeof(vec3) == sizeof(f64) * 3); + + static_assert(sizeof(uvec4) == sizeof(u32) * 4); + static_assert(sizeof(vec4) == sizeof(u64) * 4); + static_assert(sizeof(ivec4) == sizeof(i32) * 4); + static_assert(sizeof(vec4) == sizeof(i64) * 4); + static_assert(sizeof(fvec4) == sizeof(f32) * 4); + static_assert(sizeof(vec4) == sizeof(f64) * 4); //////////////////////////////////////// //////////////////////////////////////// diff --git a/modules/stormkit/core/math/linear.mpp b/modules/stormkit/core/math/linear.mpp index f979273cf..581aa1e8d 100644 --- a/modules/stormkit/core/math/linear.mpp +++ b/modules/stormkit/core/math/linear.mpp @@ -218,13 +218,13 @@ namespace stormkit { inline namespace core { namespace math { using VecData = std::array; template - using Vec2Data = VecData; + using vec2data = VecData; template - using Vec3Data = VecData; + using vec3data = VecData; template - using Vec4Data = VecData; + using vec4data = VecData; // //////////////////////////////////////// // //////////////////////////////////////// @@ -612,13 +612,13 @@ namespace stormkit { inline namespace core { namespace math { const auto sin = std::sin(angle.get()); const auto axis_norm = [&axis] noexcept { - auto axis_norm = Vec3Data {}; + auto axis_norm = vec3data {}; normalize(axis, as_mdspan_mut<3>(axis_norm)); return axis_norm; }(); const auto temp = [&axis_norm, &cos] noexcept { - auto temp = Vec3Data {}; + auto temp = vec3data {}; mul(as_mdspan<3>(axis_norm), T { 1 } - cos, as_mdspan_mut<3>(temp)); return temp; }(); @@ -710,24 +710,24 @@ namespace stormkit { inline namespace core { namespace math { EXPECTS(center.data_handle() != out.data_handle()); EXPECTS(up.data_handle() != out.data_handle()); - const auto z_temp = init_by>([&eye, ¢er](auto& out) noexcept { + const auto z_temp = init_by>([&eye, ¢er](auto& out) noexcept { sub(center, eye, as_mdspan_mut<3>(out)); }); - const auto z = init_by>([&z_temp](auto& out) noexcept { + const auto z = init_by>([&z_temp](auto& out) noexcept { normalize(as_mdspan<3>(z_temp), as_mdspan_mut<3>(out)); }); - const auto x_temp = init_by>([&up, &z](auto& out) noexcept { + const auto x_temp = init_by>([&up, &z](auto& out) noexcept { cross(up, as_mdspan<3>(z), as_mdspan_mut<3>(out)); }); - const auto x = init_by>([&x_temp](auto& out) noexcept { + const auto x = init_by>([&x_temp](auto& out) noexcept { normalize(as_mdspan<3>(x_temp), as_mdspan_mut<3>(out)); }); - const auto y_temp = init_by>([&z, &x](auto& out) noexcept { + const auto y_temp = init_by>([&z, &x](auto& out) noexcept { cross(as_mdspan<3>(z), as_mdspan<3>(x), as_mdspan_mut<3>(out)); }); - const auto y = init_by>([&y_temp](auto& out) noexcept { + const auto y = init_by>([&y_temp](auto& out) noexcept { normalize(as_mdspan<3>(y_temp), as_mdspan_mut<3>(out)); }); diff --git a/modules/stormkit/gpu/core/structs.mpp b/modules/stormkit/gpu/core/structs.mpp index c6e9451f7..cb54e9822 100644 --- a/modules/stormkit/gpu/core/structs.mpp +++ b/modules/stormkit/gpu/core/structs.mpp @@ -224,13 +224,13 @@ export { }; struct Viewport { - math::vec2f position; + math::fvec2 position; math::extent2 extent; - math::vec2f depth; + math::fvec2 depth; }; struct Scissor { - math::vec2i offset; + math::ivec2 offset; math::uextent2 extent; }; @@ -252,7 +252,7 @@ export { ImageSubresourceLayers subresource_layers; - math::vec3i offset; + math::ivec3 offset; math::uextent3 extent; }; @@ -261,12 +261,12 @@ export { ImageSubresourceLayers dst; struct { - math::vec3i position; + math::ivec3 position; math::iextent3 extent; } src_offset; struct { - math::vec3i position; + math::ivec3 position; math::iextent3 extent; } dst_offset; }; diff --git a/modules/stormkit/gpu/core/vulkan/structs.mpp b/modules/stormkit/gpu/core/vulkan/structs.mpp index 4ade52be5..911b22309 100644 --- a/modules/stormkit/gpu/core/vulkan/structs.mpp +++ b/modules/stormkit/gpu/core/vulkan/structs.mpp @@ -25,25 +25,25 @@ export namespace stormkit::gpu { template [[nodiscard]] - constexpr auto to_vk(const math::vec2i& vector) noexcept -> Out; + constexpr auto to_vk(const math::ivec2& vector) noexcept -> Out; template [[nodiscard]] - constexpr auto to_vk(const math::vec3i& vector) noexcept -> Out; + constexpr auto to_vk(const math::ivec3& vector) noexcept -> Out; // template<> // [[nodiscard]] - // constexpr auto to_vk(const math::vec2i& vector) noexcept + // constexpr auto to_vk(const math::ivec2& vector) noexcept // -> VkOffset2D; [[nodiscard]] constexpr auto from_vk(const VkFormatProperties& properties) noexcept -> FormatProperties; [[nodiscard]] - constexpr auto from_vk(const VkOffset2D& vector) noexcept -> math::vec2i; + constexpr auto from_vk(const VkOffset2D& vector) noexcept -> math::ivec2; [[nodiscard]] - constexpr auto from_vk(const VkOffset3D& vector) noexcept -> math::vec3i; + constexpr auto from_vk(const VkOffset3D& vector) noexcept -> math::ivec3; [[nodiscard]] constexpr auto to_vk(const Viewport& viewport) noexcept -> VkViewport; @@ -138,7 +138,7 @@ namespace stormkit::gpu { template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto to_vk(const math::vec2i& vector) noexcept -> Out { + constexpr auto to_vk(const math::ivec2& vector) noexcept -> Out { return Out { .x = vector.x, .y = vector.y }; } @@ -147,7 +147,7 @@ namespace stormkit::gpu { template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto to_vk(const math::vec3i& vector) noexcept -> Out { + constexpr auto to_vk(const math::ivec3& vector) noexcept -> Out { return Out { .x = vector.x, .y = vector.y, .z = vector.z }; } @@ -165,15 +165,15 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto from_vk(const VkOffset2D& offset) noexcept -> math::vec2i { - return math::vec2i { offset.x, offset.y }; + constexpr auto from_vk(const VkOffset2D& offset) noexcept -> math::ivec2 { + return math::ivec2 { offset.x, offset.y }; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto from_vk(const VkOffset3D& offset) noexcept -> math::vec3i { - return math::vec3i { offset.x, offset.y, offset.z }; + constexpr auto from_vk(const VkOffset3D& offset) noexcept -> math::ivec3 { + return math::ivec3 { offset.x, offset.y, offset.z }; } ///////////////////////////////////// diff --git a/modules/stormkit/image.mpp b/modules/stormkit/image.mpp index 157f75177..a7b07466f 100644 --- a/modules/stormkit/image.mpp +++ b/modules/stormkit/image.mpp @@ -172,9 +172,9 @@ export namespace stormkit::image { [[nodiscard]] auto pixel(usize id, u32 layer = 0u, u32 face = 0u, u32 level = 0u) const noexcept -> std::span; [[nodiscard]] - auto pixel(math::vec3u position, u32 layer = 0u, u32 face = 0u, u32 level = 0u) noexcept -> std::span; + auto pixel(math::uvec3 position, u32 layer = 0u, u32 face = 0u, u32 level = 0u) noexcept -> std::span; [[nodiscard]] - auto pixel(math::vec3u position, u32 layer = 0u, u32 face = 0u, u32 level = 0u) const noexcept -> std::span; + auto pixel(math::uvec3 position, u32 layer = 0u, u32 face = 0u, u32 level = 0u) const noexcept -> std::span; [[nodiscard]] auto extent(u32 level = 0u) const noexcept -> math::uextent3; @@ -304,7 +304,7 @@ namespace stormkit::image { ///////////////////////////////////// ///////////////////////////////////// - inline auto Image::pixel(math::vec3u position, u32 layer, u32 face, u32 level) noexcept -> std::span { + inline auto Image::pixel(math::uvec3 position, u32 layer, u32 face, u32 level) noexcept -> std::span { const auto mip_extent = extent(level); const auto id = position.x + (position.y * mip_extent.width) + (mip_extent.width * mip_extent.height * position.z); @@ -314,7 +314,7 @@ namespace stormkit::image { ///////////////////////////////////// ///////////////////////////////////// - inline auto Image::pixel(math::vec3u position, u32 layer, u32 face, u32 level) const noexcept -> std::span { + inline auto Image::pixel(math::uvec3 position, u32 layer, u32 face, u32 level) const noexcept -> std::span { const auto mip_extent = extent(level); const auto id = position.x + (position.y * mip_extent.width) + (mip_extent.width * mip_extent.height * position.z); diff --git a/modules/stormkit/wsi/window.mpp b/modules/stormkit/wsi/window.mpp index 0edc31da6..c11b9b874 100644 --- a/modules/stormkit/wsi/window.mpp +++ b/modules/stormkit/wsi/window.mpp @@ -85,16 +85,16 @@ export { using std::function::function; }; - struct MouseButtonDownEventFunc: std::function { - using std::function::function; + struct MouseButtonDownEventFunc: std::function { + using std::function::function; }; - struct MouseButtonUpEventFunc: std::function { - using std::function::function; + struct MouseButtonUpEventFunc: std::function { + using std::function::function; }; - struct MouseMovedEventFunc: std::function { - using std::function::function; + struct MouseMovedEventFunc: std::function { + using std::function::function; }; struct DeactivateEventFunc: std::function { @@ -203,7 +203,7 @@ export { [[nodiscard]] auto is_virtual_keyboard_visible() const noexcept -> bool; - auto set_mouse_position(const math::vec2i& position, u8 mouse_id = GLOBAL_MOUSE_ID) noexcept -> void; + auto set_mouse_position(const math::ivec2& position, u8 mouse_id = GLOBAL_MOUSE_ID) noexcept -> void; [[nodiscard]] auto native_handle() const noexcept -> NativeHandle; diff --git a/src/wsi/common/input_base.mpp b/src/wsi/common/input_base.mpp index 2a2b00cec..bcb826c34 100644 --- a/src/wsi/common/input_base.mpp +++ b/src/wsi/common/input_base.mpp @@ -45,8 +45,8 @@ export namespace stormkit::wsi::common { bool relative = false; bool confined = false; - math::vec2u locked_at = {}; - math::vec2u last_position = {}; + math::uvec2 locked_at = {}; + math::uvec2 last_position = {}; std::array buttons = filled_with<15>(ButtonState::UP); }; diff --git a/src/wsi/common/window_base.mpp b/src/wsi/common/window_base.mpp index 7b584848f..e2fe21f49 100644 --- a/src/wsi/common/window_base.mpp +++ b/src/wsi/common/window_base.mpp @@ -106,7 +106,7 @@ export namespace stormkit::wsi::common { f32 dpi = 1.f; - math::vec2i position = { 0, 0 }; + math::ivec2 position = { 0, 0 }; } m_state; std::vector m_mouse_states; diff --git a/src/wsi/ios/input_handler_impl.hpp b/src/wsi/ios/input_handler_impl.hpp index 2d5307ff6..409f574f3 100644 --- a/src/wsi/ios/input_handler_impl.hpp +++ b/src/wsi/ios/input_handler_impl.hpp @@ -23,10 +23,10 @@ namespace storm::window { static bool isKeyPressed(Key key); static bool isMouseButtonPressed(MouseButton button); - static void set_mouse_position(core::math::vec2u position); - static void set_mouse_position(core::math::vec2u position, const Window& relative_to); - static core::math::vec2u getMousePosition(); - static core::math::vec2u getMousePosition(const Window& relative_to); + static void set_mouse_position(core::math::uvec2 position); + static void set_mouse_position(core::math::uvec2 position, const Window& relative_to); + static core::math::uvec2 getMousePosition(); + static core::math::uvec2 getMousePosition(const Window& relative_to); static void toggle_virtual_keyboard_visibility(bool visible); diff --git a/src/wsi/linux/wayland/window.cpp b/src/wsi/linux/wayland/window.cpp index b830d2fca..8d9d3b007 100644 --- a/src/wsi/linux/wayland/window.cpp +++ b/src/wsi/linux/wayland/window.cpp @@ -430,7 +430,7 @@ namespace stormkit::wsi::linux::wayland { ///////////////////////////////////// ///////////////////////////////////// - auto Window::set_mouse_position(const math::vec2i& position, u8 mouse_id) noexcept -> void { + auto Window::set_mouse_position(const math::ivec2& position, u8 mouse_id) noexcept -> void { if (not m_state.open) return; auto& globals = wl::get_globals(); diff --git a/src/wsi/linux/wayland/window.mpp b/src/wsi/linux/wayland/window.mpp index 0493b0c2a..739d184ff 100644 --- a/src/wsi/linux/wayland/window.mpp +++ b/src/wsi/linux/wayland/window.mpp @@ -79,7 +79,7 @@ export { [[nodiscard]] auto is_virtual_keyboard_visible() const noexcept -> bool; - auto set_mouse_position(const math::vec2i& position, u8 id) noexcept -> void; + auto set_mouse_position(const math::ivec2& position, u8 id) noexcept -> void; [[nodiscard]] auto native_handle() const noexcept -> NativeHandle; diff --git a/src/wsi/linux/window.mpp b/src/wsi/linux/window.mpp index e359669aa..a4b7bc87f 100644 --- a/src/wsi/linux/window.mpp +++ b/src/wsi/linux/window.mpp @@ -88,7 +88,7 @@ export namespace stormkit::wsi::linux { [[nodiscard]] auto is_virtual_keyboard_visible() const noexcept -> bool; - auto set_mouse_position(const math::vec2i& position, u8 mouse_id = 0) noexcept -> void; + auto set_mouse_position(const math::ivec2& position, u8 mouse_id = 0) noexcept -> void; [[nodiscard]] auto native_handle() const noexcept -> NativeHandle; @@ -481,7 +481,7 @@ namespace stormkit::wsi::linux { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Window::set_mouse_position(const math::vec2i& position, u8 mouse_id) noexcept -> void { + inline auto Window::set_mouse_position(const math::ivec2& position, u8 mouse_id) noexcept -> void { switch (m_wm) { case WM::X11: as(m_impl).set_mouse_position(position, mouse_id); break; case WM::WAYLAND: as(m_impl).set_mouse_position(position, mouse_id); break; diff --git a/src/wsi/linux/x11/window.cpp b/src/wsi/linux/x11/window.cpp index 6eb1ee2c9..422b71df4 100644 --- a/src/wsi/linux/x11/window.cpp +++ b/src/wsi/linux/x11/window.cpp @@ -613,7 +613,7 @@ namespace stormkit::wsi::linux::x11 { ///////////////////////////////////// ///////////////////////////////////// - auto Window::set_mouse_position(const math::vec2i& position, u8) noexcept -> void { + auto Window::set_mouse_position(const math::ivec2& position, u8) noexcept -> void { auto& globals = xcb::get_globals(); const auto _position = position.to(); @@ -748,7 +748,7 @@ namespace stormkit::wsi::linux::x11 { auto button = button_event->detail; WindowBase::mouse_button_down_event(GLOBAL_MOUSE_ID, x11_button_to_stormkit(as(button)), - math::vec2i { button_event->event_x, button_event->event_y }); + math::ivec2 { button_event->event_x, button_event->event_y }); } break; case XCB_INPUT_BUTTON_RELEASE: [[fallthrough]]; case XCB_INPUT_RAW_BUTTON_RELEASE: { @@ -757,7 +757,7 @@ namespace stormkit::wsi::linux::x11 { auto button = button_event->detail; WindowBase::mouse_button_up_event(GLOBAL_MOUSE_ID, x11_button_to_stormkit(as(button)), - math::vec2i { button_event->event_x, button_event->event_y }); + math::ivec2 { button_event->event_x, button_event->event_y }); } break; } } diff --git a/src/wsi/linux/x11/window.mpp b/src/wsi/linux/x11/window.mpp index cb35efd11..83bf59545 100644 --- a/src/wsi/linux/x11/window.mpp +++ b/src/wsi/linux/x11/window.mpp @@ -108,7 +108,7 @@ export namespace stormkit::wsi::linux::x11 { [[nodiscard]] auto is_virtual_keyboard_visible() const noexcept -> bool; - auto set_mouse_position(const math::vec2i& position, u8 mouse_id) noexcept -> void; + auto set_mouse_position(const math::ivec2& position, u8 mouse_id) noexcept -> void; [[nodiscard]] auto native_handle() const noexcept -> NativeHandle; diff --git a/src/wsi/macos/window.mpp b/src/wsi/macos/window.mpp index 824ff620d..6e7a96901 100644 --- a/src/wsi/macos/window.mpp +++ b/src/wsi/macos/window.mpp @@ -180,7 +180,7 @@ export namespace stormkit::wsi::macos { return false; } - auto set_mouse_position([[maybe_unused]] const math::vec2i& position, + auto set_mouse_position([[maybe_unused]] const math::ivec2& position, [[maybe_unused]] u8 mouse_id) noexcept -> void {} [[nodiscard]] diff --git a/src/wsi/win32/mouse.mpp b/src/wsi/win32/mouse.mpp index c7b090c0f..41ca6ce01 100644 --- a/src/wsi/win32/mouse.mpp +++ b/src/wsi/win32/mouse.mpp @@ -20,7 +20,7 @@ export namespace stormkit::wsi::win32 { constexpr auto extract_mouse_position(HWND handle, WPARAM w_param, LPARAM l_param, - bool to_client = true) noexcept -> math::vec2i; + bool to_client = true) noexcept -> math::ivec2; } // namespace stormkit::wsi::win32 //////////////////////////////////////////////////////////////////// @@ -57,7 +57,7 @@ namespace stormkit::wsi::win32 { constexpr auto extract_mouse_position(HWND handle, WPARAM, LPARAM l_param, - bool to_client) noexcept -> math::vec2i { + bool to_client) noexcept -> math::ivec2 { auto position = POINT { GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param) }; if (to_client) ScreenToClient(handle, &position); diff --git a/src/wsi/win32/window.cpp b/src/wsi/win32/window.cpp index 34d4124a2..834f38cde 100644 --- a/src/wsi/win32/window.cpp +++ b/src/wsi/win32/window.cpp @@ -61,7 +61,7 @@ namespace stormkit::wsi::win32 { auto get_client_rect(HWND window_handle) noexcept -> RECT; - // auto get_monitor_scale(HMONITOR monitor) -> math::vec2f; + // auto get_monitor_scale(HMONITOR monitor) -> math::fvec2; auto CALLBACK global_on_event(HWND handle, UINT message, WPARAM w_param, LPARAM l_param) noexcept -> LRESULT; @@ -422,7 +422,7 @@ namespace stormkit::wsi::win32 { ///////////////////////////////////// ///////////////////////////////////// - auto Window::set_mouse_position(const math::vec2i& position, u8 id) noexcept -> void { + auto Window::set_mouse_position(const math::ivec2& position, u8 id) noexcept -> void { expects(id == GLOBAL_MOUSE_ID, "StormKit WSI win32 backend only support one mouse"); auto mouse_position = POINT { as(position.x), as(position.y) }; ClientToScreen(m_window_handle, &mouse_position); @@ -499,8 +499,8 @@ namespace stormkit::wsi::win32 { ///////////////////////////////////// ///////////////////////////////////// - // auto get_monitor_scale(HMONITOR monitor) -> math::vec2f { - // auto scale = math::vec2f {}; + // auto get_monitor_scale(HMONITOR monitor) -> math::fvec2 { + // auto scale = math::fvec2 {}; // auto x_dpi = 0u; // auto y_dpi = 0u; @@ -627,7 +627,7 @@ namespace stormkit::wsi::win32 { case WM_XBUTTONDOWN: { const auto [x, y] = extract_mouse_position(window_handle, w_param, l_param, false); const auto button = extract_mouse_button(message, w_param, l_param); - window.mouse_button_down_event(GLOBAL_MOUSE_ID, button, math::vec2i { x, y }); + window.mouse_button_down_event(GLOBAL_MOUSE_ID, button, math::ivec2 { x, y }); } break; case WM_LBUTTONUP: [[fallthrough]]; case WM_RBUTTONUP: [[fallthrough]]; @@ -635,7 +635,7 @@ namespace stormkit::wsi::win32 { case WM_XBUTTONUP: { const auto [x, y] = extract_mouse_position(window_handle, w_param, l_param, false); const auto button = extract_mouse_button(message, w_param, l_param); - window.mouse_button_up_event(GLOBAL_MOUSE_ID, button, math::vec2i { x, y }); + window.mouse_button_up_event(GLOBAL_MOUSE_ID, button, math::ivec2 { x, y }); } break; case WM_KEYDOWN: [[fallthrough]]; case WM_SYSKEYDOWN: { @@ -680,13 +680,13 @@ namespace stormkit::wsi::win32 { if (state.locked and state.relative) { const auto relative_x = x - as(state.locked_at.x); const auto relative_y = y - as(state.locked_at.y); - window.mouse_moved_event(GLOBAL_MOUSE_ID, math::vec2i { relative_x, relative_y }); + window.mouse_moved_event(GLOBAL_MOUSE_ID, math::ivec2 { relative_x, relative_y }); } else if (state.relative) { const auto relative_x = x - as(state.last_position.x); const auto relative_y = y - as(state.last_position.y); - window.mouse_moved_event(GLOBAL_MOUSE_ID, math::vec2i { relative_x, relative_y }); + window.mouse_moved_event(GLOBAL_MOUSE_ID, math::ivec2 { relative_x, relative_y }); } else - window.mouse_moved_event(GLOBAL_MOUSE_ID, math::vec2i { x, y }); + window.mouse_moved_event(GLOBAL_MOUSE_ID, math::ivec2 { x, y }); } break; default: return; } diff --git a/src/wsi/win32/window.mpp b/src/wsi/win32/window.mpp index adb9b1022..36a742a19 100644 --- a/src/wsi/win32/window.mpp +++ b/src/wsi/win32/window.mpp @@ -71,7 +71,7 @@ export namespace stormkit::wsi::win32 { [[nodiscard]] auto is_virtual_keyboard_visible() const noexcept -> bool; - auto set_mouse_position(const math::vec2i& position, u8 mouse_id) noexcept -> void; + auto set_mouse_position(const math::ivec2& position, u8 mouse_id) noexcept -> void; [[nodiscard]] auto is_mouse_inside() const noexcept -> bool; diff --git a/src/wsi/window.cpp b/src/wsi/window.cpp index 992a54017..ac294d7b6 100644 --- a/src/wsi/window.cpp +++ b/src/wsi/window.cpp @@ -221,7 +221,7 @@ namespace stormkit::wsi { ///////////////////////////////////// ///////////////////////////////////// - auto Window::set_mouse_position(const math::vec2i& position, u8 mouse_id) noexcept -> void { + auto Window::set_mouse_position(const math::ivec2& position, u8 mouse_id) noexcept -> void { m_impl->set_mouse_position(position, mouse_id); } diff --git a/tests/core/math/linear-matrix.cpp b/tests/core/math/linear-matrix.cpp index d8231a6dd..c0fa598ff 100644 --- a/tests/core/math/linear-matrix.cpp +++ b/tests/core/math/linear-matrix.cpp @@ -120,7 +120,7 @@ namespace { "linear.matrix.translate", [] static { constexpr auto a = math::mat4f::identity(); - const auto b = math::vec3f { 3, 2, 3 }; + const auto b = math::fvec3 { 3, 2, 3 }; const auto result = math::translate(a, b); EXPECTS((result[0, 0] == 1)); @@ -135,7 +135,7 @@ namespace { "linear.matrix.scale", [] static { const auto a = math::mat4i::identity(); - const auto b = math::vec3i { 3, 2, 3 }; + const auto b = math::ivec3 { 3, 2, 3 }; const auto result = math::scale(a, b); EXPECTS((result[0, 0] == 3)); diff --git a/tests/core/math/linear-vector.cpp b/tests/core/math/linear-vector.cpp index d9ff47151..05a2182f7 100644 --- a/tests/core/math/linear-vector.cpp +++ b/tests/core/math/linear-vector.cpp @@ -19,8 +19,8 @@ namespace { { "linear.vector.add", [] static { - const auto a = math::vec2i { 2, 3 }; - const auto b = math::vec2i { 3, 2 }; + const auto a = math::ivec2 { 2, 3 }; + const auto b = math::ivec2 { 3, 2 }; const auto result = add(a, b); EXPECTS(result.x == 5); @@ -29,8 +29,8 @@ namespace { }, { "linear.vector.sub", [] static { - const auto a = math::vec2i { 2, 3 }; - const auto b = math::vec2i { 3, 2 }; + const auto a = math::ivec2 { 2, 3 }; + const auto b = math::ivec2 { 3, 2 }; const auto result = sub(a, b); EXPECTS(result.x == -1); @@ -39,7 +39,7 @@ namespace { }, { "linear.vector.mul", [] static { - const auto a = math::vec2i { 10, 6 }; + const auto a = math::ivec2 { 10, 6 }; const auto result = mul(a, 2); EXPECTS(result.x == 20); @@ -48,7 +48,7 @@ namespace { }, { "linear.vector.div", [] static { - const auto a = math::vec2i { 10, 6 }; + const auto a = math::ivec2 { 10, 6 }; const auto result = div(a, 2); EXPECTS(result.x == 5); @@ -57,16 +57,16 @@ namespace { }, { "linear.vector.dot", [] static { - const auto a = math::vec2i { 2, 3 }; - const auto b = math::vec2i { 3, 2 }; + const auto a = math::ivec2 { 2, 3 }; + const auto b = math::ivec2 { 3, 2 }; EXPECTS(math::dot(a, b) == 12); }, }, { "linear.vector.cross", [] static { - const auto a = math::vec3i { 2, 3, 2 }; - const auto b = math::vec3i { 3, 2, 3 }; + const auto a = math::ivec3 { 2, 3, 2 }; + const auto b = math::ivec3 { 3, 2, 3 }; const auto result = math::cross(a, b); EXPECTS(result.x == 5 and result.y == 0 and result.z == -5); @@ -74,7 +74,7 @@ namespace { }, { "linear.vector.normalize", [] static { - const auto a = math::vec2f { + const auto a = math::fvec2 { 1, 2, }; From 422c441e74b27999fd209b681ebc8589c9a47cf7 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 19:36:17 +0100 Subject: [PATCH 046/194] (core, gpu) update matrix naming --- examples/gpu/textured_cube/src/main.cpp | 10 +- modules/stormkit/core/math/linear-matrix.mpp | 191 +++++-------------- tests/core/math/linear-matrix.cpp | 28 +-- 3 files changed, 70 insertions(+), 159 deletions(-) diff --git a/examples/gpu/textured_cube/src/main.cpp b/examples/gpu/textured_cube/src/main.cpp index 1eb2fd8ff..ab81193d2 100644 --- a/examples/gpu/textured_cube/src/main.cpp +++ b/examples/gpu/textured_cube/src/main.cpp @@ -67,9 +67,9 @@ struct Vertex { }; struct ViewerData { - math::mat4f proj; - math::mat4f view; - math::mat4f model; + math::fmat4 proj; + math::fmat4 view; + math::fmat4 model; static constexpr auto layout_binding() -> gpu::DescriptorSetLayoutBinding { return { .binding = 0, @@ -431,7 +431,7 @@ class Application: public base::Application { 0.1f, 100.f), .view = math::look_at(math::fvec3 { 0.f, 3.f, 5.f }, { 0.f, 0.f, 0.f }, { 0.f, 1.f, 0.f }), - .model = math::mat4f::identity(), + .model = math::fmat4::identity(), }; // get next swapchain image @@ -452,7 +452,7 @@ class Application: public base::Application { // update viewer data and upload const auto time = stdc::duration_cast(current_time - m_start_time).count(); viewer_data - .model = math::rotate(math::mat4f::identity(), time * math::angle::radians(90.f), math::fvec3 { 0.f, 1.f, 0.f }); + .model = math::rotate(math::fmat4::identity(), time * math::angle::radians(90.f), math::fvec3 { 0.f, 1.f, 0.f }); auto& viewer_buffer = submission_resource.viewer_buffer; TryAssert(viewer_buffer.upload(viewer_data), "Failed to upload texture to gpu"); diff --git a/modules/stormkit/core/math/linear-matrix.mpp b/modules/stormkit/core/math/linear-matrix.mpp index 12b9477f9..0562e7a02 100644 --- a/modules/stormkit/core/math/linear-matrix.mpp +++ b/modules/stormkit/core/math/linear-matrix.mpp @@ -72,147 +72,58 @@ export { template using mat2x2 = mat; - - using mat2x2f32 = mat2x2; - using mat2x2f64 = mat2x2; - using mat2x2f = mat2x2f32; - using mat2f = mat2x2f; - - using mat2x2i32 = mat2x2; - using mat2x2i64 = mat2x2; - using mat2x2i = mat2x2i32; - using mat2i = mat2x2i; - - using mat2x2u32 = mat2x2; - using mat2x2u64 = mat2x2; - using mat2x2u = mat2x2u32; - using mat2u = mat2x2u; - template using mat3x3 = mat; - - using mat3x3f32 = mat3x3; - using mat3x3f64 = mat3x3; - using mat3x3f = mat3x3f32; - using mat3f = mat3x3f; - - using mat3x3i32 = mat3x3; - using mat3x3i64 = mat3x3; - using mat3x3i = mat3x3i32; - using mat3i = mat3x3i; - - using mat3x3u32 = mat3x3; - using mat3x3u64 = mat3x3; - using mat3x3u = mat3x3u32; - using mat3u = mat3x3u; - template using mat4x4 = mat; - - using mat4x4f32 = mat4x4; - using mat4x4f64 = mat4x4; - using mat4x4f = mat4x4f32; - using mat4f = mat4x4f; - - using mat4x4i32 = mat4x4; - using mat4x4i64 = mat4x4; - using mat4x4i = mat4x4i32; - using mat4i = mat4x4i; - - using mat4x4u32 = mat4x4; - using mat4x4u64 = mat4x4; - using mat4x4u = mat4x4u32; - using mat4u = mat4x4u; - template using mat2x3 = mat; - - using mat2x3f32 = mat2x3; - using mat2x3f64 = mat2x3; - using mat2x3f = mat2x3f32; - - using mat2x3i32 = mat2x3; - using mat2x3i64 = mat2x3; - using mat2x3i = mat2x3i32; - - using mat2x3u32 = mat2x3; - using mat2x3u64 = mat2x3; - using mat2x3u = mat2x3u32; - template using mat3x2 = mat; - - using mat3x2f32 = mat3x2; - using mat3x2f64 = mat3x2; - using mat3x2f = mat3x2f32; - - using mat3x2i32 = mat3x2; - using mat3x2i64 = mat3x2; - using mat3x2i = mat3x2i32; - - using mat3x2u32 = mat3x2; - using mat3x2u64 = mat3x2; - using mat3x2u = mat3x2u32; - template using mat4x3 = mat; - - using mat4x3f32 = mat4x3; - using mat4x3f64 = mat4x3; - using mat4x3f = mat4x3f32; - - using mat4x3i32 = mat4x3; - using mat4x3i64 = mat4x3; - using mat4x3i = mat4x3i32; - - using mat4x3u32 = mat4x3; - using mat4x3u64 = mat4x3; - using mat4x3u = mat4x3u32; - template using mat3x4 = mat; - - using mat3x4f32 = mat3x4; - using mat3x4f64 = mat3x4; - using mat3x4f = mat3x4f32; - - using mat3x4i32 = mat3x4; - using mat3x4i64 = mat3x4; - using mat3x4i = mat3x4i32; - - using mat3x4u32 = mat3x4; - using mat3x4u64 = mat3x4; - using mat3x4u = mat3x4u32; - template using mat4x2 = mat; + template + using mat2x4 = mat; - using mat4x2f32 = mat4x2; - using mat4x2f64 = mat4x2; - using mat4x2f = mat4x2f32; + using fmat2 = mat2x2; + using imat2 = mat2x2; + using umat2 = mat2x2; - using mat4x2i32 = mat4x2; - using mat4x2i64 = mat4x2; - using mat4x2i = mat4x2i32; + using fmat3 = mat3x3; + using imat3 = mat3x3; + using umat3 = mat3x3; - using mat4x2u32 = mat4x2; - using mat4x2u64 = mat4x2; - using mat4x2u = mat4x2u32; + using fmat4 = mat4x4; + using imat4 = mat4x4; + using umat4 = mat4x4; - template - using mat2x4 = mat; + using fmat2x3 = mat2x3; + using imat2x3 = mat2x3; + using umat2x3 = mat2x3; + + using fmat3x2 = mat3x2; + using imat3x2 = mat3x2; + using umat3x2 = mat3x2; + + using fmat4x3 = mat4x3; + using imat4x3 = mat4x3; + using umat4x3 = mat4x3; - using mat2x4f32 = mat2x4; - using mat2x4f64 = mat2x4; - using mat2x4f = mat2x4f32; + using fmat3x4 = mat3x4; + using imat3x4 = mat3x4; + using umat3x4 = mat3x4; - using mat2x4i32 = mat2x4; - using mat2x4i64 = mat2x4; - using mat2x4i = mat2x4i32; + using fmat4x2 = mat4x2; + using imat4x2 = mat4x2; + using umat4x2 = mat4x2; - using mat2x4u32 = mat2x4; - using mat2x4u64 = mat2x4; - using mat2x4u = mat2x4u32; + using fmat2x4 = mat2x4; + using imat2x4 = mat2x4; + using umat2x4 = mat2x4; namespace meta { template @@ -335,26 +246,26 @@ namespace stdr = std::ranges; namespace stdv = std::views; namespace stormkit { inline namespace core { namespace math { - static_assert(sizeof(mat2x2i32) == sizeof(i32) * 2 * 2); - static_assert(sizeof(mat2x2i64) == sizeof(i64) * 2 * 2); - static_assert(sizeof(mat2x2u32) == sizeof(u32) * 2 * 2); - static_assert(sizeof(mat2x2u64) == sizeof(u64) * 2 * 2); - static_assert(sizeof(mat2x2f32) == sizeof(f32) * 2 * 2); - static_assert(sizeof(mat2x2f64) == sizeof(f64) * 2 * 2); - - static_assert(sizeof(mat3x3i32) == sizeof(i32) * 3 * 3); - static_assert(sizeof(mat3x3i64) == sizeof(i64) * 3 * 3); - static_assert(sizeof(mat3x3u32) == sizeof(u32) * 3 * 3); - static_assert(sizeof(mat3x3u64) == sizeof(u64) * 3 * 3); - static_assert(sizeof(mat3x3f32) == sizeof(f32) * 3 * 3); - static_assert(sizeof(mat3x3f64) == sizeof(f64) * 3 * 3); - - static_assert(sizeof(mat4x4i32) == sizeof(i32) * 4 * 4); - static_assert(sizeof(mat4x4i64) == sizeof(i64) * 4 * 4); - static_assert(sizeof(mat4x4u32) == sizeof(u32) * 4 * 4); - static_assert(sizeof(mat4x4u64) == sizeof(u64) * 4 * 4); - static_assert(sizeof(mat4x4f32) == sizeof(f32) * 4 * 4); - static_assert(sizeof(mat4x4f64) == sizeof(f64) * 4 * 4); + static_assert(sizeof(mat2x2) == sizeof(i32) * 2 * 2); + static_assert(sizeof(mat2x2) == sizeof(i64) * 2 * 2); + static_assert(sizeof(mat2x2) == sizeof(u32) * 2 * 2); + static_assert(sizeof(mat2x2) == sizeof(u64) * 2 * 2); + static_assert(sizeof(mat2x2) == sizeof(f32) * 2 * 2); + static_assert(sizeof(mat2x2) == sizeof(f64) * 2 * 2); + + static_assert(sizeof(mat3x3) == sizeof(i32) * 3 * 3); + static_assert(sizeof(mat3x3) == sizeof(i64) * 3 * 3); + static_assert(sizeof(mat3x3) == sizeof(u32) * 3 * 3); + static_assert(sizeof(mat3x3) == sizeof(u64) * 3 * 3); + static_assert(sizeof(mat3x3) == sizeof(f32) * 3 * 3); + static_assert(sizeof(mat3x3) == sizeof(f64) * 3 * 3); + + static_assert(sizeof(mat4x4) == sizeof(i32) * 4 * 4); + static_assert(sizeof(mat4x4) == sizeof(i64) * 4 * 4); + static_assert(sizeof(mat4x4) == sizeof(u32) * 4 * 4); + static_assert(sizeof(mat4x4) == sizeof(u64) * 4 * 4); + static_assert(sizeof(mat4x4) == sizeof(f32) * 4 * 4); + static_assert(sizeof(mat4x4) == sizeof(f64) * 4 * 4); //////////////////////////////////////// //////////////////////////////////////// diff --git a/tests/core/math/linear-matrix.cpp b/tests/core/math/linear-matrix.cpp index c0fa598ff..66c263931 100644 --- a/tests/core/math/linear-matrix.cpp +++ b/tests/core/math/linear-matrix.cpp @@ -19,16 +19,16 @@ namespace { { "linear.matrix.determinant", [] static { - const auto det_1 = determinant(math::mat2i { 2, 1, 4, 5 }); + const auto det_1 = determinant(math::imat2 { 2, 1, 4, 5 }); EXPECTS(det_1 == 6); - const auto det_2 = determinant(math::mat3i { 2, 1, 1, 1, 0, 1, 0, 3, 1 }); + const auto det_2 = determinant(math::imat3 { 2, 1, 1, 1, 0, 1, 0, 3, 1 }); EXPECTS(det_2 == -4); }, }, { "linear.matrix.transpose", [] static { - const auto a = math::mat4i { 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 4, 0, 0, 0 }; + const auto a = math::imat4 { 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 4, 0, 0, 0 }; const auto result = transpose(a); EXPECTS((result[0, 1] == 0)); @@ -43,13 +43,13 @@ namespace { }, { "linear.matrix.is_inversible", [] static { - EXPECTS(math::is_inversible(math::mat2i { -3, 1, 5, 0 })); + EXPECTS(math::is_inversible(math::imat2 { -3, 1, 5, 0 })); EXPECTS(not math::is_inversible(math::mat { 2, 3, 4, 2, 1, 8 })); }, }, { "linear.matrix.inverse", [] static { - const auto a = math::mat3f { 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 8.f }; + const auto a = math::fmat3 { 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 8.f }; const auto result = math::inverse(a); EXPECTS(is_equal(result[0, 0], -8.f / 3.f)); @@ -65,13 +65,13 @@ namespace { }, { "linear.matrix.is_orthogonal", [] static { - EXPECTS(math::is_orthogonal(math::mat3i { 0, 1, 0, 0, 0, 1, 1, 0, 0 })); + EXPECTS(math::is_orthogonal(math::imat3 { 0, 1, 0, 0, 0, 1, 1, 0, 0 })); EXPECTS(not math::is_orthogonal(math::mat {})); }, }, { "linear.matrix.mul.scalar", [] static { - const auto a = math::mat4i { 22, 0, 0, 0, 0, 4, 0, 0, 0, 0, 8, 0, 0, 0, 0, 10 }; + const auto a = math::imat4 { 22, 0, 0, 0, 0, 4, 0, 0, 0, 0, 8, 0, 0, 0, 0, 10 }; const auto b = 2; const auto result = math::mul(a, b); @@ -83,7 +83,7 @@ namespace { }, { "linear.matrix.div.scalar", [] static { - const auto a = math::mat4i { 22, 0, 0, 0, 0, 4, 0, 0, 0, 0, 8, 0, 0, 0, 0, 10 }; + const auto a = math::imat4 { 22, 0, 0, 0, 0, 4, 0, 0, 0, 0, 8, 0, 0, 0, 0, 10 }; const auto b = 2; const auto result = math::div(a, b); @@ -95,8 +95,8 @@ namespace { }, { "linear.matrix.mul.matrix", [] static { - const auto a = math::mat4i { 22, 0, 0, 0, 0, 4, 0, 0, 0, 0, 8, 0, 0, 0, 0, 10 }; - const auto b = math::mat4i { 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 0, 26 }; + const auto a = math::imat4 { 22, 0, 0, 0, 0, 4, 0, 0, 0, 0, 8, 0, 0, 0, 0, 10 }; + const auto b = math::imat4 { 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 10, 0, 0, 0, 0, 26 }; const auto result = math::mul(a, b); EXPECTS((result[0, 0] == 44)); @@ -107,8 +107,8 @@ namespace { }, { "linear.matrix.div.matrix", [] static { - const auto a = math::mat2f { 0, 1, 2, 3 }; - const auto b = math::mat2f { 1, 2, 3, 4 }; + const auto a = math::fmat2 { 0, 1, 2, 3 }; + const auto b = math::fmat2 { 1, 2, 3, 4 }; const auto result = math::div(a, b); EXPECTS(is_equal(result[0], 3.f / 2.f)); @@ -119,7 +119,7 @@ namespace { }, { "linear.matrix.translate", [] static { - constexpr auto a = math::mat4f::identity(); + constexpr auto a = math::fmat4::identity(); const auto b = math::fvec3 { 3, 2, 3 }; const auto result = math::translate(a, b); @@ -134,7 +134,7 @@ namespace { }, { "linear.matrix.scale", [] static { - const auto a = math::mat4i::identity(); + const auto a = math::imat4::identity(); const auto b = math::ivec3 { 3, 2, 3 }; const auto result = math::scale(a, b); From aca4183a2c62143f6e95cd23acfded4d273dd23d Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 19:40:59 +0100 Subject: [PATCH 047/194] (all) use f32 instead of float --- examples/entities/gameoflife/src/App.cpp | 8 ++--- examples/log/console-logger/src/main.cpp | 2 +- examples/log/file-logger/src/main.cpp | 2 +- modules/stormkit/core/containers/tree.mpp | 2 +- modules/stormkit/core/math/arithmetic.mpp | 4 +-- modules/stormkit/core/utils/time.mpp | 4 ++- modules/stormkit/gpu/core/structs.mpp | 32 +++++++++---------- .../gpu/execution/raster_pipeline.mpp | 14 ++++---- modules/stormkit/gpu/resource/image.mpp | 8 ++--- src/gpu/core/device.cpp | 2 +- 10 files changed, 40 insertions(+), 38 deletions(-) diff --git a/examples/entities/gameoflife/src/App.cpp b/examples/entities/gameoflife/src/App.cpp index dcc595646..c845aa0c9 100644 --- a/examples/entities/gameoflife/src/App.cpp +++ b/examples/entities/gameoflife/src/App.cpp @@ -135,11 +135,11 @@ auto App::handleMouse(const stormkit::wsi::MouseButtonPushedEventData& event) -> return; if (event.button != wsi::MouseButton::LEFT) return; - const auto cell_width = as(m_window->size().width) / as(BOARD_SIZE); - const auto cell_height = as(m_window->size().height) / as(BOARD_SIZE); + const auto cell_width = as(m_window->size().width) / as(BOARD_SIZE); + const auto cell_height = as(m_window->size().height) / as(BOARD_SIZE); - const auto x = glm::floor(as(event.position.x) / cell_width); - const auto y = glm::floor(as(event.position.y) / cell_height); + const auto x = glm::floor(as(event.position.x) / cell_width); + const auto y = glm::floor(as(event.position.y) / cell_height); const auto cells = m_entities.entities_with_component(); const auto it = std::ranges::find_if(cells, [&](const auto e) { diff --git a/examples/log/console-logger/src/main.cpp b/examples/log/console-logger/src/main.cpp index 869b4f17f..2f25ee663 100644 --- a/examples/log/console-logger/src/main.cpp +++ b/examples/log/console-logger/src/main.cpp @@ -26,7 +26,7 @@ struct std::formatter: std::formatter, Char struct Foo { u32 a = 0u; - float b = 2.3f; + f32 b = 2.3f; Bar c = Bar {}; }; diff --git a/examples/log/file-logger/src/main.cpp b/examples/log/file-logger/src/main.cpp index 79586a346..a917cea03 100644 --- a/examples/log/file-logger/src/main.cpp +++ b/examples/log/file-logger/src/main.cpp @@ -28,7 +28,7 @@ struct std::formatter: std::formatter, Char struct Foo { stormkit::u32 a = 0u; - float b = 2.3f; + f32 b = 2.3f; Bar c = Bar {}; }; diff --git a/modules/stormkit/core/containers/tree.mpp b/modules/stormkit/core/containers/tree.mpp index cf1031610..84919c7a0 100644 --- a/modules/stormkit/core/containers/tree.mpp +++ b/modules/stormkit/core/containers/tree.mpp @@ -238,7 +238,7 @@ namespace stormkit { inline namespace core { template auto Tree::get_free_node() -> TreeNodeIndexType { if (m_tree[m_first_free_index].next_sibling() == TreeNode::INVALID_INDEX) { - const auto size = as(stdr::size(m_tree)); + const auto size = as(stdr::size(m_tree)); const auto first_new = as(stdr::size(m_tree)); m_tree.resize(as(size * 1.5f)); diff --git a/modules/stormkit/core/math/arithmetic.mpp b/modules/stormkit/core/math/arithmetic.mpp index 1d7a1c886..dbf9bb6f5 100644 --- a/modules/stormkit/core/math/arithmetic.mpp +++ b/modules/stormkit/core/math/arithmetic.mpp @@ -85,10 +85,10 @@ namespace stormkit { inline namespace core { namespace math { if constexpr (meta::IsIntegral) return as(std::log2(v)); else { auto val_i = as(v); - auto log_2 = std::bit_cast(((val_i >> 23) & 255) - 128); + auto log_2 = std::bit_cast(((val_i >> 23) & 255) - 128); val_i &= ~(255 << 23); val_i += 127 << 23; - const auto val_f = std::bit_cast(val_i); + const auto val_f = std::bit_cast(val_i); log_2 += ((-0.3358287811f) * val_f + 2.0f) * val_f - 0.65871759316667f; return as(log_2); } diff --git a/modules/stormkit/core/utils/time.mpp b/modules/stormkit/core/utils/time.mpp index 6b75d54f5..8ecc3c022 100644 --- a/modules/stormkit/core/utils/time.mpp +++ b/modules/stormkit/core/utils/time.mpp @@ -6,6 +6,8 @@ export module stormkit.core:utils.time; import std; +import :typesafe.floating_point; + export namespace stormkit { inline namespace core { - using Secondf = std::chrono::duration; + using Secondf = std::chrono::duration; }} // namespace stormkit::core diff --git a/modules/stormkit/gpu/core/structs.mpp b/modules/stormkit/gpu/core/structs.mpp index cb54e9822..a877705d0 100644 --- a/modules/stormkit/gpu/core/structs.mpp +++ b/modules/stormkit/gpu/core/structs.mpp @@ -151,11 +151,11 @@ export { std::optional mipmap_precision_bits; u32 max_draw_indexed_index_value; std::optional max_draw_indirect_count; - float max_sampler_lod_bias; - float max_sampler_anisotropy; + f32 max_sampler_lod_bias; + f32 max_sampler_anisotropy; u32 max_viewports; std::array max_viewport_dimensions; - std::array viewport_bounds_range; + std::array viewport_bounds_range; std::optional viewport_sub_pixel_bits; std::optional min_memory_map_alignment; std::optional min_texel_buffer_offset_alignment; @@ -165,8 +165,8 @@ export { u32 max_texel_offset; i32 min_texel_gather_offset; u32 max_texel_gather_offset; - float min_interpolation_offset; - float max_interpolation_offset; + f32 min_interpolation_offset; + f32 max_interpolation_offset; std::optional sub_pixel_interpolation_offset_bits; u32 max_framebuffer_width; u32 max_framebuffer_height; @@ -183,15 +183,15 @@ export { SampleCountFlag storage_image_sample_counts; u32 max_sample_mask_words; bool timestamp_compute_and_engine; - float timestamp_period; + f32 timestamp_period; u32 max_clip_distances; u32 max_cull_distances; u32 max_combined_clip_and_cull_distances; u32 discrete_queue_priorities; - std::array point_size_range; - std::array line_width_range; - float point_size_granularity; - float line_width_granularity; + std::array point_size_range; + std::array line_width_range; + f32 point_size_granularity; + f32 line_width_granularity; bool strict_lines; bool standard_sample_locations; std::optional optimal_buffer_copy_offset_alignment; @@ -230,7 +230,7 @@ export { }; struct Scissor { - math::ivec2 offset; + math::ivec2 offset; math::uextent2 extent; }; @@ -239,8 +239,8 @@ export { }; struct ClearDepthStencil { - float depth = 1.f; - u32 stencil = 0; + f32 depth = 1.f; + u32 stencil = 0; }; using ClearValue = std::variant; @@ -252,7 +252,7 @@ export { ImageSubresourceLayers subresource_layers; - math::ivec3 offset; + math::ivec3 offset; math::uextent3 extent; }; @@ -261,12 +261,12 @@ export { ImageSubresourceLayers dst; struct { - math::ivec3 position; + math::ivec3 position; math::iextent3 extent; } src_offset; struct { - math::ivec3 position; + math::ivec3 position; math::iextent3 extent; } dst_offset; }; diff --git a/modules/stormkit/gpu/execution/raster_pipeline.mpp b/modules/stormkit/gpu/execution/raster_pipeline.mpp index e3e667f31..e738ac664 100644 --- a/modules/stormkit/gpu/execution/raster_pipeline.mpp +++ b/modules/stormkit/gpu/execution/raster_pipeline.mpp @@ -58,15 +58,15 @@ export namespace stormkit::gpu { CullModeFlag cull_mode = CullModeFlag::BACK; FrontFace front_face = FrontFace::CLOCKWISE; bool depth_bias_enable = false; - float depth_bias_constant_factor = 0.f; - float depth_bias_clamp = 0.f; - float depth_bias_slope_factor = 0.f; + f32 depth_bias_constant_factor = 0.f; + f32 depth_bias_clamp = 0.f; + f32 depth_bias_slope_factor = 0.f; }; struct RasterPipelineMultiSampleState { bool sample_shading_enable = false; SampleCountFlag rasterization_samples = SampleCountFlag::C1; - float min_sample_shading = 0.f; + f32 min_sample_shading = 0.f; }; struct RasterPipelineColorBlendAttachmentState { @@ -86,7 +86,7 @@ export namespace stormkit::gpu { bool logic_operation_enable = false; LogicOperation logic_operation = LogicOperation::COPY; std::vector attachments; - std::array blend_constants = { 0.f, 0.f, 0.f, 0.f }; + std::array blend_constants = { 0.f, 0.f, 0.f, 0.f }; }; using RasterPipelineDynamicState = std::vector; @@ -100,8 +100,8 @@ export namespace stormkit::gpu { bool depth_bounds_test_enable = false; - float min_depth_bounds = 0.f; - float max_depth_bounds = 1.f; + f32 min_depth_bounds = 0.f; + f32 max_depth_bounds = 1.f; }; struct RasterPipelineRenderingInfo { diff --git a/modules/stormkit/gpu/resource/image.mpp b/modules/stormkit/gpu/resource/image.mpp index b5f7436c5..d810cae77 100644 --- a/modules/stormkit/gpu/resource/image.mpp +++ b/modules/stormkit/gpu/resource/image.mpp @@ -31,7 +31,7 @@ export namespace stormkit::gpu { SamplerAddressMode address_mode_w = SamplerAddressMode::REPEAT; bool enable_anisotropy = false; - float max_anisotropy = 0.f; + f32 max_anisotropy = 0.f; BorderColor border_color = BorderColor::INT_OPAQUE_BLACK; @@ -41,10 +41,10 @@ export namespace stormkit::gpu { CompareOperation compare_operation = CompareOperation::ALWAYS; SamplerMipmapMode mipmap_mode = SamplerMipmapMode::LINEAR; - float mip_lod_bias = 0.f; + f32 mip_lod_bias = 0.f; - float min_lod = 0.f; - float max_lod = 0.f; + f32 min_lod = 0.f; + f32 max_lod = 0.f; }; static constexpr auto DEBUG_TYPE = DebugObjectType::SAMPLER; diff --git a/src/gpu/core/device.cpp b/src/gpu/core/device.cpp index 505b5d020..ee8c72c09 100644 --- a/src/gpu/core/device.cpp +++ b/src/gpu/core/device.cpp @@ -251,7 +251,7 @@ namespace stormkit::gpu { return q; }(); - auto priorities = std::vector> {}; + auto priorities = std::vector> {}; priorities.reserve(stdr::size(queues)); const auto queue_create_infos = transform(queues, [&priorities](auto queue) { From 910bb0944fb7cab994d9c66cf186d8edec1164fa Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 19:41:36 +0100 Subject: [PATCH 048/194] (core, entities) rename Secondf to fsecond --- examples/entities/gameoflife/src/App.cpp | 4 ++-- examples/entities/gameoflife/src/Constants.mpp | 2 +- examples/entities/gameoflife/src/Systems.cpp | 2 +- examples/entities/gameoflife/src/Systems.mpp | 6 +++--- examples/gpu/textured_cube/src/main.cpp | 2 +- modules/stormkit/core/string/format.mpp | 4 ++-- modules/stormkit/core/utils/time.mpp | 2 +- modules/stormkit/entities.mpp | 4 ++-- src/entities/entity_manager.cpp | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/entities/gameoflife/src/App.cpp b/examples/entities/gameoflife/src/App.cpp index c845aa0c9..35394fa67 100644 --- a/examples/entities/gameoflife/src/App.cpp +++ b/examples/entities/gameoflife/src/App.cpp @@ -124,8 +124,8 @@ auto App::handleKeyboard(const stormkit::wsi::KeyReleasedEventData& event) -> vo m_is_on_edit_mode = !m_is_on_edit_mode; m_update_system->setEditModeEnabled(m_is_on_edit_mode); break; - case wsi::Key::ADD: m_update_system->incrementDelta(Secondf { 0.01f }); break; - case wsi::Key::SUBSTRACT: m_update_system->incrementDelta(Secondf { -0.01f }); break; + case wsi::Key::ADD: m_update_system->incrementDelta(fsecond { 0.01f }); break; + case wsi::Key::SUBSTRACT: m_update_system->incrementDelta(fsecond { -0.01f }); break; default: break; } } diff --git a/examples/entities/gameoflife/src/Constants.mpp b/examples/entities/gameoflife/src/Constants.mpp index 8772b0bee..d1bf7da10 100644 --- a/examples/entities/gameoflife/src/Constants.mpp +++ b/examples/entities/gameoflife/src/Constants.mpp @@ -41,7 +41,7 @@ export { inline constexpr auto BOARD_SIZE = 100u; inline constexpr auto BOARD_BUFFERING_COUNT = 3u; - inline constexpr auto REFRESH_BOARD_DELTA = stormkit::Secondf { 1 }; + inline constexpr auto REFRESH_BOARD_DELTA = stormkit::fsecond { 1 }; inline constexpr auto SHADER_DATA = stormkit::as_bytes( #include diff --git a/examples/entities/gameoflife/src/Systems.cpp b/examples/entities/gameoflife/src/Systems.cpp index 8f621fd99..4f0fce0d4 100644 --- a/examples/entities/gameoflife/src/Systems.cpp +++ b/examples/entities/gameoflife/src/Systems.cpp @@ -24,7 +24,7 @@ UpdateBoardSystem::~UpdateBoardSystem() UpdateBoardSystem::UpdateBoardSystem(UpdateBoardSystem&&) noexcept = default; auto UpdateBoardSystem::operator=(UpdateBoardSystem&&) noexcept -> UpdateBoardSystem& = default; -auto UpdateBoardSystem::update(stormkit::Secondf delta) -> void { +auto UpdateBoardSystem::update(stormkit::fsecond delta) -> void { const auto now = Clock::now(); if (m_is_on_edit_mode) [[unlikely]] { diff --git a/examples/entities/gameoflife/src/Systems.mpp b/examples/entities/gameoflife/src/Systems.mpp index 279e12c7e..c8b333384 100644 --- a/examples/entities/gameoflife/src/Systems.mpp +++ b/examples/entities/gameoflife/src/Systems.mpp @@ -34,12 +34,12 @@ export { UpdateBoardSystem(UpdateBoardSystem&&) noexcept; auto operator=(UpdateBoardSystem&&) noexcept -> UpdateBoardSystem&; - auto update(stormkit::Secondf delta) -> void override; + auto update(stormkit::fsecond delta) -> void override; auto post_update() -> void override; auto setEditModeEnabled(bool enabled) noexcept { m_is_on_edit_mode = enabled; } - auto incrementDelta(stormkit::Secondf delta) { m_refresh_board_delta += delta; } + auto incrementDelta(stormkit::fsecond delta) { m_refresh_board_delta += delta; } private: using Clock = std::chrono::high_resolution_clock; @@ -54,7 +54,7 @@ export { bool m_updated = true; - stormkit::Secondf m_refresh_board_delta = REFRESH_BOARD_DELTA; + stormkit::fsecond m_refresh_board_delta = REFRESH_BOARD_DELTA; }; #ifdef STORMKIT_BUILD_MODULES diff --git a/examples/gpu/textured_cube/src/main.cpp b/examples/gpu/textured_cube/src/main.cpp index ab81193d2..2e7efcae1 100644 --- a/examples/gpu/textured_cube/src/main.cpp +++ b/examples/gpu/textured_cube/src/main.cpp @@ -450,7 +450,7 @@ class Application: public base::Application { const auto& signal = swapchain_image_resource.render_finished; // update viewer data and upload - const auto time = stdc::duration_cast(current_time - m_start_time).count(); + const auto time = stdc::duration_cast(current_time - m_start_time).count(); viewer_data .model = math::rotate(math::fmat4::identity(), time * math::angle::radians(90.f), math::fvec3 { 0.f, 1.f, 0.f }); diff --git a/modules/stormkit/core/string/format.mpp b/modules/stormkit/core/string/format.mpp index cab1de3f9..1704fd7c8 100644 --- a/modules/stormkit/core/string/format.mpp +++ b/modules/stormkit/core/string/format.mpp @@ -45,7 +45,7 @@ export { auto format_as(std::byte, FormatContext& ctx) noexcept -> decltype(ctx.out()); template - auto format_as(stormkit::Secondf, FormatContext& ctx) noexcept -> decltype(ctx.out()); + auto format_as(stormkit::fsecond, FormatContext& ctx) noexcept -> decltype(ctx.out()); }} // namespace stormkit::core template @@ -110,7 +110,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto format_as(Secondf value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { + inline auto format_as(fsecond value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { auto&& out = ctx.out(); return std::format_to(out, "{}", value.count()); } diff --git a/modules/stormkit/core/utils/time.mpp b/modules/stormkit/core/utils/time.mpp index 8ecc3c022..ef1b07fda 100644 --- a/modules/stormkit/core/utils/time.mpp +++ b/modules/stormkit/core/utils/time.mpp @@ -9,5 +9,5 @@ import std; import :typesafe.floating_point; export namespace stormkit { inline namespace core { - using Secondf = std::chrono::duration; + using fsecond = std::chrono::duration; }} // namespace stormkit::core diff --git a/modules/stormkit/entities.mpp b/modules/stormkit/entities.mpp index 4bf27e6dc..4b25ee496 100644 --- a/modules/stormkit/entities.mpp +++ b/modules/stormkit/entities.mpp @@ -109,7 +109,7 @@ export namespace stormkit::entities { virtual ~System(); virtual auto pre_update() -> void; - virtual auto update(Secondf delta) -> void = 0; + virtual auto update(fsecond delta) -> void = 0; virtual auto post_update() -> void; [[nodiscard]] @@ -202,7 +202,7 @@ export namespace stormkit::entities { template auto get_system(this Self& self) noexcept -> core::meta::ForwardConst; - auto step(Secondf delta) -> void; + auto step(fsecond delta) -> void; auto entity_count() const noexcept -> usize; diff --git a/src/entities/entity_manager.cpp b/src/entities/entity_manager.cpp index 56b4c1d9a..b3619ddbb 100644 --- a/src/entities/entity_manager.cpp +++ b/src/entities/entity_manager.cpp @@ -90,7 +90,7 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - auto EntityManager::step(Secondf delta) -> void { + auto EntityManager::step(fsecond delta) -> void { for (auto entity : m_removed_entities) { auto it = m_registered_components_for_entities.find(entity); // a this point, all entities should be valid From e29a6428a4b148a4ed312bcd515b8f08405118b9 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 20:32:52 +0100 Subject: [PATCH 049/194] (log) add a flag to enabled debug logging, and disable it by default, and make the logger thread safe --- examples/gpu/common/app.mpp | 13 +-- examples/gpu/imgui/src/logger.mpp | 15 ++++ examples/gpu/imgui/src/main.cpp | 2 - examples/gpu/imgui/xmake.lua | 3 +- examples/gpu/textured_cube/src/logger.mpp | 15 ++++ examples/gpu/textured_cube/src/main.cpp | 2 - examples/gpu/textured_cube/xmake.lua | 2 +- examples/gpu/triangle/src/logger.mpp | 15 ++++ examples/gpu/triangle/src/main.cpp | 3 - examples/gpu/triangle/xmake.lua | 3 +- examples/gpu/triangleclear | 0 examples/log/console-logger/src/main.cpp | 29 ++++--- examples/log/file-logger/src/main.cpp | 26 +++--- examples/wsi/events/src/main.cpp | 2 + examples/wsi/framebuffer/src/main.cpp | 1 + examples/wsi/luau/src/main.cpp | 2 + modules/stormkit/log.mpp | 97 ++++++++++------------- src/gpu/core/device.cpp | 2 +- src/gpu/core/instance.cpp | 4 +- src/log/logger.cpp | 29 ++++--- 20 files changed, 154 insertions(+), 111 deletions(-) create mode 100644 examples/gpu/imgui/src/logger.mpp create mode 100644 examples/gpu/textured_cube/src/logger.mpp create mode 100644 examples/gpu/triangle/src/logger.mpp create mode 100644 examples/gpu/triangleclear diff --git a/examples/gpu/common/app.mpp b/examples/gpu/common/app.mpp index 7e1aa30c7..d15edbf5e 100644 --- a/examples/gpu/common/app.mpp +++ b/examples/gpu/common/app.mpp @@ -11,6 +11,8 @@ export module gpu_app; import std; import stormkit; +export import :logger; + using namespace stormkit; namespace stdr = std::ranges; @@ -20,12 +22,13 @@ export namespace base { class Application { public: auto run(this auto& self, std::span args) { + wsi::parse_args(args); + log::parse_args(args); + const auto example_name = self.example_name(); auto logger_singleton = log::Logger::create_logger_instance(); - wsi::parse_args(args); - self.init_window(example_name); self.init_gpu(example_name); @@ -73,10 +76,10 @@ export namespace base { // pick the best physical device const auto& physical_devices = m_instance->physical_devices(); if (stdr::empty(physical_devices)) { - log::Logger::elog("No render physical device found!"); + elog("No render physical device found!"); return; } - log::Logger::ilog("Physical devices: {}", physical_devices); + ilog("Physical devices: {}", physical_devices); m_physical_device = as_opt_ref(physical_devices.front()); auto score = gpu::score_physical_device(*m_physical_device); @@ -89,7 +92,7 @@ export namespace base { } } - log::Logger::ilog("Picked gpu: {}", *m_physical_device); + ilog("Picked gpu: {}", *m_physical_device); // create gpu device m_device = TryAssert(gpu::Device::create(*m_physical_device, m_instance), "Failed to initialize gpu device"); diff --git a/examples/gpu/imgui/src/logger.mpp b/examples/gpu/imgui/src/logger.mpp new file mode 100644 index 000000000..ca004b433 --- /dev/null +++ b/examples/gpu/imgui/src/logger.mpp @@ -0,0 +1,15 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module gpu_app:logger; + +import std; + +import stormkit.log; + +export { IN_MODULE_LOGGER("Imgui"); } diff --git a/examples/gpu/imgui/src/main.cpp b/examples/gpu/imgui/src/main.cpp index 2b2c45518..4adbb8b57 100644 --- a/examples/gpu/imgui/src/main.cpp +++ b/examples/gpu/imgui/src/main.cpp @@ -17,8 +17,6 @@ import gpu_app; #include #undef assert -LOGGER("stormkit.examples.gpu.imgui"); - namespace stdr = std::ranges; namespace stdfs = std::filesystem; diff --git a/examples/gpu/imgui/xmake.lua b/examples/gpu/imgui/xmake.lua index b7cfa0a5b..4b69a62e0 100644 --- a/examples/gpu/imgui/xmake.lua +++ b/examples/gpu/imgui/xmake.lua @@ -23,8 +23,7 @@ target("imgui", function() add_defines("STORMKIT_ASSERT=0") end - add_files("../common/app.mpp") - add_files("src/*.cpp") + add_files("src/*.cpp", "src/*.mpp", "../common/app.mpp") if is_plat("windows") then add_files("win32/*.manifest") end if get_config("devmode") then set_rundir("$(projectdir)") end diff --git a/examples/gpu/textured_cube/src/logger.mpp b/examples/gpu/textured_cube/src/logger.mpp new file mode 100644 index 000000000..30e39ca8f --- /dev/null +++ b/examples/gpu/textured_cube/src/logger.mpp @@ -0,0 +1,15 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module gpu_app:logger; + +import std; + +import stormkit.log; + +export { IN_MODULE_LOGGER("Textured Cube"); } diff --git a/examples/gpu/textured_cube/src/main.cpp b/examples/gpu/textured_cube/src/main.cpp index 2e7efcae1..681992319 100644 --- a/examples/gpu/textured_cube/src/main.cpp +++ b/examples/gpu/textured_cube/src/main.cpp @@ -14,8 +14,6 @@ import gpu_app; #include #include -LOGGER("stormkit.examples.gpu.textured_cube"); - #ifndef SHADER_DIR #define SHADER_DIR "../share/stormkit/shaders/" #endif diff --git a/examples/gpu/textured_cube/xmake.lua b/examples/gpu/textured_cube/xmake.lua index c3acc4dee..fc23ad046 100644 --- a/examples/gpu/textured_cube/xmake.lua +++ b/examples/gpu/textured_cube/xmake.lua @@ -19,7 +19,7 @@ target("textured_cube", function() add_defines("STORMKIT_ASSERT=0") end - add_files("src/*.cpp", "../common/app.mpp") + add_files("src/*.cpp", "src/*.mpp", "../common/app.mpp") add_files("shaders/*.nzsl") if is_plat("windows") then add_files("win32/*.manifest") end diff --git a/examples/gpu/triangle/src/logger.mpp b/examples/gpu/triangle/src/logger.mpp new file mode 100644 index 000000000..7aa06a6b7 --- /dev/null +++ b/examples/gpu/triangle/src/logger.mpp @@ -0,0 +1,15 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module gpu_app:logger; + +import std; + +import stormkit.log; + +export { IN_MODULE_LOGGER("Triangle"); } diff --git a/examples/gpu/triangle/src/main.cpp b/examples/gpu/triangle/src/main.cpp index 48fd5f700..55e6d8981 100644 --- a/examples/gpu/triangle/src/main.cpp +++ b/examples/gpu/triangle/src/main.cpp @@ -10,11 +10,8 @@ import stormkit; import gpu_app; #include -#include #include -LOGGER("stormkit.examples.gpu.triangle"); - #ifndef SHADER_DIR #define SHADER_DIR "../share/stormkit/shaders/" #endif diff --git a/examples/gpu/triangle/xmake.lua b/examples/gpu/triangle/xmake.lua index a50ca16c1..023faa518 100644 --- a/examples/gpu/triangle/xmake.lua +++ b/examples/gpu/triangle/xmake.lua @@ -32,8 +32,7 @@ target("triangle", function() add_defines("STORMKIT_ASSERT=0") end - add_files("../common/app.mpp") - add_files("src/*.cpp") + add_files("src/*.cpp", "src/*.mpp", "../common/app.mpp") add_files("shaders/*.nzsl") if is_plat("windows") then add_files("win32/*.manifest") end diff --git a/examples/gpu/triangleclear b/examples/gpu/triangleclear new file mode 100644 index 000000000..e69de29bb diff --git a/examples/log/console-logger/src/main.cpp b/examples/log/console-logger/src/main.cpp index 2f25ee663..31bdb07e3 100644 --- a/examples/log/console-logger/src/main.cpp +++ b/examples/log/console-logger/src/main.cpp @@ -20,30 +20,35 @@ struct std::formatter: std::formatter, Char template auto format(const Bar& data, FormatContext& ctx) const -> decltype(ctx.out()) { auto&& out = ctx.out(); - return format_to(out, "[Bar: d = {}]", data.d); + return format_to(out, "[Bar d: {}]", data.d); } }; struct Foo { - u32 a = 0u; + u32 a = 0u; f32 b = 2.3f; - Bar c = Bar {}; + Bar c = Bar {}; }; -template -struct std::formatter: std::formatter, CharT> { - template - auto format(const Foo& data, FormatContext& ctx) const -> decltype(ctx.out()) { - auto&& out = ctx.out(); - return format_to(out, "[Foo: a = {}, b = {}, c = {}]", data.a, data.b, data.c); - } -}; +template +auto format_as(const Foo& data, FormatContext& ctx) -> decltype(ctx.out()) { + return std::format_to(ctx.out(), "[Foo a: {}, b: {}, c: {}]", data.a, data.b, data.c); +} + +namespace stdr = std::ranges; +namespace stdv = std::views; //////////////////////////////////////// //////////////////////////////////////// -auto main(std::span) -> int { +auto main(std::span args) -> int { using log::operator""_module; + // force debug + auto args2 = std::vector { std::from_range, args }; + args2.emplace_back("--debug"); + + log::parse_args(args2); + auto logger = log::Logger::create_logger_instance(); log::Logger::ilog("This is an information"); diff --git a/examples/log/file-logger/src/main.cpp b/examples/log/file-logger/src/main.cpp index a917cea03..475eb6e2b 100644 --- a/examples/log/file-logger/src/main.cpp +++ b/examples/log/file-logger/src/main.cpp @@ -21,25 +21,20 @@ template struct std::formatter: std::formatter, CharT> { template auto format(const Bar& data, FormatContext& ctx) const -> decltype(ctx.out()) { - auto&& out = ctx.out(); - return format_to(out, "[Bar: d = {}]", data.d); + return format_to(ctx.out(), "[Bar d: {}]", data.d); } }; struct Foo { stormkit::u32 a = 0u; - f32 b = 2.3f; + f32 b = 2.3f; Bar c = Bar {}; }; -template -struct std::formatter: std::formatter, CharT> { - template - auto format(const Foo& data, FormatContext& ctx) const -> decltype(ctx.out()) { - auto&& out = ctx.out(); - return format_to(out, "[Foo: a = {}, b = {}, c = {}]", data.a, data.b, data.c); - } -}; +template +auto format_as(const Foo& data, FormatContext& ctx) -> decltype(ctx.out()) { + return std::format_to(ctx.out(), "[Foo a: {}, b: {}, c: {}]", data.a, data.b, data.c); +} #ifdef STORMKIT_COMPILER_MSVC static const auto LOG_DIR = std::filesystem::path { L"log/" }; @@ -49,10 +44,15 @@ static const auto LOG_DIR = std::filesystem::path { "log/" }; //////////////////////////////////////// //////////////////////////////////////// -auto main(std::span _) -> int { - using namespace stormkit; +auto main(std::span args) -> int { using log::operator""_module; + // force debug + auto args2 = std::vector { std::from_range, args }; + args2.emplace_back("--debug"); + + log::parse_args(args2); + auto logger = log::Logger::create_logger_instance(LOG_DIR); log::Logger::ilog("This is an information"); diff --git a/examples/wsi/events/src/main.cpp b/examples/wsi/events/src/main.cpp index bcfe3b4e5..8e5e97bc3 100644 --- a/examples/wsi/events/src/main.cpp +++ b/examples/wsi/events/src/main.cpp @@ -23,6 +23,8 @@ namespace stdr = std::ranges; //////////////////////////////////////// auto main(std::span args) -> int { wsi::parse_args(args); + log::parse_args(args); + auto logger = log::Logger::create_logger_instance(); const auto monitors = wsi::get_monitors(); diff --git a/examples/wsi/framebuffer/src/main.cpp b/examples/wsi/framebuffer/src/main.cpp index 06defffe9..8af3a7cfe 100644 --- a/examples/wsi/framebuffer/src/main.cpp +++ b/examples/wsi/framebuffer/src/main.cpp @@ -54,6 +54,7 @@ auto update_pixels(stormkit::ThreadPool& pool, std::vector>& pixels auto main(std::span args) -> int { wsi::parse_args(args); + log::parse_args(args); auto logger = log::Logger::create_logger_instance(); diff --git a/examples/wsi/luau/src/main.cpp b/examples/wsi/luau/src/main.cpp index 725bec20a..196351df0 100644 --- a/examples/wsi/luau/src/main.cpp +++ b/examples/wsi/luau/src/main.cpp @@ -32,6 +32,8 @@ using namespace stormkit; //////////////////////////////////////// auto main(std::span args) -> int { wsi::parse_args(args); + log::parse_args(args); + auto logger = log::Logger::create_logger_instance(); auto engine = luau::Engine::create(LUAU_FILE); diff --git a/modules/stormkit/log.mpp b/modules/stormkit/log.mpp index 9b139ac81..7e65d07ca 100644 --- a/modules/stormkit/log.mpp +++ b/modules/stormkit/log.mpp @@ -22,12 +22,12 @@ export import :lua; export { namespace stormkit::log { struct Module; - enum class Severity { - INFO = 1, - WARNING, - ERROR, - FATAL, - DEBUG, + enum class Severity : u8 { + INFO = 1, + WARNING = 2, + ERROR = 4, + FATAL = 8, + DEBUG = 16, }; [[nodiscard]] @@ -35,6 +35,9 @@ export { [[nodiscard]] constexpr auto to_string(Severity severity) noexcept -> std::string; + STORMKIT_API + auto parse_args(std::span args) noexcept -> void; + class STORMKIT_API Logger { public: using LogClock = std::chrono::high_resolution_clock; @@ -53,6 +56,9 @@ export { [[nodiscard]] auto log_level() const noexcept -> const Severity&; + [[nodiscard]] + auto mutex() noexcept -> std::mutex&; + template [[nodiscard]] static auto create_logger_instance(Args&&... param_args) noexcept -> T; @@ -93,6 +99,8 @@ export { protected: LogClock::time_point m_start_time; Severity m_log_level; + + std::mutex m_mutex; }; struct Module { @@ -129,8 +137,8 @@ export { FileLogger(const FileLogger&) noexcept = delete; auto operator=(const FileLogger&) noexcept -> FileLogger& = delete; - FileLogger(FileLogger&&) noexcept; - auto operator=(FileLogger&&) noexcept -> FileLogger&; + FileLogger(FileLogger&&) noexcept = delete; + auto operator=(FileLogger&&) noexcept -> FileLogger& = delete; auto write(Severity severity, const Module& module, CZString string) noexcept -> void override; auto flush() noexcept -> void override; @@ -146,11 +154,11 @@ export { explicit ConsoleLogger(LogClock::time_point start) noexcept; ConsoleLogger(LogClock::time_point start, Severity log_level) noexcept; - ConsoleLogger(const ConsoleLogger&) noexcept; - auto operator=(const ConsoleLogger&) noexcept -> ConsoleLogger&; + ConsoleLogger(const ConsoleLogger&) noexcept = delete; + auto operator=(const ConsoleLogger&) noexcept -> ConsoleLogger& = delete; - ConsoleLogger(ConsoleLogger&&) noexcept; - auto operator=(ConsoleLogger&&) noexcept -> ConsoleLogger&; + ConsoleLogger(ConsoleLogger&&) noexcept = delete; + auto operator=(ConsoleLogger&&) noexcept -> ConsoleLogger& = delete; ~ConsoleLogger() noexcept override; @@ -173,11 +181,11 @@ namespace stormkit::log { STORMKIT_FORCE_INLINE STORMKIT_CONST inline constexpr auto as_string(Severity severity) noexcept -> std::string_view { switch (severity) { - case Severity::INFO: return "INFO"; - case Severity::WARNING: return "WARNING"; - case Severity::ERROR: return "ERROR"; - case Severity::FATAL: return "FATAL"; - case Severity::DEBUG: return "DEBUG"; + case Severity::INFO: return "Severity::INFO"; + case Severity::WARNING: return "Severity::WARNING"; + case Severity::ERROR: return "Severity::ERROR"; + case Severity::FATAL: return "Severity::FATAL"; + case Severity::DEBUG: return "Severity::DEBUG"; default: break; } @@ -186,7 +194,7 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE + STORMKIT_FORCE_INLINE inline constexpr auto to_string(Severity severity) noexcept -> std::string { return std::string { as_string(severity) }; } @@ -200,23 +208,29 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE + STORMKIT_FORCE_INLINE inline auto Logger::start_time() const noexcept -> const LogClock::time_point& { return m_start_time; } //////////////////////////////////////// //////////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE + STORMKIT_FORCE_INLINE inline auto Logger::log_level() const noexcept -> const Severity& { return m_log_level; } + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Logger::mutex() noexcept -> std::mutex& { + return m_mutex; + } + //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_FORCE_INLINE - STORMKIT_PURE inline auto Logger::create_logger_instance(Args&&... param_args) noexcept -> T { static_assert(std::is_base_of::value, "T must inherit Logger"); @@ -229,7 +243,6 @@ namespace stormkit::log { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - STORMKIT_PURE auto Logger::allocate_logger_instance(Args&&... param_args) noexcept -> Heap { static_assert(std::is_base_of::value, "T must inherit Logger"); @@ -246,49 +259,22 @@ namespace stormkit::log { auto Logger::log(Severity severity, const Module& m, std::string_view format_string, Args&&... param_args) noexcept -> void { EXPECTS(has_logger()); - const auto format = format_string; - auto memory_buffer = std::string {}; + const auto log_level = instance().log_level(); + if (not check_flag_bit(log_level, severity)) return; + + auto memory_buffer = std::string {}; memory_buffer.reserve(std::size(format_string)); - std::vformat_to(std::back_inserter(memory_buffer), format, std::make_format_args(param_args...)); + std::vformat_to(std::back_inserter(memory_buffer), format_string, std::make_format_args(param_args...)); + auto _ = std::unique_lock(instance().mutex()); instance().write(severity, m, std::data(memory_buffer)); } - //////////////////////////////////////// - //////////////////////////////////////// - STORMKIT_FORCE_INLINE - inline ConsoleLogger::ConsoleLogger(const ConsoleLogger&) noexcept = default; - - //////////////////////////////////////// - //////////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto ConsoleLogger::operator=(const ConsoleLogger&) noexcept -> ConsoleLogger& = default; - - //////////////////////////////////////// - //////////////////////////////////////// - STORMKIT_FORCE_INLINE - inline ConsoleLogger::ConsoleLogger(ConsoleLogger&&) noexcept = default; - - //////////////////////////////////////// - //////////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto ConsoleLogger::operator=(ConsoleLogger&&) noexcept -> ConsoleLogger& = default; - //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE inline ConsoleLogger::~ConsoleLogger() noexcept = default; - //////////////////////////////////////// - //////////////////////////////////////// - STORMKIT_FORCE_INLINE - inline FileLogger::FileLogger(FileLogger&&) noexcept = default; - - //////////////////////////////////////// - //////////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto FileLogger::operator=(FileLogger&&) noexcept -> FileLogger& = default; - //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE @@ -393,7 +379,6 @@ namespace stormkit::log { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - STORMKIT_CONST inline constexpr auto operator""_module() noexcept -> stormkit::log::Module { return Module { str.view() }; } diff --git a/src/gpu/core/device.cpp b/src/gpu/core/device.cpp index ee8c72c09..bbd97f04f 100644 --- a/src/gpu/core/device.cpp +++ b/src/gpu/core/device.cpp @@ -318,7 +318,7 @@ namespace stormkit::gpu { return e; }(); - device_logger.ilog("Enabled device extensions: {}", extensions); + device_logger.dlog("Enabled device extensions: {}", extensions); // const auto acceleration_feature = [] static noexcept { // auto out = zeroed(); diff --git a/src/gpu/core/instance.cpp b/src/gpu/core/instance.cpp index ca1c43803..66323249e 100644 --- a/src/gpu/core/instance.cpp +++ b/src/gpu/core/instance.cpp @@ -144,7 +144,7 @@ namespace stormkit::gpu { } }); - ilog("Enabled layers: {}", validation_layers); + dlog("Enabled layers: {}", validation_layers); const auto instance_extensions = [this]() noexcept { auto e = concat(BASE_EXTENSIONS, SURFACE_EXTENSIONS); @@ -158,7 +158,7 @@ namespace stormkit::gpu { return e; }(); - ilog("Enabled instance extensions: {}", instance_extensions); + dlog("Enabled instance extensions: {}", instance_extensions); constexpr auto ENGINE_NAME = "StormKit"; diff --git a/src/log/logger.cpp b/src/log/logger.cpp index b77785771..eb9297479 100644 --- a/src/log/logger.cpp +++ b/src/log/logger.cpp @@ -12,23 +12,32 @@ import std; import stormkit.core; +namespace stdr = std::ranges; + namespace stormkit::log { namespace { -#ifdef STORMKIT_BUILD_DEBUG - constexpr auto DEFAULT_SEVERITY = Severity::INFO - | Severity::DEBUG - | Severity::ERROR - | Severity::FATAL - | Severity::WARNING; -#else - constexpr auto DEFAULT_SEVERITY = Severity::INFO | Severity::ERROR | Severity::FATAL; -#endif constinit Logger* logger = nullptr; + + constinit auto debug_enabled = false; + + auto make_default_severity() noexcept { + auto severity = Severity::INFO | Severity::ERROR | Severity::FATAL | Severity::WARNING; + + if (debug_enabled) severity |= Severity::DEBUG; + + return severity; + } } // namespace ///////////////////////////////////// ///////////////////////////////////// - Logger::Logger(LogClock::time_point start_time) noexcept : Logger { std::move(start_time), DEFAULT_SEVERITY } { + auto parse_args(std::span args) noexcept -> void { + debug_enabled = stdr::find_if(args, [](auto&& v) { return v == "--debug" or v == "-d"; }) != stdr::cend(args); + } + + ///////////////////////////////////// + ///////////////////////////////////// + Logger::Logger(LogClock::time_point start_time) noexcept : Logger { std::move(start_time), make_default_severity() } { EXPECTS(not logger); logger = this; From ec2e19396ac65af6eaafaded2a7794bd7d105c16 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 20:41:05 +0100 Subject: [PATCH 050/194] (wsi) fix close event on windows --- src/wsi/win32/window.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/wsi/win32/window.cpp b/src/wsi/win32/window.cpp index 834f38cde..d6de96bfe 100644 --- a/src/wsi/win32/window.cpp +++ b/src/wsi/win32/window.cpp @@ -32,13 +32,13 @@ using namespace stormkit; template constexpr auto format_as(const POINT& point, FormatContext& ctx) -> decltype(ctx.out()) { - return std::format_to(ctx.out(), "{{ .x = {}, .y = {} }}", point.x, point.y); + return std::format_to(ctx.out(), "[vec2 x: {}, y: {}]", point.x, point.y); } template constexpr auto format_as(const RECT& rect, FormatContext& ctx) -> decltype(ctx.out()) { return std::format_to(ctx.out(), - "{{ .left = {}, .top = {}, .right = {}, .bottom = {} }}", + "[rect left: {}, top: {}, right: {}, bottom: {}]", rect.left, rect.top, rect.right, @@ -125,8 +125,7 @@ namespace stormkit::wsi::win32 { SetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_SYSTEM_AWARE); - const auto adjusted = adjust_extent(extent, style, style_ex); - std::println("{} => {}", extent, adjusted); + const auto adjusted = adjust_extent(extent, style, style_ex); m_window_handle = CreateWindowExA(style_ex, CLASS_NAME, std::data(title), @@ -529,7 +528,9 @@ namespace stormkit::wsi::win32 { switch (message) { case WM_DESTROY: PostQuitMessage(0); return 0; - case WM_CLOSE: window.closed_event(); return 0; + case WM_CLOSE: + if (window.closed_event()) DestroyWindow(window_handle); + return 0; case WM_CREATE: window.WindowBase::set_open(true); break; case WM_NCDESTROY: window.WindowBase::set_open(false); break; case WM_MOUSEACTIVATE: { From 333d8390b91cb55393d5b569b5d52e6312137dbd Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 20:56:05 +0100 Subject: [PATCH 051/194] (core) fix format_as for extent --- modules/stormkit/core/math/extent.mpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/stormkit/core/math/extent.mpp b/modules/stormkit/core/math/extent.mpp index 337dc019c..ad391254c 100644 --- a/modules/stormkit/core/math/extent.mpp +++ b/modules/stormkit/core/math/extent.mpp @@ -353,14 +353,14 @@ namespace stormkit { inline namespace core { namespace math { ///////////////////////////////////// template inline auto format_as(const extent& extent, FormatContext& ctx) noexcept -> decltype(ctx.out()) { - return format_to(ctx.out(), "[extent2 width: {}, height: {}]", extent.width, extent.height); + return std::format_to(ctx.out(), "[extent2 width: {}, height: {}]", extent.width, extent.height); } ///////////////////////////////////// ///////////////////////////////////// template inline auto format_as(const extent& extent, FormatContext& ctx) noexcept -> decltype(ctx.out()) { - return format_to(ctx.out(), "[extent3 width: {}, height: {}, depth: {}]", extent.width, extent.height, extent.depth); + return std::format_to(ctx.out(), "[extent3 width: {}, height: {}, depth: {}]", extent.width, extent.height, extent.depth); } ///////////////////////////////////// From e80d4d0db154f7611f59325a49020043882c2120 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 20:56:22 +0100 Subject: [PATCH 052/194] (luau) fix rgbcolor binding --- modules/stormkit/luau/core.mpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stormkit/luau/core.mpp b/modules/stormkit/luau/core.mpp index 55097da26..506cfc246 100644 --- a/modules/stormkit/luau/core.mpp +++ b/modules/stormkit/luau/core.mpp @@ -22,7 +22,7 @@ namespace stormkit::luau::core { //////////////////////////////////////// //////////////////////////////////////// inline auto bind_color(lb::Namespace& global_namespace) noexcept -> lb::Namespace { - return global_namespace.beginClass("fcolor").endClass().beginClass("ucolor").endClass(); + return global_namespace.beginClass>("fcolor").endClass().beginClass>("ucolor").endClass(); } //////////////////////////////////////// From f66bf1be82823a6cf527c161d0cdcbbbbadcca2f Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 20:56:31 +0100 Subject: [PATCH 053/194] (luau) workaround for clang ICE --- modules/stormkit/wsi/lua.mpp | 235 ++++++----------------------------- src/wsi/lua.cpp | 130 +++++++++++++++++++ 2 files changed, 171 insertions(+), 194 deletions(-) create mode 100644 src/wsi/lua.cpp diff --git a/modules/stormkit/wsi/lua.mpp b/modules/stormkit/wsi/lua.mpp index 2da42af9a..35fb8f101 100644 --- a/modules/stormkit/wsi/lua.mpp +++ b/modules/stormkit/wsi/lua.mpp @@ -13,209 +13,56 @@ export module stormkit.wsi:lua; import std; import stormkit.core; + import :core; -import :mouse; -import :keyboard; -import :monitor; import :window; namespace lb = luabridge; -export namespace stormkit::wsi::lua { - inline auto init_lua(lb::Namespace global_namespace) noexcept -> void; -} // namespace stormkit::wsi::lua +export { + namespace stormkit::wsi::lua { + STORMKIT_API + auto init_lua(lb::Namespace global_namespace) noexcept -> void; + } // namespace stormkit::wsi::lua + + template<> + struct lb::Stack: lb::Enum {}; + + template<> + struct lb::Stack + : lb::Enum {}; + + template<> + struct lb::Stack + : lb::Enum {}; +} namespace stormkit::wsi::lua { - using stormkit::wsi::EventType; - using stormkit::wsi::Window; - using stormkit::wsi::WindowFlag; - using stormkit::wsi::WM; - - //////////////////////////////////////// //////////////////////////////////////// - inline auto open_window(std::string name, u32 width, u32 height, wsi::WindowFlag flags) noexcept -> decltype(auto) { - return wsi::Window::open(std::move(name), { width, height }, flags); - } - //////////////////////////////////////// - //////////////////////////////////////// - inline auto bind_core(lb::Namespace& global_namespace) noexcept -> lb::Namespace { - return global_namespace.beginNamespace("wsi") - .beginNamespace("wm") - .addProperty( - "WIN32", - +[] static noexcept { return wsi::WM::WIN32; }) - .addProperty( - "WAYLAND", - +[] static noexcept { return wsi::WM::WAYLAND; }) - .addProperty( - "X11", - +[] static noexcept { return wsi::WM::X11; }) - .addProperty( - "ANDROID", - +[] static noexcept { return wsi::WM::ANDROID; }) - .addProperty( - "MACOS", - +[] static noexcept { return wsi::WM::MACOS; }) - .addProperty( - "IOS", - +[] static noexcept { return wsi::WM::IOS; }) - .addProperty( - "TVOS", - +[] static noexcept { return wsi::WM::TVOS; }) - .addProperty( - "SWITCH", - +[] static noexcept { return wsi::WM::SWITCH; }) - .endNamespace() - .endNamespace(); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template STORMKIT_FORCE_INLINE - inline constexpr auto make_lua_closure() noexcept { - return [](Window* window, lb::LuaRef func) static noexcept { - window->on([func = std::move(func)](Args&&... args) noexcept { - const auto result = func(std::forward(args)...); - ensures(result.wasOk(), result.errorMessage()); - }); - }; - } - - //////////////////////////////////////// - //////////////////////////////////////// - inline auto bind_window(lb::Namespace& global_namespace) noexcept -> lb::Namespace { - return global_namespace.beginNamespace("wsi") - .beginNamespace("window_flag") - .addProperty( - "DEFAULT", - +[] static noexcept { return wsi::WindowFlag::DEFAULT; }) - .addProperty( - "BORDERLESS", - +[] static noexcept { return wsi::WindowFlag::BORDERLESS; }) - .addProperty( - "RESIZEABLE", - +[] static noexcept { return wsi::WindowFlag::RESIZEABLE; }) - .addProperty( - "EXTERNAL_CONTEXT", - +[] static noexcept { return wsi::WindowFlag::EXTERNAL_CONTEXT; }) - .endNamespace() - .beginNamespace("EventType") - .addProperty( - "NONE", - +[] static noexcept { return wsi::EventType::NONE; }) - .addProperty( - "CLOSED", - +[] static noexcept { return wsi::EventType::CLOSED; }) - .addProperty( - "MONITOR_CHANGED", - +[] static noexcept { return wsi::EventType::MONITOR_CHANGED; }) - .addProperty( - "RESIZED", - +[] static noexcept { return wsi::EventType::RESIZED; }) - .addProperty( - "RESTORED", - +[] static noexcept { return wsi::EventType::RESTORED; }) - .addProperty( - "MINIMIZED", - +[] static noexcept { return wsi::EventType::MINIMIZED; }) - .addProperty( - "KEY_DOWN", - +[] static noexcept { return wsi::EventType::KEY_DOWN; }) - .addProperty( - "KEY_UP", - +[] static noexcept { return wsi::EventType::KEY_UP; }) - .addProperty( - "MOUSE_BUTTON_DOWN", - +[] static noexcept { return wsi::EventType::MOUSE_BUTTON_DOWN; }) - .addProperty( - "MOUSE_BUTTON_UP", - +[] static noexcept { return wsi::EventType::MOUSE_BUTTON_UP; }) - .addProperty( - "MOUSE_MOVED", - +[] static noexcept { return wsi::EventType::MOUSE_MOVED; }) - .addProperty( - "ACTIVATE", - +[] static noexcept { return wsi::EventType::ACTIVATE; }) - .addProperty( - "DEACTIVATE", - +[] static noexcept { return wsi::EventType::DEACTIVATE; }) - .endNamespace() - .beginClass("window") - .addFunction("wm", &wsi::Window::wm) - .addFunction("extent", &wsi::Window::extent) - .addFunction("clear", [](Window* window) static noexcept { window->clear(); }) - .addFunction( - "event_loop", - +[](Window* window, lb::LuaRef func) static noexcept { - window->event_loop([func = std::move(func)] noexcept { - const auto result = func(); - ensures(result.wasOk(), result.errorMessage()); - }); - }) - .addFunction( - "on_closed", - +[](Window* window, lb::LuaRef func) static noexcept { - expects(func.isCallable()); - - window->on([func = std::move(func)] noexcept { - const auto result = func(); - ensures(result.wasOk(), result.errorMessage()); - const auto return_value = result[0]; - ensures(return_value.isValid()); - ensures(return_value.isBool(), "on_closed closure must return a boolean value"); - return return_value.cast().value(); - }); - }) - .addFunction("on_resized", +(make_lua_closure())) - .addFunction("on_restored", +(make_lua_closure())) - .addFunction("on_minimized", +(make_lua_closure())) - .addFunction("on_activate", +(make_lua_closure())) - .addFunction("on_deactivate", +(make_lua_closure())) - .endClass() - .addFunction("open_window", &open_window) - .endNamespace(); - } - - //////////////////////////////////////// - //////////////////////////////////////// - inline auto init_lua(lb::Namespace global_namespace) noexcept -> void { - global_namespace = bind_core(global_namespace); - global_namespace = bind_window(global_namespace); + inline auto open_window(std::string name, u32 width, u32 height, wsi::WindowFlag flags) noexcept -> wsi::Window { + return wsi::Window::open(std::move(name), { width, height }, flags); } } // namespace stormkit::wsi::lua - -using namespace stormkit; - -template<> -struct lb::Stack: lb::Enum {}; - -template<> -struct lb::Stack - : lb::Enum {}; - -template<> -struct lb::Stack - : lb::Enum {}; diff --git a/src/wsi/lua.cpp b/src/wsi/lua.cpp new file mode 100644 index 000000000..adc4dca08 --- /dev/null +++ b/src/wsi/lua.cpp @@ -0,0 +1,130 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +module stormkit.wsi; + +import std; + +import stormkit.core; + +import :core; + +import :core; +import :mouse; +import :keyboard; +import :monitor; +import :window; + +namespace lb = luabridge; + +namespace stormkit::wsi::lua { + using stormkit::wsi::EventType; + using stormkit::wsi::Window; + using stormkit::wsi::WindowFlag; + using stormkit::wsi::WM; + + namespace { + //////////////////////////////////////// + //////////////////////////////////////// + auto bind_core(lb::Namespace& global_namespace) noexcept -> lb::Namespace { + return global_namespace.beginNamespace("wsi") + .beginNamespace("wm") + .addProperty("WIN32", [] static noexcept { return WM::WIN32; }) + .addProperty("WAYLAND", [] static noexcept { return WM::WAYLAND; }) + .addProperty("X11", [] static noexcept { return WM::X11; }) + .addProperty("ANDROID", [] static noexcept { return WM::ANDROID; }) + .addProperty("MACOS", [] static noexcept { return WM::MACOS; }) + .addProperty("IOS", [] static noexcept { return WM::IOS; }) + .addProperty("TVOS", [] static noexcept { return WM::TVOS; }) + .addProperty("SWITCH", [] static noexcept { return WM::SWITCH; }) + .endNamespace() + .endNamespace(); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto make_lua_closure() noexcept { + return [](Window* window, lb::LuaRef func) static noexcept { + window->on([func = std::move(func)](Args&&... args) noexcept { + const auto result = func(std::forward(args)...); + ensures(result.wasOk(), result.errorMessage()); + }); + }; + } + + //////////////////////////////////////// + //////////////////////////////////////// + auto bind_window(lb::Namespace& global_namespace) noexcept -> lb::Namespace { + return global_namespace.beginNamespace("wsi") + .beginNamespace("window_flag") + .addProperty("DEFAULT", [] static noexcept { return WindowFlag::DEFAULT; }) + .addProperty("BORDERLESS", [] static noexcept { return WindowFlag::BORDERLESS; }) + .addProperty("RESIZEABLE", [] static noexcept { return WindowFlag::RESIZEABLE; }) + .addProperty("EXTERNAL_CONTEXT", [] static noexcept { return WindowFlag::EXTERNAL_CONTEXT; }) + .endNamespace() + .beginNamespace("EventType") + .addProperty("NONE", [] static noexcept { return EventType::NONE; }) + .addProperty("CLOSED", [] static noexcept { return EventType::CLOSED; }) + .addProperty("MONITOR_CHANGED", [] static noexcept { return EventType::MONITOR_CHANGED; }) + .addProperty("RESIZED", [] static noexcept { return EventType::RESIZED; }) + .addProperty("RESTORED", [] static noexcept { return EventType::RESTORED; }) + .addProperty("MINIMIZED", [] static noexcept { return EventType::MINIMIZED; }) + .addProperty("KEY_DOWN", [] static noexcept { return EventType::KEY_DOWN; }) + .addProperty("KEY_UP", [] static noexcept { return EventType::KEY_UP; }) + .addProperty("MOUSE_BUTTON_DOWN", [] static noexcept { return EventType::MOUSE_BUTTON_DOWN; }) + .addProperty("MOUSE_BUTTON_UP", [] static noexcept { return EventType::MOUSE_BUTTON_UP; }) + .addProperty("MOUSE_MOVED", [] static noexcept { return EventType::MOUSE_MOVED; }) + .addProperty("ACTIVATE", [] static noexcept { return EventType::ACTIVATE; }) + .addProperty("DEACTIVATE", [] static noexcept { return EventType::DEACTIVATE; }) + .endNamespace() + .beginClass("window") + .addFunction("wm", &Window::wm) + .addFunction("extent", &Window::extent) + .addFunction("clear", [](Window* window) static noexcept { window->clear(); }) + .addFunction("event_loop", + [](Window* window, lb::LuaRef func) static noexcept { + window->event_loop([func = std::move(func)] noexcept { + const auto result = func(); + ensures(result.wasOk(), result.errorMessage()); + }); + }) + .addFunction("on_closed", + [](Window* window, lb::LuaRef func) static noexcept { + expects(func.isCallable()); + + window->on([func = std::move(func)] noexcept { + const auto result = func(); + ensures(result.wasOk(), result.errorMessage()); + const auto return_value = result[0]; + ensures(return_value.isValid()); + ensures(return_value.isBool(), "on_closed closure must return a boolean value"); + return return_value.cast().value(); + }); + }) + .addFunction("on_resized", (make_lua_closure())) + .addFunction("on_restored", (make_lua_closure())) + .addFunction("on_minimized", (make_lua_closure())) + .addFunction("on_activate", (make_lua_closure())) + .addFunction("on_deactivate", (make_lua_closure())) + .endClass() + .addFunction("open_window", &open_window) + .endNamespace(); + } + } // namespace + + //////////////////////////////////////// + //////////////////////////////////////// + auto init_lua(lb::Namespace global_namespace) noexcept -> void { + global_namespace = bind_core(global_namespace); + global_namespace = bind_window(global_namespace); + } +} // namespace stormkit::wsi::lua From 62081f65da95b297a877e05178308b3ceacae392 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 22:06:18 +0100 Subject: [PATCH 054/194] (all) remove unaccessary inline --- modules/stormkit/core/typesafe/byte.mpp | 14 +-- modules/stormkit/core/utils/pimpl.mpp | 28 +++-- modules/stormkit/gpu/core/instance.mpp | 18 ++-- .../stormkit/gpu/core/vulkan/enums.mpp.tpl | 101 ++---------------- modules/stormkit/gpu/core/vulkan/utils.mpp | 8 +- modules/stormkit/log.mpp | 14 ++- 6 files changed, 44 insertions(+), 139 deletions(-) diff --git a/modules/stormkit/core/typesafe/byte.mpp b/modules/stormkit/core/typesafe/byte.mpp index e76480fe1..9724c1e9b 100644 --- a/modules/stormkit/core/typesafe/byte.mpp +++ b/modules/stormkit/core/typesafe/byte.mpp @@ -260,49 +260,49 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST STORMKIT_INTRINSIC - inline constexpr auto operator""_b(unsigned long long value) noexcept -> byte { + constexpr auto operator""_b(unsigned long long value) noexcept -> byte { return static_cast(value); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST - inline constexpr auto operator""_kb(unsigned long long x) noexcept -> u64 { + constexpr auto operator""_kb(unsigned long long x) noexcept -> u64 { return x * 1000ULL; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST - inline constexpr auto operator""_mb(unsigned long long x) noexcept -> u64 { + constexpr auto operator""_mb(unsigned long long x) noexcept -> u64 { return x * 1000_kb; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST - inline constexpr auto operator""_gb(unsigned long long x) noexcept -> u64 { + constexpr auto operator""_gb(unsigned long long x) noexcept -> u64 { return x * 1000_mb; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST - inline constexpr auto operator""_kib(unsigned long long x) noexcept -> u64 { + constexpr auto operator""_kib(unsigned long long x) noexcept -> u64 { return x * 1024; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST - inline constexpr auto operator""_mib(unsigned long long x) noexcept -> u64 { + constexpr auto operator""_mib(unsigned long long x) noexcept -> u64 { return x * 1024_kib; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST - inline constexpr auto operator""_gib(unsigned long long x) noexcept -> u64 { + constexpr auto operator""_gib(unsigned long long x) noexcept -> u64 { return x * 1024_mib; } } // namespace literals diff --git a/modules/stormkit/core/utils/pimpl.mpp b/modules/stormkit/core/utils/pimpl.mpp index b13abce03..1979024c5 100644 --- a/modules/stormkit/core/utils/pimpl.mpp +++ b/modules/stormkit/core/utils/pimpl.mpp @@ -63,7 +63,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - Pimpl::Pimpl() noexcept(not Defer) { + inline Pimpl::Pimpl() noexcept(not Defer) { if constexpr (not Defer) init(); } @@ -71,8 +71,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - Pimpl::~Pimpl() - = default; + inline Pimpl::~Pimpl() = default; ///////////////////////////////////// ///////////////////////////////////// @@ -80,7 +79,7 @@ namespace stormkit { inline namespace core { template requires(meta::EnableCtor, Args...>) STORMKIT_FORCE_INLINE - Pimpl::Pimpl(Args&&... args) { + inline Pimpl::Pimpl(Args&&... args) { init(std::forward(args)...); } @@ -88,21 +87,20 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - Pimpl::Pimpl(Pimpl&&) noexcept - = default; + inline Pimpl::Pimpl(Pimpl&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE - auto Pimpl::operator=(Pimpl&&) noexcept -> Pimpl& = default; + inline auto Pimpl::operator=(Pimpl&&) noexcept -> Pimpl& = default; ///////////////////////////////////// ///////////////////////////////////// template template STORMKIT_FORCE_INLINE - auto Pimpl::init(Args&&... args) -> void { + inline auto Pimpl::init(Args&&... args) -> void { m_data = std::make_unique(std::forward(args)...); } @@ -110,7 +108,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - auto Pimpl::operator->() noexcept -> T* { + inline auto Pimpl::operator->() noexcept -> T* { return &get(); } @@ -118,7 +116,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - auto Pimpl::operator->() const noexcept -> const T* { + inline auto Pimpl::operator->() const noexcept -> const T* { return &get(); } @@ -126,7 +124,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - auto Pimpl::operator*() noexcept -> T& { + inline auto Pimpl::operator*() noexcept -> T& { return get(); } @@ -134,7 +132,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - auto Pimpl::operator*() const noexcept -> const T& { + inline auto Pimpl::operator*() const noexcept -> const T& { return get(); } @@ -142,7 +140,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - auto Pimpl::get() noexcept -> T& { + inline auto Pimpl::get() noexcept -> T& { EXPECTS(m_data != nullptr); return *m_data; } @@ -151,7 +149,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - auto Pimpl::get() const noexcept -> const T& { + inline auto Pimpl::get() const noexcept -> const T& { EXPECTS(m_data != nullptr); return *m_data; } @@ -160,7 +158,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - Pimpl::operator bool() const noexcept { + inline Pimpl::operator bool() const noexcept { return m_data != nullptr; } }} // namespace stormkit::core diff --git a/modules/stormkit/gpu/core/instance.mpp b/modules/stormkit/gpu/core/instance.mpp index 2ac495960..4de01a234 100644 --- a/modules/stormkit/gpu/core/instance.mpp +++ b/modules/stormkit/gpu/core/instance.mpp @@ -229,14 +229,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Instance::~Instance() - = default; + inline Instance::~Instance() = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Instance::Instance(Instance&&) noexcept - = default; + inline Instance::Instance(Instance&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// @@ -312,20 +310,18 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline constexpr Surface::Surface(PrivateFuncTag) noexcept { + constexpr Surface::Surface(PrivateFuncTag) noexcept { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Surface::~Surface() - = default; + inline Surface::~Surface() = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Surface::Surface(Surface&&) noexcept - = default; + inline Surface::Surface(Surface&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// @@ -335,7 +331,7 @@ namespace stormkit::gpu { #if false ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE auto Surface::create_offscreen(const Instance& instance) noexcept + STORMKIT_FORCE_INLINE inline auto Surface::create_offscreen(const Instance& instance) noexcept -> Expected { auto surface = Surface { PrivateFuncTag {} }; return surface.do_init_offscreen(instance).transform(core::monadic::consume(instance)); @@ -343,7 +339,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE auto Surface::allocate_offscreen(const Instance& instance) noexcept + STORMKIT_FORCE_INLINE inline auto Surface::allocate_offscreen(const Instance& instance) noexcept -> Expected> { auto surface = core::allocate_unsafe(PrivateFuncTag {}); return surface->do_init_offscreen(instance).transform(core::monadic::consume(instance)); diff --git a/modules/stormkit/gpu/core/vulkan/enums.mpp.tpl b/modules/stormkit/gpu/core/vulkan/enums.mpp.tpl index 92a42adc2..43c11e742 100644 --- a/modules/stormkit/gpu/core/vulkan/enums.mpp.tpl +++ b/modules/stormkit/gpu/core/vulkan/enums.mpp.tpl @@ -87,7 +87,6 @@ export { } template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::{% outfile:write(name) %} value) noexcept -> std::string { switch(value) { {% for val_name, value in table.orderpairs(enumeration["values"]) do %}case stormkit::gpu::{% outfile:write(name) %}::{% outfile:write(val_name) %}: return "{% outfile:write(name) %}::{% outfile:write(val_name) %}"; @@ -96,99 +95,6 @@ export { std::unreachable(); } {% end %} - // enum class Format : u8 { - // BYTE, - // BYTE2, - // BYTE3, - // BYTE4, - - // BYTE_NORM, - // BYTE2_NORM, - // BYTE3_NORM, - // BYTE4_NORM, - - // BYTE_SCALED, - // BYTE2_SCALED, - // BYTE3_SCALED, - // BYTE4_SCALED, - - // UBYTE, - // UBYTE2, - // UBYTE3, - // UBYTE4, - - // UBYTE_NORM, - // UBYTE2_NORM, - // UBYTE3_NORM, - // UBYTE4_NORM, - - // UBYTE_UCALED, - // UBYTE2_UCALED, - // UBYTE3_UCALED, - // UBYTE4_UCALED, - - // SHORT, - // SHORT2, - // SHORT3, - // SHORT4, - - // SHORT_NORM, - // SHORT2_NORM, - // SHORT3_NORM, - // SHORT4_NORM, - - // SHORT_SCALED, - // SHORT2_SCALED, - // SHORT3_SCALED, - // SHORT4_SCALED, - - // USHORT, - // USHORT2, - // USHORT3, - // USHORT4, - - // USHORT_NORM, - // USHORT2_NORM, - // USHORT3_NORM, - // USHORT4_NORM, - - // USHORT_UCALED, - // USHORT2_UCALED, - // USHORT3_UCALED, - // USHORT4_UCALED, - - // INT, - // INT2, - // INT3, - // INT4, - - // UINT, - // UINT2, - // UINT3, - // UINT4, - - // LONG, - // LONG2, - // LONG3, - // LONG4, - - // ULONG, - // ULONG2, - // ULONG3, - // ULONG4, - - // FLOAT, - // FLOAT2, - // FLOAT3, - // FLOAT4, - - // DOUBLE, - // DOUBLE2, - // DOUBLE3, - // DOUBLE4, - - // UNDEFINED, - // }; } //////////////////////////////////////////////////////////////////// @@ -199,6 +105,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE + STORMKIT_CONST constexpr auto is_depth_only_format(PixelFormat format) noexcept -> bool { return format == PixelFormat::DEPTH16_UNORM or format == PixelFormat::DEPTH24_UNORM_PACK32 @@ -208,6 +115,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE + STORMKIT_CONST constexpr auto is_depth_stencil_format(PixelFormat format) noexcept -> bool { return format == PixelFormat::DEPTH16_UNORM_STENCIL8U or format == PixelFormat::DEPTH24_UNORM_STENCIL8U @@ -217,6 +125,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE + STORMKIT_CONST constexpr auto is_depth_format(PixelFormat format) noexcept -> bool { return is_depth_only_format(format) or is_depth_stencil_format(format); } @@ -224,6 +133,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE + STORMKIT_CONST constexpr auto get_format_channel_count(PixelFormat format) noexcept -> u8 { switch (format) { case PixelFormat::R8_SNORM: @@ -301,6 +211,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE + STORMKIT_CONST constexpr auto get_format_element_count(PixelFormat format) noexcept -> u8 { switch (format) { case PixelFormat::R8_SNORM: @@ -369,6 +280,7 @@ namespace stormkit::gpu { template requires(core::meta::IsPlainEnumeration or core::meta::Is) STORMKIT_FORCE_INLINE + STORMKIT_CONST STORMKIT_INTRINSIC constexpr auto to_vk(U value) noexcept -> T{ return narrow(value); @@ -379,6 +291,7 @@ namespace stormkit::gpu { template requires(core::meta::IsPlainEnumeration or core::meta::Is) STORMKIT_FORCE_INLINE + STORMKIT_CONST STORMKIT_INTRINSIC constexpr auto from_vk(U value) noexcept -> T { return narrow(value); diff --git a/modules/stormkit/gpu/core/vulkan/utils.mpp b/modules/stormkit/gpu/core/vulkan/utils.mpp index c0e7b1980..b7f579ed6 100644 --- a/modules/stormkit/gpu/core/vulkan/utils.mpp +++ b/modules/stormkit/gpu/core/vulkan/utils.mpp @@ -152,28 +152,28 @@ namespace stormkit::gpu { template STORMKIT_FORCE_INLINE STORMKIT_CONST - inline constexpr auto vk_make_version(T major, T minor, T patch) noexcept -> u32 { + constexpr auto vk_make_version(T major, T minor, T patch) noexcept -> u32 { return vk_version_major(major) | vk_version_minor(minor) | vk_version_patch(patch); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST STORMKIT_INTRINSIC - inline constexpr auto vk_version_major(std::integral auto version) noexcept -> u32 { + constexpr auto vk_version_major(std::integral auto version) noexcept -> u32 { return as(version) >> 22u; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST STORMKIT_INTRINSIC - inline constexpr auto vk_version_minor(std::integral auto version) noexcept -> u32 { + constexpr auto vk_version_minor(std::integral auto version) noexcept -> u32 { return ((as(version) >> 12u) & 0x3ffu); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST STORMKIT_INTRINSIC - inline constexpr auto vk_version_patch(std::integral auto version) noexcept -> u32 { + constexpr auto vk_version_patch(std::integral auto version) noexcept -> u32 { return as(version) & 0xfffu; } diff --git a/modules/stormkit/log.mpp b/modules/stormkit/log.mpp index 7e65d07ca..f0e59d33a 100644 --- a/modules/stormkit/log.mpp +++ b/modules/stormkit/log.mpp @@ -179,7 +179,7 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST - inline constexpr auto as_string(Severity severity) noexcept -> std::string_view { + constexpr auto as_string(Severity severity) noexcept -> std::string_view { switch (severity) { case Severity::INFO: return "Severity::INFO"; case Severity::WARNING: return "Severity::WARNING"; @@ -195,7 +195,7 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline constexpr auto to_string(Severity severity) noexcept -> std::string { + constexpr auto to_string(Severity severity) noexcept -> std::string { return std::string { as_string(severity) }; } @@ -230,7 +230,6 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// template - STORMKIT_FORCE_INLINE inline auto Logger::create_logger_instance(Args&&... param_args) noexcept -> T { static_assert(std::is_base_of::value, "T must inherit Logger"); @@ -242,8 +241,7 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// template - STORMKIT_FORCE_INLINE - auto Logger::allocate_logger_instance(Args&&... param_args) noexcept -> Heap { + inline auto Logger::allocate_logger_instance(Args&&... param_args) noexcept -> Heap { static_assert(std::is_base_of::value, "T must inherit Logger"); auto time_point = LogClock::now(); @@ -255,8 +253,8 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// template - STORMKIT_FORCE_INLINE - auto Logger::log(Severity severity, const Module& m, std::string_view format_string, Args&&... param_args) noexcept -> void { + inline auto Logger::log(Severity severity, const Module& m, std::string_view format_string, Args&&... param_args) noexcept + -> void { EXPECTS(has_logger()); const auto log_level = instance().log_level(); @@ -379,7 +377,7 @@ namespace stormkit::log { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline constexpr auto operator""_module() noexcept -> stormkit::log::Module { + constexpr auto operator""_module() noexcept -> stormkit::log::Module { return Module { str.view() }; } } // namespace stormkit::log From db40bfda0bb6326057ed846ea1c85234740d9a99 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 23:20:38 +0100 Subject: [PATCH 055/194] (gpu) add STORMKIT_API to to_vk / from_vk for enums --- modules/stormkit/gpu/core/vulkan/enums.mpp | 770 ++++++++---------- .../stormkit/gpu/core/vulkan/enums.mpp.tpl | 18 +- tools/terra/src/main.cpp | 10 +- 3 files changed, 338 insertions(+), 460 deletions(-) diff --git a/modules/stormkit/gpu/core/vulkan/enums.mpp b/modules/stormkit/gpu/core/vulkan/enums.mpp index 2d840048a..99b74f0ff 100644 --- a/modules/stormkit/gpu/core/vulkan/enums.mpp +++ b/modules/stormkit/gpu/core/vulkan/enums.mpp @@ -448,8 +448,8 @@ export { EQUIVALENT = VK_LOGIC_OP_EQUIVALENT, INVERT = VK_LOGIC_OP_INVERT, NAND = VK_LOGIC_OP_NAND, - NO_OP = VK_LOGIC_OP_NO_OP, NOR = VK_LOGIC_OP_NOR, + NO_OP = VK_LOGIC_OP_NO_OP, OR = VK_LOGIC_OP_OR, OR_INVERTED = VK_LOGIC_OP_OR_INVERTED, OR_REVERSE = VK_LOGIC_OP_OR_REVERSE, @@ -515,9 +515,9 @@ export { enum class PixelFormat : u32 { A1_RGB5_UNORM_PACK16 = VK_FORMAT_A1R5G5B5_UNORM_PACK16, A2_RGB10I_PACK32 = VK_FORMAT_A2R10G10B10_SINT_PACK32, + A2_RGB10U_PACK32 = VK_FORMAT_A2R10G10B10_UINT_PACK32, A2_RGB10_SNORM_PACK32 = VK_FORMAT_A2R10G10B10_SNORM_PACK32, A2_RGB10_UNORM_PACK32 = VK_FORMAT_A2R10G10B10_UNORM_PACK32, - A2_RGB10U_PACK32 = VK_FORMAT_A2R10G10B10_UINT_PACK32, B10_GR11UF_PACK32 = VK_FORMAT_B10G11R11_UFLOAT_PACK32, BGR8_UNORM = VK_FORMAT_B8G8R8_UNORM, BGRA8_UNORM = VK_FORMAT_B8G8R8A8_UNORM, @@ -529,53 +529,53 @@ export { DEPTH32F_STENCIL8U = VK_FORMAT_D32_SFLOAT_S8_UINT, R16F = VK_FORMAT_R16_SFLOAT, R16I = VK_FORMAT_R16_SINT, - R16_SNORM = VK_FORMAT_R16_SNORM, R16U = VK_FORMAT_R16_UINT, + R16_SNORM = VK_FORMAT_R16_SNORM, R16_UNORM = VK_FORMAT_R16_UNORM, R32F = VK_FORMAT_R32_SFLOAT, R32I = VK_FORMAT_R32_SINT, R32U = VK_FORMAT_R32_UINT, R5_G6_B5_UNORM_PACK16 = VK_FORMAT_R5G6B5_UNORM_PACK16, R8I = VK_FORMAT_R8_SINT, - R8_SNORM = VK_FORMAT_R8_SNORM, R8U = VK_FORMAT_R8_UINT, + R8_SNORM = VK_FORMAT_R8_SNORM, R8_UNORM = VK_FORMAT_R8_UNORM, RG16F = VK_FORMAT_R16G16_SFLOAT, RG16I = VK_FORMAT_R16G16_SINT, - RG16_SNORM = VK_FORMAT_R16G16_SNORM, RG16U = VK_FORMAT_R16G16_UINT, + RG16_SNORM = VK_FORMAT_R16G16_SNORM, RG16_UNORM = VK_FORMAT_R16G16_UNORM, RG32F = VK_FORMAT_R32G32_SFLOAT, RG32I = VK_FORMAT_R32G32_SINT, RG32U = VK_FORMAT_R32G32_UINT, RG8I = VK_FORMAT_R8G8_SINT, - RG8_SNORM = VK_FORMAT_R8G8_SNORM, RG8U = VK_FORMAT_R8G8_UINT, + RG8_SNORM = VK_FORMAT_R8G8_SNORM, RG8_UNORM = VK_FORMAT_R8G8_UNORM, RGB16F = VK_FORMAT_R16G16B16_SFLOAT, RGB16I = VK_FORMAT_R16G16B16_SINT, - RGB16_SNORM = VK_FORMAT_R16G16B16_SNORM, RGB16U = VK_FORMAT_R16G16B16_UINT, + RGB16_SNORM = VK_FORMAT_R16G16B16_SNORM, RGB16_UNORM = VK_FORMAT_R16G16B16_UNORM, RGB32F = VK_FORMAT_R32G32B32_SFLOAT, RGB32I = VK_FORMAT_R32G32B32_SINT, RGB32U = VK_FORMAT_R32G32B32_UINT, RGB8I = VK_FORMAT_R8G8B8_SINT, - RGB8_SNORM = VK_FORMAT_R8G8B8_SNORM, RGB8U = VK_FORMAT_R8G8B8_UINT, + RGB8_SNORM = VK_FORMAT_R8G8B8_SNORM, RGB8_UNORM = VK_FORMAT_R8G8B8_UNORM, RGBA16F = VK_FORMAT_R16G16B16A16_SFLOAT, RGBA16I = VK_FORMAT_R16G16B16A16_SINT, - RGBA16_SNORM = VK_FORMAT_R16G16B16A16_SNORM, RGBA16U = VK_FORMAT_R16G16B16A16_UINT, + RGBA16_SNORM = VK_FORMAT_R16G16B16A16_SNORM, RGBA16_UNORM = VK_FORMAT_R16G16B16A16_UNORM, RGBA32F = VK_FORMAT_R32G32B32A32_SFLOAT, RGBA32I = VK_FORMAT_R32G32B32A32_SINT, RGBA32U = VK_FORMAT_R32G32B32A32_UINT, RGBA4_UNORM_PACK16 = VK_FORMAT_R4G4B4A4_UNORM_PACK16, RGBA8I = VK_FORMAT_R8G8B8A8_SINT, - RGBA8_SNORM = VK_FORMAT_R8G8B8A8_SNORM, RGBA8U = VK_FORMAT_R8G8B8A8_UINT, + RGBA8_SNORM = VK_FORMAT_R8G8B8A8_SNORM, RGBA8_UNORM = VK_FORMAT_R8G8B8A8_UNORM, SBGR8 = VK_FORMAT_B8G8R8_SRGB, SBGRA8 = VK_FORMAT_B8G8R8A8_SRGB, @@ -704,8 +704,8 @@ export { enum class SamplerAddressMode : u8 { CLAMP_TO_BORDER = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, - MIRROR_CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, MIRRORED_REPEAT = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, + MIRROR_CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, REPEAT = VK_SAMPLER_ADDRESS_MODE_REPEAT, }; @@ -764,8 +764,6 @@ export { constexpr auto is_depth_stencil_format(PixelFormat format) noexcept -> bool; [[nodiscard]] constexpr auto is_depth_format(PixelFormat format) noexcept -> bool; - [[nodiscard]] - constexpr auto is_stencil_format(PixelFormat format) noexcept -> bool; [[nodiscard]] constexpr auto get_format_channel_count(PixelFormat format) noexcept -> u8; @@ -829,7 +827,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::AccessFlag value) noexcept -> std::string { switch (value) { case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; @@ -881,7 +878,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentLoadOperation value) noexcept -> std::string { switch (value) { @@ -918,7 +914,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentStoreOperation value) noexcept -> std::string { switch (value) { @@ -988,7 +983,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::BlendFactor value) noexcept -> std::string { switch (value) { @@ -1045,7 +1039,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::BlendOperation value) noexcept -> std::string { switch (value) { @@ -1089,7 +1082,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::BorderColor value) noexcept -> std::string { switch (value) { @@ -1139,7 +1131,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::BufferUsageFlag value) noexcept -> std::string { switch (value) { @@ -1190,7 +1181,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::ColorComponentFlag value) noexcept -> std::string { switch (value) { @@ -1260,7 +1250,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::ColorSpace value) noexcept -> std::string { switch (value) { case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; @@ -1309,7 +1298,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::CommandBufferLevel value) noexcept -> std::string { switch (value) { @@ -1353,7 +1341,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::CompareOperation value) noexcept -> std::string { switch (value) { @@ -1399,7 +1386,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::CullModeFlag value) noexcept -> std::string { switch (value) { @@ -1493,7 +1479,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::DebugObjectType value) noexcept -> std::string { switch (value) { @@ -1561,7 +1546,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::DependencyFlag value) noexcept -> std::string { switch (value) { @@ -1612,7 +1596,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::DescriptorType value) noexcept -> std::string { switch (value) { @@ -1667,7 +1650,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::DynamicState value) noexcept -> std::string { switch (value) { @@ -1711,7 +1693,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::Filter value) noexcept -> std::string { switch (value) { case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; @@ -1796,7 +1777,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::FormatFeatureFlag value) noexcept -> std::string { switch (value) { @@ -1860,7 +1840,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::FrontFace value) noexcept -> std::string { switch (value) { case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; @@ -1896,7 +1875,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryFlag value) noexcept -> std::string { switch (value) { @@ -1935,7 +1913,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryType value) noexcept -> std::string { switch (value) { @@ -1976,7 +1953,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::ImageAspectFlag value) noexcept -> std::string { switch (value) { @@ -2038,7 +2014,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::ImageCreateFlag value) noexcept -> std::string { switch (value) { @@ -2115,7 +2090,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::ImageLayout value) noexcept -> std::string { switch (value) { @@ -2167,7 +2141,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::ImageTiling value) noexcept -> std::string { switch (value) { @@ -2205,7 +2178,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::ImageType value) noexcept -> std::string { switch (value) { case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; @@ -2249,7 +2221,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::ImageUsageFlag value) noexcept -> std::string { switch (value) { @@ -2298,7 +2269,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::ImageViewType value) noexcept -> std::string { switch (value) { @@ -2323,8 +2293,8 @@ export { stormkit::gpu::LogicOperation::AND_REVERSE, stormkit::gpu::LogicOperation::CLEAR, stormkit::gpu::LogicOperation::COPY, stormkit::gpu::LogicOperation::COPY_INVERTED, stormkit::gpu::LogicOperation::EQUIVALENT, stormkit::gpu::LogicOperation::INVERT, - stormkit::gpu::LogicOperation::NAND, stormkit::gpu::LogicOperation::NO_OP, - stormkit::gpu::LogicOperation::NOR, stormkit::gpu::LogicOperation::OR, + stormkit::gpu::LogicOperation::NAND, stormkit::gpu::LogicOperation::NOR, + stormkit::gpu::LogicOperation::NO_OP, stormkit::gpu::LogicOperation::OR, stormkit::gpu::LogicOperation::OR_INVERTED, stormkit::gpu::LogicOperation::OR_REVERSE, stormkit::gpu::LogicOperation::SET, stormkit::gpu::LogicOperation::XOR, @@ -2346,8 +2316,8 @@ export { case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; - case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; + case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; case stormkit::gpu::LogicOperation::OR: return "LogicOperation::OR"; case stormkit::gpu::LogicOperation::OR_INVERTED: return "LogicOperation::OR_INVERTED"; case stormkit::gpu::LogicOperation::OR_REVERSE: return "LogicOperation::OR_REVERSE"; @@ -2359,7 +2329,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::LogicOperation value) noexcept -> std::string { switch (value) { @@ -2372,8 +2341,8 @@ export { case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; - case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; + case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; case stormkit::gpu::LogicOperation::OR: return "LogicOperation::OR"; case stormkit::gpu::LogicOperation::OR_INVERTED: return "LogicOperation::OR_INVERTED"; case stormkit::gpu::LogicOperation::OR_REVERSE: return "LogicOperation::OR_REVERSE"; @@ -2413,7 +2382,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::MemoryPropertyFlag value) noexcept -> std::string { switch (value) { @@ -2457,7 +2425,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::PhysicalDeviceType value) noexcept -> std::string { switch (value) { @@ -2496,7 +2463,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineBindPoint value) noexcept -> std::string { switch (value) { @@ -2564,7 +2530,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineStageFlag value) noexcept -> std::string { switch (value) { @@ -2599,9 +2564,9 @@ export { return std::array { stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16, stormkit::gpu::PixelFormat::A2_RGB10I_PACK32, + stormkit::gpu::PixelFormat::A2_RGB10U_PACK32, stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32, stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32, - stormkit::gpu::PixelFormat::A2_RGB10U_PACK32, stormkit::gpu::PixelFormat::B10_GR11UF_PACK32, stormkit::gpu::PixelFormat::BGR8_UNORM, stormkit::gpu::PixelFormat::BGRA8_UNORM, @@ -2613,53 +2578,53 @@ export { stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U, stormkit::gpu::PixelFormat::R16F, stormkit::gpu::PixelFormat::R16I, - stormkit::gpu::PixelFormat::R16_SNORM, stormkit::gpu::PixelFormat::R16U, + stormkit::gpu::PixelFormat::R16_SNORM, stormkit::gpu::PixelFormat::R16_UNORM, stormkit::gpu::PixelFormat::R32F, stormkit::gpu::PixelFormat::R32I, stormkit::gpu::PixelFormat::R32U, stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16, stormkit::gpu::PixelFormat::R8I, - stormkit::gpu::PixelFormat::R8_SNORM, stormkit::gpu::PixelFormat::R8U, + stormkit::gpu::PixelFormat::R8_SNORM, stormkit::gpu::PixelFormat::R8_UNORM, stormkit::gpu::PixelFormat::RG16F, stormkit::gpu::PixelFormat::RG16I, - stormkit::gpu::PixelFormat::RG16_SNORM, stormkit::gpu::PixelFormat::RG16U, + stormkit::gpu::PixelFormat::RG16_SNORM, stormkit::gpu::PixelFormat::RG16_UNORM, stormkit::gpu::PixelFormat::RG32F, stormkit::gpu::PixelFormat::RG32I, stormkit::gpu::PixelFormat::RG32U, stormkit::gpu::PixelFormat::RG8I, - stormkit::gpu::PixelFormat::RG8_SNORM, stormkit::gpu::PixelFormat::RG8U, + stormkit::gpu::PixelFormat::RG8_SNORM, stormkit::gpu::PixelFormat::RG8_UNORM, stormkit::gpu::PixelFormat::RGB16F, stormkit::gpu::PixelFormat::RGB16I, - stormkit::gpu::PixelFormat::RGB16_SNORM, stormkit::gpu::PixelFormat::RGB16U, + stormkit::gpu::PixelFormat::RGB16_SNORM, stormkit::gpu::PixelFormat::RGB16_UNORM, stormkit::gpu::PixelFormat::RGB32F, stormkit::gpu::PixelFormat::RGB32I, stormkit::gpu::PixelFormat::RGB32U, stormkit::gpu::PixelFormat::RGB8I, - stormkit::gpu::PixelFormat::RGB8_SNORM, stormkit::gpu::PixelFormat::RGB8U, + stormkit::gpu::PixelFormat::RGB8_SNORM, stormkit::gpu::PixelFormat::RGB8_UNORM, stormkit::gpu::PixelFormat::RGBA16F, stormkit::gpu::PixelFormat::RGBA16I, - stormkit::gpu::PixelFormat::RGBA16_SNORM, stormkit::gpu::PixelFormat::RGBA16U, + stormkit::gpu::PixelFormat::RGBA16_SNORM, stormkit::gpu::PixelFormat::RGBA16_UNORM, stormkit::gpu::PixelFormat::RGBA32F, stormkit::gpu::PixelFormat::RGBA32I, stormkit::gpu::PixelFormat::RGBA32U, stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16, stormkit::gpu::PixelFormat::RGBA8I, - stormkit::gpu::PixelFormat::RGBA8_SNORM, stormkit::gpu::PixelFormat::RGBA8U, + stormkit::gpu::PixelFormat::RGBA8_SNORM, stormkit::gpu::PixelFormat::RGBA8_UNORM, stormkit::gpu::PixelFormat::SBGR8, stormkit::gpu::PixelFormat::SBGRA8, @@ -2680,9 +2645,9 @@ export { switch (value) { case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; @@ -2694,53 +2659,53 @@ export { case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; - case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; + case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; case stormkit::gpu::PixelFormat::R16_UNORM: return "PixelFormat::R16_UNORM"; case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; - case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; + case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; case stormkit::gpu::PixelFormat::R8_UNORM: return "PixelFormat::R8_UNORM"; case stormkit::gpu::PixelFormat::RG16F: return "PixelFormat::RG16F"; case stormkit::gpu::PixelFormat::RG16I: return "PixelFormat::RG16I"; - case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; + case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; case stormkit::gpu::PixelFormat::RG16_UNORM: return "PixelFormat::RG16_UNORM"; case stormkit::gpu::PixelFormat::RG32F: return "PixelFormat::RG32F"; case stormkit::gpu::PixelFormat::RG32I: return "PixelFormat::RG32I"; case stormkit::gpu::PixelFormat::RG32U: return "PixelFormat::RG32U"; case stormkit::gpu::PixelFormat::RG8I: return "PixelFormat::RG8I"; - case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; + case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; case stormkit::gpu::PixelFormat::RG8_UNORM: return "PixelFormat::RG8_UNORM"; case stormkit::gpu::PixelFormat::RGB16F: return "PixelFormat::RGB16F"; case stormkit::gpu::PixelFormat::RGB16I: return "PixelFormat::RGB16I"; - case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; + case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; case stormkit::gpu::PixelFormat::RGB16_UNORM: return "PixelFormat::RGB16_UNORM"; case stormkit::gpu::PixelFormat::RGB32F: return "PixelFormat::RGB32F"; case stormkit::gpu::PixelFormat::RGB32I: return "PixelFormat::RGB32I"; case stormkit::gpu::PixelFormat::RGB32U: return "PixelFormat::RGB32U"; case stormkit::gpu::PixelFormat::RGB8I: return "PixelFormat::RGB8I"; - case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; + case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; case stormkit::gpu::PixelFormat::RGB8_UNORM: return "PixelFormat::RGB8_UNORM"; case stormkit::gpu::PixelFormat::RGBA16F: return "PixelFormat::RGBA16F"; case stormkit::gpu::PixelFormat::RGBA16I: return "PixelFormat::RGBA16I"; - case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; + case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; case stormkit::gpu::PixelFormat::RGBA16_UNORM: return "PixelFormat::RGBA16_UNORM"; case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; - case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; + case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; case stormkit::gpu::PixelFormat::RGBA8_UNORM: return "PixelFormat::RGBA8_UNORM"; case stormkit::gpu::PixelFormat::SBGR8: return "PixelFormat::SBGR8"; case stormkit::gpu::PixelFormat::SBGRA8: return "PixelFormat::SBGRA8"; @@ -2755,15 +2720,14 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::PixelFormat value) noexcept -> std::string { switch (value) { case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; @@ -2775,53 +2739,53 @@ export { case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; - case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; + case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; case stormkit::gpu::PixelFormat::R16_UNORM: return "PixelFormat::R16_UNORM"; case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; - case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; + case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; case stormkit::gpu::PixelFormat::R8_UNORM: return "PixelFormat::R8_UNORM"; case stormkit::gpu::PixelFormat::RG16F: return "PixelFormat::RG16F"; case stormkit::gpu::PixelFormat::RG16I: return "PixelFormat::RG16I"; - case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; + case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; case stormkit::gpu::PixelFormat::RG16_UNORM: return "PixelFormat::RG16_UNORM"; case stormkit::gpu::PixelFormat::RG32F: return "PixelFormat::RG32F"; case stormkit::gpu::PixelFormat::RG32I: return "PixelFormat::RG32I"; case stormkit::gpu::PixelFormat::RG32U: return "PixelFormat::RG32U"; case stormkit::gpu::PixelFormat::RG8I: return "PixelFormat::RG8I"; - case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; + case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; case stormkit::gpu::PixelFormat::RG8_UNORM: return "PixelFormat::RG8_UNORM"; case stormkit::gpu::PixelFormat::RGB16F: return "PixelFormat::RGB16F"; case stormkit::gpu::PixelFormat::RGB16I: return "PixelFormat::RGB16I"; - case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; + case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; case stormkit::gpu::PixelFormat::RGB16_UNORM: return "PixelFormat::RGB16_UNORM"; case stormkit::gpu::PixelFormat::RGB32F: return "PixelFormat::RGB32F"; case stormkit::gpu::PixelFormat::RGB32I: return "PixelFormat::RGB32I"; case stormkit::gpu::PixelFormat::RGB32U: return "PixelFormat::RGB32U"; case stormkit::gpu::PixelFormat::RGB8I: return "PixelFormat::RGB8I"; - case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; + case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; case stormkit::gpu::PixelFormat::RGB8_UNORM: return "PixelFormat::RGB8_UNORM"; case stormkit::gpu::PixelFormat::RGBA16F: return "PixelFormat::RGBA16F"; case stormkit::gpu::PixelFormat::RGBA16I: return "PixelFormat::RGBA16I"; - case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; + case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; case stormkit::gpu::PixelFormat::RGBA16_UNORM: return "PixelFormat::RGBA16_UNORM"; case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; - case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; + case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; case stormkit::gpu::PixelFormat::RGBA8_UNORM: return "PixelFormat::RGBA8_UNORM"; case stormkit::gpu::PixelFormat::SBGR8: return "PixelFormat::SBGR8"; case stormkit::gpu::PixelFormat::SBGRA8: return "PixelFormat::SBGRA8"; @@ -2862,7 +2826,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::PolygonMode value) noexcept -> std::string { switch (value) { @@ -2907,7 +2870,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::PresentMode value) noexcept -> std::string { switch (value) { @@ -2952,7 +2914,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::PrimitiveTopology value) noexcept -> std::string { switch (value) { @@ -2996,7 +2957,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::QueueFlag value) noexcept -> std::string { switch (value) { case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; @@ -3041,7 +3001,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::ResolveModeFlag value) noexcept -> std::string { switch (value) { @@ -3151,7 +3110,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::Result value) noexcept -> std::string { switch (value) { case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; @@ -3228,7 +3186,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::SampleCountFlag value) noexcept -> std::string { switch (value) { @@ -3249,10 +3206,8 @@ export { STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER, - stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE, - stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE, - stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT, + stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER, stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE, + stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT, stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE, stormkit::gpu::SamplerAddressMode::REPEAT, }; @@ -3266,8 +3221,8 @@ export { switch (value) { case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; + case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; } std::unreachable(); @@ -3275,14 +3230,13 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerAddressMode value) noexcept -> std::string { switch (value) { case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; + case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; } std::unreachable(); @@ -3314,7 +3268,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerMipmapMode value) noexcept -> std::string { switch (value) { @@ -3354,7 +3307,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::ShaderStageFlag value) noexcept -> std::string { switch (value) { @@ -3395,7 +3347,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::StencilFaceFlag value) noexcept -> std::string { switch (value) { @@ -3432,7 +3383,6 @@ export { template<> STORMKIT_FORCE_INLINE - STORMKIT_CONST constexpr auto stormkit::core::to_string(stormkit::gpu::VertexInputRate value) noexcept -> std::string { switch (value) { @@ -3441,100 +3391,6 @@ export { } std::unreachable(); } - - // enum class Format : u8 { - // BYTE, - // BYTE2, - // BYTE3, - // BYTE4, - - // BYTE_NORM, - // BYTE2_NORM, - // BYTE3_NORM, - // BYTE4_NORM, - - // BYTE_SCALED, - // BYTE2_SCALED, - // BYTE3_SCALED, - // BYTE4_SCALED, - - // UBYTE, - // UBYTE2, - // UBYTE3, - // UBYTE4, - - // UBYTE_NORM, - // UBYTE2_NORM, - // UBYTE3_NORM, - // UBYTE4_NORM, - - // UBYTE_UCALED, - // UBYTE2_UCALED, - // UBYTE3_UCALED, - // UBYTE4_UCALED, - - // SHORT, - // SHORT2, - // SHORT3, - // SHORT4, - - // SHORT_NORM, - // SHORT2_NORM, - // SHORT3_NORM, - // SHORT4_NORM, - - // SHORT_SCALED, - // SHORT2_SCALED, - // SHORT3_SCALED, - // SHORT4_SCALED, - - // USHORT, - // USHORT2, - // USHORT3, - // USHORT4, - - // USHORT_NORM, - // USHORT2_NORM, - // USHORT3_NORM, - // USHORT4_NORM, - - // USHORT_UCALED, - // USHORT2_UCALED, - // USHORT3_UCALED, - // USHORT4_UCALED, - - // INT, - // INT2, - // INT3, - // INT4, - - // UINT, - // UINT2, - // UINT3, - // UINT4, - - // LONG, - // LONG2, - // LONG3, - // LONG4, - - // ULONG, - // ULONG2, - // ULONG3, - // ULONG4, - - // FLOAT, - // FLOAT2, - // FLOAT3, - // FLOAT4, - - // DOUBLE, - // DOUBLE2, - // DOUBLE3, - // DOUBLE4, - - // UNDEFINED, - // }; } //////////////////////////////////////////////////////////////////// @@ -3544,7 +3400,7 @@ export { namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE + STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto is_depth_only_format(PixelFormat format) noexcept -> bool { return format == PixelFormat::DEPTH16_UNORM or format == PixelFormat::DEPTH24_UNORM_PACK32 @@ -3553,7 +3409,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE + STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto is_depth_stencil_format(PixelFormat format) noexcept -> bool { return format == PixelFormat::DEPTH16_UNORM_STENCIL8U or format == PixelFormat::DEPTH24_UNORM_STENCIL8U @@ -3562,14 +3418,14 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE + STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto is_depth_format(PixelFormat format) noexcept -> bool { return is_depth_only_format(format) or is_depth_stencil_format(format); } ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE + STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto get_format_channel_count(PixelFormat format) noexcept -> u8 { switch (format) { case PixelFormat::R8_SNORM: @@ -3646,7 +3502,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE + STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto get_format_element_count(PixelFormat format) noexcept -> u8 { switch (format) { case PixelFormat::R8_SNORM: @@ -3715,6 +3571,7 @@ namespace stormkit::gpu { template requires(core::meta::IsPlainEnumeration or core::meta::Is) STORMKIT_FORCE_INLINE + STORMKIT_CONST STORMKIT_INTRINSIC constexpr auto to_vk(U value) noexcept -> T { return narrow(value); @@ -3725,262 +3582,279 @@ namespace stormkit::gpu { template requires(core::meta::IsPlainEnumeration or core::meta::Is) STORMKIT_FORCE_INLINE + STORMKIT_CONST STORMKIT_INTRINSIC constexpr auto from_vk(U value) noexcept -> T { return narrow(value); } } // namespace stormkit::gpu -template stormkit::gpu::AccessFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::AccessFlag stormkit::gpu::from_vk(VkAccessFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); -template VkAccessFlagBits stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); - -template stormkit::gpu::AttachmentLoadOperation stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::AttachmentLoadOperation stormkit::gpu::from_vk(VkAttachmentLoadOp); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); -template VkAttachmentLoadOp stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); - -template stormkit::gpu::AttachmentStoreOperation stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::AttachmentStoreOperation stormkit::gpu::from_vk(VkAttachmentStoreOp); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); -template VkAttachmentStoreOp stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); - -template stormkit::gpu::BlendFactor stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::BlendFactor stormkit::gpu::from_vk(VkBlendFactor); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); -template VkBlendFactor stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); - -template stormkit::gpu::BlendOperation stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::BlendOperation stormkit::gpu::from_vk(VkBlendOp); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); -template VkBlendOp stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); - -template stormkit::gpu::BorderColor stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::BorderColor stormkit::gpu::from_vk(VkBorderColor); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BorderColor); -template VkBorderColor stormkit::gpu::to_vk(stormkit::gpu::BorderColor); - -template stormkit::gpu::BufferUsageFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::BufferUsageFlag stormkit::gpu::from_vk(VkBufferUsageFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); -template VkBufferUsageFlagBits stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); - -template stormkit::gpu::ColorComponentFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ColorComponentFlag stormkit::gpu::from_vk(VkColorComponentFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); -template VkColorComponentFlagBits stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); - -template stormkit::gpu::ColorSpace stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ColorSpace stormkit::gpu::from_vk(VkColorSpaceKHR); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); -template VkColorSpaceKHR stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); - -template stormkit::gpu::CommandBufferLevel stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::CommandBufferLevel stormkit::gpu::from_vk(VkCommandBufferLevel); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); -template VkCommandBufferLevel stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); - -template stormkit::gpu::CompareOperation stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::CompareOperation stormkit::gpu::from_vk(VkCompareOp); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); -template VkCompareOp stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); - -template stormkit::gpu::CullModeFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::CullModeFlag stormkit::gpu::from_vk(VkCullModeFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); -template VkCullModeFlagBits stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); - -template stormkit::gpu::DebugObjectType stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::DebugObjectType stormkit::gpu::from_vk(VkObjectType); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); -template VkObjectType stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); - -template stormkit::gpu::DependencyFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::DependencyFlag stormkit::gpu::from_vk(VkDependencyFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); -template VkDependencyFlagBits stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); - -template stormkit::gpu::DescriptorType stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::DescriptorType stormkit::gpu::from_vk(VkDescriptorType); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); -template VkDescriptorType stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); - -template stormkit::gpu::DynamicState stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::DynamicState stormkit::gpu::from_vk(VkDynamicState); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::DynamicState); -template VkDynamicState stormkit::gpu::to_vk(stormkit::gpu::DynamicState); - -template stormkit::gpu::Filter stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::Filter stormkit::gpu::from_vk(VkFilter); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::Filter); -template VkFilter stormkit::gpu::to_vk(stormkit::gpu::Filter); - -template stormkit::gpu::FormatFeatureFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::FormatFeatureFlag stormkit::gpu::from_vk(VkFormatFeatureFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); -template VkFormatFeatureFlagBits stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); - -template stormkit::gpu::FrontFace stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::FrontFace stormkit::gpu::from_vk(VkFrontFace); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::FrontFace); -template VkFrontFace stormkit::gpu::to_vk(stormkit::gpu::FrontFace); - -template stormkit::gpu::GeometryFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::GeometryFlag stormkit::gpu::from_vk(VkGeometryFlagBitsKHR); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); -template VkGeometryFlagBitsKHR stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); - -template stormkit::gpu::GeometryType stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::GeometryType stormkit::gpu::from_vk(VkGeometryTypeKHR); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::GeometryType); -template VkGeometryTypeKHR stormkit::gpu::to_vk(stormkit::gpu::GeometryType); - -template stormkit::gpu::ImageAspectFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageAspectFlag stormkit::gpu::from_vk(VkImageAspectFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); -template VkImageAspectFlagBits stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); - -template stormkit::gpu::ImageCreateFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageCreateFlag stormkit::gpu::from_vk(VkImageCreateFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); -template VkImageCreateFlagBits stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); - -template stormkit::gpu::ImageLayout stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageLayout stormkit::gpu::from_vk(VkImageLayout); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); -template VkImageLayout stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); - -template stormkit::gpu::ImageTiling stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageTiling stormkit::gpu::from_vk(VkImageTiling); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); -template VkImageTiling stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); - -template stormkit::gpu::ImageType stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageType stormkit::gpu::from_vk(VkImageType); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageType); -template VkImageType stormkit::gpu::to_vk(stormkit::gpu::ImageType); - -template stormkit::gpu::ImageUsageFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageUsageFlag stormkit::gpu::from_vk(VkImageUsageFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); -template VkImageUsageFlagBits stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); - -template stormkit::gpu::ImageViewType stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageViewType stormkit::gpu::from_vk(VkImageViewType); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); -template VkImageViewType stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); - -template stormkit::gpu::LogicOperation stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::LogicOperation stormkit::gpu::from_vk(VkLogicOp); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); -template VkLogicOp stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); - -template stormkit::gpu::MemoryPropertyFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::MemoryPropertyFlag stormkit::gpu::from_vk(VkMemoryPropertyFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); -template VkMemoryPropertyFlagBits stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); - -template stormkit::gpu::PhysicalDeviceType stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PhysicalDeviceType stormkit::gpu::from_vk(VkPhysicalDeviceType); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); -template VkPhysicalDeviceType stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); - -template stormkit::gpu::PipelineBindPoint stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PipelineBindPoint stormkit::gpu::from_vk(VkPipelineBindPoint); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); -template VkPipelineBindPoint stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); - -template stormkit::gpu::PipelineStageFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PipelineStageFlag stormkit::gpu::from_vk(VkPipelineStageFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); -template VkPipelineStageFlagBits stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); - -template stormkit::gpu::PixelFormat stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PixelFormat stormkit::gpu::from_vk(VkFormat); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); -template VkFormat stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); - -template stormkit::gpu::PolygonMode stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PolygonMode stormkit::gpu::from_vk(VkPolygonMode); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); -template VkPolygonMode stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); - -template stormkit::gpu::PresentMode stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PresentMode stormkit::gpu::from_vk(VkPresentModeKHR); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PresentMode); -template VkPresentModeKHR stormkit::gpu::to_vk(stormkit::gpu::PresentMode); - -template stormkit::gpu::PrimitiveTopology stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PrimitiveTopology stormkit::gpu::from_vk(VkPrimitiveTopology); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); -template VkPrimitiveTopology stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); - -template stormkit::gpu::QueueFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::QueueFlag stormkit::gpu::from_vk(VkQueueFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); -template VkQueueFlagBits stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); - -template stormkit::gpu::ResolveModeFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ResolveModeFlag stormkit::gpu::from_vk(VkResolveModeFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ResolveModeFlag); -template VkResolveModeFlagBits stormkit::gpu::to_vk(stormkit::gpu::ResolveModeFlag); - -template stormkit::gpu::Result stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::Result stormkit::gpu::from_vk(VkResult); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::Result); -template VkResult stormkit::gpu::to_vk(stormkit::gpu::Result); - -template stormkit::gpu::SampleCountFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::SampleCountFlag stormkit::gpu::from_vk(VkSampleCountFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); -template VkSampleCountFlagBits stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); - -template stormkit::gpu::SamplerAddressMode stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::SamplerAddressMode stormkit::gpu::from_vk(VkSamplerAddressMode); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); -template VkSamplerAddressMode stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); - -template stormkit::gpu::SamplerMipmapMode stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::SamplerMipmapMode stormkit::gpu::from_vk(VkSamplerMipmapMode); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); -template VkSamplerMipmapMode stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); - -template stormkit::gpu::ShaderStageFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ShaderStageFlag stormkit::gpu::from_vk(VkShaderStageFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); -template VkShaderStageFlagBits stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); - -template stormkit::gpu::StencilFaceFlag stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::StencilFaceFlag stormkit::gpu::from_vk(VkStencilFaceFlagBits); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); -template VkStencilFaceFlagBits stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); - -template stormkit::gpu::VertexInputRate stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::VertexInputRate stormkit::gpu::from_vk(VkVertexInputRate); -template VkFlags stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); -template VkVertexInputRate stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); +template stormkit::gpu::AccessFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::AccessFlag + STORMKIT_API stormkit::gpu::from_vk(VkAccessFlagBits); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); +template VkAccessFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); + +template stormkit::gpu::AttachmentLoadOperation + STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::AttachmentLoadOperation + STORMKIT_API stormkit::gpu::from_vk(VkAttachmentLoadOp); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); +template VkAttachmentLoadOp STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); + +template stormkit::gpu::AttachmentStoreOperation + STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::AttachmentStoreOperation + STORMKIT_API stormkit::gpu::from_vk(VkAttachmentStoreOp); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); +template VkAttachmentStoreOp STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); + +template stormkit::gpu::BlendFactor STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::BlendFactor STORMKIT_API stormkit::gpu::from_vk(VkBlendFactor); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); +template VkBlendFactor STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); + +template stormkit::gpu::BlendOperation STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::BlendOperation STORMKIT_API stormkit::gpu::from_vk(VkBlendOp); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); +template VkBlendOp STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); + +template stormkit::gpu::BorderColor STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::BorderColor STORMKIT_API stormkit::gpu::from_vk(VkBorderColor); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::BorderColor); +template VkBorderColor STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::BorderColor); + +template stormkit::gpu::BufferUsageFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::BufferUsageFlag + STORMKIT_API stormkit::gpu::from_vk(VkBufferUsageFlagBits); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); +template VkBufferUsageFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); + +template stormkit::gpu::ColorComponentFlag + STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ColorComponentFlag + STORMKIT_API stormkit::gpu::from_vk(VkColorComponentFlagBits); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); +template VkColorComponentFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); + +template stormkit::gpu::ColorSpace STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ColorSpace + STORMKIT_API stormkit::gpu::from_vk(VkColorSpaceKHR); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); +template VkColorSpaceKHR STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); + +template stormkit::gpu::CommandBufferLevel + STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::CommandBufferLevel + STORMKIT_API stormkit::gpu::from_vk(VkCommandBufferLevel); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); +template VkCommandBufferLevel STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); + +template stormkit::gpu::CompareOperation STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::CompareOperation + STORMKIT_API stormkit::gpu::from_vk(VkCompareOp); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); +template VkCompareOp STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); + +template stormkit::gpu::CullModeFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::CullModeFlag + STORMKIT_API stormkit::gpu::from_vk(VkCullModeFlagBits); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); +template VkCullModeFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); + +template stormkit::gpu::DebugObjectType STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::DebugObjectType + STORMKIT_API stormkit::gpu::from_vk(VkObjectType); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); +template VkObjectType STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); + +template stormkit::gpu::DependencyFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::DependencyFlag + STORMKIT_API stormkit::gpu::from_vk(VkDependencyFlagBits); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); +template VkDependencyFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); + +template stormkit::gpu::DescriptorType STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::DescriptorType + STORMKIT_API stormkit::gpu::from_vk(VkDescriptorType); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); +template VkDescriptorType STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); + +template stormkit::gpu::DynamicState STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::DynamicState + STORMKIT_API stormkit::gpu::from_vk(VkDynamicState); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::DynamicState); +template VkDynamicState STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::DynamicState); + +template stormkit::gpu::Filter STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::Filter STORMKIT_API stormkit::gpu::from_vk(VkFilter); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::Filter); +template VkFilter STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::Filter); + +template stormkit::gpu::FormatFeatureFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::FormatFeatureFlag + STORMKIT_API stormkit::gpu::from_vk(VkFormatFeatureFlagBits); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); +template VkFormatFeatureFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); + +template stormkit::gpu::FrontFace STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::FrontFace STORMKIT_API stormkit::gpu::from_vk(VkFrontFace); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::FrontFace); +template VkFrontFace STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::FrontFace); + +template stormkit::gpu::GeometryFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::GeometryFlag + STORMKIT_API stormkit::gpu::from_vk(VkGeometryFlagBitsKHR); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); +template VkGeometryFlagBitsKHR STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); + +template stormkit::gpu::GeometryType STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::GeometryType + STORMKIT_API stormkit::gpu::from_vk(VkGeometryTypeKHR); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::GeometryType); +template VkGeometryTypeKHR STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::GeometryType); + +template stormkit::gpu::ImageAspectFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageAspectFlag + STORMKIT_API stormkit::gpu::from_vk(VkImageAspectFlagBits); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); +template VkImageAspectFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); + +template stormkit::gpu::ImageCreateFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageCreateFlag + STORMKIT_API stormkit::gpu::from_vk(VkImageCreateFlagBits); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); +template VkImageCreateFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); + +template stormkit::gpu::ImageLayout STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageLayout STORMKIT_API stormkit::gpu::from_vk(VkImageLayout); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); +template VkImageLayout STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); + +template stormkit::gpu::ImageTiling STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageTiling STORMKIT_API stormkit::gpu::from_vk(VkImageTiling); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); +template VkImageTiling STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); + +template stormkit::gpu::ImageType STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageType STORMKIT_API stormkit::gpu::from_vk(VkImageType); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageType); +template VkImageType STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageType); + +template stormkit::gpu::ImageUsageFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageUsageFlag + STORMKIT_API stormkit::gpu::from_vk(VkImageUsageFlagBits); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); +template VkImageUsageFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); + +template stormkit::gpu::ImageViewType STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageViewType + STORMKIT_API stormkit::gpu::from_vk(VkImageViewType); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); +template VkImageViewType STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); + +template stormkit::gpu::LogicOperation STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::LogicOperation STORMKIT_API stormkit::gpu::from_vk(VkLogicOp); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); +template VkLogicOp STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); + +template stormkit::gpu::MemoryPropertyFlag + STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::MemoryPropertyFlag + STORMKIT_API stormkit::gpu::from_vk(VkMemoryPropertyFlagBits); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); +template VkMemoryPropertyFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); + +template stormkit::gpu::PhysicalDeviceType + STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PhysicalDeviceType + STORMKIT_API stormkit::gpu::from_vk(VkPhysicalDeviceType); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); +template VkPhysicalDeviceType STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); + +template stormkit::gpu::PipelineBindPoint STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PipelineBindPoint + STORMKIT_API stormkit::gpu::from_vk(VkPipelineBindPoint); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); +template VkPipelineBindPoint STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); + +template stormkit::gpu::PipelineStageFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PipelineStageFlag + STORMKIT_API stormkit::gpu::from_vk(VkPipelineStageFlagBits); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); +template VkPipelineStageFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); + +template stormkit::gpu::PixelFormat STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PixelFormat STORMKIT_API stormkit::gpu::from_vk(VkFormat); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); +template VkFormat STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); + +template stormkit::gpu::PolygonMode STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PolygonMode STORMKIT_API stormkit::gpu::from_vk(VkPolygonMode); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); +template VkPolygonMode STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); + +template stormkit::gpu::PresentMode STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PresentMode + STORMKIT_API stormkit::gpu::from_vk(VkPresentModeKHR); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PresentMode); +template VkPresentModeKHR STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PresentMode); + +template stormkit::gpu::PrimitiveTopology STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PrimitiveTopology + STORMKIT_API stormkit::gpu::from_vk(VkPrimitiveTopology); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); +template VkPrimitiveTopology STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); + +template stormkit::gpu::QueueFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::QueueFlag STORMKIT_API stormkit::gpu::from_vk(VkQueueFlagBits); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); +template VkQueueFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); + +template stormkit::gpu::ResolveModeFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ResolveModeFlag + STORMKIT_API stormkit::gpu::from_vk(VkResolveModeFlagBits); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ResolveModeFlag); +template VkResolveModeFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ResolveModeFlag); + +template stormkit::gpu::Result STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::Result STORMKIT_API stormkit::gpu::from_vk(VkResult); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::Result); +template VkResult STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::Result); + +template stormkit::gpu::SampleCountFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::SampleCountFlag + STORMKIT_API stormkit::gpu::from_vk(VkSampleCountFlagBits); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); +template VkSampleCountFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); + +template stormkit::gpu::SamplerAddressMode + STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::SamplerAddressMode + STORMKIT_API stormkit::gpu::from_vk(VkSamplerAddressMode); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); +template VkSamplerAddressMode STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); + +template stormkit::gpu::SamplerMipmapMode STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::SamplerMipmapMode + STORMKIT_API stormkit::gpu::from_vk(VkSamplerMipmapMode); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); +template VkSamplerMipmapMode STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); + +template stormkit::gpu::ShaderStageFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ShaderStageFlag + STORMKIT_API stormkit::gpu::from_vk(VkShaderStageFlagBits); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); +template VkShaderStageFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); + +template stormkit::gpu::StencilFaceFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::StencilFaceFlag + STORMKIT_API stormkit::gpu::from_vk(VkStencilFaceFlagBits); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); +template VkStencilFaceFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); + +template stormkit::gpu::VertexInputRate STORMKIT_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::VertexInputRate + STORMKIT_API stormkit::gpu::from_vk(VkVertexInputRate); +template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); +template VkVertexInputRate STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); diff --git a/modules/stormkit/gpu/core/vulkan/enums.mpp.tpl b/modules/stormkit/gpu/core/vulkan/enums.mpp.tpl index 43c11e742..5e5ec2f38 100644 --- a/modules/stormkit/gpu/core/vulkan/enums.mpp.tpl +++ b/modules/stormkit/gpu/core/vulkan/enums.mpp.tpl @@ -16,8 +16,8 @@ import stormkit.core; import :vulkan.volk; {% - import("core.base.json") - local json_data = json.loadfile("modules/stormkit/gpu/core/vulkan/mapping.json") +import("core.base.json") +local json_data = json.loadfile("modules/stormkit/gpu/core/vulkan/mapping.json") %} export { @@ -298,10 +298,14 @@ namespace stormkit::gpu { } } + {% for name, enumeration in table.orderpairs(json_data) do %} - template stormkit::gpu::{% outfile:write(name) %} stormkit::gpu::from_vk(VkFlags); - template stormkit::gpu::{% outfile:write(name) %} stormkit::gpu::from_vk({% outfile:write(enumeration.vktype) %}); - template VkFlags stormkit::gpu::to_vk(stormkit::gpu::{% outfile:write(name) %}); - template {% outfile:write(enumeration.vktype) %} stormkit::gpu::to_vk<{% outfile:write(enumeration.vktype) %}>(stormkit::gpu::{% outfile:write(name) %}); + template + stormkit::gpu::{% outfile:write(name) %} STORMKIT_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::{% outfile:write(name) %} STORMKIT_API stormkit::gpu::from_vk({% outfile:write(enumeration.vktype) %}); + template + VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::{% print("lool") outfile:write(name) %}); + template + {% outfile:write(enumeration.vktype) %} STORMKIT_API stormkit::gpu::to_vk<{% print("lol") outfile:write(enumeration.vktype) %}>(stormkit::gpu::{% print("lel") outfile:write(name) %}); {% end %} - diff --git a/tools/terra/src/main.cpp b/tools/terra/src/main.cpp index 5e1eb116b..b6097621c 100644 --- a/tools/terra/src/main.cpp +++ b/tools/terra/src/main.cpp @@ -20,10 +20,10 @@ auto main(const std::span args) noexcept -> int { } const auto template_path = stdfs::path { args[1] }; if (not stdfs::exists(template_path)) { - std::println(get_stderr(), "Template file {} doesn't exists", template_path.c_str()); + std::println(get_stderr(), "Template file {} doesn't exists", template_path.string()); return -1; } else if (not stdfs::is_regular_file(template_path)) { - std::println(get_stderr(), "Template file {} path is not a regular file", template_path.c_str()); + std::println(get_stderr(), "Template file {} path is not a regular file", template_path.string()); return -1; } @@ -32,8 +32,8 @@ auto main(const std::span args) noexcept -> int { return stdfs::path { args[2] }; }(); - const auto template_data = TryAssert(io::read_text(template_path), - std::format("Failed to read file {}, reason: ", template_path.c_str())); + const auto template_data = TryAssert(io::read_text(template_path), + std::format("Failed to read file {}, reason: ", template_path.string())); auto out = std::string {}; out.reserve(stdr::size(template_data)); @@ -45,7 +45,7 @@ auto main(const std::span args) noexcept -> int { out += std::format(R"( outfile = io.open("{}", "w") )", - out_path.c_str()); + replace(out_path.string(), "\\", "/")); bool last_char_was_bracket = false; bool is_parsing_lua = false; From b74dbbf1e1166259e7744bffaa14e6d27d3936bd Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 23:21:46 +0100 Subject: [PATCH 056/194] (luau) fix luau on windows --- examples/wsi/luau/xmake.lua | 6 +-- modules/stormkit/core/utils/filesystem.mpp | 60 ++++++++++++---------- modules/stormkit/luau.mpp | 6 +-- 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/examples/wsi/luau/xmake.lua b/examples/wsi/luau/xmake.lua index f8676ba80..83dfe4f6b 100644 --- a/examples/wsi/luau/xmake.lua +++ b/examples/wsi/luau/xmake.lua @@ -20,13 +20,11 @@ if get_config("luau") then end add_files("src/main.cpp") - if is_plat("windows") then add_files("win32/*.manifest") end + -- if is_plat("windows") then add_files("win32/*.manifest") end if get_config("devmode") then - add_defines('LUAU_DIR="$(builddir)/luau"') + add_defines('LUAU_DIR="examples/wsi/luau/luau"') set_rundir("$(projectdir)") - - after_build(function(target) os.cp("examples/wsi/luau/luau", "$(builddir)") end) end set_group("examples/stormkit-wsi/luau") diff --git a/modules/stormkit/core/utils/filesystem.mpp b/modules/stormkit/core/utils/filesystem.mpp index 868fa4466..48186300c 100644 --- a/modules/stormkit/core/utils/filesystem.mpp +++ b/modules/stormkit/core/utils/filesystem.mpp @@ -12,6 +12,8 @@ module; #include #ifdef STORMKIT_OS_WINDOWS + #include + #include #include #include @@ -141,21 +143,32 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// template inline auto Descriptor::open(const stdfs::path& path, Access access) noexcept -> Expected> { - const auto p = path.string(); + if (not stdfs::exists(path)) return std::unexpected { SystemError { .code = std::errc::no_such_file_or_directory } }; + if (stdfs::is_directory(path)) return std::unexpected { SystemError { .code = std::errc::is_a_directory } }; + const auto posix_access = [&access]() noexcept { +#ifdef STORMKIT_OS_WINDOWS + if (access == Access::READ) return _O_RDONLY; + else if (access == Access::WRITE) + return _O_WRONLY; + else + return _O_RDWR; +#else if (access == Access::READ) return O_RDONLY; else if (access == Access::WRITE) return O_WRONLY; else return O_RDWR; +#endif std::unreachable(); }(); #ifdef STORMKIT_OS_WINDOWS const auto text_mode = []() noexcept { switch (mode) { - case Mode::BINARY: return 0; #ifdef STORMKIT_OS_WINDOWS + case Mode::BINARY: return _O_BINARY; + case Mode::AINSI: return _O_TEXT; case Mode::UTF8: return _O_U8TEXT; case Mode::WIDE: return _O_WTEXT; default: break; @@ -166,23 +179,14 @@ namespace stormkit { inline namespace core { namespace io { std::unreachable(); }(); - const auto win32_access = [&access]() noexcept { - if (access == Access::READ) return _S_IREAD; - else if (access == Access::WRITE) - return _S_IWRITE; - else - return _S_IREAD | _S_IWRITE; - std::unreachable(); - }(); - auto ret = 0; - const auto - // err = _sopen_s(&ret, stdr::data(p), posix_access | text_mode, _SH_DENYNO, - // win32_access); - err = _sopen_s(&ret, stdr::data(p), posix_access | text_mode, _SH_SECURE, win32_access); + auto str = path.string(); + const auto // + err = _sopen_s(&ret, str.c_str(), posix_access | text_mode, _SH_DENYWR, 0); + // err = _sopen_s(&ret, stdr::data(p), posix_access | text_mode, _SH_SECURE, 0); if (err != 0) return std::unexpected { SystemError::from_errno() }; #else - const auto ret = ::open(stdr::data(p), posix_access); + const auto ret = ::open(path.c_str(), posix_access); if (ret == -1) return std::unexpected { SystemError::from_errno() }; #endif return Expected> { std::in_place, PrivateFuncTag {}, ret }; @@ -262,7 +266,6 @@ namespace stormkit { inline namespace core { namespace io { inline auto Descriptor::read_to(std::span out) noexcept -> Expected requires(mode == Mode::UTF8 or mode == Mode::AINSI) { - static_assert(stdr::contiguous_range>); return read_to(as_bytes_mut(out)); } @@ -321,13 +324,15 @@ namespace stormkit { inline namespace core { namespace io { inline auto Descriptor::flush() noexcept -> void { EXPECTS(m_descriptor != 0); #ifdef STORMKIT_OS_WINDOWS - _commit -#elifdef STORMKIT_OS_LINUX - fdatasync + FlushFileBuffers(reinterpret_cast(m_descriptor)); #else + #if STORMKIT_OS_LINUX + fdatasync + #else fsync -#endif + #endif (m_descriptor); +#endif } //////////////////////////////////////// @@ -389,8 +394,9 @@ namespace stormkit { inline namespace core { namespace io { template STORMKIT_FORCE_INLINE inline auto read_text_to(const stdfs::path& path, std::span> out) noexcept -> Expected { - auto file = Try((TextFile::open(path, Access::READ))); - Return Try(file.read_to(std::span> { out })); + auto file = Try((TextFile::open(path, Access::READ))); + ENSURES(stdr::size(out) >= file.size()); + Return Try(file.read_to(out)); } //////////////////////////////////////// @@ -401,7 +407,8 @@ namespace stormkit { inline namespace core { namespace io { auto file = Try((TextFile::open(path, Access::READ))); auto out = std::vector> {}; out.resize(file.size()); - TryDiscard(file.read_to(std::span> { out })); + auto readed = Try(file.read_to(out)); + out.resize(readed); Return out; } @@ -410,7 +417,7 @@ namespace stormkit { inline namespace core { namespace io { STORMKIT_FORCE_INLINE inline auto read_to(const stdfs::path& path, std::span out) noexcept -> Expected { auto file = Try((File::open(path, Access::READ))); - Return Try(file.read_to(std::span { out })); + Return Try(file.read_to(out)); } //////////////////////////////////////// @@ -420,7 +427,8 @@ namespace stormkit { inline namespace core { namespace io { auto file = Try((File::open(path, Access::READ))); auto out = std::vector {}; out.resize(file.size()); - TryDiscard(file.read_to(std::span { out })); + auto readed = Try(file.read_to(out)); + out.resize(readed); Return out; } diff --git a/modules/stormkit/luau.mpp b/modules/stormkit/luau.mpp index a99aa1b30..4ec5b4bf9 100644 --- a/modules/stormkit/luau.mpp +++ b/modules/stormkit/luau.mpp @@ -4,6 +4,7 @@ module; +#include #include #include @@ -51,8 +52,7 @@ export namespace stormkit::luau { } auto load(const stdfs::path& file) noexcept { - expects(not stdr::empty(file)); - auto data = *io::read_text(file).transform_error(monadic::assert(std::format("Failed to load {}", file.string()))); + auto data = TryAssert(io::read_text(file), std::format("Failed to load {}", file.string())); auto bytecode_size = 0_usize; auto bytecode = luau_compile(stdr::data(data), stdr::size(data), nullptr, &bytecode_size); @@ -79,7 +79,7 @@ export namespace stormkit::luau { } auto lua_main() noexcept -> std::expected { - expects(m_main_thread); + EXPECTS(m_main_thread); auto out = std::expected {}; From a78069eec35cb275dbb470913b094517342e5226 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 23:22:50 +0100 Subject: [PATCH 057/194] (core) disable STORMKIT_FORCE_INLINE on debug build --- include/stormkit/core/platform_macro.hpp | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/include/stormkit/core/platform_macro.hpp b/include/stormkit/core/platform_macro.hpp index 19c4b63e6..d4a3dba60 100644 --- a/include/stormkit/core/platform_macro.hpp +++ b/include/stormkit/core/platform_macro.hpp @@ -97,27 +97,23 @@ #define STORMKIT_LIFETIMEBOUND #endif -#if not defined(STORMKIT_COMPILER_MSVC) - #if __has_cpp_attribute(gnu::pure) - #define STORMKIT_PURE [[gnu::pure]] - #else - #define STORMKIT_PURE - #endif +#if __has_cpp_attribute(gnu::pure) + #define STORMKIT_PURE [[gnu::pure]] #else #define STORMKIT_PURE #endif -#if not defined(STORMKIT_COMPILER_MSVC) - #if __has_cpp_attribute(gnu::const) - #define STORMKIT_CONST [[gnu::const]] - #else - #define STORMKIT_CONST - #endif +#if __has_cpp_attribute(gnu::const) + #define STORMKIT_CONST [[gnu::const]] #else #define STORMKIT_CONST #endif -#define STORMKIT_FORCE_INLINE STORMKIT_FORCE_INLINE_IMPL +#ifdef STORMKIT_BUILD_DEBUG + #define STORMKIT_FORCE_INLINE +#else + #define STORMKIT_FORCE_INLINE STORMKIT_FORCE_INLINE_IMPL +#endif #if defined(__MINGW32__) #define STORMKIT_COMPILER STORMKIT_COMPILER_MINGW From 4e6c3d01a2d6ccbf8e38353b766400274a4d3e38 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 23:43:33 +0100 Subject: [PATCH 058/194] (core) add hasher for color --- modules/stormkit/core/utils/color.mpp | 113 ++++++++++++++++---------- 1 file changed, 68 insertions(+), 45 deletions(-) diff --git a/modules/stormkit/core/utils/color.mpp b/modules/stormkit/core/utils/color.mpp index 5fcc0dd4a..14e4f38ec 100644 --- a/modules/stormkit/core/utils/color.mpp +++ b/modules/stormkit/core/utils/color.mpp @@ -167,7 +167,10 @@ export namespace stormkit { inline namespace core { using abgrcolor_u = abgrcolor; template - constexpr auto format_as(const color& color, FormatContext& ctx) noexcept -> decltype(ctx.out()); + auto format_as(const color& color, FormatContext& ctx) noexcept -> decltype(ctx.out()); + + template + constexpr auto hasher(const color& color) noexcept -> Ret; }} // namespace stormkit::core namespace stormkit { inline namespace core { namespace details { @@ -304,9 +307,6 @@ export namespace stormkit { inline namespace core { .c = { .r = 0, .g = 0, .b = 0, .a = 0 } }; } // namespace colors - - template - constexpr auto format_as(const color& color, FormatContext& ctx) noexcept -> decltype(ctx.out()); }} // namespace stormkit::core //////////////////////////////////////////////////////////////////// @@ -407,47 +407,6 @@ namespace stormkit { inline namespace core { return to_storage(to_layout(c)); } - ///////////////////////////////////// - ///////////////////////////////////// - template - constexpr auto format_as(const color& color, FormatContext& ctx) noexcept -> decltype(ctx.out()) { - if constexpr (LAYOUT == ColorLayout::R) return std::format_to(ctx.out(), "[color layout: R red: {}]", color.r); - else if constexpr (LAYOUT == ColorLayout::RG) - return std::format_to(ctx.out(), "[color layout: RG red: {}, green: {}]", color.r, color.g); - else if constexpr (LAYOUT == ColorLayout::RGB) - return std::format_to(ctx.out(), "[color layout: RGB red: {}, green: {}, blue: {}]", color.r, color.g, color.b); - else if constexpr (LAYOUT == ColorLayout::BGR) - return std::format_to(ctx.out(), "[color layout: BGR blue: {}, green: {}, red: {}]", color.r, color.g); - else if constexpr (LAYOUT == ColorLayout::RGBA) - return std::format_to(ctx.out(), - "[color layout: RGBA red: {}, green: {}, blue: {}, alpha: {}]", - color.r, - color.g, - color.b, - color.a); - else if constexpr (LAYOUT == ColorLayout::ARGB) - return std::format_to(ctx.out(), - "[color layout: ARGB alpha: {}, red: {}, green: {}, blue: {}]", - color.a, - color.r, - color.g, - color.b); - else if constexpr (LAYOUT == ColorLayout::BGRA) - return std::format_to(ctx.out(), - "[color layout: BGRA bue: {}, green: {}, red: {}, alpha: {}]", - color.b, - color.g, - color.r, - color.a); - else if constexpr (LAYOUT == ColorLayout::ABGR) - return std::format_to(ctx.out(), - "[color layout: ABGR alpha: {}, blue: {}, green: {}, red: {}]", - color.a, - color.b, - color.g, - color.r); - } - ///////////////////////////////////// ///////////////////////////////////// template @@ -511,4 +470,68 @@ namespace stormkit { inline namespace core { constexpr auto color::operator==(const color& other) const noexcept -> bool { return r == other.r and g == other.g and b == other.b and a == other.a; } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto format_as(const color& color, FormatContext& ctx) noexcept -> decltype(ctx.out()) { + if constexpr (LAYOUT == ColorLayout::R) return std::format_to(ctx.out(), "[color layout: R red: {}]", color.r); + else if constexpr (LAYOUT == ColorLayout::RG) + return std::format_to(ctx.out(), "[color layout: RG red: {}, green: {}]", color.r, color.g); + else if constexpr (LAYOUT == ColorLayout::RGB) + return std::format_to(ctx.out(), "[color layout: RGB red: {}, green: {}, blue: {}]", color.r, color.g, color.b); + else if constexpr (LAYOUT == ColorLayout::BGR) + return std::format_to(ctx.out(), "[color layout: BGR blue: {}, green: {}, red: {}]", color.r, color.g); + else if constexpr (LAYOUT == ColorLayout::RGBA) + return std::format_to(ctx.out(), + "[color layout: RGBA red: {}, green: {}, blue: {}, alpha: {}]", + color.r, + color.g, + color.b, + color.a); + else if constexpr (LAYOUT == ColorLayout::ARGB) + return std::format_to(ctx.out(), + "[color layout: ARGB alpha: {}, red: {}, green: {}, blue: {}]", + color.a, + color.r, + color.g, + color.b); + else if constexpr (LAYOUT == ColorLayout::BGRA) + return std::format_to(ctx.out(), + "[color layout: BGRA bue: {}, green: {}, red: {}, alpha: {}]", + color.b, + color.g, + color.r, + color.a); + else if constexpr (LAYOUT == ColorLayout::ABGR) + return std::format_to(ctx.out(), + "[color layout: ABGR alpha: {}, blue: {}, green: {}, red: {}]", + color.a, + color.b, + color.g, + color.r); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto hasher(const color& color) noexcept -> Ret { + if constexpr (LAYOUT == ColorLayout::R) return hash(color.r); + else if constexpr (LAYOUT == ColorLayout::RG) + return hash(color.r, color.g); + else if constexpr (LAYOUT == ColorLayout::RGB) + return hash(color.r, color.g, color.b); + else if constexpr (LAYOUT == ColorLayout::BGR) + return hash(color.b, color.g, color.r); + else if constexpr (LAYOUT == ColorLayout::RGBA) + return hash(color.r, color.g, color.b, color.a); + else if constexpr (LAYOUT == ColorLayout::ARGB) + return hash(color.a, color.r, color.g, color.b); + else if constexpr (LAYOUT == ColorLayout::BGRA) + return hash(color.b, color.g, color.r, color.a); + else if constexpr (LAYOUT == ColorLayout::ABGR) + return hash(color.a, color.b, color.g, color.r); + } }} // namespace stormkit::core From ba111f7b77434726a7d50cff9a4cf6a0cb709ca9 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Feb 2026 23:44:22 +0100 Subject: [PATCH 059/194] (gpu) add hasher and operator== for ClearValues --- modules/stormkit/gpu/core/structs.mpp | 70 +++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/modules/stormkit/gpu/core/structs.mpp b/modules/stormkit/gpu/core/structs.mpp index a877705d0..081ef0519 100644 --- a/modules/stormkit/gpu/core/structs.mpp +++ b/modules/stormkit/gpu/core/structs.mpp @@ -236,11 +236,22 @@ export { struct ClearColor { rgbacolor_f color = stormkit::colors::SILVER; + + constexpr auto operator==(const ClearColor& other) const noexcept -> bool; + }; + + struct ClearDepth { + f32 depth = 1.f; + constexpr auto operator==(const ClearDepth& other) const noexcept -> bool; }; - struct ClearDepthStencil { - f32 depth = 1.f; - u32 stencil = 0; + struct ClearStencil { + u32 stencil = 0u; + constexpr auto operator==(const ClearStencil& other) const noexcept -> bool; + }; + + struct ClearDepthStencil: ClearDepth, ClearStencil { + constexpr auto operator==(const ClearDepthStencil& other) const noexcept -> bool; }; using ClearValue = std::variant; @@ -320,6 +331,12 @@ export { template constexpr auto hasher(const Scissor& value) noexcept -> Ret; + + template + constexpr auto hasher(const ClearColor& value) noexcept -> Ret; + + template + constexpr auto hasher(const ClearDepthStencil& value) noexcept -> Ret; } // namespace stormkit::gpu } @@ -328,6 +345,34 @@ export { //////////////////////////////////////////////////////////////////// namespace stormkit::gpu { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto ClearColor::operator==(const ClearColor& other) const noexcept -> bool { + return color == other.color; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto ClearDepth::operator==(const ClearDepth& other) const noexcept -> bool { + return depth == other.depth; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto ClearStencil::operator==(const ClearStencil& other) const noexcept -> bool { + return stencil == other.stencil; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto ClearDepthStencil::operator==(const ClearDepthStencil& other) const noexcept -> bool { + return depth == other.depth and stencil == other.stencil; + } + ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE @@ -371,13 +416,32 @@ namespace stormkit::gpu { data.type); } + ///////////////////////////////////// + ///////////////////////////////////// template constexpr auto hasher(const Viewport& value) noexcept -> Ret { return hash(value.position, value.extent, value.depth); } + ///////////////////////////////////// + ///////////////////////////////////// + template constexpr auto hasher(const Scissor& value) noexcept -> Ret { return hash(value.offset, value.extent); } + + ///////////////////////////////////// + ///////////////////////////////////// + template + constexpr auto hasher(const ClearColor& value) noexcept -> Ret { + return hash(value.color); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + constexpr auto hasher(const ClearDepthStencil& value) noexcept -> Ret { + return hash(value.depth, value.stencil); + } } // namespace stormkit::gpu From 19bd8f722e2ec22a85e1eda4a5d268ceffc5a91a Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 4 Feb 2026 00:15:41 +0100 Subject: [PATCH 060/194] (xmake) fix warning --- xmake/dependencies.xmake.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/xmake/dependencies.xmake.lua b/xmake/dependencies.xmake.lua index 0f54eba2a..de453a3b8 100644 --- a/xmake/dependencies.xmake.lua +++ b/xmake/dependencies.xmake.lua @@ -32,7 +32,6 @@ local package_configs = { }, luau = { global = { - override = true, system = false, version = "master", configs = { From f1d855f40f655bbaa4c3088ecf95690c8783afbe Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 4 Feb 2026 00:15:58 +0100 Subject: [PATCH 061/194] (examples) ensures path are correctly defined --- examples/gpu/textured_cube/xmake.lua | 16 +++++++++++----- examples/gpu/triangle/xmake.lua | 13 +++++++++---- examples/wsi/luau/xmake.lua | 12 ++++++++---- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/examples/gpu/textured_cube/xmake.lua b/examples/gpu/textured_cube/xmake.lua index fc23ad046..df6b7da89 100644 --- a/examples/gpu/textured_cube/xmake.lua +++ b/examples/gpu/textured_cube/xmake.lua @@ -25,11 +25,17 @@ target("textured_cube", function() add_includedirs("$(builddir)/shaders") - if get_config("devmode") then - add_defines('TEXTURE_DIR="examples/gpu/textured_cube/textures"') - add_defines('SHADER_DIR="$(builddir)/shaders"') - set_rundir("$(projectdir)") - end + on_load(function(target) + if get_config("devmode") then + import("core.project.config") + local shader_dir = path.unix(path.join(config.builddir(), "shaders")) + target:add("defines", format('SHADER_DIR="%s"', shader_dir)) + local texture_dir = path.unix(path.join(os.projectdir(), "examples", "gpu", "textured_cube", "textures")) + target:add("defines", format('TEXTURE_DIR="%s"', texture_dir)) + end + end) + + if get_config("devmode") then set_rundir("$(projectdir)") end set_group("examples/stormkit-gpu") end) diff --git a/examples/gpu/triangle/xmake.lua b/examples/gpu/triangle/xmake.lua index 023faa518..d03e808e2 100644 --- a/examples/gpu/triangle/xmake.lua +++ b/examples/gpu/triangle/xmake.lua @@ -38,10 +38,15 @@ target("triangle", function() add_includedirs("$(builddir)/shaders") - if get_config("devmode") then - add_defines('SHADER_DIR="$(builddir)/shaders"') - set_rundir("$(projectdir)") - end + on_load(function(target) + if get_config("devmode") then + import("core.project.config") + local shader_dir = path.unix(path.join(config.builddir(), "shaders")) + target:add("defines", format('SHADER_DIR="%s"', shader_dir)) + end + end) + + if get_config("devmode") then set_rundir("$(projectdir)") end add_embeddirs("$(builddir)/shaders") diff --git a/examples/wsi/luau/xmake.lua b/examples/wsi/luau/xmake.lua index 83dfe4f6b..3b210b059 100644 --- a/examples/wsi/luau/xmake.lua +++ b/examples/wsi/luau/xmake.lua @@ -22,10 +22,14 @@ if get_config("luau") then add_files("src/main.cpp") -- if is_plat("windows") then add_files("win32/*.manifest") end - if get_config("devmode") then - add_defines('LUAU_DIR="examples/wsi/luau/luau"') - set_rundir("$(projectdir)") - end + on_load(function(target) + if get_config("devmode") then + local lua_dir = path.unix(path.join(os.projectdir(), "examples", "wsi", "luau", "luau")) + target:add("defines", format('LUAU_DIR="%s"', lua_dir)) + end + end) + + if get_config("devmode") then set_rundir("$(projectdir)") end set_group("examples/stormkit-wsi/luau") end) From 95ab54be8704eddf41349c2c834c40ddf96b7fac Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 4 Feb 2026 00:31:20 +0100 Subject: [PATCH 062/194] (gpu) fix descriptor set move constructor / assignement operator --- .../stormkit/gpu/execution/descriptors.mpp | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/modules/stormkit/gpu/execution/descriptors.mpp b/modules/stormkit/gpu/execution/descriptors.mpp index 129674cbc..35c0da849 100644 --- a/modules/stormkit/gpu/execution/descriptors.mpp +++ b/modules/stormkit/gpu/execution/descriptors.mpp @@ -200,6 +200,7 @@ namespace stormkit::gpu { m_vk_device_table { as_ref(device_table) }, m_vk_handle { std::move(set) }, m_deleter { std::move(deleter) } { + ensures(m_deleter.operator bool()); } ///////////////////////////////////// @@ -212,12 +213,27 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorSet::DescriptorSet(DescriptorSet&&) noexcept = default; + inline DescriptorSet::DescriptorSet(DescriptorSet&& other) noexcept + : m_vk_device { std::exchange(other.m_vk_device, nullptr) }, + m_vk_device_table { other.m_vk_device_table }, + m_vk_handle { std::exchange(other.m_vk_handle, nullptr) }, + m_deleter { std::move(other.m_deleter) } { + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorSet::operator=(DescriptorSet&&) noexcept -> DescriptorSet& = default; + inline auto DescriptorSet::operator=(DescriptorSet&& other) noexcept -> DescriptorSet& { + if (&other == this) [[unlikely]] + return *this; + + m_vk_device = std::exchange(other.m_vk_device, nullptr); + m_vk_device_table = as_ref(other.m_vk_device_table); + m_vk_handle = std::exchange(other.m_vk_handle, nullptr); + m_deleter = std::move(other.m_deleter); + + return *this; + } ///////////////////////////////////// ///////////////////////////////////// From 88c1699ed111b1dc565be0f298d3461a2001fa0f Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 4 Feb 2026 01:33:09 +0100 Subject: [PATCH 063/194] (xmake) fix vulkan-headers version --- xmake/dependencies.xmake.lua | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/xmake/dependencies.xmake.lua b/xmake/dependencies.xmake.lua index de453a3b8..9cdf097e7 100644 --- a/xmake/dependencies.xmake.lua +++ b/xmake/dependencies.xmake.lua @@ -91,11 +91,10 @@ local package_configs = { }, }, }, - ["vulkan-header"] = { + ["vulkan-headers"] = { global = { - version = "v1.4.335", + version = "1.4.335", system = false, - override = true, configs = { modules = false, }, From 4a8255f540f7331611f653c7e51ffae48faa6aed Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 4 Feb 2026 01:33:48 +0100 Subject: [PATCH 064/194] (xmake) add volk version --- xmake/dependencies.xmake.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/xmake/dependencies.xmake.lua b/xmake/dependencies.xmake.lua index 9cdf097e7..84453e5e3 100644 --- a/xmake/dependencies.xmake.lua +++ b/xmake/dependencies.xmake.lua @@ -91,6 +91,12 @@ local package_configs = { }, }, }, + ["volk"] = { + global = { + version = "1.4.335", + system = false, + }, + }, ["vulkan-headers"] = { global = { version = "1.4.335", From 971ed0d5812b5d03345b3e07fff4ab981fb58777 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 4 Feb 2026 01:54:18 +0100 Subject: [PATCH 065/194] (all) temporarily disable force inline --- include/stormkit/core/platform_macro.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/stormkit/core/platform_macro.hpp b/include/stormkit/core/platform_macro.hpp index d4a3dba60..356616710 100644 --- a/include/stormkit/core/platform_macro.hpp +++ b/include/stormkit/core/platform_macro.hpp @@ -109,11 +109,11 @@ #define STORMKIT_CONST #endif -#ifdef STORMKIT_BUILD_DEBUG - #define STORMKIT_FORCE_INLINE -#else - #define STORMKIT_FORCE_INLINE STORMKIT_FORCE_INLINE_IMPL -#endif +// #if defined(STORMKIT_BUILD_DEBUG) +#define STORMKIT_FORCE_INLINE +// #else +// #define STORMKIT_FORCE_INLINE STORMKIT_FORCE_INLINE_IMPL +// #endif #if defined(__MINGW32__) #define STORMKIT_COMPILER STORMKIT_COMPILER_MINGW From 27a064145c7f42e692139c2b5cef1ed07ec6be63 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 4 Feb 2026 16:26:42 +0100 Subject: [PATCH 066/194] (core, xmake) improve xmake code --- modules/stormkit/{core.mpp => core.cppm} | 42 +++++++++---------- src/core/xmake.lua | 52 ++++++++++++++++++++++++ xmake.lua | 4 ++ xmake/targets.xmake.lua | 29 ------------- 4 files changed, 77 insertions(+), 50 deletions(-) rename modules/stormkit/{core.mpp => core.cppm} (96%) create mode 100644 src/core/xmake.lua diff --git a/modules/stormkit/core.mpp b/modules/stormkit/core.cppm similarity index 96% rename from modules/stormkit/core.mpp rename to modules/stormkit/core.cppm index 00bbfad9b..56488a9c0 100644 --- a/modules/stormkit/core.mpp +++ b/modules/stormkit/core.cppm @@ -1,21 +1,21 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -export module stormkit.core; - -import std.compat; - -export import :config; -export import :containers; -export import :console; -export import :coroutines; -export import :functional; -export import :errors; -export import :hash; -export import :meta; -export import :math; -export import :parallelism; -export import :string; -export import :typesafe; -export import :utils; +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +export module stormkit.core; + +import std.compat; + +export import :config; +export import :containers; +export import :console; +export import :coroutines; +export import :functional; +export import :errors; +export import :hash; +export import :meta; +export import :math; +export import :parallelism; +export import :string; +export import :typesafe; +export import :utils; diff --git a/src/core/xmake.lua b/src/core/xmake.lua new file mode 100644 index 000000000..db4410619 --- /dev/null +++ b/src/core/xmake.lua @@ -0,0 +1,52 @@ +add_requires("frozen", { system = false, configs = { modules = true, std_import = true, cpp = "latest" } }) +add_requires("unordered_dense", { system = false, configs = { modules = true, std_import = true } }) +add_requires("tl_function_ref", { system = false, configs = { modules = true, std_import = true } }) + +target("core", function() + set_kind("$(kind)") + + set_languages("cxxlatest", "clatest") + + add_defines("STORMKIT_BUILD", { public = false }) + if is_mode("debug") then add_defines("STORMKIT_BUILD_DEBUG", { public = true }) end + + if is_kind("static") then add_defines("STORMKIT_STATIC", { public = true }) end + + add_files("$(projectdir)/modules/stormkit/core.cppm", { public = true }) + add_files("$(projectdir)/modules/stormkit/core/**.cppm", { public = true }) + add_files("*.cpp", "*.cppm") + + if is_plat("linux", "macosx", "ios", "tvos", "android") then add_files("posix/**.cpp") end + if is_plat("linux") then add_files("linux/**.cpp") end + if is_plat("windows") then add_files("win32/**.cpp") end + if is_plat("macosx", "ios", "tvos", "watchos") then add_files("darwin/**.cpp", "darwin/**.m") end + + set_configdir("$(builddir)/.gens/include/") + add_configfiles("$(projectdir)/include/(stormkit/core/config.hpp.in)") + add_headerfiles( + "$(builddir)/.gens/include/(stormkit/core/*.hpp)", + "$(projectdir)/include/(stormkit/core/**.inl)", + "$(projectdir)/include/(stormkit/core/**.hpp)" + ) + add_includedirs("$(projectdir)/include", { public = true }) + + add_packages("frozen", "unordered_dense", "tl_function_ref", { public = true }) + + on_config(function(target) + local output, errors = os.iorunv("git", { "rev-parse", "--abbrev-ref", "HEAD" }) + + if not errors == "" then + print("Failed to get git hash and branch, reason: ", errors, output) + target:set("configvar", "STORMKIT_GIT_BRANCH", " ") + target:set("configvar", "STORMKIT_GIT_COMMIT_HASH", " ") + return + end + + target:set("configvar", "STORMKIT_GIT_BRANCH", output:trim()) + output, errors = os.iorunv("git", { "rev-parse", "--verify", "HEAD" }) + + target:set("configvar", "STORMKIT_GIT_COMMIT_HASH", output:trim()) + end) + + set_group("libraries") +end) diff --git a/xmake.lua b/xmake.lua index e9448a963..726e46c4c 100644 --- a/xmake.lua +++ b/xmake.lua @@ -70,12 +70,16 @@ for name, module in pairs(modules) do end end +set_suffixname("-d") + ---------------------------- targets ---------------------------- namespace("stormkit", function() for _, name in ipairs({ "log", "entities", "image", "wsi", "gpu", "luau" }) do if get_config(name) then set_configvar("STORMKIT_LIB_" .. string.upper(name) .. "_ENABLED", "true") end end + includes("src/core/xmake.lua") + for name, module in pairs(modules) do if module then local modulename = module.modulename diff --git a/xmake/targets.xmake.lua b/xmake/targets.xmake.lua index 6690102f3..c782accb3 100644 --- a/xmake/targets.xmake.lua +++ b/xmake/targets.xmake.lua @@ -1,33 +1,4 @@ modules = { - core = { - public_packages = { "frozen", "unordered_dense", "tl_function_ref" }, - modulename = "core", - has_headers = true, - custom = function() - if is_plat("windows") then add_packages("wil") end - - set_configdir("$(builddir)/.gens/include/") - add_configfiles("include/(stormkit/core/config.hpp.in)") - add_headerfiles("$(builddir)/.gens/include/(stormkit/core/*.hpp)") - -- add_cxflags("clang::-Wno-language-extension-token") - - on_config(function(target) - local output, errors = os.iorunv("git", { "rev-parse", "--abbrev-ref", "HEAD" }) - - if not errors == "" then - print("Failed to get git hash and branch, reason: ", errors, output) - target:set("configvar", "STORMKIT_GIT_BRANCH", " ") - target:set("configvar", "STORMKIT_GIT_COMMIT_HASH", " ") - return - end - - target:set("configvar", "STORMKIT_GIT_BRANCH", output:trim()) - output, errors = os.iorunv("git", { "rev-parse", "--verify", "HEAD" }) - - target:set("configvar", "STORMKIT_GIT_COMMIT_HASH", output:trim()) - end) - end, - }, test = { modulename = "test", public_deps = { "core" }, From 707663b9fe370d118fa61a61438a4e766280e089 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 4 Feb 2026 16:29:42 +0100 Subject: [PATCH 067/194] (all) use cppm instead of mpp extension for modules --- .../gameoflife/src/{App.mpp => App.cppm} | 118 +- .../src/{Components.mpp => Components.cppm} | 56 +- .../src/{Constants.mpp => Constants.cppm} | 108 +- .../src/{Renderer.mpp => Renderer.cppm} | 154 +- .../src/{Systems.mpp => Systems.cppm} | 124 +- examples/entities/gameoflife/xmake.lua | 2 +- examples/gpu/common/{app.mpp => app.cppm} | 0 .../gpu/imgui/src/{logger.mpp => logger.cppm} | 0 examples/gpu/imgui/xmake.lua | 2 +- .../src/{logger.mpp => logger.cppm} | 0 examples/gpu/textured_cube/xmake.lua | 2 +- .../triangle/src/{logger.mpp => logger.cppm} | 0 examples/gpu/triangle/xmake.lua | 2 +- modules/{stormkit.mpp => stormkit.cppm} | 0 .../stormkit/core/{config.mpp => config.cppm} | 46 +- .../core/{console.mpp => console.cppm} | 0 .../stormkit/core/console/{io.mpp => io.cppm} | 0 .../core/console/{style.mpp => style.cppm} | 0 .../core/{containers.mpp => containers.cppm} | 0 .../core/containers/{dag.mpp => dag.cppm} | 0 .../{multi_buffer.mpp => multi_buffer.cppm} | 0 .../{raii_capsule.mpp => raii_capsule.cppm} | 0 .../{ringbuffer.mpp => ringbuffer.cppm} | 558 +++---- .../{shmbuffer.mpp => shmbuffer.cppm} | 0 .../core/containers/{tree.mpp => tree.cppm} | 1062 ++++++------- .../core/containers/{utils.mpp => utils.cppm} | 0 .../core/{coroutines.mpp => coroutines.cppm} | 1114 ++++++------- .../stormkit/core/{errors.mpp => errors.cppm} | 0 .../core/{functional.mpp => functional.cppm} | 0 ...error_handling.mpp => error_handling.cppm} | 0 .../functional/{monadic.mpp => monadic.cppm} | 0 .../core/functional/{utils.mpp => utils.cppm} | 242 +-- modules/stormkit/core/{hash.mpp => hash.cppm} | 26 +- .../core/hash/{base.mpp => base.cppm} | 0 .../stormkit/core/hash/{map.mpp => map.cppm} | 48 +- .../core/hash/{string.mpp => string.cppm} | 0 modules/stormkit/core/{math.mpp => math.cppm} | 0 .../math/{arithmetic.mpp => arithmetic.cppm} | 0 .../{combinatoric.mpp => combinatoric.cppm} | 0 .../core/math/{extent.mpp => extent.cppm} | 0 .../core/math/{geometry.mpp => geometry.cppm} | 0 .../{hypercomplex.mpp => hypercomplex.cppm} | 0 .../{linear-matrix.mpp => linear-matrix.cppm} | 0 .../{linear-vector.mpp => linear-vector.cppm} | 0 .../core/math/{linear.mpp => linear.cppm} | 0 .../{trigonometry.mpp => trigonometry.cppm} | 0 modules/stormkit/core/{meta.mpp => meta.cppm} | 64 +- .../meta/{algorithms.mpp => algorithms.cppm} | 0 .../core/meta/{concepts.mpp => concepts.cppm} | 848 +++++----- .../{priority_tag.mpp => priority_tag.cppm} | 0 ...anipulation.mpp => type_manipulation.cppm} | 0 .../meta/{type_query.mpp => type_query.cppm} | 0 .../{type_traits.mpp => type_traits.cppm} | 0 .../{parallelism.mpp => parallelism.cppm} | 18 +- .../parallelism/{locked.mpp => locked.cppm} | 0 .../{threadpool.mpp => threadpool.cppm} | 450 +++--- .../{threadutils.mpp => threadutils.cppm} | 68 +- .../stormkit/core/{string.mpp => string.cppm} | 22 +- ...texpr_string.mpp => constexpr_string.cppm} | 0 .../string/{czstring.mpp => czstring.cppm} | 24 +- .../string/{encodings.mpp => encodings.cppm} | 0 .../core/string/{format.mpp => format.cppm} | 376 ++--- .../{operations.mpp => operations.cppm} | 0 .../core/{typesafe.mpp => typesafe.cppm} | 0 .../typesafe/{boolean.mpp => boolean.cppm} | 0 .../core/typesafe/{byte.mpp => byte.cppm} | 618 ++++---- .../{character.mpp => character.cppm} | 0 .../{checked_value.mpp => checked_value.cppm} | 0 .../core/typesafe/{flags.mpp => flags.cppm} | 600 +++---- .../core/typesafe/{float.mpp => float.cppm} | 0 .../typesafe/{integer.mpp => integer.cppm} | 0 .../core/typesafe/{ref.mpp => ref.cppm} | 0 .../{safecasts.mpp => safecasts.cppm} | 0 .../{strong_type.mpp => strong_type.cppm} | 0 .../stormkit/core/{utils.mpp => utils.cppm} | 48 +- .../utils/{algorithms.mpp => algorithms.cppm} | 188 +-- .../utils/{allocation.mpp => allocation.cppm} | 0 .../stormkit/core/utils/{app.mpp => app.cppm} | 62 +- .../core/utils/{color.mpp => color.cppm} | 0 .../utils/{contract.mpp => contract.cppm} | 384 ++--- .../utils/{deferinit.mpp => deferinit.cppm} | 0 ...dynamic_loader.mpp => dynamic_loader.cppm} | 266 ++-- .../utils/{filesystem.mpp => filesystem.cppm} | 0 .../{function_ref.mpp => function_ref.cppm} | 0 .../core/utils/{handle.mpp => handle.cppm} | 272 ++-- .../{numeric_range.mpp => numeric_range.cppm} | 616 ++++---- .../core/utils/{pimpl.mpp => pimpl.cppm} | 328 ++-- .../core/utils/{random.mpp => random.cppm} | 132 +- ...signal_handler.mpp => signal_handler.cppm} | 0 .../utils/{singleton.mpp => singleton.cppm} | 114 +- .../utils/{stacktrace.mpp => stacktrace.cppm} | 0 .../core/utils/{tags.mpp => tags.cppm} | 0 .../core/utils/{time.mpp => time.cppm} | 0 .../stormkit/{entities.mpp => entities.cppm} | 926 +++++------ .../stormkit/entities/{lua.mpp => lua.cppm} | 0 modules/stormkit/{gpu.mpp => gpu.cppm} | 28 +- modules/stormkit/gpu/{core.mpp => core.cppm} | 24 +- .../gpu/core/{device.mpp => device.cppm} | 0 .../gpu/core/{instance.mpp => instance.cppm} | 0 .../gpu/core/{loader.mpp => loader.cppm} | 0 .../gpu/core/{structs.mpp => structs.cppm} | 0 .../stormkit/gpu/core/{sync.mpp => sync.cppm} | 0 .../gpu/core/{vulkan.mpp => vulkan.cppm} | 0 .../gpu/core/vulkan/{enums.mpp => enums.cppm} | 0 .../core/vulkan/{structs.mpp => structs.cppm} | 0 .../gpu/core/vulkan/{utils.mpp => utils.cppm} | 0 .../gpu/core/vulkan/{vma.mpp => vma.cppm} | 0 .../gpu/core/vulkan/{volk.mpp => volk.cppm} | 0 .../gpu/{execution.mpp => execution.cppm} | 0 ...command_buffer.mpp => command_buffer.cppm} | 0 .../{descriptors.mpp => descriptors.cppm} | 0 .../execution/{pipeline.mpp => pipeline.cppm} | 0 ...ster_pipeline.mpp => raster_pipeline.cppm} | 0 .../{render_pass.mpp => render_pass.cppm} | 0 .../{swapchain.mpp => swapchain.cppm} | 0 modules/stormkit/gpu/{lua.mpp => lua.cppm} | 0 .../gpu/{resource.mpp => resource.cppm} | 0 .../gpu/resource/{buffer.mpp => buffer.cppm} | 660 ++++---- .../gpu/resource/{image.mpp => image.cppm} | 1140 +++++++------- .../gpu/resource/{shader.mpp => shader.cppm} | 524 +++---- modules/stormkit/{image.mpp => image.cppm} | 1384 ++++++++--------- modules/stormkit/image/{lua.mpp => lua.cppm} | 0 modules/stormkit/{log.mpp => log.cppm} | 766 ++++----- modules/stormkit/log/{lua.mpp => lua.cppm} | 0 modules/stormkit/{luau.mpp => luau.cppm} | 0 modules/stormkit/luau/{core.mpp => core.cppm} | 0 modules/stormkit/{main.mpp => main.cppm} | 18 +- modules/stormkit/{test.mpp => test.cppm} | 0 modules/stormkit/{wsi.mpp => wsi.cppm} | 32 +- modules/stormkit/wsi/{core.mpp => core.cppm} | 0 .../wsi/{keyboard.mpp => keyboard.cppm} | 0 modules/stormkit/wsi/{lua.mpp => lua.cppm} | 0 .../wsi/{monitor.mpp => monitor.cppm} | 0 .../stormkit/wsi/{mouse.mpp => mouse.cppm} | 0 .../stormkit/wsi/{window.mpp => window.cppm} | 0 src/core/{contract.mpp => contract.cppm} | 0 src/image/{hdr.mpp => hdr.cppm} | 100 +- src/image/{jpg.mpp => jpg.cppm} | 522 +++---- src/image/{ktx.mpp => ktx.cppm} | 302 ++-- src/image/{png.mpp => png.cppm} | 508 +++--- src/image/{ppm.mpp => ppm.cppm} | 180 +-- src/image/{qoi.mpp => qoi.cppm} | 418 ++--- src/image/{tga.mpp => tga.cppm} | 110 +- .../{input_base.mpp => input_base.cppm} | 0 .../{monitor_base.mpp => monitor_base.cppm} | 0 .../{window_base.mpp => window_base.cppm} | 0 src/wsi/linux/common/{fd.mpp => fd.cppm} | 0 src/wsi/linux/common/{xkb.mpp => xkb.cppm} | 412 ++--- src/wsi/linux/{monitor.mpp => monitor.cppm} | 0 src/wsi/linux/{mouse.mpp => mouse.cppm} | 0 .../wayland/{context.mpp => context.cppm} | 0 .../linux/wayland/{inputs.mpp => inputs.cppm} | 0 src/wsi/linux/wayland/{log.mpp => log.cppm} | 36 +- .../wayland/{monitor.mpp => monitor.cppm} | 0 .../wayland/{wayland.mpp => wayland.cppm} | 238 +-- .../linux/wayland/{window.mpp => window.cppm} | 306 ++-- src/wsi/linux/{window.mpp => window.cppm} | 1274 +++++++-------- .../linux/x11/{context.mpp => context.cppm} | 0 src/wsi/linux/x11/{log.mpp => log.cppm} | 36 +- .../linux/x11/{monitor.mpp => monitor.cppm} | 0 src/wsi/linux/x11/{utils.mpp => utils.cppm} | 344 ++-- src/wsi/linux/x11/{window.mpp => window.cppm} | 426 ++--- src/wsi/linux/x11/{xcb.mpp => xcb.cppm} | 134 +- src/wsi/macos/{monitor.mpp => monitor.cppm} | 0 src/wsi/macos/{window.mpp => window.cppm} | 0 src/wsi/win32/{keyboard.mpp => keyboard.cppm} | 0 src/wsi/win32/{log.mpp => log.cppm} | 0 src/wsi/win32/{monitor.mpp => monitor.cppm} | 0 src/wsi/win32/{mouse.mpp => mouse.cppm} | 0 src/wsi/win32/{utils.mpp => utils.cppm} | 0 src/wsi/win32/{window.mpp => window.cppm} | 0 xmake.lua | 10 +- 172 files changed, 10010 insertions(+), 10010 deletions(-) rename examples/entities/gameoflife/src/{App.mpp => App.cppm} (95%) rename examples/entities/gameoflife/src/{Components.mpp => Components.cppm} (94%) rename examples/entities/gameoflife/src/{Constants.mpp => Constants.cppm} (97%) rename examples/entities/gameoflife/src/{Renderer.mpp => Renderer.cppm} (96%) rename examples/entities/gameoflife/src/{Systems.mpp => Systems.cppm} (96%) rename examples/gpu/common/{app.mpp => app.cppm} (100%) rename examples/gpu/imgui/src/{logger.mpp => logger.cppm} (100%) rename examples/gpu/textured_cube/src/{logger.mpp => logger.cppm} (100%) rename examples/gpu/triangle/src/{logger.mpp => logger.cppm} (100%) rename modules/{stormkit.mpp => stormkit.cppm} (100%) rename modules/stormkit/core/{config.mpp => config.cppm} (96%) rename modules/stormkit/core/{console.mpp => console.cppm} (100%) rename modules/stormkit/core/console/{io.mpp => io.cppm} (100%) rename modules/stormkit/core/console/{style.mpp => style.cppm} (100%) rename modules/stormkit/core/{containers.mpp => containers.cppm} (100%) rename modules/stormkit/core/containers/{dag.mpp => dag.cppm} (100%) rename modules/stormkit/core/containers/{multi_buffer.mpp => multi_buffer.cppm} (100%) rename modules/stormkit/core/containers/{raii_capsule.mpp => raii_capsule.cppm} (100%) rename modules/stormkit/core/containers/{ringbuffer.mpp => ringbuffer.cppm} (96%) rename modules/stormkit/core/containers/{shmbuffer.mpp => shmbuffer.cppm} (100%) rename modules/stormkit/core/containers/{tree.mpp => tree.cppm} (97%) rename modules/stormkit/core/containers/{utils.mpp => utils.cppm} (100%) rename modules/stormkit/core/{coroutines.mpp => coroutines.cppm} (97%) rename modules/stormkit/core/{errors.mpp => errors.cppm} (100%) rename modules/stormkit/core/{functional.mpp => functional.cppm} (100%) rename modules/stormkit/core/functional/{error_handling.mpp => error_handling.cppm} (100%) rename modules/stormkit/core/functional/{monadic.mpp => monadic.cppm} (100%) rename modules/stormkit/core/functional/{utils.mpp => utils.cppm} (97%) rename modules/stormkit/core/{hash.mpp => hash.cppm} (96%) rename modules/stormkit/core/hash/{base.mpp => base.cppm} (100%) rename modules/stormkit/core/hash/{map.mpp => map.cppm} (97%) rename modules/stormkit/core/hash/{string.mpp => string.cppm} (100%) rename modules/stormkit/core/{math.mpp => math.cppm} (100%) rename modules/stormkit/core/math/{arithmetic.mpp => arithmetic.cppm} (100%) rename modules/stormkit/core/math/{combinatoric.mpp => combinatoric.cppm} (100%) rename modules/stormkit/core/math/{extent.mpp => extent.cppm} (100%) rename modules/stormkit/core/math/{geometry.mpp => geometry.cppm} (100%) rename modules/stormkit/core/math/{hypercomplex.mpp => hypercomplex.cppm} (100%) rename modules/stormkit/core/math/{linear-matrix.mpp => linear-matrix.cppm} (100%) rename modules/stormkit/core/math/{linear-vector.mpp => linear-vector.cppm} (100%) rename modules/stormkit/core/math/{linear.mpp => linear.cppm} (100%) rename modules/stormkit/core/math/{trigonometry.mpp => trigonometry.cppm} (100%) rename modules/stormkit/core/{meta.mpp => meta.cppm} (96%) rename modules/stormkit/core/meta/{algorithms.mpp => algorithms.cppm} (100%) rename modules/stormkit/core/meta/{concepts.mpp => concepts.cppm} (97%) rename modules/stormkit/core/meta/{priority_tag.mpp => priority_tag.cppm} (100%) rename modules/stormkit/core/meta/{type_manipulation.mpp => type_manipulation.cppm} (100%) rename modules/stormkit/core/meta/{type_query.mpp => type_query.cppm} (100%) rename modules/stormkit/core/meta/{type_traits.mpp => type_traits.cppm} (100%) rename modules/stormkit/core/{parallelism.mpp => parallelism.cppm} (97%) rename modules/stormkit/core/parallelism/{locked.mpp => locked.cppm} (100%) rename modules/stormkit/core/parallelism/{threadpool.mpp => threadpool.cppm} (97%) rename modules/stormkit/core/parallelism/{threadutils.mpp => threadutils.cppm} (97%) rename modules/stormkit/core/{string.mpp => string.cppm} (97%) rename modules/stormkit/core/string/{constexpr_string.mpp => constexpr_string.cppm} (100%) rename modules/stormkit/core/string/{czstring.mpp => czstring.cppm} (97%) rename modules/stormkit/core/string/{encodings.mpp => encodings.cppm} (100%) rename modules/stormkit/core/string/{format.mpp => format.cppm} (97%) rename modules/stormkit/core/string/{operations.mpp => operations.cppm} (100%) rename modules/stormkit/core/{typesafe.mpp => typesafe.cppm} (100%) rename modules/stormkit/core/typesafe/{boolean.mpp => boolean.cppm} (100%) rename modules/stormkit/core/typesafe/{byte.mpp => byte.cppm} (97%) rename modules/stormkit/core/typesafe/{character.mpp => character.cppm} (100%) rename modules/stormkit/core/typesafe/{checked_value.mpp => checked_value.cppm} (100%) rename modules/stormkit/core/typesafe/{flags.mpp => flags.cppm} (97%) rename modules/stormkit/core/typesafe/{float.mpp => float.cppm} (100%) rename modules/stormkit/core/typesafe/{integer.mpp => integer.cppm} (100%) rename modules/stormkit/core/typesafe/{ref.mpp => ref.cppm} (100%) rename modules/stormkit/core/typesafe/{safecasts.mpp => safecasts.cppm} (100%) rename modules/stormkit/core/typesafe/{strong_type.mpp => strong_type.cppm} (100%) rename modules/stormkit/core/{utils.mpp => utils.cppm} (97%) rename modules/stormkit/core/utils/{algorithms.mpp => algorithms.cppm} (98%) rename modules/stormkit/core/utils/{allocation.mpp => allocation.cppm} (100%) rename modules/stormkit/core/utils/{app.mpp => app.cppm} (96%) rename modules/stormkit/core/utils/{color.mpp => color.cppm} (100%) rename modules/stormkit/core/utils/{contract.mpp => contract.cppm} (97%) rename modules/stormkit/core/utils/{deferinit.mpp => deferinit.cppm} (100%) rename modules/stormkit/core/utils/{dynamic_loader.mpp => dynamic_loader.cppm} (97%) rename modules/stormkit/core/utils/{filesystem.mpp => filesystem.cppm} (100%) rename modules/stormkit/core/utils/{function_ref.mpp => function_ref.cppm} (100%) rename modules/stormkit/core/utils/{handle.mpp => handle.cppm} (96%) rename modules/stormkit/core/utils/{numeric_range.mpp => numeric_range.cppm} (97%) rename modules/stormkit/core/utils/{pimpl.mpp => pimpl.cppm} (96%) rename modules/stormkit/core/utils/{random.mpp => random.cppm} (96%) rename modules/stormkit/core/utils/{signal_handler.mpp => signal_handler.cppm} (100%) rename modules/stormkit/core/utils/{singleton.mpp => singleton.cppm} (97%) rename modules/stormkit/core/utils/{stacktrace.mpp => stacktrace.cppm} (100%) rename modules/stormkit/core/utils/{tags.mpp => tags.cppm} (100%) rename modules/stormkit/core/utils/{time.mpp => time.cppm} (100%) rename modules/stormkit/{entities.mpp => entities.cppm} (97%) rename modules/stormkit/entities/{lua.mpp => lua.cppm} (100%) rename modules/stormkit/{gpu.mpp => gpu.cppm} (96%) rename modules/stormkit/gpu/{core.mpp => core.cppm} (96%) rename modules/stormkit/gpu/core/{device.mpp => device.cppm} (100%) rename modules/stormkit/gpu/core/{instance.mpp => instance.cppm} (100%) rename modules/stormkit/gpu/core/{loader.mpp => loader.cppm} (100%) rename modules/stormkit/gpu/core/{structs.mpp => structs.cppm} (100%) rename modules/stormkit/gpu/core/{sync.mpp => sync.cppm} (100%) rename modules/stormkit/gpu/core/{vulkan.mpp => vulkan.cppm} (100%) rename modules/stormkit/gpu/core/vulkan/{enums.mpp => enums.cppm} (100%) rename modules/stormkit/gpu/core/vulkan/{structs.mpp => structs.cppm} (100%) rename modules/stormkit/gpu/core/vulkan/{utils.mpp => utils.cppm} (100%) rename modules/stormkit/gpu/core/vulkan/{vma.mpp => vma.cppm} (100%) rename modules/stormkit/gpu/core/vulkan/{volk.mpp => volk.cppm} (100%) rename modules/stormkit/gpu/{execution.mpp => execution.cppm} (100%) rename modules/stormkit/gpu/execution/{command_buffer.mpp => command_buffer.cppm} (100%) rename modules/stormkit/gpu/execution/{descriptors.mpp => descriptors.cppm} (100%) rename modules/stormkit/gpu/execution/{pipeline.mpp => pipeline.cppm} (100%) rename modules/stormkit/gpu/execution/{raster_pipeline.mpp => raster_pipeline.cppm} (100%) rename modules/stormkit/gpu/execution/{render_pass.mpp => render_pass.cppm} (100%) rename modules/stormkit/gpu/execution/{swapchain.mpp => swapchain.cppm} (100%) rename modules/stormkit/gpu/{lua.mpp => lua.cppm} (100%) rename modules/stormkit/gpu/{resource.mpp => resource.cppm} (100%) rename modules/stormkit/gpu/resource/{buffer.mpp => buffer.cppm} (97%) rename modules/stormkit/gpu/resource/{image.mpp => image.cppm} (97%) rename modules/stormkit/gpu/resource/{shader.mpp => shader.cppm} (97%) rename modules/stormkit/{image.mpp => image.cppm} (97%) rename modules/stormkit/image/{lua.mpp => lua.cppm} (100%) rename modules/stormkit/{log.mpp => log.cppm} (97%) rename modules/stormkit/log/{lua.mpp => lua.cppm} (100%) rename modules/stormkit/{luau.mpp => luau.cppm} (100%) rename modules/stormkit/luau/{core.mpp => core.cppm} (100%) rename modules/stormkit/{main.mpp => main.cppm} (96%) rename modules/stormkit/{test.mpp => test.cppm} (100%) rename modules/stormkit/{wsi.mpp => wsi.cppm} (96%) rename modules/stormkit/wsi/{core.mpp => core.cppm} (100%) rename modules/stormkit/wsi/{keyboard.mpp => keyboard.cppm} (100%) rename modules/stormkit/wsi/{lua.mpp => lua.cppm} (100%) rename modules/stormkit/wsi/{monitor.mpp => monitor.cppm} (100%) rename modules/stormkit/wsi/{mouse.mpp => mouse.cppm} (100%) rename modules/stormkit/wsi/{window.mpp => window.cppm} (100%) rename src/core/{contract.mpp => contract.cppm} (100%) rename src/image/{hdr.mpp => hdr.cppm} (97%) rename src/image/{jpg.mpp => jpg.cppm} (97%) rename src/image/{ktx.mpp => ktx.cppm} (98%) rename src/image/{png.mpp => png.cppm} (97%) rename src/image/{ppm.mpp => ppm.cppm} (97%) rename src/image/{qoi.mpp => qoi.cppm} (97%) rename src/image/{tga.mpp => tga.cppm} (97%) rename src/wsi/common/{input_base.mpp => input_base.cppm} (100%) rename src/wsi/common/{monitor_base.mpp => monitor_base.cppm} (100%) rename src/wsi/common/{window_base.mpp => window_base.cppm} (100%) rename src/wsi/linux/common/{fd.mpp => fd.cppm} (100%) rename src/wsi/linux/common/{xkb.mpp => xkb.cppm} (97%) rename src/wsi/linux/{monitor.mpp => monitor.cppm} (100%) rename src/wsi/linux/{mouse.mpp => mouse.cppm} (100%) rename src/wsi/linux/wayland/{context.mpp => context.cppm} (100%) rename src/wsi/linux/wayland/{inputs.mpp => inputs.cppm} (100%) rename src/wsi/linux/wayland/{log.mpp => log.cppm} (96%) rename src/wsi/linux/wayland/{monitor.mpp => monitor.cppm} (100%) rename src/wsi/linux/wayland/{wayland.mpp => wayland.cppm} (98%) rename src/wsi/linux/wayland/{window.mpp => window.cppm} (97%) rename src/wsi/linux/{window.mpp => window.cppm} (97%) rename src/wsi/linux/x11/{context.mpp => context.cppm} (100%) rename src/wsi/linux/x11/{log.mpp => log.cppm} (96%) rename src/wsi/linux/x11/{monitor.mpp => monitor.cppm} (100%) rename src/wsi/linux/x11/{utils.mpp => utils.cppm} (97%) rename src/wsi/linux/x11/{window.mpp => window.cppm} (97%) rename src/wsi/linux/x11/{xcb.mpp => xcb.cppm} (97%) rename src/wsi/macos/{monitor.mpp => monitor.cppm} (100%) rename src/wsi/macos/{window.mpp => window.cppm} (100%) rename src/wsi/win32/{keyboard.mpp => keyboard.cppm} (100%) rename src/wsi/win32/{log.mpp => log.cppm} (100%) rename src/wsi/win32/{monitor.mpp => monitor.cppm} (100%) rename src/wsi/win32/{mouse.mpp => mouse.cppm} (100%) rename src/wsi/win32/{utils.mpp => utils.cppm} (100%) rename src/wsi/win32/{window.mpp => window.cppm} (100%) diff --git a/examples/entities/gameoflife/src/App.mpp b/examples/entities/gameoflife/src/App.cppm similarity index 95% rename from examples/entities/gameoflife/src/App.mpp rename to examples/entities/gameoflife/src/App.cppm index 0c76586fc..591a0e84e 100644 --- a/examples/entities/gameoflife/src/App.mpp +++ b/examples/entities/gameoflife/src/App.cppm @@ -1,59 +1,59 @@ - - -#ifdef STORMKIT_BUILD_MODULES -export module App; - -import std; - -import stormkit.core; -import stormkit.image; -import stormkit.wsi; -import stormkit.entities; - -import Renderer; - -export { -#else - #include - - #include - #include - #include - #include - - #include "Renderer.mpp" -#endif - - class UpdateBoardSystem; - - class App: public stormkit::App { - public: - App(); - ~App() override; - - auto run(const int argc, CZString argv[]) -> stormkit::i32 override; - - private: - auto do_initWindow() -> void; - - auto handleKeyboard(const stormkit::wsi::KeyReleasedEventData& event) -> void; - auto handleMouse(const stormkit::wsi::MouseButtonPushedEventData& event) -> void; - auto createCell(stormkit::u32 x, stormkit::u32 y) -> void; - - std::unique_ptr m_window; - - bool m_fullscreen_enabled = false; - bool m_is_on_edit_mode = true; - - std::unique_ptr m_renderer; - - stormkit::entities::EntityManager m_entities; - - stormkit::image::Image m_board; - - UpdateBoardSystem* m_update_system = nullptr; - }; - -#ifdef STORMKIT_BUILD_MODULES -} -#endif + + +#ifdef STORMKIT_BUILD_MODULES +export module App; + +import std; + +import stormkit.core; +import stormkit.image; +import stormkit.wsi; +import stormkit.entities; + +import Renderer; + +export { +#else + #include + + #include + #include + #include + #include + + #include "Renderer.mpp" +#endif + + class UpdateBoardSystem; + + class App: public stormkit::App { + public: + App(); + ~App() override; + + auto run(const int argc, CZString argv[]) -> stormkit::i32 override; + + private: + auto do_initWindow() -> void; + + auto handleKeyboard(const stormkit::wsi::KeyReleasedEventData& event) -> void; + auto handleMouse(const stormkit::wsi::MouseButtonPushedEventData& event) -> void; + auto createCell(stormkit::u32 x, stormkit::u32 y) -> void; + + std::unique_ptr m_window; + + bool m_fullscreen_enabled = false; + bool m_is_on_edit_mode = true; + + std::unique_ptr m_renderer; + + stormkit::entities::EntityManager m_entities; + + stormkit::image::Image m_board; + + UpdateBoardSystem* m_update_system = nullptr; + }; + +#ifdef STORMKIT_BUILD_MODULES +} +#endif diff --git a/examples/entities/gameoflife/src/Components.mpp b/examples/entities/gameoflife/src/Components.cppm similarity index 94% rename from examples/entities/gameoflife/src/Components.mpp rename to examples/entities/gameoflife/src/Components.cppm index 290615e1f..89d08f7b5 100644 --- a/examples/entities/gameoflife/src/Components.mpp +++ b/examples/entities/gameoflife/src/Components.cppm @@ -1,28 +1,28 @@ - - -#ifdef STORMKIT_BUILD_MODULES -export module Components; - -import std; - -import stormkit.core; -import stormkit.entities; - -export { -#else - #include - - #include - #include -#endif - - struct PositionComponent: public stormkit::entities::Component { - stormkit::u32 x; - stormkit::u32 y; - - static constexpr Type TYPE = stormkit::entities::component_hash("PositionComponent"); - }; - -#ifdef STORMKIT_BUILD_MODULES -} -#endif + + +#ifdef STORMKIT_BUILD_MODULES +export module Components; + +import std; + +import stormkit.core; +import stormkit.entities; + +export { +#else + #include + + #include + #include +#endif + + struct PositionComponent: public stormkit::entities::Component { + stormkit::u32 x; + stormkit::u32 y; + + static constexpr Type TYPE = stormkit::entities::component_hash("PositionComponent"); + }; + +#ifdef STORMKIT_BUILD_MODULES +} +#endif diff --git a/examples/entities/gameoflife/src/Constants.mpp b/examples/entities/gameoflife/src/Constants.cppm similarity index 97% rename from examples/entities/gameoflife/src/Constants.mpp rename to examples/entities/gameoflife/src/Constants.cppm index d1bf7da10..eddf70094 100644 --- a/examples/entities/gameoflife/src/Constants.mpp +++ b/examples/entities/gameoflife/src/Constants.cppm @@ -1,54 +1,54 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -#ifdef STORMKIT_BUILD_MODULES -export module Constants; - -import std; - -import stormkit.core; -import stormkit.log; -import stormkit.gpu; - -export { -#else - #include - - #include - #include - #include -#endif - - inline constexpr auto VERTEX_SIZE - = sizeof(stormkit::math::fvec2) + sizeof(stormkit::fvec3); - inline constexpr auto WINDOW_TITLE = "StormKit GameOfLife Example"; - inline constexpr auto MESH_VERTEX_BUFFER_SIZE = VERTEX_SIZE * 3; - inline constexpr auto MESH_VERTEX_BINDING_DESCRIPTIONS = std::array { - stormkit::gpu::VertexBindingDescription { .binding = 0, .stride = VERTEX_SIZE } - }; - inline constexpr auto MESH_VERTEX_ATTRIBUTE_DESCRIPTIONS = std::array { - stormkit::gpu::VertexInputAttributeDescription { .location = 0, - .binding = 0, - .format = stormkit::gpu::format::f322, - .offset = 0 }, - stormkit::gpu::VertexInputAttributeDescription { .location = 1, - .binding = 0, - .format = stormkit::gpu::format::f322, - .offset - = sizeof(stormkit::math::fvec2) } - }; - - inline constexpr auto BOARD_SIZE = 100u; - inline constexpr auto BOARD_BUFFERING_COUNT = 3u; - inline constexpr auto REFRESH_BOARD_DELTA = stormkit::fsecond { 1 }; - - inline constexpr auto SHADER_DATA = stormkit::as_bytes( -#include - ); - - IN_MODULE_LOGGER("StormKit.GameOfLife"); - -#ifdef STORMKIT_BUILD_MODULES -} -#endif +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +#ifdef STORMKIT_BUILD_MODULES +export module Constants; + +import std; + +import stormkit.core; +import stormkit.log; +import stormkit.gpu; + +export { +#else + #include + + #include + #include + #include +#endif + + inline constexpr auto VERTEX_SIZE + = sizeof(stormkit::math::fvec2) + sizeof(stormkit::fvec3); + inline constexpr auto WINDOW_TITLE = "StormKit GameOfLife Example"; + inline constexpr auto MESH_VERTEX_BUFFER_SIZE = VERTEX_SIZE * 3; + inline constexpr auto MESH_VERTEX_BINDING_DESCRIPTIONS = std::array { + stormkit::gpu::VertexBindingDescription { .binding = 0, .stride = VERTEX_SIZE } + }; + inline constexpr auto MESH_VERTEX_ATTRIBUTE_DESCRIPTIONS = std::array { + stormkit::gpu::VertexInputAttributeDescription { .location = 0, + .binding = 0, + .format = stormkit::gpu::format::f322, + .offset = 0 }, + stormkit::gpu::VertexInputAttributeDescription { .location = 1, + .binding = 0, + .format = stormkit::gpu::format::f322, + .offset + = sizeof(stormkit::math::fvec2) } + }; + + inline constexpr auto BOARD_SIZE = 100u; + inline constexpr auto BOARD_BUFFERING_COUNT = 3u; + inline constexpr auto REFRESH_BOARD_DELTA = stormkit::fsecond { 1 }; + + inline constexpr auto SHADER_DATA = stormkit::as_bytes( +#include + ); + + IN_MODULE_LOGGER("StormKit.GameOfLife"); + +#ifdef STORMKIT_BUILD_MODULES +} +#endif diff --git a/examples/entities/gameoflife/src/Renderer.mpp b/examples/entities/gameoflife/src/Renderer.cppm similarity index 96% rename from examples/entities/gameoflife/src/Renderer.mpp rename to examples/entities/gameoflife/src/Renderer.cppm index 63f6aa419..8d7f8558b 100644 --- a/examples/entities/gameoflife/src/Renderer.mpp +++ b/examples/entities/gameoflife/src/Renderer.cppm @@ -1,77 +1,77 @@ - - -#ifdef STORMKIT_BUILD_MODULES -export module Renderer; - -import std; - -import stormkit.core; -import stormkit.wsi; -import stormkit.gpu; - -export { -#else - #include - - #include - #include - #include -#endif - - class Renderer { - public: - Renderer(const stormkit::wsi::Window& window); - ~Renderer(); - - Renderer(const Renderer&) = delete; - auto operator=(const Renderer&) -> Renderer& = delete; - - Renderer(Renderer&&) noexcept; - auto operator=(Renderer&&) noexcept -> Renderer&; - - auto renderFrame() -> void; - - auto updateBoard(const stormkit::image::Image& board) -> void; - - private: - auto do_initBaseRenderObjects() -> void; - auto do_initMeshRenderObjects() -> void; - auto do_initPerFrameObjects() -> void; - - const stormkit::wsi::Window* m_window = nullptr; - - std::unique_ptr m_instance; - std::unique_ptr m_device; - std::unique_ptr m_surface; - stormkit::gpu::Fence* m_current_fence = nullptr; - - const stormkit::gpu::Queue* m_queue = nullptr; - std::vector m_surface_views; - - std::unique_ptr m_descriptor_set_layout; - std::unique_ptr m_descriptor_pool; - - std::unique_ptr m_render_pass; - - struct Board { - std::vector images; - std::vector image_views; - std::unique_ptr sampler; - - stormkit::u32 current_image = 0; - - std::unique_ptr vertex_shader; - std::unique_ptr fragment_shader; - - std::unique_ptr pipeline; - - std::unique_ptr descriptor_set; - } m_board; - - std::vector m_command_buffers; - std::vector m_framebuffers; - }; - -#ifdef STORMKIT_BUILD_MODULES -} -#endif + + +#ifdef STORMKIT_BUILD_MODULES +export module Renderer; + +import std; + +import stormkit.core; +import stormkit.wsi; +import stormkit.gpu; + +export { +#else + #include + + #include + #include + #include +#endif + + class Renderer { + public: + Renderer(const stormkit::wsi::Window& window); + ~Renderer(); + + Renderer(const Renderer&) = delete; + auto operator=(const Renderer&) -> Renderer& = delete; + + Renderer(Renderer&&) noexcept; + auto operator=(Renderer&&) noexcept -> Renderer&; + + auto renderFrame() -> void; + + auto updateBoard(const stormkit::image::Image& board) -> void; + + private: + auto do_initBaseRenderObjects() -> void; + auto do_initMeshRenderObjects() -> void; + auto do_initPerFrameObjects() -> void; + + const stormkit::wsi::Window* m_window = nullptr; + + std::unique_ptr m_instance; + std::unique_ptr m_device; + std::unique_ptr m_surface; + stormkit::gpu::Fence* m_current_fence = nullptr; + + const stormkit::gpu::Queue* m_queue = nullptr; + std::vector m_surface_views; + + std::unique_ptr m_descriptor_set_layout; + std::unique_ptr m_descriptor_pool; + + std::unique_ptr m_render_pass; + + struct Board { + std::vector images; + std::vector image_views; + std::unique_ptr sampler; + + stormkit::u32 current_image = 0; + + std::unique_ptr vertex_shader; + std::unique_ptr fragment_shader; + + std::unique_ptr pipeline; + + std::unique_ptr descriptor_set; + } m_board; + + std::vector m_command_buffers; + std::vector m_framebuffers; + }; + +#ifdef STORMKIT_BUILD_MODULES +} +#endif diff --git a/examples/entities/gameoflife/src/Systems.mpp b/examples/entities/gameoflife/src/Systems.cppm similarity index 96% rename from examples/entities/gameoflife/src/Systems.mpp rename to examples/entities/gameoflife/src/Systems.cppm index c8b333384..e7c4d5cf6 100644 --- a/examples/entities/gameoflife/src/Systems.mpp +++ b/examples/entities/gameoflife/src/Systems.cppm @@ -1,62 +1,62 @@ - - -#ifdef STORMKIT_BUILD_MODULES -export module Systems; - -import std; - -import stormkit.core; -import stormkit.image; -import stormkit.entities; - -import Constants; -import Renderer; - -export { -#else - #include - - #include - #include - #include - - #include "Constants.mpp" - #include "Renderer.mpp" -#endif - - class UpdateBoardSystem final: public stormkit::entities::System { - public: - UpdateBoardSystem(stormkit::image::Image& board, - Renderer& renderer, - stormkit::entities::EntityManager& manager); - ~UpdateBoardSystem() override; - - UpdateBoardSystem(UpdateBoardSystem&&) noexcept; - auto operator=(UpdateBoardSystem&&) noexcept -> UpdateBoardSystem&; - - auto update(stormkit::fsecond delta) -> void override; - auto post_update() -> void override; - - auto setEditModeEnabled(bool enabled) noexcept { m_is_on_edit_mode = enabled; } - - auto incrementDelta(stormkit::fsecond delta) { m_refresh_board_delta += delta; } - - private: - using Clock = std::chrono::high_resolution_clock; - - auto on_message_received(const stormkit::entities::Message& message) -> void override {}; - - bool m_is_on_edit_mode = true; - stormkit::image::Image* m_board = nullptr; - Renderer* m_renderer = nullptr; - - Clock::time_point m_last_update; - - bool m_updated = true; - - stormkit::fsecond m_refresh_board_delta = REFRESH_BOARD_DELTA; - }; - -#ifdef STORMKIT_BUILD_MODULES -} -#endif + + +#ifdef STORMKIT_BUILD_MODULES +export module Systems; + +import std; + +import stormkit.core; +import stormkit.image; +import stormkit.entities; + +import Constants; +import Renderer; + +export { +#else + #include + + #include + #include + #include + + #include "Constants.mpp" + #include "Renderer.mpp" +#endif + + class UpdateBoardSystem final: public stormkit::entities::System { + public: + UpdateBoardSystem(stormkit::image::Image& board, + Renderer& renderer, + stormkit::entities::EntityManager& manager); + ~UpdateBoardSystem() override; + + UpdateBoardSystem(UpdateBoardSystem&&) noexcept; + auto operator=(UpdateBoardSystem&&) noexcept -> UpdateBoardSystem&; + + auto update(stormkit::fsecond delta) -> void override; + auto post_update() -> void override; + + auto setEditModeEnabled(bool enabled) noexcept { m_is_on_edit_mode = enabled; } + + auto incrementDelta(stormkit::fsecond delta) { m_refresh_board_delta += delta; } + + private: + using Clock = std::chrono::high_resolution_clock; + + auto on_message_received(const stormkit::entities::Message& message) -> void override {}; + + bool m_is_on_edit_mode = true; + stormkit::image::Image* m_board = nullptr; + Renderer* m_renderer = nullptr; + + Clock::time_point m_last_update; + + bool m_updated = true; + + stormkit::fsecond m_refresh_board_delta = REFRESH_BOARD_DELTA; + }; + +#ifdef STORMKIT_BUILD_MODULES +} +#endif diff --git a/examples/entities/gameoflife/xmake.lua b/examples/entities/gameoflife/xmake.lua index 9e96e6baf..0ca9c398b 100644 --- a/examples/entities/gameoflife/xmake.lua +++ b/examples/entities/gameoflife/xmake.lua @@ -18,7 +18,7 @@ if has_config("enable_gpu") and has_config("enable_wsi") and has_config("enable- end add_files("src/*.cpp") - add_files("src/*.mpp") + add_files("src/*.cppm") add_files("shaders/*.nzsl") if is_plat("windows") then add_files("win32/*.manifest") end diff --git a/examples/gpu/common/app.mpp b/examples/gpu/common/app.cppm similarity index 100% rename from examples/gpu/common/app.mpp rename to examples/gpu/common/app.cppm diff --git a/examples/gpu/imgui/src/logger.mpp b/examples/gpu/imgui/src/logger.cppm similarity index 100% rename from examples/gpu/imgui/src/logger.mpp rename to examples/gpu/imgui/src/logger.cppm diff --git a/examples/gpu/imgui/xmake.lua b/examples/gpu/imgui/xmake.lua index 4b69a62e0..6c6a9e0a7 100644 --- a/examples/gpu/imgui/xmake.lua +++ b/examples/gpu/imgui/xmake.lua @@ -23,7 +23,7 @@ target("imgui", function() add_defines("STORMKIT_ASSERT=0") end - add_files("src/*.cpp", "src/*.mpp", "../common/app.mpp") + add_files("src/*.cpp", "src/*.cppm", "../common/app.cppm") if is_plat("windows") then add_files("win32/*.manifest") end if get_config("devmode") then set_rundir("$(projectdir)") end diff --git a/examples/gpu/textured_cube/src/logger.mpp b/examples/gpu/textured_cube/src/logger.cppm similarity index 100% rename from examples/gpu/textured_cube/src/logger.mpp rename to examples/gpu/textured_cube/src/logger.cppm diff --git a/examples/gpu/textured_cube/xmake.lua b/examples/gpu/textured_cube/xmake.lua index df6b7da89..71c387533 100644 --- a/examples/gpu/textured_cube/xmake.lua +++ b/examples/gpu/textured_cube/xmake.lua @@ -19,7 +19,7 @@ target("textured_cube", function() add_defines("STORMKIT_ASSERT=0") end - add_files("src/*.cpp", "src/*.mpp", "../common/app.mpp") + add_files("src/*.cpp", "src/*.cppm", "../common/app.cppm") add_files("shaders/*.nzsl") if is_plat("windows") then add_files("win32/*.manifest") end diff --git a/examples/gpu/triangle/src/logger.mpp b/examples/gpu/triangle/src/logger.cppm similarity index 100% rename from examples/gpu/triangle/src/logger.mpp rename to examples/gpu/triangle/src/logger.cppm diff --git a/examples/gpu/triangle/xmake.lua b/examples/gpu/triangle/xmake.lua index d03e808e2..d79cfc520 100644 --- a/examples/gpu/triangle/xmake.lua +++ b/examples/gpu/triangle/xmake.lua @@ -32,7 +32,7 @@ target("triangle", function() add_defines("STORMKIT_ASSERT=0") end - add_files("src/*.cpp", "src/*.mpp", "../common/app.mpp") + add_files("src/*.cpp", "src/*.cppm", "../common/app.cppm") add_files("shaders/*.nzsl") if is_plat("windows") then add_files("win32/*.manifest") end diff --git a/modules/stormkit.mpp b/modules/stormkit.cppm similarity index 100% rename from modules/stormkit.mpp rename to modules/stormkit.cppm diff --git a/modules/stormkit/core/config.mpp b/modules/stormkit/core/config.cppm similarity index 96% rename from modules/stormkit/core/config.mpp rename to modules/stormkit/core/config.cppm index 9edb9fbae..cea2c8eaf 100644 --- a/modules/stormkit/core/config.mpp +++ b/modules/stormkit/core/config.cppm @@ -1,23 +1,23 @@ -// Copyright (C) 2021 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -export module stormkit.core:config; - -import std; - -#if defined(__clang__) - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" -#elif defined(_MSC_VER) - #pragma warning(push) - #pragma warning(disable: 5244) -#endif -#define _STORMKIT_EXPORT export -#include -#if defined(__clang__) - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" -#elif defined(_MSC_VER) - #pragma warning(pop) -#endif +// Copyright (C) 2021 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +export module stormkit.core:config; + +import std; + +#if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" +#elif defined(_MSC_VER) + #pragma warning(push) + #pragma warning(disable: 5244) +#endif +#define _STORMKIT_EXPORT export +#include +#if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" +#elif defined(_MSC_VER) + #pragma warning(pop) +#endif diff --git a/modules/stormkit/core/console.mpp b/modules/stormkit/core/console.cppm similarity index 100% rename from modules/stormkit/core/console.mpp rename to modules/stormkit/core/console.cppm diff --git a/modules/stormkit/core/console/io.mpp b/modules/stormkit/core/console/io.cppm similarity index 100% rename from modules/stormkit/core/console/io.mpp rename to modules/stormkit/core/console/io.cppm diff --git a/modules/stormkit/core/console/style.mpp b/modules/stormkit/core/console/style.cppm similarity index 100% rename from modules/stormkit/core/console/style.mpp rename to modules/stormkit/core/console/style.cppm diff --git a/modules/stormkit/core/containers.mpp b/modules/stormkit/core/containers.cppm similarity index 100% rename from modules/stormkit/core/containers.mpp rename to modules/stormkit/core/containers.cppm diff --git a/modules/stormkit/core/containers/dag.mpp b/modules/stormkit/core/containers/dag.cppm similarity index 100% rename from modules/stormkit/core/containers/dag.mpp rename to modules/stormkit/core/containers/dag.cppm diff --git a/modules/stormkit/core/containers/multi_buffer.mpp b/modules/stormkit/core/containers/multi_buffer.cppm similarity index 100% rename from modules/stormkit/core/containers/multi_buffer.mpp rename to modules/stormkit/core/containers/multi_buffer.cppm diff --git a/modules/stormkit/core/containers/raii_capsule.mpp b/modules/stormkit/core/containers/raii_capsule.cppm similarity index 100% rename from modules/stormkit/core/containers/raii_capsule.mpp rename to modules/stormkit/core/containers/raii_capsule.cppm diff --git a/modules/stormkit/core/containers/ringbuffer.mpp b/modules/stormkit/core/containers/ringbuffer.cppm similarity index 96% rename from modules/stormkit/core/containers/ringbuffer.mpp rename to modules/stormkit/core/containers/ringbuffer.cppm index be740f6f5..91451496b 100644 --- a/modules/stormkit/core/containers/ringbuffer.mpp +++ b/modules/stormkit/core/containers/ringbuffer.cppm @@ -1,279 +1,279 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -#include - -export module stormkit.core:containers.ringbuffer; - -import std; - -import :utils.contract; -import :typesafe.integer; -import :typesafe.byte; -import :meta; - -export namespace stormkit { inline namespace core { - template - class RingBuffer { - public: - using ValueType = T; - using ExtentType = usize; - - using value_type = ValueType; - using size_type = ExtentType; - - RingBuffer(ExtentType capacity); - - RingBuffer(const RingBuffer& copy); - auto operator=(const RingBuffer& copy) -> RingBuffer&; - - RingBuffer(RingBuffer&& moved) noexcept; - auto operator=(RingBuffer&& moved) noexcept -> RingBuffer&; - - ~RingBuffer() noexcept; - - auto clear() noexcept -> void; - - [[nodiscard]] - auto empty() const noexcept -> bool; - [[nodiscard]] - auto full() const noexcept -> bool; - [[nodiscard]] - auto size() const noexcept -> ExtentType; - [[nodiscard]] - auto capacity() const noexcept -> ExtentType; - - template - requires meta::Is> - auto push(U&& value) noexcept(std::is_nothrow_constructible_v) -> void; - - template - auto emplace(Args&&... values) noexcept(std::is_nothrow_constructible_v) -> void; - - auto next() noexcept -> void; - - auto pop() noexcept -> void; - - template - [[nodiscard]] - auto get(this Self& self) noexcept -> decltype(auto); - - [[nodiscard]] - auto data() const noexcept -> std::span; - - private: - template - [[nodiscard]] - auto get_ptr(this Self& self, ExtentType pos) noexcept -> decltype(auto); - - ExtentType m_capacity = 0; - ExtentType m_count = 0; - - std::vector m_buffer; - - ExtentType m_write = 0; - ExtentType m_read = 0; - }; -}} // namespace stormkit::core - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit { inline namespace core { - //////////////////////////////////////// - //////////////////////////////////////// - template - RingBuffer::RingBuffer(ExtentType capacity) : m_capacity { capacity } { - m_buffer.resize(m_capacity * sizeof(ValueType)); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - RingBuffer::RingBuffer(const RingBuffer& copy) { - m_capacity = copy.m_capacity; - m_count = copy.m_count; - m_write = copy.m_write; - m_read = copy.m_read; - - m_buffer.resize(m_capacity * sizeof(ValueType)); - if (not empty()) { - for (auto i = m_read; i < m_write;) { - new (&m_buffer[i * sizeof(ValueType)]) T { *copy.get_ptr(i) }; - - i += 1; - if (i >= m_capacity) i -= m_capacity; - } - } - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto RingBuffer::operator=(const RingBuffer& copy) -> RingBuffer& { - if (© == this) return *this; - - m_capacity = copy.m_capacity; - m_count = copy.m_count; - m_write = copy.m_write; - m_read = copy.m_read; - - m_buffer.resize(m_capacity * sizeof(ValueType)); - if (not empty()) - for (auto i = m_read; i < m_write;) { - new (&m_buffer[i * sizeof(ValueType)]) T { *copy.get_ptr(i) }; - - i += 1; - if (i >= m_capacity) i -= m_capacity; - } - - return *this; - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - RingBuffer::RingBuffer(RingBuffer&& moved) noexcept { - m_buffer = std::exchange(moved.m_buffer, std::vector {}); - - m_capacity = std::exchange(moved.m_capacity, 0); - m_count = std::exchange(moved.m_count, 0); - m_write = std::exchange(moved.m_write, 0); - m_read = std::exchange(moved.m_read, 0); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto RingBuffer::operator=(RingBuffer&& moved) noexcept -> RingBuffer& { - if (&moved == this) return *this; - - m_buffer = std::exchange(moved.m_buffer, std::vector {}); - - m_capacity = std::exchange(moved.m_capacity, 0); - m_count = std::exchange(moved.m_count, 0); - m_write = std::exchange(moved.m_write, 0); - m_read = std::exchange(moved.m_read, 0); - - return *this; - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - RingBuffer::~RingBuffer() noexcept { - clear(); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto RingBuffer::clear() noexcept -> void { - while (not empty()) pop(); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto RingBuffer::empty() const noexcept -> bool { - return m_count == 0; - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto RingBuffer::full() const noexcept -> bool { - return m_count == m_capacity; - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto RingBuffer::size() const noexcept -> ExtentType { - return m_count; - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto RingBuffer::capacity() const noexcept -> ExtentType { - return m_capacity; - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - template - requires meta::Is> - auto RingBuffer::push(U&& value) noexcept(std::is_nothrow_constructible_v) -> void { - emplace(std::forward(value)); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - template - auto RingBuffer::emplace(Args&&... values) noexcept(std::is_nothrow_constructible_v) -> void { - if (m_count == m_capacity) pop(); - - new (&m_buffer[m_write * sizeof(ValueType)]) ValueType { std::forward(values)... }; - - m_write += 1; - if (m_write >= m_capacity) m_write -= m_capacity; - - m_count++; - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto RingBuffer::next() noexcept -> void { - m_read += 1; - if (m_read >= m_capacity) m_read -= m_capacity; - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto RingBuffer::pop() noexcept -> void { - EXPECTS(not empty()); - - get_ptr(m_write)->~ValueType(); - - --m_count; - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - template - auto RingBuffer::get(this Self& self) noexcept -> decltype(auto) { - EXPECTS(not self.empty()); - - return std::forward_like(self.get_ptr(self.m_read)); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto RingBuffer::data() const noexcept -> std::span { - return std::span { get_ptr(0), m_capacity }; - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - template - auto RingBuffer::get_ptr(this Self& self, ExtentType pos) noexcept -> decltype(auto) { - using OutPtr = meta::ForwardConst; - auto addr = std::forward_like(&(self.m_buffer[pos * sizeof(ValueType)])); - - return std::launder(std::bit_cast(addr)); - } -}} // namespace stormkit::core +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +export module stormkit.core:containers.ringbuffer; + +import std; + +import :utils.contract; +import :typesafe.integer; +import :typesafe.byte; +import :meta; + +export namespace stormkit { inline namespace core { + template + class RingBuffer { + public: + using ValueType = T; + using ExtentType = usize; + + using value_type = ValueType; + using size_type = ExtentType; + + RingBuffer(ExtentType capacity); + + RingBuffer(const RingBuffer& copy); + auto operator=(const RingBuffer& copy) -> RingBuffer&; + + RingBuffer(RingBuffer&& moved) noexcept; + auto operator=(RingBuffer&& moved) noexcept -> RingBuffer&; + + ~RingBuffer() noexcept; + + auto clear() noexcept -> void; + + [[nodiscard]] + auto empty() const noexcept -> bool; + [[nodiscard]] + auto full() const noexcept -> bool; + [[nodiscard]] + auto size() const noexcept -> ExtentType; + [[nodiscard]] + auto capacity() const noexcept -> ExtentType; + + template + requires meta::Is> + auto push(U&& value) noexcept(std::is_nothrow_constructible_v) -> void; + + template + auto emplace(Args&&... values) noexcept(std::is_nothrow_constructible_v) -> void; + + auto next() noexcept -> void; + + auto pop() noexcept -> void; + + template + [[nodiscard]] + auto get(this Self& self) noexcept -> decltype(auto); + + [[nodiscard]] + auto data() const noexcept -> std::span; + + private: + template + [[nodiscard]] + auto get_ptr(this Self& self, ExtentType pos) noexcept -> decltype(auto); + + ExtentType m_capacity = 0; + ExtentType m_count = 0; + + std::vector m_buffer; + + ExtentType m_write = 0; + ExtentType m_read = 0; + }; +}} // namespace stormkit::core + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit { inline namespace core { + //////////////////////////////////////// + //////////////////////////////////////// + template + RingBuffer::RingBuffer(ExtentType capacity) : m_capacity { capacity } { + m_buffer.resize(m_capacity * sizeof(ValueType)); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + RingBuffer::RingBuffer(const RingBuffer& copy) { + m_capacity = copy.m_capacity; + m_count = copy.m_count; + m_write = copy.m_write; + m_read = copy.m_read; + + m_buffer.resize(m_capacity * sizeof(ValueType)); + if (not empty()) { + for (auto i = m_read; i < m_write;) { + new (&m_buffer[i * sizeof(ValueType)]) T { *copy.get_ptr(i) }; + + i += 1; + if (i >= m_capacity) i -= m_capacity; + } + } + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto RingBuffer::operator=(const RingBuffer& copy) -> RingBuffer& { + if (© == this) return *this; + + m_capacity = copy.m_capacity; + m_count = copy.m_count; + m_write = copy.m_write; + m_read = copy.m_read; + + m_buffer.resize(m_capacity * sizeof(ValueType)); + if (not empty()) + for (auto i = m_read; i < m_write;) { + new (&m_buffer[i * sizeof(ValueType)]) T { *copy.get_ptr(i) }; + + i += 1; + if (i >= m_capacity) i -= m_capacity; + } + + return *this; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + RingBuffer::RingBuffer(RingBuffer&& moved) noexcept { + m_buffer = std::exchange(moved.m_buffer, std::vector {}); + + m_capacity = std::exchange(moved.m_capacity, 0); + m_count = std::exchange(moved.m_count, 0); + m_write = std::exchange(moved.m_write, 0); + m_read = std::exchange(moved.m_read, 0); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto RingBuffer::operator=(RingBuffer&& moved) noexcept -> RingBuffer& { + if (&moved == this) return *this; + + m_buffer = std::exchange(moved.m_buffer, std::vector {}); + + m_capacity = std::exchange(moved.m_capacity, 0); + m_count = std::exchange(moved.m_count, 0); + m_write = std::exchange(moved.m_write, 0); + m_read = std::exchange(moved.m_read, 0); + + return *this; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + RingBuffer::~RingBuffer() noexcept { + clear(); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto RingBuffer::clear() noexcept -> void { + while (not empty()) pop(); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto RingBuffer::empty() const noexcept -> bool { + return m_count == 0; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto RingBuffer::full() const noexcept -> bool { + return m_count == m_capacity; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto RingBuffer::size() const noexcept -> ExtentType { + return m_count; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto RingBuffer::capacity() const noexcept -> ExtentType { + return m_capacity; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + template + requires meta::Is> + auto RingBuffer::push(U&& value) noexcept(std::is_nothrow_constructible_v) -> void { + emplace(std::forward(value)); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + template + auto RingBuffer::emplace(Args&&... values) noexcept(std::is_nothrow_constructible_v) -> void { + if (m_count == m_capacity) pop(); + + new (&m_buffer[m_write * sizeof(ValueType)]) ValueType { std::forward(values)... }; + + m_write += 1; + if (m_write >= m_capacity) m_write -= m_capacity; + + m_count++; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto RingBuffer::next() noexcept -> void { + m_read += 1; + if (m_read >= m_capacity) m_read -= m_capacity; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto RingBuffer::pop() noexcept -> void { + EXPECTS(not empty()); + + get_ptr(m_write)->~ValueType(); + + --m_count; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + template + auto RingBuffer::get(this Self& self) noexcept -> decltype(auto) { + EXPECTS(not self.empty()); + + return std::forward_like(self.get_ptr(self.m_read)); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto RingBuffer::data() const noexcept -> std::span { + return std::span { get_ptr(0), m_capacity }; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + template + auto RingBuffer::get_ptr(this Self& self, ExtentType pos) noexcept -> decltype(auto) { + using OutPtr = meta::ForwardConst; + auto addr = std::forward_like(&(self.m_buffer[pos * sizeof(ValueType)])); + + return std::launder(std::bit_cast(addr)); + } +}} // namespace stormkit::core diff --git a/modules/stormkit/core/containers/shmbuffer.mpp b/modules/stormkit/core/containers/shmbuffer.cppm similarity index 100% rename from modules/stormkit/core/containers/shmbuffer.mpp rename to modules/stormkit/core/containers/shmbuffer.cppm diff --git a/modules/stormkit/core/containers/tree.mpp b/modules/stormkit/core/containers/tree.cppm similarity index 97% rename from modules/stormkit/core/containers/tree.mpp rename to modules/stormkit/core/containers/tree.cppm index 84919c7a0..02dfe1eca 100644 --- a/modules/stormkit/core/containers/tree.mpp +++ b/modules/stormkit/core/containers/tree.cppm @@ -1,531 +1,531 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -#include - -#include - -export module stormkit.core:containers.tree; - -import std; - -import :typesafe.integer; -import :typesafe.byte; -import :typesafe.safecasts; -import :utils.handle; -import :utils.contract; -import :utils.function_ref; -import :utils.filesystem; - -namespace stdr = std::ranges; -namespace stdfs = std::filesystem; - -export namespace stormkit { inline namespace core { - class STORMKIT_API TreeNode { - public: - using IndexType = Handle32; - using DirtyBitType = u32; - - static constexpr auto INVALID_INDEX = IndexType { IndexType::INVALID_HANDLE_VALUE }; - - [[nodiscard]] - auto name() const noexcept -> const std::string&; - auto set_name(std::string name) noexcept -> void; - - [[nodiscard]] - auto parent() const noexcept -> IndexType; - auto set_parent(IndexType index) noexcept -> void; - - auto next_sibling() const noexcept -> IndexType; - auto set_next_sibling(IndexType index) noexcept -> void; - - auto first_child() const noexcept -> IndexType; - auto set_first_child(IndexType index) noexcept -> void; - - auto dirty_bits() const noexcept -> const DirtyBitType&; - auto set_dirty_bits(DirtyBitType bits) noexcept -> void; - - auto invalidate() noexcept -> void; - - private: - IndexType m_parent = INVALID_INDEX; - IndexType m_next_sibling = INVALID_INDEX; - IndexType m_first_child = INVALID_INDEX; - DirtyBitType m_dirty_bits = 0; - - std::string m_name; - }; - - template - class Tree { - public: - static constexpr auto DEFAULT_PREALLOCATED_TREE_SIZE = usize { 10 }; - - using TreeNodeType = TreeNodeClass; - using TreeNodeIndexType = typename TreeNodeType::IndexType; - using TreeNodeDirtyBitType = typename TreeNodeType::DirtyBitType; - - Tree(); - ~Tree(); - - Tree(const Tree&); - auto operator=(const Tree&) -> Tree&; - - Tree(Tree&&); - auto operator=(Tree&&) -> Tree&; - - auto get_free_node() -> TreeNodeIndexType; - - auto insert(TreeNodeType&& node, TreeNodeIndexType parent_index, TreeNodeIndexType previous_sibling) -> TreeNodeIndexType; - auto remove(TreeNodeIndexType index) -> void; - - auto mark_dirty(TreeNodeIndexType index, TreeNodeDirtyBitType bits) -> void; - - auto operator[](TreeNodeIndexType index) noexcept -> TreeNodeType&; - auto operator[](TreeNodeIndexType index) const noexcept -> const TreeNodeType&; - - [[nodiscard]] - auto size() const noexcept -> usize; - - [[nodiscard]] - auto begin() noexcept; - [[nodiscard]] - auto begin() const noexcept; - [[nodiscard]] - auto cbegin() const noexcept; - - [[nodiscard]] - auto end() noexcept; - [[nodiscard]] - auto end() const noexcept; - [[nodiscard]] - auto cend() const noexcept; - - auto clear_dirties() noexcept -> void; - [[nodiscard]] - auto dirties() const noexcept -> std::span; - - auto gen_dot_file(stdfs::path filepath, FunctionRef colorize_node) const noexcept - -> io::Expected; - - auto gen_dot_file(stdfs::path filepath, - core::u32 highlight, - FunctionRef colorize_node) const noexcept -> io::Expected; - - private: - TreeNodeIndexType m_first_free_index = 0; - std::vector m_tree; - std::vector m_dirties; - }; -}} // namespace stormkit::core - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit { inline namespace core { - //////////////////////////////////////// - //////////////////////////////////////// - inline auto TreeNode::name() const noexcept -> const std::string& { - return m_name; - } - - //////////////////////////////////////// - //////////////////////////////////////// - inline auto TreeNode::set_name(std::string name) noexcept -> void { - m_name = std::move(name); - } - - //////////////////////////////////////// - //////////////////////////////////////// - inline auto TreeNode::parent() const noexcept -> TreeNode::IndexType { - return m_parent; - } - - //////////////////////////////////////// - //////////////////////////////////////// - inline auto TreeNode::set_parent(IndexType index) noexcept -> void { - m_parent = index; - } - - //////////////////////////////////////// - //////////////////////////////////////// - inline auto TreeNode::next_sibling() const noexcept -> TreeNode::IndexType { - return m_next_sibling; - } - - //////////////////////////////////////// - //////////////////////////////////////// - inline auto TreeNode::set_next_sibling(IndexType index) noexcept -> void { - m_next_sibling = index; - } - - //////////////////////////////////////// - //////////////////////////////////////// - inline auto TreeNode::first_child() const noexcept -> TreeNode::IndexType { - return m_first_child; - } - - //////////////////////////////////////// - //////////////////////////////////////// - inline auto TreeNode::set_first_child(IndexType index) noexcept -> void { - m_first_child = index; - } - - //////////////////////////////////////// - //////////////////////////////////////// - inline auto TreeNode::dirty_bits() const noexcept -> const TreeNode::DirtyBitType& { - return m_dirty_bits; - } - - //////////////////////////////////////// - //////////////////////////////////////// - inline auto TreeNode::set_dirty_bits(DirtyBitType bits) noexcept -> void { - m_dirty_bits = bits; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto TreeNode::invalidate() noexcept -> void { - m_parent = { INVALID_INDEX }; - m_next_sibling = { INVALID_INDEX }; - m_first_child = { INVALID_INDEX }; - m_dirty_bits = 0; - m_name = ""; - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - Tree::Tree() { - m_tree.resize(DEFAULT_PREALLOCATED_TREE_SIZE); - - for (auto i : range(stdr::size(m_tree) - 1u)) m_tree[i].set_next_sibling(i + 1u); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - Tree::~Tree() = default; - - //////////////////////////////////////// - //////////////////////////////////////// - template - Tree::Tree(const Tree&) = default; - - //////////////////////////////////////// - //////////////////////////////////////// - template - Tree::Tree(Tree&&) = default; - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto Tree::operator=(const Tree&) -> Tree& = default; - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto Tree::operator=(Tree&&) -> Tree& = default; - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto Tree::get_free_node() -> TreeNodeIndexType { - if (m_tree[m_first_free_index].next_sibling() == TreeNode::INVALID_INDEX) { - const auto size = as(stdr::size(m_tree)); - const auto first_new = as(stdr::size(m_tree)); - - m_tree.resize(as(size * 1.5f)); - const auto new_size = stdr::size(m_tree); - - // generate a new chain of free objects, with the last one pointing to - // ~0 - m_tree[m_first_free_index].set_next_sibling(first_new); - for (auto i : range(first_new, new_size - 1u)) m_tree[i].set_next_sibling(i + 1u); - } - - auto index = m_first_free_index; - m_first_free_index = m_tree[m_first_free_index].next_sibling(); - - return index; - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto Tree::insert(TreeNodeType&& node, TreeNodeIndexType parent_index, TreeNodeIndexType previous_sibling) - -> TreeNodeIndexType { - const auto index = get_free_node(); - - auto& _node = m_tree[index]; - _node = std::forward(node); - - _node.set_parent(parent_index); - - // check if parent is real node - if (parent_index != TreeNode::INVALID_INDEX) { - auto& parent_node = *(std::ranges::begin(m_tree) + parent_index); - - // new node is first child - if (parent_node.first_child() == TreeNode::INVALID_INDEX) parent_node.set_first_child(index); - else if (previous_sibling == TreeNode::INVALID_INDEX) { // insert a beginning of childs - _node.set_next_sibling(parent_node.first_child()); - parent_node.set_first_child(index); - } else { // insert at the end - auto& prev_sibling_node = m_tree[previous_sibling]; - _node.set_next_sibling(prev_sibling_node.next_sibling()); - prev_sibling_node.set_next_sibling(index); - } - } - - return index; - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto Tree::remove(TreeNodeIndexType index) -> void { - auto& node = m_tree[index]; - - if (node.parent() != TreeNode::INVALID_INDEX) { - auto& parent = m_tree[node.parent()]; - - // Remove sibling - auto current_index = parent.first_child(); - while (current_index != TreeNode::INVALID_INDEX) { - auto& current_node = m_tree[current_index]; - - if (current_node.next_sibling() == index) { - current_node.set_next_sibling(node.next_sibling()); - break; - } - current_index = current_node.next_sibling(); - } - - // remove parent - if (parent.first_child() == index) parent.set_first_child(node.next_sibling()); - - node.set_parent(TreeNode::INVALID_INDEX); - } - - auto last_index = TreeNode::INVALID_INDEX; - auto queue = std::deque {}; - queue.emplace_back(index); - while (not queue.empty()) { - auto current_index = queue.front(); - auto& current_node = m_tree[current_index]; - queue.pop_front(); - - auto child_index = current_node.first_child(); - while (child_index != TreeNode::INVALID_INDEX) { - queue.emplace_back(child_index); - child_index = m_tree[child_index].next_sibling(); - } - - node.invalidate(); - - if (last_index != TreeNode::INVALID_INDEX) m_tree[last_index].set_next_sibling(current_index); - - last_index = current_index; - } - - m_tree[last_index].set_next_sibling(m_first_free_index); - m_first_free_index = index; - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto Tree::mark_dirty(TreeNodeIndexType index, TreeNodeDirtyBitType bits) -> void { - auto& node = m_tree[index]; - if (not node.dirty_bits()) { - m_dirties.emplace_back(index); - node.set_dirty_bits(bits); - return; - } - - node.set_dirty_bits(bits); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto Tree::operator[](TreeNodeIndexType index) noexcept -> TreeNodeType& { - EXPECTS(index < stdr::size(m_tree)); - - return m_tree[index]; - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto Tree::operator[](TreeNodeIndexType index) const noexcept -> const TreeNodeType& { - EXPECTS(index < stdr::size(m_tree)); - - return m_tree[index]; - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto Tree::size() const noexcept -> usize { - return stdr::size(m_tree); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto Tree::begin() noexcept { - return std::ranges::begin(m_tree); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto Tree::begin() const noexcept { - return std::cbegin(m_tree); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto Tree::cbegin() const noexcept { - return std::cbegin(m_tree); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto Tree::end() noexcept { - return std::ranges::end(m_tree); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto Tree::end() const noexcept { - return std::cend(m_tree); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto Tree::cend() const noexcept { - return std::cend(m_tree); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto Tree::clear_dirties() noexcept -> void { - if (std::empty(m_dirties)) return; - - for (auto i : m_dirties) { m_tree[i].set_dirty_bits(0); } - - m_dirties.clear(); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto Tree::dirties() const noexcept -> std::span { - return m_dirties; - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto Tree::gen_dot_file(stdfs::path filepath, - FunctionRef colorize_node) const noexcept - -> io::Expected { - using namespace stormkit::literals; - auto out = std::string {}; - out.reserve(1_kb); - - out += "digraph G { \n" - " rankdir = LR\n" - " bgcolor = black\n\n" - " node [shape=box, fontname=\"helvetica\", fontsize=12];\n\n"; - - for (auto i : range(m_first_free_index)) { - const auto name = operator[](i).name(); - const auto dirty = bool(operator[](i).dirty_bits()); - - out += std::format(" \"node{}\" [label=\"id: {} type: {} dirty: {} \", style=filled,color=\"{}\"];\n", - i, - i, - name, - dirty, - colorize_node(name)); - } - - for (auto i : range(m_first_free_index)) { - if (operator[](i).first_child() == TreeNodeClass::INVALID_INDEX) continue; - - for (auto current = operator[](i).first_child(); current != TreeNodeClass::INVALID_INDEX; - current = operator[](current).next_sibling()) { - out += std::format(" \"node{}\" -> \"node{}\" [color=seagreen] ;\n", i, current); - } - } - - out += "}"; - - return io::write_text(filepath, out); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - auto Tree::gen_dot_file(stdfs::path filepath, - core::u32 highlight, - FunctionRef colorize_node) const noexcept - -> io::Expected { - using namespace stormkit::literals; - auto out = std::string {}; - out.reserve(1_kb); - - out += "digraph G { \n" - " rankdir = LR\n" - " bgcolor = black\n\n" - " node [shape=box, fontname=\"helvetica\", fontsize=12];\n\n"; - - for (auto i : range(m_first_free_index)) { - const auto name = operator[](i).name(); - const auto dirty = bool(operator[](i).dirty_bits()); - if (i != highlight) - out += std::format(" \"node{}\" [label=\"id: {} type: {} dirty: {} \", style=filled,color=\"{}\"];\n", - i, - i, - name, - dirty, - colorize_node(name)); - else - out += std::format(" \"node{}\" [shape = polygon,sides=5,peripheries=3, label=\"id: {} type: {} dirty: {} \", " - "style=filled,color=\"{}\"];\n", - i, - i, - name, - dirty, - colorize_node(name)); - } - - for (auto i : range(m_first_free_index)) { - if (operator[](i).first_child() == TreeNodeClass::INVALID_INDEX) continue; - - for (auto current = operator[](i).first_child(); current != TreeNodeClass::INVALID_INDEX; - current = operator[](current).next_sibling()) { - out += std::format(" \"node{}\" -> \"node{}\" [color=seagreen] ;\n", i, current); - } - } - - out += "}"; - - return io::write_text(filepath, out); - } -}} // namespace stormkit::core +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +#include + +export module stormkit.core:containers.tree; + +import std; + +import :typesafe.integer; +import :typesafe.byte; +import :typesafe.safecasts; +import :utils.handle; +import :utils.contract; +import :utils.function_ref; +import :utils.filesystem; + +namespace stdr = std::ranges; +namespace stdfs = std::filesystem; + +export namespace stormkit { inline namespace core { + class STORMKIT_API TreeNode { + public: + using IndexType = Handle32; + using DirtyBitType = u32; + + static constexpr auto INVALID_INDEX = IndexType { IndexType::INVALID_HANDLE_VALUE }; + + [[nodiscard]] + auto name() const noexcept -> const std::string&; + auto set_name(std::string name) noexcept -> void; + + [[nodiscard]] + auto parent() const noexcept -> IndexType; + auto set_parent(IndexType index) noexcept -> void; + + auto next_sibling() const noexcept -> IndexType; + auto set_next_sibling(IndexType index) noexcept -> void; + + auto first_child() const noexcept -> IndexType; + auto set_first_child(IndexType index) noexcept -> void; + + auto dirty_bits() const noexcept -> const DirtyBitType&; + auto set_dirty_bits(DirtyBitType bits) noexcept -> void; + + auto invalidate() noexcept -> void; + + private: + IndexType m_parent = INVALID_INDEX; + IndexType m_next_sibling = INVALID_INDEX; + IndexType m_first_child = INVALID_INDEX; + DirtyBitType m_dirty_bits = 0; + + std::string m_name; + }; + + template + class Tree { + public: + static constexpr auto DEFAULT_PREALLOCATED_TREE_SIZE = usize { 10 }; + + using TreeNodeType = TreeNodeClass; + using TreeNodeIndexType = typename TreeNodeType::IndexType; + using TreeNodeDirtyBitType = typename TreeNodeType::DirtyBitType; + + Tree(); + ~Tree(); + + Tree(const Tree&); + auto operator=(const Tree&) -> Tree&; + + Tree(Tree&&); + auto operator=(Tree&&) -> Tree&; + + auto get_free_node() -> TreeNodeIndexType; + + auto insert(TreeNodeType&& node, TreeNodeIndexType parent_index, TreeNodeIndexType previous_sibling) -> TreeNodeIndexType; + auto remove(TreeNodeIndexType index) -> void; + + auto mark_dirty(TreeNodeIndexType index, TreeNodeDirtyBitType bits) -> void; + + auto operator[](TreeNodeIndexType index) noexcept -> TreeNodeType&; + auto operator[](TreeNodeIndexType index) const noexcept -> const TreeNodeType&; + + [[nodiscard]] + auto size() const noexcept -> usize; + + [[nodiscard]] + auto begin() noexcept; + [[nodiscard]] + auto begin() const noexcept; + [[nodiscard]] + auto cbegin() const noexcept; + + [[nodiscard]] + auto end() noexcept; + [[nodiscard]] + auto end() const noexcept; + [[nodiscard]] + auto cend() const noexcept; + + auto clear_dirties() noexcept -> void; + [[nodiscard]] + auto dirties() const noexcept -> std::span; + + auto gen_dot_file(stdfs::path filepath, FunctionRef colorize_node) const noexcept + -> io::Expected; + + auto gen_dot_file(stdfs::path filepath, + core::u32 highlight, + FunctionRef colorize_node) const noexcept -> io::Expected; + + private: + TreeNodeIndexType m_first_free_index = 0; + std::vector m_tree; + std::vector m_dirties; + }; +}} // namespace stormkit::core + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit { inline namespace core { + //////////////////////////////////////// + //////////////////////////////////////// + inline auto TreeNode::name() const noexcept -> const std::string& { + return m_name; + } + + //////////////////////////////////////// + //////////////////////////////////////// + inline auto TreeNode::set_name(std::string name) noexcept -> void { + m_name = std::move(name); + } + + //////////////////////////////////////// + //////////////////////////////////////// + inline auto TreeNode::parent() const noexcept -> TreeNode::IndexType { + return m_parent; + } + + //////////////////////////////////////// + //////////////////////////////////////// + inline auto TreeNode::set_parent(IndexType index) noexcept -> void { + m_parent = index; + } + + //////////////////////////////////////// + //////////////////////////////////////// + inline auto TreeNode::next_sibling() const noexcept -> TreeNode::IndexType { + return m_next_sibling; + } + + //////////////////////////////////////// + //////////////////////////////////////// + inline auto TreeNode::set_next_sibling(IndexType index) noexcept -> void { + m_next_sibling = index; + } + + //////////////////////////////////////// + //////////////////////////////////////// + inline auto TreeNode::first_child() const noexcept -> TreeNode::IndexType { + return m_first_child; + } + + //////////////////////////////////////// + //////////////////////////////////////// + inline auto TreeNode::set_first_child(IndexType index) noexcept -> void { + m_first_child = index; + } + + //////////////////////////////////////// + //////////////////////////////////////// + inline auto TreeNode::dirty_bits() const noexcept -> const TreeNode::DirtyBitType& { + return m_dirty_bits; + } + + //////////////////////////////////////// + //////////////////////////////////////// + inline auto TreeNode::set_dirty_bits(DirtyBitType bits) noexcept -> void { + m_dirty_bits = bits; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto TreeNode::invalidate() noexcept -> void { + m_parent = { INVALID_INDEX }; + m_next_sibling = { INVALID_INDEX }; + m_first_child = { INVALID_INDEX }; + m_dirty_bits = 0; + m_name = ""; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + Tree::Tree() { + m_tree.resize(DEFAULT_PREALLOCATED_TREE_SIZE); + + for (auto i : range(stdr::size(m_tree) - 1u)) m_tree[i].set_next_sibling(i + 1u); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + Tree::~Tree() = default; + + //////////////////////////////////////// + //////////////////////////////////////// + template + Tree::Tree(const Tree&) = default; + + //////////////////////////////////////// + //////////////////////////////////////// + template + Tree::Tree(Tree&&) = default; + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto Tree::operator=(const Tree&) -> Tree& = default; + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto Tree::operator=(Tree&&) -> Tree& = default; + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto Tree::get_free_node() -> TreeNodeIndexType { + if (m_tree[m_first_free_index].next_sibling() == TreeNode::INVALID_INDEX) { + const auto size = as(stdr::size(m_tree)); + const auto first_new = as(stdr::size(m_tree)); + + m_tree.resize(as(size * 1.5f)); + const auto new_size = stdr::size(m_tree); + + // generate a new chain of free objects, with the last one pointing to + // ~0 + m_tree[m_first_free_index].set_next_sibling(first_new); + for (auto i : range(first_new, new_size - 1u)) m_tree[i].set_next_sibling(i + 1u); + } + + auto index = m_first_free_index; + m_first_free_index = m_tree[m_first_free_index].next_sibling(); + + return index; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto Tree::insert(TreeNodeType&& node, TreeNodeIndexType parent_index, TreeNodeIndexType previous_sibling) + -> TreeNodeIndexType { + const auto index = get_free_node(); + + auto& _node = m_tree[index]; + _node = std::forward(node); + + _node.set_parent(parent_index); + + // check if parent is real node + if (parent_index != TreeNode::INVALID_INDEX) { + auto& parent_node = *(std::ranges::begin(m_tree) + parent_index); + + // new node is first child + if (parent_node.first_child() == TreeNode::INVALID_INDEX) parent_node.set_first_child(index); + else if (previous_sibling == TreeNode::INVALID_INDEX) { // insert a beginning of childs + _node.set_next_sibling(parent_node.first_child()); + parent_node.set_first_child(index); + } else { // insert at the end + auto& prev_sibling_node = m_tree[previous_sibling]; + _node.set_next_sibling(prev_sibling_node.next_sibling()); + prev_sibling_node.set_next_sibling(index); + } + } + + return index; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto Tree::remove(TreeNodeIndexType index) -> void { + auto& node = m_tree[index]; + + if (node.parent() != TreeNode::INVALID_INDEX) { + auto& parent = m_tree[node.parent()]; + + // Remove sibling + auto current_index = parent.first_child(); + while (current_index != TreeNode::INVALID_INDEX) { + auto& current_node = m_tree[current_index]; + + if (current_node.next_sibling() == index) { + current_node.set_next_sibling(node.next_sibling()); + break; + } + current_index = current_node.next_sibling(); + } + + // remove parent + if (parent.first_child() == index) parent.set_first_child(node.next_sibling()); + + node.set_parent(TreeNode::INVALID_INDEX); + } + + auto last_index = TreeNode::INVALID_INDEX; + auto queue = std::deque {}; + queue.emplace_back(index); + while (not queue.empty()) { + auto current_index = queue.front(); + auto& current_node = m_tree[current_index]; + queue.pop_front(); + + auto child_index = current_node.first_child(); + while (child_index != TreeNode::INVALID_INDEX) { + queue.emplace_back(child_index); + child_index = m_tree[child_index].next_sibling(); + } + + node.invalidate(); + + if (last_index != TreeNode::INVALID_INDEX) m_tree[last_index].set_next_sibling(current_index); + + last_index = current_index; + } + + m_tree[last_index].set_next_sibling(m_first_free_index); + m_first_free_index = index; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto Tree::mark_dirty(TreeNodeIndexType index, TreeNodeDirtyBitType bits) -> void { + auto& node = m_tree[index]; + if (not node.dirty_bits()) { + m_dirties.emplace_back(index); + node.set_dirty_bits(bits); + return; + } + + node.set_dirty_bits(bits); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto Tree::operator[](TreeNodeIndexType index) noexcept -> TreeNodeType& { + EXPECTS(index < stdr::size(m_tree)); + + return m_tree[index]; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto Tree::operator[](TreeNodeIndexType index) const noexcept -> const TreeNodeType& { + EXPECTS(index < stdr::size(m_tree)); + + return m_tree[index]; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto Tree::size() const noexcept -> usize { + return stdr::size(m_tree); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto Tree::begin() noexcept { + return std::ranges::begin(m_tree); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto Tree::begin() const noexcept { + return std::cbegin(m_tree); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto Tree::cbegin() const noexcept { + return std::cbegin(m_tree); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto Tree::end() noexcept { + return std::ranges::end(m_tree); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto Tree::end() const noexcept { + return std::cend(m_tree); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto Tree::cend() const noexcept { + return std::cend(m_tree); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto Tree::clear_dirties() noexcept -> void { + if (std::empty(m_dirties)) return; + + for (auto i : m_dirties) { m_tree[i].set_dirty_bits(0); } + + m_dirties.clear(); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto Tree::dirties() const noexcept -> std::span { + return m_dirties; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto Tree::gen_dot_file(stdfs::path filepath, + FunctionRef colorize_node) const noexcept + -> io::Expected { + using namespace stormkit::literals; + auto out = std::string {}; + out.reserve(1_kb); + + out += "digraph G { \n" + " rankdir = LR\n" + " bgcolor = black\n\n" + " node [shape=box, fontname=\"helvetica\", fontsize=12];\n\n"; + + for (auto i : range(m_first_free_index)) { + const auto name = operator[](i).name(); + const auto dirty = bool(operator[](i).dirty_bits()); + + out += std::format(" \"node{}\" [label=\"id: {} type: {} dirty: {} \", style=filled,color=\"{}\"];\n", + i, + i, + name, + dirty, + colorize_node(name)); + } + + for (auto i : range(m_first_free_index)) { + if (operator[](i).first_child() == TreeNodeClass::INVALID_INDEX) continue; + + for (auto current = operator[](i).first_child(); current != TreeNodeClass::INVALID_INDEX; + current = operator[](current).next_sibling()) { + out += std::format(" \"node{}\" -> \"node{}\" [color=seagreen] ;\n", i, current); + } + } + + out += "}"; + + return io::write_text(filepath, out); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto Tree::gen_dot_file(stdfs::path filepath, + core::u32 highlight, + FunctionRef colorize_node) const noexcept + -> io::Expected { + using namespace stormkit::literals; + auto out = std::string {}; + out.reserve(1_kb); + + out += "digraph G { \n" + " rankdir = LR\n" + " bgcolor = black\n\n" + " node [shape=box, fontname=\"helvetica\", fontsize=12];\n\n"; + + for (auto i : range(m_first_free_index)) { + const auto name = operator[](i).name(); + const auto dirty = bool(operator[](i).dirty_bits()); + if (i != highlight) + out += std::format(" \"node{}\" [label=\"id: {} type: {} dirty: {} \", style=filled,color=\"{}\"];\n", + i, + i, + name, + dirty, + colorize_node(name)); + else + out += std::format(" \"node{}\" [shape = polygon,sides=5,peripheries=3, label=\"id: {} type: {} dirty: {} \", " + "style=filled,color=\"{}\"];\n", + i, + i, + name, + dirty, + colorize_node(name)); + } + + for (auto i : range(m_first_free_index)) { + if (operator[](i).first_child() == TreeNodeClass::INVALID_INDEX) continue; + + for (auto current = operator[](i).first_child(); current != TreeNodeClass::INVALID_INDEX; + current = operator[](current).next_sibling()) { + out += std::format(" \"node{}\" -> \"node{}\" [color=seagreen] ;\n", i, current); + } + } + + out += "}"; + + return io::write_text(filepath, out); + } +}} // namespace stormkit::core diff --git a/modules/stormkit/core/containers/utils.mpp b/modules/stormkit/core/containers/utils.cppm similarity index 100% rename from modules/stormkit/core/containers/utils.mpp rename to modules/stormkit/core/containers/utils.cppm diff --git a/modules/stormkit/core/coroutines.mpp b/modules/stormkit/core/coroutines.cppm similarity index 97% rename from modules/stormkit/core/coroutines.mpp rename to modules/stormkit/core/coroutines.cppm index cfdf6b380..653d6931e 100644 --- a/modules/stormkit/core/coroutines.mpp +++ b/modules/stormkit/core/coroutines.cppm @@ -1,557 +1,557 @@ -module; - -#include -#include - -#include - -export module stormkit.core:coroutines; - -export import std; - -#if not defined(__cpp_lib_generator) or __cpp_lib_generator < 202207L -export namespace std { - struct use_allocator_arg {}; - - template, typename _Alloc = use_allocator_arg> - class generator; - - template - class __manual_lifetime { - public: - __manual_lifetime() noexcept {} - - ~__manual_lifetime() {} - - template - _T& construct(_Args&&... __args) noexcept(is_nothrow_constructible_v<_T, _Args...>) { - return *::new (static_cast(addressof(__value_))) _T((_Args&&)__args...); - } - - void destruct() noexcept(is_nothrow_destructible_v<_T>) { __value_.~_T(); } - - _T& get() & noexcept { return __value_; } - - _T&& get() && noexcept { return static_cast<_T&&>(__value_); } - - const _T& get() const & noexcept { return __value_; } - - const _T&& get() const && noexcept { return static_cast(__value_); } - - private: - union { - remove_const_t<_T> __value_; - }; - }; - - template - class __manual_lifetime<_T&> { - public: - __manual_lifetime() noexcept : __value_(nullptr) {} - - ~__manual_lifetime() {} - - _T& construct(_T& __value) noexcept { - __value_ = addressof(__value); - return __value; - } - - void destruct() noexcept {} - - _T& get() const noexcept { return *__value_; } - - private: - _T* __value_; - }; - - template - class __manual_lifetime<_T&&> { - public: - __manual_lifetime() noexcept : __value_(nullptr) {} - - ~__manual_lifetime() {} - - _T&& construct(_T&& __value) noexcept { - __value_ = addressof(__value); - return static_cast<_T&&>(__value); - } - - void destruct() noexcept {} - - _T&& get() const noexcept { return static_cast<_T&&>(*__value_); } - - private: - _T* __value_; - }; - - template - inline constexpr bool __allocator_needs_to_be_stored = !allocator_traits<_Alloc>::is_always_equal::value - || !is_default_constructible_v<_Alloc>; - - // Round s up to next multiple of a. - constexpr size_t __aligned_allocation_size(size_t s, size_t a) { - return (s + a - 1) & ~(a - 1); - } - - template - class __promise_base_alloc { - static constexpr size_t __offset_of_allocator(size_t __frameSize) noexcept { - return __aligned_allocation_size(__frameSize, alignof(_Alloc)); - } - - static constexpr size_t __padded_frame_size(size_t __frameSize) noexcept { - return __offset_of_allocator(__frameSize) + sizeof(_Alloc); - } - - static _Alloc& __get_allocator(void* __frame, size_t __frameSize) noexcept { - return *reinterpret_cast<_Alloc*>(static_cast(__frame) + __offset_of_allocator(__frameSize)); - } - - public: - template - static void* operator new(size_t __frameSize, allocator_arg_t, _Alloc __alloc, _Args&...) { - void* __frame = __alloc.allocate(__padded_frame_size(__frameSize)); - - // Store allocator at end of the coroutine frame. - // Assuming the allocator's move constructor is non-throwing (a requirement for - // allocators) - ::new (static_cast(addressof(__get_allocator(__frame, __frameSize)))) _Alloc(move(__alloc)); - - return __frame; - } - - template - static void* operator new(size_t __frameSize, _This&, allocator_arg_t, _Alloc __alloc, _Args&...) { - return __promise_base_alloc::operator new(__frameSize, allocator_arg, move(__alloc)); - } - - static void operator delete(void* __ptr, size_t __frameSize) noexcept { - _Alloc& __alloc = __get_allocator(__ptr, __frameSize); - _Alloc __localAlloc(move(__alloc)); - __alloc.~Alloc(); - __localAlloc.deallocate(static_cast(__ptr), __padded_frame_size(__frameSize)); - } - }; - - template - requires(!__allocator_needs_to_be_stored<_Alloc>) - class __promise_base_alloc<_Alloc> { - public: - static void* operator new(size_t __size) { - _Alloc __alloc; - return __alloc.allocate(__size); - } - - static void operator delete(void* __ptr, size_t __size) noexcept { - _Alloc __alloc; - __alloc.deallocate(static_cast(__ptr), __size); - } - }; - - template - struct __generator_promise_base { - template - friend class generator; - - __generator_promise_base* __root_; - coroutine_handle<> __parentOrLeaf_; - // Note: Using manual_lifetime here to avoid extra calls to exception_ptr - // constructor/destructor in cases where it is not needed (i.e. where this - // generator coroutine is not used as a nested coroutine). - // This member is lazily constructed by the __yield_sequence_awaiter::await_suspend() - // method if this generator is used as a nested generator. - __manual_lifetime __exception_; - __manual_lifetime<_Ref> __value_; - - explicit __generator_promise_base(coroutine_handle<> thisCoro) noexcept : __root_(this), __parentOrLeaf_(thisCoro) {} - - ~__generator_promise_base() { - if (__root_ != this) { - // This coroutine was used as a nested generator and so will - // have constructed its __exception_ member which needs to be - // destroyed here. - __exception_.destruct(); - } - } - - suspend_always initial_suspend() noexcept { return {}; } - - void return_void() noexcept {} - - void unhandled_exception() { - if (__root_ != this) { - __exception_.get() = current_exception(); - } else { - throw; - } - } - - // Transfers control back to the parent of a nested coroutine - struct __final_awaiter { - bool await_ready() noexcept { return false; } - - template - coroutine_handle<> await_suspend(coroutine_handle<_Promise> __h) noexcept { - _Promise& __promise = __h.promise(); - __generator_promise_base& __root = *__promise.__root_; - if (&__root != &__promise) { - auto __parent = __promise.__parentOrLeaf_; - __root.__parentOrLeaf_ = __parent; - return __parent; - } - return noop_coroutine(); - } - - void await_resume() noexcept {} - }; - - __final_awaiter final_suspend() noexcept { return {}; } - - suspend_always yield_value(_Ref&& __x) noexcept(is_nothrow_move_constructible_v<_Ref>) { - __root_->__value_.construct((_Ref&&)__x); - return {}; - } - - template - requires(!is_reference_v<_Ref>) && is_convertible_v<_T, _Ref> - suspend_always yield_value(_T&& __x) noexcept(is_nothrow_constructible_v<_Ref, _T>) { - __root_->__value_.construct((_T&&)__x); - return {}; - } - - template - struct __yield_sequence_awaiter { - _Gen __gen_; - - __yield_sequence_awaiter(_Gen&& __g) noexcept - // Taking ownership of the generator ensures frame are destroyed - // in the reverse order of their execution. - : __gen_((_Gen&&)__g) {} - - bool await_ready() noexcept { return false; } - - // set the parent, root and exceptions pointer and - // resume the nested - template - coroutine_handle<> await_suspend(coroutine_handle<_Promise> __h) noexcept { - __generator_promise_base& __current = __h.promise(); - __generator_promise_base& __nested = *__gen_.__get_promise(); - __generator_promise_base& __root = *__current.__root_; - - __nested.__root_ = __current.__root_; - __nested.__parentOrLeaf_ = __h; - - // Lazily construct the __exception_ member here now that we - // know it will be used as a nested generator. This will be - // destroyed by the promise destructor. - __nested.__exception_.construct(); - __root.__parentOrLeaf_ = __gen_.__get_coro(); - - // Immediately resume the nested coroutine (nested generator) - return __gen_.__get_coro(); - } - - void await_resume() { - __generator_promise_base& __nestedPromise = *__gen_.__get_promise(); - if (__nestedPromise.__exception_.get()) { rethrow_exception(std::move(__nestedPromise.__exception_.get())); } - } - }; - - template - __yield_sequence_awaiter> yield_value(ranges::elements_of< - generator<_Ref, _OValue, _OAlloc>> __g) noexcept { - return move(__g).get(); - } - - template - __yield_sequence_awaiter, _Allocator>> yield_value(ranges::elements_of<_Rng, - _Allocator>&& - __x) { - return [](allocator_arg_t, - [[maybe_unused]] - _Allocator alloc, - auto&& __rng) -> generator<_Ref, remove_cvref_t<_Ref>, _Allocator> { - for (auto&& e : __rng) co_yield static_cast(e); - }(allocator_arg, __x.get_allocator(), forward<_Rng>(__x.get())); - } - - void resume() { __parentOrLeaf_.resume(); } - - // Disable use of co_await within this coroutine. - void await_transform() = delete; - }; - - template - struct __generator_promise; - - template - struct __generator_promise, _ByteAllocator, _ExplicitAllocator> final - : public __generator_promise_base<_Ref>, - public __promise_base_alloc<_ByteAllocator> { - __generator_promise() noexcept - : __generator_promise_base<_Ref>(coroutine_handle<__generator_promise>::from_promise(*this)) {} - - generator<_Ref, _Value, _Alloc> get_return_object() noexcept { - return generator<_Ref, _Value, _Alloc> { coroutine_handle<__generator_promise>::from_promise(*this) }; - } - - using __generator_promise_base<_Ref>::yield_value; - - template - typename __generator_promise_base<_Ref>::template __yield_sequence_awaiter> - yield_value(ranges::elements_of<_Rng>&& __x) { - static_assert(!_ExplicitAllocator, - "This coroutine has an explicit allocator specified with " - "allocator_arg so an allocator needs to be passed " - "explicitely to elements_of"); - return [](auto&& __rng) -> generator<_Ref, _Value, _Alloc> { - for (auto&& e : __rng) co_yield static_cast(e); - }(forward<_Rng>(__x.get())); - } - }; - - template - using __byte_allocator_t = typename allocator_traits>::template rebind_alloc; - - // Type-erased allocator with default allocator behaviour. - template - struct coroutine_traits, _Args...> { - using promise_type = __generator_promise, allocator>; - }; - - // Type-erased allocator with allocator_arg parameter - template - struct coroutine_traits, allocator_arg_t, _Alloc, _Args...> { - private: - using __byte_allocator = __byte_allocator_t<_Alloc>; - - public: - using promise_type = __generator_promise, __byte_allocator, true /*explicit Allocator*/>; - }; - - // Type-erased allocator with allocator_arg parameter (non-static member functions) - template - struct coroutine_traits, _This, allocator_arg_t, _Alloc, _Args...> { - private: - using __byte_allocator = __byte_allocator_t<_Alloc>; - - public: - using promise_type = __generator_promise, __byte_allocator, true /*explicit Allocator*/>; - }; - - // Generator with specified allocator type - template - struct coroutine_traits, _Args...> { - using __byte_allocator = __byte_allocator_t<_Alloc>; - - public: - using promise_type = __generator_promise, __byte_allocator>; - }; - - // TODO : make layout compatible promise casts possible - template - class generator { - using __byte_allocator = __byte_allocator_t<_Alloc>; - - public: - using promise_type = __generator_promise, __byte_allocator>; - friend promise_type; - - private: - using __coroutine_handle = coroutine_handle; - - public: - generator() noexcept = default; - - generator(generator&& __other) noexcept - : __coro_(exchange(__other.__coro_, {})), __started_(exchange(__other.__started_, false)) {} - - ~generator() noexcept { - if (__coro_) { - if (__started_ && !__coro_.done()) { __coro_.promise().__value_.destruct(); } - __coro_.destroy(); - } - } - - generator& operator=(generator&& g) noexcept { - swap(g); - return *this; - } - - void swap(generator& __other) noexcept { - swap(__coro_, __other.__coro_); - swap(__started_, __other.__started_); - } - - struct sentinel {}; - - class iterator { - public: - using iterator_category = input_iterator_tag; - using difference_type = ptrdiff_t; - using value_type = _Value; - using reference = _Ref; - using pointer = add_pointer_t<_Ref>; - - iterator() noexcept = default; - iterator(const iterator&) = delete; - - iterator(iterator&& __other) noexcept : __coro_(exchange(__other.__coro_, {})) {} - - iterator& operator=(iterator&& __other) { - std::swap(__coro_, __other.__coro_); - return *this; - } - - ~iterator() {} - - friend bool operator==(const iterator& it, sentinel) noexcept { return it.__coro_.done(); } - - iterator& operator++() { - __coro_.promise().__value_.destruct(); - __coro_.promise().resume(); - return *this; - } - - void operator++(int) { (void)operator++(); } - - reference operator*() const noexcept { return static_cast(__coro_.promise().__value_.get()); } - - private: - friend generator; - - explicit iterator(__coroutine_handle __coro) noexcept : __coro_(__coro) {} - - __coroutine_handle __coro_; - }; - - iterator begin() { - assert(__coro_); - assert(!__started_); - __started_ = true; - __coro_.resume(); - return iterator { __coro_ }; - } - - sentinel end() noexcept { return {}; } - - private: - explicit generator(__coroutine_handle __coro) noexcept : __coro_(__coro) {} - - public: // to get around access restrictions for __yield_sequence_awaitable - coroutine_handle<> __get_coro() noexcept { return __coro_; } - - promise_type* __get_promise() noexcept { return addressof(__coro_.promise()); } - - private: - __coroutine_handle __coro_; - bool __started_ = false; - }; - - // Specialisation for type-erased allocator implementation. - template - class generator<_Ref, _Value, use_allocator_arg> { - using __promise_base = __generator_promise_base<_Ref>; - - public: - generator() noexcept : __promise_(nullptr), __coro_(), __started_(false) {} - - generator(generator&& __other) noexcept - : __promise_(exchange(__other.__promise_, nullptr)), - __coro_(exchange(__other.__coro_, {})), - __started_(exchange(__other.__started_, false)) {} - - ~generator() noexcept { - if (__coro_) { - if (__started_ && !__coro_.done()) { __promise_->__value_.destruct(); } - __coro_.destroy(); - } - } - - generator& operator=(generator g) noexcept { - swap(g); - return *this; - } - - void swap(generator& __other) noexcept { - swap(__promise_, __other.__promise_); - swap(__coro_, __other.__coro_); - swap(__started_, __other.__started_); - } - - struct sentinel {}; - - class iterator { - public: - using iterator_category = input_iterator_tag; - using difference_type = ptrdiff_t; - using value_type = _Value; - using reference = _Ref; - using pointer = add_pointer_t<_Ref>; - - iterator() noexcept = default; - iterator(const iterator&) = delete; - - iterator(iterator&& __other) noexcept - : __promise_(exchange(__other.__promise_, nullptr)), __coro_(exchange(__other.__coro_, {})) {} - - iterator& operator=(iterator&& __other) { - __promise_ = exchange(__other.__promise_, nullptr); - __coro_ = exchange(__other.__coro_, {}); - return *this; - } - - ~iterator() = default; - - friend bool operator==(const iterator& it, sentinel) noexcept { return it.__coro_.done(); } - - iterator& operator++() { - __promise_->__value_.destruct(); - __promise_->resume(); - return *this; - } - - void operator++(int) { (void)operator++(); } - - reference operator*() const noexcept { return static_cast(__promise_->__value_.get()); } - - private: - friend generator; - - explicit iterator(__promise_base* __promise, coroutine_handle<> __coro) noexcept - : __promise_(__promise), __coro_(__coro) {} - - __promise_base* __promise_; - coroutine_handle<> __coro_; - }; - - iterator begin() { - assert(__coro_); - assert(!__started_); - __started_ = true; - __coro_.resume(); - return iterator { __promise_, __coro_ }; - } - - sentinel end() noexcept { return {}; } - - private: - template - friend struct __generator_promise; - - template - explicit generator(coroutine_handle<_Promise> __coro) noexcept - : __promise_(addressof(__coro.promise())), __coro_(__coro) {} - - public: // to get around access restrictions for __yield_sequence_awaitable - coroutine_handle<> __get_coro() noexcept { return __coro_; } - - __promise_base* __get_promise() noexcept { return __promise_; } - - private: - __promise_base* __promise_; - coroutine_handle<> __coro_; - bool __started_ = false; - }; -} // namespace std -#endif +module; + +#include +#include + +#include + +export module stormkit.core:coroutines; + +export import std; + +#if not defined(__cpp_lib_generator) or __cpp_lib_generator < 202207L +export namespace std { + struct use_allocator_arg {}; + + template, typename _Alloc = use_allocator_arg> + class generator; + + template + class __manual_lifetime { + public: + __manual_lifetime() noexcept {} + + ~__manual_lifetime() {} + + template + _T& construct(_Args&&... __args) noexcept(is_nothrow_constructible_v<_T, _Args...>) { + return *::new (static_cast(addressof(__value_))) _T((_Args&&)__args...); + } + + void destruct() noexcept(is_nothrow_destructible_v<_T>) { __value_.~_T(); } + + _T& get() & noexcept { return __value_; } + + _T&& get() && noexcept { return static_cast<_T&&>(__value_); } + + const _T& get() const & noexcept { return __value_; } + + const _T&& get() const && noexcept { return static_cast(__value_); } + + private: + union { + remove_const_t<_T> __value_; + }; + }; + + template + class __manual_lifetime<_T&> { + public: + __manual_lifetime() noexcept : __value_(nullptr) {} + + ~__manual_lifetime() {} + + _T& construct(_T& __value) noexcept { + __value_ = addressof(__value); + return __value; + } + + void destruct() noexcept {} + + _T& get() const noexcept { return *__value_; } + + private: + _T* __value_; + }; + + template + class __manual_lifetime<_T&&> { + public: + __manual_lifetime() noexcept : __value_(nullptr) {} + + ~__manual_lifetime() {} + + _T&& construct(_T&& __value) noexcept { + __value_ = addressof(__value); + return static_cast<_T&&>(__value); + } + + void destruct() noexcept {} + + _T&& get() const noexcept { return static_cast<_T&&>(*__value_); } + + private: + _T* __value_; + }; + + template + inline constexpr bool __allocator_needs_to_be_stored = !allocator_traits<_Alloc>::is_always_equal::value + || !is_default_constructible_v<_Alloc>; + + // Round s up to next multiple of a. + constexpr size_t __aligned_allocation_size(size_t s, size_t a) { + return (s + a - 1) & ~(a - 1); + } + + template + class __promise_base_alloc { + static constexpr size_t __offset_of_allocator(size_t __frameSize) noexcept { + return __aligned_allocation_size(__frameSize, alignof(_Alloc)); + } + + static constexpr size_t __padded_frame_size(size_t __frameSize) noexcept { + return __offset_of_allocator(__frameSize) + sizeof(_Alloc); + } + + static _Alloc& __get_allocator(void* __frame, size_t __frameSize) noexcept { + return *reinterpret_cast<_Alloc*>(static_cast(__frame) + __offset_of_allocator(__frameSize)); + } + + public: + template + static void* operator new(size_t __frameSize, allocator_arg_t, _Alloc __alloc, _Args&...) { + void* __frame = __alloc.allocate(__padded_frame_size(__frameSize)); + + // Store allocator at end of the coroutine frame. + // Assuming the allocator's move constructor is non-throwing (a requirement for + // allocators) + ::new (static_cast(addressof(__get_allocator(__frame, __frameSize)))) _Alloc(move(__alloc)); + + return __frame; + } + + template + static void* operator new(size_t __frameSize, _This&, allocator_arg_t, _Alloc __alloc, _Args&...) { + return __promise_base_alloc::operator new(__frameSize, allocator_arg, move(__alloc)); + } + + static void operator delete(void* __ptr, size_t __frameSize) noexcept { + _Alloc& __alloc = __get_allocator(__ptr, __frameSize); + _Alloc __localAlloc(move(__alloc)); + __alloc.~Alloc(); + __localAlloc.deallocate(static_cast(__ptr), __padded_frame_size(__frameSize)); + } + }; + + template + requires(!__allocator_needs_to_be_stored<_Alloc>) + class __promise_base_alloc<_Alloc> { + public: + static void* operator new(size_t __size) { + _Alloc __alloc; + return __alloc.allocate(__size); + } + + static void operator delete(void* __ptr, size_t __size) noexcept { + _Alloc __alloc; + __alloc.deallocate(static_cast(__ptr), __size); + } + }; + + template + struct __generator_promise_base { + template + friend class generator; + + __generator_promise_base* __root_; + coroutine_handle<> __parentOrLeaf_; + // Note: Using manual_lifetime here to avoid extra calls to exception_ptr + // constructor/destructor in cases where it is not needed (i.e. where this + // generator coroutine is not used as a nested coroutine). + // This member is lazily constructed by the __yield_sequence_awaiter::await_suspend() + // method if this generator is used as a nested generator. + __manual_lifetime __exception_; + __manual_lifetime<_Ref> __value_; + + explicit __generator_promise_base(coroutine_handle<> thisCoro) noexcept : __root_(this), __parentOrLeaf_(thisCoro) {} + + ~__generator_promise_base() { + if (__root_ != this) { + // This coroutine was used as a nested generator and so will + // have constructed its __exception_ member which needs to be + // destroyed here. + __exception_.destruct(); + } + } + + suspend_always initial_suspend() noexcept { return {}; } + + void return_void() noexcept {} + + void unhandled_exception() { + if (__root_ != this) { + __exception_.get() = current_exception(); + } else { + throw; + } + } + + // Transfers control back to the parent of a nested coroutine + struct __final_awaiter { + bool await_ready() noexcept { return false; } + + template + coroutine_handle<> await_suspend(coroutine_handle<_Promise> __h) noexcept { + _Promise& __promise = __h.promise(); + __generator_promise_base& __root = *__promise.__root_; + if (&__root != &__promise) { + auto __parent = __promise.__parentOrLeaf_; + __root.__parentOrLeaf_ = __parent; + return __parent; + } + return noop_coroutine(); + } + + void await_resume() noexcept {} + }; + + __final_awaiter final_suspend() noexcept { return {}; } + + suspend_always yield_value(_Ref&& __x) noexcept(is_nothrow_move_constructible_v<_Ref>) { + __root_->__value_.construct((_Ref&&)__x); + return {}; + } + + template + requires(!is_reference_v<_Ref>) && is_convertible_v<_T, _Ref> + suspend_always yield_value(_T&& __x) noexcept(is_nothrow_constructible_v<_Ref, _T>) { + __root_->__value_.construct((_T&&)__x); + return {}; + } + + template + struct __yield_sequence_awaiter { + _Gen __gen_; + + __yield_sequence_awaiter(_Gen&& __g) noexcept + // Taking ownership of the generator ensures frame are destroyed + // in the reverse order of their execution. + : __gen_((_Gen&&)__g) {} + + bool await_ready() noexcept { return false; } + + // set the parent, root and exceptions pointer and + // resume the nested + template + coroutine_handle<> await_suspend(coroutine_handle<_Promise> __h) noexcept { + __generator_promise_base& __current = __h.promise(); + __generator_promise_base& __nested = *__gen_.__get_promise(); + __generator_promise_base& __root = *__current.__root_; + + __nested.__root_ = __current.__root_; + __nested.__parentOrLeaf_ = __h; + + // Lazily construct the __exception_ member here now that we + // know it will be used as a nested generator. This will be + // destroyed by the promise destructor. + __nested.__exception_.construct(); + __root.__parentOrLeaf_ = __gen_.__get_coro(); + + // Immediately resume the nested coroutine (nested generator) + return __gen_.__get_coro(); + } + + void await_resume() { + __generator_promise_base& __nestedPromise = *__gen_.__get_promise(); + if (__nestedPromise.__exception_.get()) { rethrow_exception(std::move(__nestedPromise.__exception_.get())); } + } + }; + + template + __yield_sequence_awaiter> yield_value(ranges::elements_of< + generator<_Ref, _OValue, _OAlloc>> __g) noexcept { + return move(__g).get(); + } + + template + __yield_sequence_awaiter, _Allocator>> yield_value(ranges::elements_of<_Rng, + _Allocator>&& + __x) { + return [](allocator_arg_t, + [[maybe_unused]] + _Allocator alloc, + auto&& __rng) -> generator<_Ref, remove_cvref_t<_Ref>, _Allocator> { + for (auto&& e : __rng) co_yield static_cast(e); + }(allocator_arg, __x.get_allocator(), forward<_Rng>(__x.get())); + } + + void resume() { __parentOrLeaf_.resume(); } + + // Disable use of co_await within this coroutine. + void await_transform() = delete; + }; + + template + struct __generator_promise; + + template + struct __generator_promise, _ByteAllocator, _ExplicitAllocator> final + : public __generator_promise_base<_Ref>, + public __promise_base_alloc<_ByteAllocator> { + __generator_promise() noexcept + : __generator_promise_base<_Ref>(coroutine_handle<__generator_promise>::from_promise(*this)) {} + + generator<_Ref, _Value, _Alloc> get_return_object() noexcept { + return generator<_Ref, _Value, _Alloc> { coroutine_handle<__generator_promise>::from_promise(*this) }; + } + + using __generator_promise_base<_Ref>::yield_value; + + template + typename __generator_promise_base<_Ref>::template __yield_sequence_awaiter> + yield_value(ranges::elements_of<_Rng>&& __x) { + static_assert(!_ExplicitAllocator, + "This coroutine has an explicit allocator specified with " + "allocator_arg so an allocator needs to be passed " + "explicitely to elements_of"); + return [](auto&& __rng) -> generator<_Ref, _Value, _Alloc> { + for (auto&& e : __rng) co_yield static_cast(e); + }(forward<_Rng>(__x.get())); + } + }; + + template + using __byte_allocator_t = typename allocator_traits>::template rebind_alloc; + + // Type-erased allocator with default allocator behaviour. + template + struct coroutine_traits, _Args...> { + using promise_type = __generator_promise, allocator>; + }; + + // Type-erased allocator with allocator_arg parameter + template + struct coroutine_traits, allocator_arg_t, _Alloc, _Args...> { + private: + using __byte_allocator = __byte_allocator_t<_Alloc>; + + public: + using promise_type = __generator_promise, __byte_allocator, true /*explicit Allocator*/>; + }; + + // Type-erased allocator with allocator_arg parameter (non-static member functions) + template + struct coroutine_traits, _This, allocator_arg_t, _Alloc, _Args...> { + private: + using __byte_allocator = __byte_allocator_t<_Alloc>; + + public: + using promise_type = __generator_promise, __byte_allocator, true /*explicit Allocator*/>; + }; + + // Generator with specified allocator type + template + struct coroutine_traits, _Args...> { + using __byte_allocator = __byte_allocator_t<_Alloc>; + + public: + using promise_type = __generator_promise, __byte_allocator>; + }; + + // TODO : make layout compatible promise casts possible + template + class generator { + using __byte_allocator = __byte_allocator_t<_Alloc>; + + public: + using promise_type = __generator_promise, __byte_allocator>; + friend promise_type; + + private: + using __coroutine_handle = coroutine_handle; + + public: + generator() noexcept = default; + + generator(generator&& __other) noexcept + : __coro_(exchange(__other.__coro_, {})), __started_(exchange(__other.__started_, false)) {} + + ~generator() noexcept { + if (__coro_) { + if (__started_ && !__coro_.done()) { __coro_.promise().__value_.destruct(); } + __coro_.destroy(); + } + } + + generator& operator=(generator&& g) noexcept { + swap(g); + return *this; + } + + void swap(generator& __other) noexcept { + swap(__coro_, __other.__coro_); + swap(__started_, __other.__started_); + } + + struct sentinel {}; + + class iterator { + public: + using iterator_category = input_iterator_tag; + using difference_type = ptrdiff_t; + using value_type = _Value; + using reference = _Ref; + using pointer = add_pointer_t<_Ref>; + + iterator() noexcept = default; + iterator(const iterator&) = delete; + + iterator(iterator&& __other) noexcept : __coro_(exchange(__other.__coro_, {})) {} + + iterator& operator=(iterator&& __other) { + std::swap(__coro_, __other.__coro_); + return *this; + } + + ~iterator() {} + + friend bool operator==(const iterator& it, sentinel) noexcept { return it.__coro_.done(); } + + iterator& operator++() { + __coro_.promise().__value_.destruct(); + __coro_.promise().resume(); + return *this; + } + + void operator++(int) { (void)operator++(); } + + reference operator*() const noexcept { return static_cast(__coro_.promise().__value_.get()); } + + private: + friend generator; + + explicit iterator(__coroutine_handle __coro) noexcept : __coro_(__coro) {} + + __coroutine_handle __coro_; + }; + + iterator begin() { + assert(__coro_); + assert(!__started_); + __started_ = true; + __coro_.resume(); + return iterator { __coro_ }; + } + + sentinel end() noexcept { return {}; } + + private: + explicit generator(__coroutine_handle __coro) noexcept : __coro_(__coro) {} + + public: // to get around access restrictions for __yield_sequence_awaitable + coroutine_handle<> __get_coro() noexcept { return __coro_; } + + promise_type* __get_promise() noexcept { return addressof(__coro_.promise()); } + + private: + __coroutine_handle __coro_; + bool __started_ = false; + }; + + // Specialisation for type-erased allocator implementation. + template + class generator<_Ref, _Value, use_allocator_arg> { + using __promise_base = __generator_promise_base<_Ref>; + + public: + generator() noexcept : __promise_(nullptr), __coro_(), __started_(false) {} + + generator(generator&& __other) noexcept + : __promise_(exchange(__other.__promise_, nullptr)), + __coro_(exchange(__other.__coro_, {})), + __started_(exchange(__other.__started_, false)) {} + + ~generator() noexcept { + if (__coro_) { + if (__started_ && !__coro_.done()) { __promise_->__value_.destruct(); } + __coro_.destroy(); + } + } + + generator& operator=(generator g) noexcept { + swap(g); + return *this; + } + + void swap(generator& __other) noexcept { + swap(__promise_, __other.__promise_); + swap(__coro_, __other.__coro_); + swap(__started_, __other.__started_); + } + + struct sentinel {}; + + class iterator { + public: + using iterator_category = input_iterator_tag; + using difference_type = ptrdiff_t; + using value_type = _Value; + using reference = _Ref; + using pointer = add_pointer_t<_Ref>; + + iterator() noexcept = default; + iterator(const iterator&) = delete; + + iterator(iterator&& __other) noexcept + : __promise_(exchange(__other.__promise_, nullptr)), __coro_(exchange(__other.__coro_, {})) {} + + iterator& operator=(iterator&& __other) { + __promise_ = exchange(__other.__promise_, nullptr); + __coro_ = exchange(__other.__coro_, {}); + return *this; + } + + ~iterator() = default; + + friend bool operator==(const iterator& it, sentinel) noexcept { return it.__coro_.done(); } + + iterator& operator++() { + __promise_->__value_.destruct(); + __promise_->resume(); + return *this; + } + + void operator++(int) { (void)operator++(); } + + reference operator*() const noexcept { return static_cast(__promise_->__value_.get()); } + + private: + friend generator; + + explicit iterator(__promise_base* __promise, coroutine_handle<> __coro) noexcept + : __promise_(__promise), __coro_(__coro) {} + + __promise_base* __promise_; + coroutine_handle<> __coro_; + }; + + iterator begin() { + assert(__coro_); + assert(!__started_); + __started_ = true; + __coro_.resume(); + return iterator { __promise_, __coro_ }; + } + + sentinel end() noexcept { return {}; } + + private: + template + friend struct __generator_promise; + + template + explicit generator(coroutine_handle<_Promise> __coro) noexcept + : __promise_(addressof(__coro.promise())), __coro_(__coro) {} + + public: // to get around access restrictions for __yield_sequence_awaitable + coroutine_handle<> __get_coro() noexcept { return __coro_; } + + __promise_base* __get_promise() noexcept { return __promise_; } + + private: + __promise_base* __promise_; + coroutine_handle<> __coro_; + bool __started_ = false; + }; +} // namespace std +#endif diff --git a/modules/stormkit/core/errors.mpp b/modules/stormkit/core/errors.cppm similarity index 100% rename from modules/stormkit/core/errors.mpp rename to modules/stormkit/core/errors.cppm diff --git a/modules/stormkit/core/functional.mpp b/modules/stormkit/core/functional.cppm similarity index 100% rename from modules/stormkit/core/functional.mpp rename to modules/stormkit/core/functional.cppm diff --git a/modules/stormkit/core/functional/error_handling.mpp b/modules/stormkit/core/functional/error_handling.cppm similarity index 100% rename from modules/stormkit/core/functional/error_handling.mpp rename to modules/stormkit/core/functional/error_handling.cppm diff --git a/modules/stormkit/core/functional/monadic.mpp b/modules/stormkit/core/functional/monadic.cppm similarity index 100% rename from modules/stormkit/core/functional/monadic.mpp rename to modules/stormkit/core/functional/monadic.cppm diff --git a/modules/stormkit/core/functional/utils.mpp b/modules/stormkit/core/functional/utils.cppm similarity index 97% rename from modules/stormkit/core/functional/utils.mpp rename to modules/stormkit/core/functional/utils.cppm index 0c2084cb0..1987426ea 100644 --- a/modules/stormkit/core/functional/utils.mpp +++ b/modules/stormkit/core/functional/utils.cppm @@ -1,121 +1,121 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -export module stormkit.core:functional.utils; - -import std; - -import :meta; - -namespace stormkit { inline namespace core { namespace details { - struct EitherFunc { - [[nodiscard]] - static constexpr auto operator()(bool condition, std::invocable auto&& true_, std::invocable auto&& false_) noexcept - -> decltype(false_()); - - template - using ForwardArg = meta::ForwardLike>>; - - template - [[nodiscard]] - static constexpr auto operator()(T value, - std::invocable&> auto&& true_, - std::invocable auto&& false_) noexcept -> decltype(false_()); - - template - requires(meta::IsConvertibleTo) - [[nodiscard]] - static constexpr auto operator()(T&& value, - std::invocable> auto&& true_, - std::invocable auto&& false_) noexcept -> decltype(false_()); - }; -}}} // namespace stormkit::core::details - -export namespace stormkit { inline namespace core { - inline constexpr auto either = details::EitherFunc {}; - - using std::bind_back; - using std::bind_front; - - template - requires(std::invocable and meta::Is, void>) - [[nodiscard]] - constexpr auto init_by(Func&& func, Args&&... args) noexcept -> T; -}} // namespace stormkit::core - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit { inline namespace core { - namespace details { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - constexpr auto EitherFunc::operator()(bool condition, std::invocable auto&& true_, std::invocable auto&& false_) noexcept - -> decltype(false_()) { - if (condition) return true_(); - return false_(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto EitherFunc::operator()(T value, - std::invocable&> auto&& true_, - std::invocable auto&& false_) noexcept -> decltype(false_()) { - if (static_cast(value)) return true_(*value); - return false_(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - requires(meta::IsConvertibleTo) - STORMKIT_FORCE_INLINE - constexpr auto EitherFunc::operator()(T&& value, - std::invocable> auto&& true_, - std::invocable auto&& false_) noexcept -> decltype(false_()) { - if (static_cast(value)) return true_(std::forward_like(*value)); - return false_(); - } - } // namespace details - -#if not(defined(__cpp_lib_bind_back) and __cpp_lib_bind_back >= 202306L) - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto bind_back(Args&&... args) noexcept -> decltype(auto) { - return std::bind_back(std::forward(args)...); - using FuncType = decltype(Func); - if constexpr (meta::IsPointer or std::is_member_pointer_v) static_assert(Func != nullptr); - return - [... bound_args(std::forward(args))]( - this Self&&, - CallArgs&&... call_args) noexcept(std::is_nothrow_invocable_v>...>) - -> decltype(auto) { - return std::invoke(Func, std::forward(call_args)..., std::forward_like(bound_args)...); - }; - } -#endif - - ///////////////////////////////////// - ///////////////////////////////////// - template - requires(std::invocable and meta::Is, void>) - STORMKIT_CONST STORMKIT_FORCE_INLINE - constexpr auto init_by(Func&& func, Args&&... args) noexcept -> T { - auto out = T {}; - std::invoke(std::forward(func), out, std::forward(args)...); - return out; - } -}} // namespace stormkit::core +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.core:functional.utils; + +import std; + +import :meta; + +namespace stormkit { inline namespace core { namespace details { + struct EitherFunc { + [[nodiscard]] + static constexpr auto operator()(bool condition, std::invocable auto&& true_, std::invocable auto&& false_) noexcept + -> decltype(false_()); + + template + using ForwardArg = meta::ForwardLike>>; + + template + [[nodiscard]] + static constexpr auto operator()(T value, + std::invocable&> auto&& true_, + std::invocable auto&& false_) noexcept -> decltype(false_()); + + template + requires(meta::IsConvertibleTo) + [[nodiscard]] + static constexpr auto operator()(T&& value, + std::invocable> auto&& true_, + std::invocable auto&& false_) noexcept -> decltype(false_()); + }; +}}} // namespace stormkit::core::details + +export namespace stormkit { inline namespace core { + inline constexpr auto either = details::EitherFunc {}; + + using std::bind_back; + using std::bind_front; + + template + requires(std::invocable and meta::Is, void>) + [[nodiscard]] + constexpr auto init_by(Func&& func, Args&&... args) noexcept -> T; +}} // namespace stormkit::core + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit { inline namespace core { + namespace details { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto EitherFunc::operator()(bool condition, std::invocable auto&& true_, std::invocable auto&& false_) noexcept + -> decltype(false_()) { + if (condition) return true_(); + return false_(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto EitherFunc::operator()(T value, + std::invocable&> auto&& true_, + std::invocable auto&& false_) noexcept -> decltype(false_()) { + if (static_cast(value)) return true_(*value); + return false_(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(meta::IsConvertibleTo) + STORMKIT_FORCE_INLINE + constexpr auto EitherFunc::operator()(T&& value, + std::invocable> auto&& true_, + std::invocable auto&& false_) noexcept -> decltype(false_()) { + if (static_cast(value)) return true_(std::forward_like(*value)); + return false_(); + } + } // namespace details + +#if not(defined(__cpp_lib_bind_back) and __cpp_lib_bind_back >= 202306L) + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto bind_back(Args&&... args) noexcept -> decltype(auto) { + return std::bind_back(std::forward(args)...); + using FuncType = decltype(Func); + if constexpr (meta::IsPointer or std::is_member_pointer_v) static_assert(Func != nullptr); + return + [... bound_args(std::forward(args))]( + this Self&&, + CallArgs&&... call_args) noexcept(std::is_nothrow_invocable_v>...>) + -> decltype(auto) { + return std::invoke(Func, std::forward(call_args)..., std::forward_like(bound_args)...); + }; + } +#endif + + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(std::invocable and meta::Is, void>) + STORMKIT_CONST STORMKIT_FORCE_INLINE + constexpr auto init_by(Func&& func, Args&&... args) noexcept -> T { + auto out = T {}; + std::invoke(std::forward(func), out, std::forward(args)...); + return out; + } +}} // namespace stormkit::core diff --git a/modules/stormkit/core/hash.mpp b/modules/stormkit/core/hash.cppm similarity index 96% rename from modules/stormkit/core/hash.mpp rename to modules/stormkit/core/hash.cppm index adb4875cb..665cf3dd3 100644 --- a/modules/stormkit/core/hash.mpp +++ b/modules/stormkit/core/hash.cppm @@ -1,13 +1,13 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -export module stormkit.core:hash; - -export import :hash.base; -export import :hash.map; -export import :hash.string; +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.core:hash; + +export import :hash.base; +export import :hash.map; +export import :hash.string; diff --git a/modules/stormkit/core/hash/base.mpp b/modules/stormkit/core/hash/base.cppm similarity index 100% rename from modules/stormkit/core/hash/base.mpp rename to modules/stormkit/core/hash/base.cppm diff --git a/modules/stormkit/core/hash/map.mpp b/modules/stormkit/core/hash/map.cppm similarity index 97% rename from modules/stormkit/core/hash/map.mpp rename to modules/stormkit/core/hash/map.cppm index f610b9737..e93d39fc0 100644 --- a/modules/stormkit/core/hash/map.mpp +++ b/modules/stormkit/core/hash/map.cppm @@ -1,24 +1,24 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -export module stormkit.core:hash.map; - -import std; - -import ankerl.unordered_dense; - -export namespace stormkit { inline namespace core { - template, - class KeyEqual = std::equal_to, - class AllocatorOrContainer = std::allocator>> - using HashMap = ankerl::unordered_dense::map; - - template, - class KeyEqual = std::equal_to, - class AllocatorOrContainer = std::allocator> - using HashSet = ankerl::unordered_dense::set; -}} // namespace stormkit::core +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +export module stormkit.core:hash.map; + +import std; + +import ankerl.unordered_dense; + +export namespace stormkit { inline namespace core { + template, + class KeyEqual = std::equal_to, + class AllocatorOrContainer = std::allocator>> + using HashMap = ankerl::unordered_dense::map; + + template, + class KeyEqual = std::equal_to, + class AllocatorOrContainer = std::allocator> + using HashSet = ankerl::unordered_dense::set; +}} // namespace stormkit::core diff --git a/modules/stormkit/core/hash/string.mpp b/modules/stormkit/core/hash/string.cppm similarity index 100% rename from modules/stormkit/core/hash/string.mpp rename to modules/stormkit/core/hash/string.cppm diff --git a/modules/stormkit/core/math.mpp b/modules/stormkit/core/math.cppm similarity index 100% rename from modules/stormkit/core/math.mpp rename to modules/stormkit/core/math.cppm diff --git a/modules/stormkit/core/math/arithmetic.mpp b/modules/stormkit/core/math/arithmetic.cppm similarity index 100% rename from modules/stormkit/core/math/arithmetic.mpp rename to modules/stormkit/core/math/arithmetic.cppm diff --git a/modules/stormkit/core/math/combinatoric.mpp b/modules/stormkit/core/math/combinatoric.cppm similarity index 100% rename from modules/stormkit/core/math/combinatoric.mpp rename to modules/stormkit/core/math/combinatoric.cppm diff --git a/modules/stormkit/core/math/extent.mpp b/modules/stormkit/core/math/extent.cppm similarity index 100% rename from modules/stormkit/core/math/extent.mpp rename to modules/stormkit/core/math/extent.cppm diff --git a/modules/stormkit/core/math/geometry.mpp b/modules/stormkit/core/math/geometry.cppm similarity index 100% rename from modules/stormkit/core/math/geometry.mpp rename to modules/stormkit/core/math/geometry.cppm diff --git a/modules/stormkit/core/math/hypercomplex.mpp b/modules/stormkit/core/math/hypercomplex.cppm similarity index 100% rename from modules/stormkit/core/math/hypercomplex.mpp rename to modules/stormkit/core/math/hypercomplex.cppm diff --git a/modules/stormkit/core/math/linear-matrix.mpp b/modules/stormkit/core/math/linear-matrix.cppm similarity index 100% rename from modules/stormkit/core/math/linear-matrix.mpp rename to modules/stormkit/core/math/linear-matrix.cppm diff --git a/modules/stormkit/core/math/linear-vector.mpp b/modules/stormkit/core/math/linear-vector.cppm similarity index 100% rename from modules/stormkit/core/math/linear-vector.mpp rename to modules/stormkit/core/math/linear-vector.cppm diff --git a/modules/stormkit/core/math/linear.mpp b/modules/stormkit/core/math/linear.cppm similarity index 100% rename from modules/stormkit/core/math/linear.mpp rename to modules/stormkit/core/math/linear.cppm diff --git a/modules/stormkit/core/math/trigonometry.mpp b/modules/stormkit/core/math/trigonometry.cppm similarity index 100% rename from modules/stormkit/core/math/trigonometry.mpp rename to modules/stormkit/core/math/trigonometry.cppm diff --git a/modules/stormkit/core/meta.mpp b/modules/stormkit/core/meta.cppm similarity index 96% rename from modules/stormkit/core/meta.mpp rename to modules/stormkit/core/meta.cppm index 2d993429e..4693e4746 100644 --- a/modules/stormkit/core/meta.mpp +++ b/modules/stormkit/core/meta.cppm @@ -1,32 +1,32 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -export module stormkit.core:meta; - -export import :meta.algorithms; -export import :meta.concepts; -export import :meta.type_traits; -export import :meta.type_query; -export import :meta.type_manipulation; -export import :meta.priority_tag; - -export namespace stormkit { inline namespace core { - template - struct Overloaded: Ts... { - using Ts::operator()...; - }; - - template - Overloaded(Ts...) -> Overloaded; - - namespace meta { - template - consteval auto find_type_index_of() noexcept -> std::size_t { - static_assert(IsOneOf); - auto i = 0u; - ((not Is and ++i) and ...); - return i; - } - } // namespace meta -}} // namespace stormkit::core +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +export module stormkit.core:meta; + +export import :meta.algorithms; +export import :meta.concepts; +export import :meta.type_traits; +export import :meta.type_query; +export import :meta.type_manipulation; +export import :meta.priority_tag; + +export namespace stormkit { inline namespace core { + template + struct Overloaded: Ts... { + using Ts::operator()...; + }; + + template + Overloaded(Ts...) -> Overloaded; + + namespace meta { + template + consteval auto find_type_index_of() noexcept -> std::size_t { + static_assert(IsOneOf); + auto i = 0u; + ((not Is and ++i) and ...); + return i; + } + } // namespace meta +}} // namespace stormkit::core diff --git a/modules/stormkit/core/meta/algorithms.mpp b/modules/stormkit/core/meta/algorithms.cppm similarity index 100% rename from modules/stormkit/core/meta/algorithms.mpp rename to modules/stormkit/core/meta/algorithms.cppm diff --git a/modules/stormkit/core/meta/concepts.mpp b/modules/stormkit/core/meta/concepts.cppm similarity index 97% rename from modules/stormkit/core/meta/concepts.mpp rename to modules/stormkit/core/meta/concepts.cppm index 11f88cb73..163a5fb91 100644 --- a/modules/stormkit/core/meta/concepts.mpp +++ b/modules/stormkit/core/meta/concepts.cppm @@ -1,424 +1,424 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -export module stormkit.core:meta.concepts; - -import std; - -namespace stormkit { inline namespace core { namespace meta::details { - template - concept IsBooleanTestable = std::convertible_to; - - template class T, typename... Args> - constexpr auto is_specialization_of_helper(const T&) noexcept -> std::true_type { - return {}; - } - - template class T, typename T2, auto... Args> - constexpr auto is_specialization_of_with_nttp_helper(const T&) noexcept -> std::true_type { - return {}; - } - - template class T, typename T1, auto... Args> - constexpr auto is_specialization_of_helper_nttp_tv(const T&) noexcept -> std::true_type { - return {}; - } - - template typename T, typename T1, typename T2, auto... Args> - constexpr auto is_specialization_of_helper_nttp_ttv(const T&) noexcept -> std::true_type { - return {}; - } - - template typename T, typename T1, typename T2, auto Arg, typename... Ts> - constexpr auto is_specialization_of_helper_nttp_ttvts(const T&) noexcept -> std::true_type { - return {}; - } -}}} // namespace stormkit::core::meta::details - -export namespace stormkit { inline namespace core { namespace meta { - template - concept IsStrict = std::same_as; - - template - concept Same = std::same_as; - - template - concept SameAs = std::same_as; - - template - concept DerivedFrom = std::derived_from; - - template - concept Is = SameAs or DerivedFrom; - - template - concept IsNot = not Is; - - // template concept C> - // concept Not = not C; - - // template concept... C> - // concept AllOf = (C and ...); - - // template concept... C> - // concept AnyOf = (C or ...); - - template - concept ConvertibleTo = std::convertible_to; - - template - concept IsConvertibleTo = std::convertible_to; - - template - concept HasStdHashSpecialization = requires(T&& a) { std::hash> {}(std::forward(a)); }; - - template - concept IsCanonical = IsStrict, std::remove_cvref_t>; - - template - concept PlainIs = Is, std::remove_cvref_t>; - - template - concept IsPlain = Is>; - - template - concept Are = (Is and ...); - - template - concept AnyOf = (Is or ...); - - template - concept IsOneOf = (Is or ...); - - template - concept SameAsOneOf = (SameAs or ...); - - template - concept IsByte = IsStrict; - - template - concept IsByteSized = sizeof(T) == sizeof(std::byte); - - template - concept IsNotByte = not IsByte; - - template - concept IsStringLike = std::convertible_to; - - template - concept IsRawPointer = std::is_pointer_v; - - template - concept IsNonOwningPointer = IsRawPointer or (requires { - typename T::element_type; - } and requires(T a) { - { a.operator->() } -> std::convertible_to; - { a.operator*() }; - { static_cast(a) }; - }); - - template - concept IsOwningPointer = IsNonOwningPointer and requires(T a) { - { a.reset() }; - }; - - template - concept IsPointer = IsNonOwningPointer or IsOwningPointer; - - template - concept IsNotPointer = not IsPointer; - - template - concept IsLValueReference = std::is_lvalue_reference_v; - - template - concept IsRValueReference = std::is_rvalue_reference_v; - - template - concept IsReference = IsLValueReference or IsRValueReference; - - template - concept IsNotReference = not IsReference; - - template - concept IsReferenceTo = IsReference and Is, U>; - - template - concept IsMovedOwningPointer = IsOwningPointer and IsRValueReference; - - template - concept IsViewPointer = (IsOwningPointer> and not IsMovedOwningPointer) - or IsNonOwningPointer>; - - template - concept IsRawPointerOrLValueReference = IsRawPointer or IsLValueReference; - - template - concept IsIndirection = IsLValueReference or IsPointer; - - template - concept AreIndirections = ((IsLValueReference or IsPointer) && ...); - - template - concept IsPolymorphic = std::is_polymorphic_v; - - template - concept IsPolymorphicPointer = IsPointer and IsPolymorphic::element_type>; - - template - concept IsPolymorphicReference = IsReference and IsPolymorphic>; - - template - concept IsPolymorphicIndirection = IsPolymorphicReference or IsPolymorphicPointer; - - template - concept IsRawIndirection = IsLValueReference or IsRawPointer; - - template - concept IsNotRawIndirection = not IsRawIndirection; - - template - concept IsNotIndirection = not IsIndirection; - - template - concept IsScopedEnumeration = std::is_scoped_enum_v and IsNotByte; - - template - concept IsPlainEnumeration = not IsScopedEnumeration and std::is_enum_v and IsNotByte; - - template - concept IsEnumeration = std::is_enum_v and IsNotByte; - - template - concept IsIntegral = (std::integral and not IsStrict and not IsByte) - or Is>> - or Is>> -#if defined(STORMKIT_COMPILER_MSVC) - or Is - or Is; -#else - or Is - or Is; -#endif - - template - concept IsIntegralOrEnumeration = IsIntegral or IsEnumeration; - - template - concept IsFloatingPoint = std::floating_point; - - template - concept IsArithmetic = (IsIntegral or IsFloatingPoint) and not IsPointer and not IsEnumeration; - - template - concept IsScalar = IsArithmetic or IsPointer or IsEnumeration; - - template - concept IsPreIncrementable = requires(T& a) { a.operator--(); }; - - template - concept IsBooleanTestable = details::IsBooleanTestable && requires(T&& t) { - { not std::forward(t) } -> details::IsBooleanTestable; - }; - - template - concept IsContainedSemantics = requires(T& val) { - typename T::value_type; - { val.operator*() } -> IsReferenceTo; - }; - - template class T> - concept IsSpecializationOf = requires(S&& s) { - { details::is_specialization_of_helper(std::forward(s)) } -> IsStrict; - }; - - template typename T> - concept IsSpecializationOfNTTP_TV = requires(S&& s) { - { details::is_specialization_of_helper_nttp_tv(std::forward(s)) } -> IsStrict; - }; - - template typename T> - concept IsSpecializationOfNTTP_TTV = requires(S&& s) { - { details::is_specialization_of_helper_nttp_ttv(std::forward(s)) } -> IsStrict; - }; - - template typename T> - concept IsSpecializationOfNTTP_TTVTs = requires(S&& s) { - { details::is_specialization_of_helper_nttp_ttvts(std::forward(s)) } -> IsStrict; - }; - - template class T> - concept IsSpecializationWithNTTPOf = requires(S&& s) { - { details::is_specialization_of_with_nttp_helper(std::forward(s)) } -> IsStrict; - }; - - template - concept IsOptionalType = IsSpecializationOf; - - template - concept IsExpectedType = IsSpecializationOf; - - template - concept IsVariantType = IsSpecializationOf; - - template - concept IsMdspanType = IsSpecializationOf; - - template - concept IsArrayType = IsSpecializationWithNTTPOf; - - template - concept IsPredicate = std::predicate; - - template - concept IsUnaryPredicate = IsPredicate; - - template - concept IsBinaryPredicate = IsPredicate; - - template - concept IsHashFunc = std::regular_invocable and std::convertible_to, std::uint64_t>; - - // doesn't work atm - template - concept IsFormattable = true; // requires(std::formatter f, T val) { f.format("{}", - // val); }; - - template - concept IsCharacter = IsOneOf; - - template - concept IsCharType = IsOneOf; - - template - concept IsColorComponent = IsOneOf; - - template - concept IsConst = std::is_const_v; - - template - concept IsVolatile = std::is_volatile_v; - - template - concept IsNotConst = not IsConst; - - template - concept IsBraceInitializableTo = requires(From&& from) { To { std::forward(from) }; }; - - template - concept IsConvertibleToOneOf = (IsConvertibleTo or ...); - - template - concept IsExplicitConvertibleTo = IsConvertibleTo or requires(From&& from) { - { static_cast(std::forward(from)) } -> Is; - }; - - template - concept IsUnsigned = std::is_unsigned_v -#if defined(STORMKIT_COMPILER_MSVC) - or Is; -#else - or Is; -#endif - - template - concept IsSigned = std::is_signed_v -#if defined(STORMKIT_COMPILER_MSVC) - or Is; -#else - or Is; -#endif - - template - concept IsSameSigneness = (IsSigned and IsSigned) or (IsUnsigned and IsUnsigned); - - template - concept IsSignNarrowing = (IsSigned ? not IsSigned : IsSigned and sizeof(From) == sizeof(To)); - - template - concept IsByteNarrowing = ((IsArithmetic and IsByte) or (IsByte and IsArithmetic)) - and (IsByte and sizeof(To) != sizeof(From)); - - template - concept IsNarrowing = (IsFloatingPoint and IsIntegral) - or (IsFloatingPoint and IsFloatingPoint and sizeof(From) > sizeof(To)) - or (IsIntegralOrEnumeration and IsFloatingPoint) - or (IsIntegral and IsIntegral and (sizeof(From) > sizeof(To) or IsSignNarrowing)) - or (IsEnumeration - and IsIntegral - and (sizeof(From) > sizeof(To) or IsSignNarrowing, From>)) - or (IsPointer and Is); - - template - concept IsUnsafePointerConvertion = IsPointer and IsPointer and not requires(To to, From from) { to = from; }; - - template - concept IsSafeNarrowing = IsArithmetic and IsArithmetic and not is_safe_narrowing(from); - - template - concept HasEqualityOperator = requires(const T1& first, const T2& second) { - { first == second } -> IsBooleanTestable; - }; - - static_assert(HasEqualityOperator); - - template - concept EnableCtor = sizeof...(Args) != 1 || (sizeof...(Args) == 1 && !Is::type>); - - template - concept IsNoexceptDefaultConstructible = std::is_nothrow_default_constructible_v; - - template - concept IsNoexceptConstructible = std::is_nothrow_constructible_v; - - template - concept IsNoexceptCopyConstructible = std::is_nothrow_copy_constructible_v; - - template - concept IsNoexceptMoveConstructible = std::is_nothrow_move_constructible_v; - - template - concept IsNoexceptCopyAssignable = std::is_nothrow_copy_assignable_v; - - template - concept IsNoexceptMoveAssignable = std::is_nothrow_move_assignable_v; - - template - concept IsNoexceptAssignable = std::is_nothrow_assignable_v; - - template - concept IsNoexceptDestructible = std::is_nothrow_destructible_v; - - template - concept IsDefaultConstructible = std::is_default_constructible_v; - - template - concept IsConstructible = std::is_constructible_v; - - template - concept IsCopyConstructible = std::is_copy_constructible_v; - - template - concept IsMoveConstructible = std::is_move_constructible_v; - - template - concept IsCopyAssignable = std::is_copy_assignable_v; - - template - concept IsMoveAssignable = std::is_move_assignable_v; - - template - concept IsAssignable = std::is_assignable_v; -}}} // namespace stormkit::core::meta +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +export module stormkit.core:meta.concepts; + +import std; + +namespace stormkit { inline namespace core { namespace meta::details { + template + concept IsBooleanTestable = std::convertible_to; + + template class T, typename... Args> + constexpr auto is_specialization_of_helper(const T&) noexcept -> std::true_type { + return {}; + } + + template class T, typename T2, auto... Args> + constexpr auto is_specialization_of_with_nttp_helper(const T&) noexcept -> std::true_type { + return {}; + } + + template class T, typename T1, auto... Args> + constexpr auto is_specialization_of_helper_nttp_tv(const T&) noexcept -> std::true_type { + return {}; + } + + template typename T, typename T1, typename T2, auto... Args> + constexpr auto is_specialization_of_helper_nttp_ttv(const T&) noexcept -> std::true_type { + return {}; + } + + template typename T, typename T1, typename T2, auto Arg, typename... Ts> + constexpr auto is_specialization_of_helper_nttp_ttvts(const T&) noexcept -> std::true_type { + return {}; + } +}}} // namespace stormkit::core::meta::details + +export namespace stormkit { inline namespace core { namespace meta { + template + concept IsStrict = std::same_as; + + template + concept Same = std::same_as; + + template + concept SameAs = std::same_as; + + template + concept DerivedFrom = std::derived_from; + + template + concept Is = SameAs or DerivedFrom; + + template + concept IsNot = not Is; + + // template concept C> + // concept Not = not C; + + // template concept... C> + // concept AllOf = (C and ...); + + // template concept... C> + // concept AnyOf = (C or ...); + + template + concept ConvertibleTo = std::convertible_to; + + template + concept IsConvertibleTo = std::convertible_to; + + template + concept HasStdHashSpecialization = requires(T&& a) { std::hash> {}(std::forward(a)); }; + + template + concept IsCanonical = IsStrict, std::remove_cvref_t>; + + template + concept PlainIs = Is, std::remove_cvref_t>; + + template + concept IsPlain = Is>; + + template + concept Are = (Is and ...); + + template + concept AnyOf = (Is or ...); + + template + concept IsOneOf = (Is or ...); + + template + concept SameAsOneOf = (SameAs or ...); + + template + concept IsByte = IsStrict; + + template + concept IsByteSized = sizeof(T) == sizeof(std::byte); + + template + concept IsNotByte = not IsByte; + + template + concept IsStringLike = std::convertible_to; + + template + concept IsRawPointer = std::is_pointer_v; + + template + concept IsNonOwningPointer = IsRawPointer or (requires { + typename T::element_type; + } and requires(T a) { + { a.operator->() } -> std::convertible_to; + { a.operator*() }; + { static_cast(a) }; + }); + + template + concept IsOwningPointer = IsNonOwningPointer and requires(T a) { + { a.reset() }; + }; + + template + concept IsPointer = IsNonOwningPointer or IsOwningPointer; + + template + concept IsNotPointer = not IsPointer; + + template + concept IsLValueReference = std::is_lvalue_reference_v; + + template + concept IsRValueReference = std::is_rvalue_reference_v; + + template + concept IsReference = IsLValueReference or IsRValueReference; + + template + concept IsNotReference = not IsReference; + + template + concept IsReferenceTo = IsReference and Is, U>; + + template + concept IsMovedOwningPointer = IsOwningPointer and IsRValueReference; + + template + concept IsViewPointer = (IsOwningPointer> and not IsMovedOwningPointer) + or IsNonOwningPointer>; + + template + concept IsRawPointerOrLValueReference = IsRawPointer or IsLValueReference; + + template + concept IsIndirection = IsLValueReference or IsPointer; + + template + concept AreIndirections = ((IsLValueReference or IsPointer) && ...); + + template + concept IsPolymorphic = std::is_polymorphic_v; + + template + concept IsPolymorphicPointer = IsPointer and IsPolymorphic::element_type>; + + template + concept IsPolymorphicReference = IsReference and IsPolymorphic>; + + template + concept IsPolymorphicIndirection = IsPolymorphicReference or IsPolymorphicPointer; + + template + concept IsRawIndirection = IsLValueReference or IsRawPointer; + + template + concept IsNotRawIndirection = not IsRawIndirection; + + template + concept IsNotIndirection = not IsIndirection; + + template + concept IsScopedEnumeration = std::is_scoped_enum_v and IsNotByte; + + template + concept IsPlainEnumeration = not IsScopedEnumeration and std::is_enum_v and IsNotByte; + + template + concept IsEnumeration = std::is_enum_v and IsNotByte; + + template + concept IsIntegral = (std::integral and not IsStrict and not IsByte) + or Is>> + or Is>> +#if defined(STORMKIT_COMPILER_MSVC) + or Is + or Is; +#else + or Is + or Is; +#endif + + template + concept IsIntegralOrEnumeration = IsIntegral or IsEnumeration; + + template + concept IsFloatingPoint = std::floating_point; + + template + concept IsArithmetic = (IsIntegral or IsFloatingPoint) and not IsPointer and not IsEnumeration; + + template + concept IsScalar = IsArithmetic or IsPointer or IsEnumeration; + + template + concept IsPreIncrementable = requires(T& a) { a.operator--(); }; + + template + concept IsBooleanTestable = details::IsBooleanTestable && requires(T&& t) { + { not std::forward(t) } -> details::IsBooleanTestable; + }; + + template + concept IsContainedSemantics = requires(T& val) { + typename T::value_type; + { val.operator*() } -> IsReferenceTo; + }; + + template class T> + concept IsSpecializationOf = requires(S&& s) { + { details::is_specialization_of_helper(std::forward(s)) } -> IsStrict; + }; + + template typename T> + concept IsSpecializationOfNTTP_TV = requires(S&& s) { + { details::is_specialization_of_helper_nttp_tv(std::forward(s)) } -> IsStrict; + }; + + template typename T> + concept IsSpecializationOfNTTP_TTV = requires(S&& s) { + { details::is_specialization_of_helper_nttp_ttv(std::forward(s)) } -> IsStrict; + }; + + template typename T> + concept IsSpecializationOfNTTP_TTVTs = requires(S&& s) { + { details::is_specialization_of_helper_nttp_ttvts(std::forward(s)) } -> IsStrict; + }; + + template class T> + concept IsSpecializationWithNTTPOf = requires(S&& s) { + { details::is_specialization_of_with_nttp_helper(std::forward(s)) } -> IsStrict; + }; + + template + concept IsOptionalType = IsSpecializationOf; + + template + concept IsExpectedType = IsSpecializationOf; + + template + concept IsVariantType = IsSpecializationOf; + + template + concept IsMdspanType = IsSpecializationOf; + + template + concept IsArrayType = IsSpecializationWithNTTPOf; + + template + concept IsPredicate = std::predicate; + + template + concept IsUnaryPredicate = IsPredicate; + + template + concept IsBinaryPredicate = IsPredicate; + + template + concept IsHashFunc = std::regular_invocable and std::convertible_to, std::uint64_t>; + + // doesn't work atm + template + concept IsFormattable = true; // requires(std::formatter f, T val) { f.format("{}", + // val); }; + + template + concept IsCharacter = IsOneOf; + + template + concept IsCharType = IsOneOf; + + template + concept IsColorComponent = IsOneOf; + + template + concept IsConst = std::is_const_v; + + template + concept IsVolatile = std::is_volatile_v; + + template + concept IsNotConst = not IsConst; + + template + concept IsBraceInitializableTo = requires(From&& from) { To { std::forward(from) }; }; + + template + concept IsConvertibleToOneOf = (IsConvertibleTo or ...); + + template + concept IsExplicitConvertibleTo = IsConvertibleTo or requires(From&& from) { + { static_cast(std::forward(from)) } -> Is; + }; + + template + concept IsUnsigned = std::is_unsigned_v +#if defined(STORMKIT_COMPILER_MSVC) + or Is; +#else + or Is; +#endif + + template + concept IsSigned = std::is_signed_v +#if defined(STORMKIT_COMPILER_MSVC) + or Is; +#else + or Is; +#endif + + template + concept IsSameSigneness = (IsSigned and IsSigned) or (IsUnsigned and IsUnsigned); + + template + concept IsSignNarrowing = (IsSigned ? not IsSigned : IsSigned and sizeof(From) == sizeof(To)); + + template + concept IsByteNarrowing = ((IsArithmetic and IsByte) or (IsByte and IsArithmetic)) + and (IsByte and sizeof(To) != sizeof(From)); + + template + concept IsNarrowing = (IsFloatingPoint and IsIntegral) + or (IsFloatingPoint and IsFloatingPoint and sizeof(From) > sizeof(To)) + or (IsIntegralOrEnumeration and IsFloatingPoint) + or (IsIntegral and IsIntegral and (sizeof(From) > sizeof(To) or IsSignNarrowing)) + or (IsEnumeration + and IsIntegral + and (sizeof(From) > sizeof(To) or IsSignNarrowing, From>)) + or (IsPointer and Is); + + template + concept IsUnsafePointerConvertion = IsPointer and IsPointer and not requires(To to, From from) { to = from; }; + + template + concept IsSafeNarrowing = IsArithmetic and IsArithmetic and not is_safe_narrowing(from); + + template + concept HasEqualityOperator = requires(const T1& first, const T2& second) { + { first == second } -> IsBooleanTestable; + }; + + static_assert(HasEqualityOperator); + + template + concept EnableCtor = sizeof...(Args) != 1 || (sizeof...(Args) == 1 && !Is::type>); + + template + concept IsNoexceptDefaultConstructible = std::is_nothrow_default_constructible_v; + + template + concept IsNoexceptConstructible = std::is_nothrow_constructible_v; + + template + concept IsNoexceptCopyConstructible = std::is_nothrow_copy_constructible_v; + + template + concept IsNoexceptMoveConstructible = std::is_nothrow_move_constructible_v; + + template + concept IsNoexceptCopyAssignable = std::is_nothrow_copy_assignable_v; + + template + concept IsNoexceptMoveAssignable = std::is_nothrow_move_assignable_v; + + template + concept IsNoexceptAssignable = std::is_nothrow_assignable_v; + + template + concept IsNoexceptDestructible = std::is_nothrow_destructible_v; + + template + concept IsDefaultConstructible = std::is_default_constructible_v; + + template + concept IsConstructible = std::is_constructible_v; + + template + concept IsCopyConstructible = std::is_copy_constructible_v; + + template + concept IsMoveConstructible = std::is_move_constructible_v; + + template + concept IsCopyAssignable = std::is_copy_assignable_v; + + template + concept IsMoveAssignable = std::is_move_assignable_v; + + template + concept IsAssignable = std::is_assignable_v; +}}} // namespace stormkit::core::meta diff --git a/modules/stormkit/core/meta/priority_tag.mpp b/modules/stormkit/core/meta/priority_tag.cppm similarity index 100% rename from modules/stormkit/core/meta/priority_tag.mpp rename to modules/stormkit/core/meta/priority_tag.cppm diff --git a/modules/stormkit/core/meta/type_manipulation.mpp b/modules/stormkit/core/meta/type_manipulation.cppm similarity index 100% rename from modules/stormkit/core/meta/type_manipulation.mpp rename to modules/stormkit/core/meta/type_manipulation.cppm diff --git a/modules/stormkit/core/meta/type_query.mpp b/modules/stormkit/core/meta/type_query.cppm similarity index 100% rename from modules/stormkit/core/meta/type_query.mpp rename to modules/stormkit/core/meta/type_query.cppm diff --git a/modules/stormkit/core/meta/type_traits.mpp b/modules/stormkit/core/meta/type_traits.cppm similarity index 100% rename from modules/stormkit/core/meta/type_traits.mpp rename to modules/stormkit/core/meta/type_traits.cppm diff --git a/modules/stormkit/core/parallelism.mpp b/modules/stormkit/core/parallelism.cppm similarity index 97% rename from modules/stormkit/core/parallelism.mpp rename to modules/stormkit/core/parallelism.cppm index 8ab882df4..16ef24cea 100644 --- a/modules/stormkit/core/parallelism.mpp +++ b/modules/stormkit/core/parallelism.cppm @@ -1,9 +1,9 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -export module stormkit.core:parallelism; - -export import :parallelism.locked; -export import :parallelism.threadpool; -export import :parallelism.threadutils; +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +export module stormkit.core:parallelism; + +export import :parallelism.locked; +export import :parallelism.threadpool; +export import :parallelism.threadutils; diff --git a/modules/stormkit/core/parallelism/locked.mpp b/modules/stormkit/core/parallelism/locked.cppm similarity index 100% rename from modules/stormkit/core/parallelism/locked.mpp rename to modules/stormkit/core/parallelism/locked.cppm diff --git a/modules/stormkit/core/parallelism/threadpool.mpp b/modules/stormkit/core/parallelism/threadpool.cppm similarity index 97% rename from modules/stormkit/core/parallelism/threadpool.mpp rename to modules/stormkit/core/parallelism/threadpool.cppm index 9f8127d28..e1cc1c6e4 100644 --- a/modules/stormkit/core/parallelism/threadpool.mpp +++ b/modules/stormkit/core/parallelism/threadpool.cppm @@ -1,225 +1,225 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -export module stormkit.core:parallelism.threadpool; - -import std; - -import :parallelism.threadutils; - -import :meta; - -import :utils.numeric_range; -import :typesafe.integer; - -export namespace stormkit { inline namespace core { - class STORMKIT_API ThreadPool { - public: - static constexpr struct NoFutureType { - } NO_FUTURE = {}; - - template - using Closure = std::function; - // using Closure = std::move_only_function; - - explicit ThreadPool(u32 worker_count = std::thread::hardware_concurrency() / 2); - ~ThreadPool(); - - ThreadPool(const ThreadPool&) = delete; - auto operator=(const ThreadPool&) -> ThreadPool& = delete; - - ThreadPool(ThreadPool&&) noexcept; - auto operator=(ThreadPool&&) noexcept -> ThreadPool&; - - [[nodiscard]] - auto worker_count() const noexcept -> u32; - - template - [[nodiscard]] - auto post_task(Closure task) noexcept -> decltype(auto); - - template - auto post_task(Closure task, NoFutureType) noexcept -> void; - - auto join_all() noexcept -> void; - - auto set_name(std::string_view name) noexcept -> void; - - private: - struct Task { - enum class Type { - Standard, - Terminate, - }; - - Task() = default; - - inline Task(Type _type, std::function _work) : type { _type }, work { std::move(_work) } {} - - Task(Task&&) noexcept = default; - auto operator=(Task&&) noexcept -> Task& = default; - - Type type; - std::function work; - }; - - template - auto post_task(Task::Type type, Closure task) noexcept -> decltype(auto); - - template - auto post_task(Task::Type type, Closure task, NoFutureType) noexcept -> void; - - auto worker_main() noexcept -> void; - - u32 m_worker_count = 0; - - std::vector m_workers; - - mutable std::mutex m_mutex; - std::condition_variable m_work_signal; - std::queue m_tasks; - }; - - template&> F> - auto parallel_for(ThreadPool& pool, Range&& range, F&& f) noexcept -> void; - - template&> F> - auto parallel_for_async(ThreadPool& pool, Range& range, F&& f) noexcept -> std::vector>; -}} // namespace stormkit::core - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stdr = std::ranges; -namespace stdv = std::views; - -namespace stormkit { inline namespace core { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline ThreadPool::ThreadPool(u32 worker_count) - : m_worker_count { worker_count } { - m_workers.reserve(m_worker_count); - - for (auto i : range(m_worker_count)) { - auto& worker = m_workers.emplace_back([this] { worker_main(); }); - set_thread_name(worker, std::format("StormKit:WorkerThread:{}", i)); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline ThreadPool::~ThreadPool() { - join_all(); - } - - //////////////////////////////////////// - //////////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto ThreadPool::worker_count() const noexcept -> u32 { - return m_worker_count; - } - - //////////////////////////////////////// - //////////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto ThreadPool::set_name(std::string_view name) noexcept -> void { - // for (auto&& [i, worker] : stdv::enumerate(m_workers)) - for (auto i : range(m_worker_count)) set_thread_name(m_workers[i], std::format("{}:{}", name, i)); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto ThreadPool::post_task(Closure task) noexcept -> decltype(auto) { - return post_task(Task::Type::Standard, std::move(task)); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto ThreadPool::post_task(Closure task, NoFutureType t) noexcept -> void { - auto _ = post_task(Task::Type::Standard, std::move(task), t); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - inline auto ThreadPool::post_task(Task::Type type, Closure closure) noexcept -> decltype(auto) { - auto packaged_task = std::make_shared>(std::move(closure)); - - auto future = packaged_task->get_future(); - - auto task = Task { type, [task = std::move(packaged_task)]() { (*task)(); } }; - - { - auto _ = std::unique_lock { m_mutex }; - - m_tasks.emplace(std::move(task)); - } - - m_work_signal.notify_one(); - - return future; - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - inline auto ThreadPool::post_task(Task::Type type, Closure closure, NoFutureType) noexcept -> void { - auto task = Task { type, [task = std::move(closure)]() { task(); } }; - - { - auto lock = std::unique_lock { m_mutex }; - - m_tasks.emplace(std::move(task)); - } - - m_work_signal.notify_one(); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template&> F> - inline auto parallel_for(ThreadPool& pool, Range&& range, F&& f) noexcept -> void { - auto futures = parallel_for_async(pool, range, std::forward(f)); - wait_all(futures); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template&> F> - inline auto parallel_for_async(ThreadPool& pool, Range& range, F&& f) noexcept -> std::vector> { - const auto size = stdr::size(range); - const auto chunk_size = size / pool.worker_count(); - const auto chunk_count = size / chunk_size; - - auto out = std::vector> {}; - out.reserve(chunk_count); - - for (auto chunk : stormkit::range(chunk_count)) { - const auto start = chunk * chunk_size; - auto end = (chunk + 1u) * chunk_size; - if (end >= (chunk_count * size)) end = size; - - out.emplace_back(pool.post_task([&f, &range, start, end] mutable noexcept { - auto it = std::begin(range) + start; - for (auto _ : stormkit::range(start, end)) { - f(*it); - ++it; - } - })); - } - - return out; - } -}} // namespace stormkit::core +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.core:parallelism.threadpool; + +import std; + +import :parallelism.threadutils; + +import :meta; + +import :utils.numeric_range; +import :typesafe.integer; + +export namespace stormkit { inline namespace core { + class STORMKIT_API ThreadPool { + public: + static constexpr struct NoFutureType { + } NO_FUTURE = {}; + + template + using Closure = std::function; + // using Closure = std::move_only_function; + + explicit ThreadPool(u32 worker_count = std::thread::hardware_concurrency() / 2); + ~ThreadPool(); + + ThreadPool(const ThreadPool&) = delete; + auto operator=(const ThreadPool&) -> ThreadPool& = delete; + + ThreadPool(ThreadPool&&) noexcept; + auto operator=(ThreadPool&&) noexcept -> ThreadPool&; + + [[nodiscard]] + auto worker_count() const noexcept -> u32; + + template + [[nodiscard]] + auto post_task(Closure task) noexcept -> decltype(auto); + + template + auto post_task(Closure task, NoFutureType) noexcept -> void; + + auto join_all() noexcept -> void; + + auto set_name(std::string_view name) noexcept -> void; + + private: + struct Task { + enum class Type { + Standard, + Terminate, + }; + + Task() = default; + + inline Task(Type _type, std::function _work) : type { _type }, work { std::move(_work) } {} + + Task(Task&&) noexcept = default; + auto operator=(Task&&) noexcept -> Task& = default; + + Type type; + std::function work; + }; + + template + auto post_task(Task::Type type, Closure task) noexcept -> decltype(auto); + + template + auto post_task(Task::Type type, Closure task, NoFutureType) noexcept -> void; + + auto worker_main() noexcept -> void; + + u32 m_worker_count = 0; + + std::vector m_workers; + + mutable std::mutex m_mutex; + std::condition_variable m_work_signal; + std::queue m_tasks; + }; + + template&> F> + auto parallel_for(ThreadPool& pool, Range&& range, F&& f) noexcept -> void; + + template&> F> + auto parallel_for_async(ThreadPool& pool, Range& range, F&& f) noexcept -> std::vector>; +}} // namespace stormkit::core + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stdr = std::ranges; +namespace stdv = std::views; + +namespace stormkit { inline namespace core { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline ThreadPool::ThreadPool(u32 worker_count) + : m_worker_count { worker_count } { + m_workers.reserve(m_worker_count); + + for (auto i : range(m_worker_count)) { + auto& worker = m_workers.emplace_back([this] { worker_main(); }); + set_thread_name(worker, std::format("StormKit:WorkerThread:{}", i)); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline ThreadPool::~ThreadPool() { + join_all(); + } + + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto ThreadPool::worker_count() const noexcept -> u32 { + return m_worker_count; + } + + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto ThreadPool::set_name(std::string_view name) noexcept -> void { + // for (auto&& [i, worker] : stdv::enumerate(m_workers)) + for (auto i : range(m_worker_count)) set_thread_name(m_workers[i], std::format("{}:{}", name, i)); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto ThreadPool::post_task(Closure task) noexcept -> decltype(auto) { + return post_task(Task::Type::Standard, std::move(task)); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto ThreadPool::post_task(Closure task, NoFutureType t) noexcept -> void { + auto _ = post_task(Task::Type::Standard, std::move(task), t); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + inline auto ThreadPool::post_task(Task::Type type, Closure closure) noexcept -> decltype(auto) { + auto packaged_task = std::make_shared>(std::move(closure)); + + auto future = packaged_task->get_future(); + + auto task = Task { type, [task = std::move(packaged_task)]() { (*task)(); } }; + + { + auto _ = std::unique_lock { m_mutex }; + + m_tasks.emplace(std::move(task)); + } + + m_work_signal.notify_one(); + + return future; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + inline auto ThreadPool::post_task(Task::Type type, Closure closure, NoFutureType) noexcept -> void { + auto task = Task { type, [task = std::move(closure)]() { task(); } }; + + { + auto lock = std::unique_lock { m_mutex }; + + m_tasks.emplace(std::move(task)); + } + + m_work_signal.notify_one(); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template&> F> + inline auto parallel_for(ThreadPool& pool, Range&& range, F&& f) noexcept -> void { + auto futures = parallel_for_async(pool, range, std::forward(f)); + wait_all(futures); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template&> F> + inline auto parallel_for_async(ThreadPool& pool, Range& range, F&& f) noexcept -> std::vector> { + const auto size = stdr::size(range); + const auto chunk_size = size / pool.worker_count(); + const auto chunk_count = size / chunk_size; + + auto out = std::vector> {}; + out.reserve(chunk_count); + + for (auto chunk : stormkit::range(chunk_count)) { + const auto start = chunk * chunk_size; + auto end = (chunk + 1u) * chunk_size; + if (end >= (chunk_count * size)) end = size; + + out.emplace_back(pool.post_task([&f, &range, start, end] mutable noexcept { + auto it = std::begin(range) + start; + for (auto _ : stormkit::range(start, end)) { + f(*it); + ++it; + } + })); + } + + return out; + } +}} // namespace stormkit::core diff --git a/modules/stormkit/core/parallelism/threadutils.mpp b/modules/stormkit/core/parallelism/threadutils.cppm similarity index 97% rename from modules/stormkit/core/parallelism/threadutils.mpp rename to modules/stormkit/core/parallelism/threadutils.cppm index a55d1c978..55ba248a2 100644 --- a/modules/stormkit/core/parallelism/threadutils.mpp +++ b/modules/stormkit/core/parallelism/threadutils.cppm @@ -1,34 +1,34 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -export module stormkit.core:parallelism.threadutils; - -import std; - -import :meta; - -export namespace stormkit { inline namespace core { - STORMKIT_API - auto set_current_thread_name(std::string_view name) noexcept -> void; - STORMKIT_API - auto set_thread_name(std::thread& thread, std::string_view name) noexcept -> void; - STORMKIT_API - auto set_thread_name(std::jthread& thread, std::string_view name) noexcept -> void; - STORMKIT_API - auto get_current_thread_name() noexcept -> std::string; - STORMKIT_API - auto get_thread_name(const std::thread& thread) noexcept -> std::string; - STORMKIT_API - auto get_thread_name(const std::jthread& thread) noexcept -> std::string; - - template - requires(meta::IsSpecializationOf, std::future>) - inline auto wait_all(Range&& futures) noexcept { - for (auto&& future : std::forward(futures)) future.wait(); - } -}} // namespace stormkit::core +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.core:parallelism.threadutils; + +import std; + +import :meta; + +export namespace stormkit { inline namespace core { + STORMKIT_API + auto set_current_thread_name(std::string_view name) noexcept -> void; + STORMKIT_API + auto set_thread_name(std::thread& thread, std::string_view name) noexcept -> void; + STORMKIT_API + auto set_thread_name(std::jthread& thread, std::string_view name) noexcept -> void; + STORMKIT_API + auto get_current_thread_name() noexcept -> std::string; + STORMKIT_API + auto get_thread_name(const std::thread& thread) noexcept -> std::string; + STORMKIT_API + auto get_thread_name(const std::jthread& thread) noexcept -> std::string; + + template + requires(meta::IsSpecializationOf, std::future>) + inline auto wait_all(Range&& futures) noexcept { + for (auto&& future : std::forward(futures)) future.wait(); + } +}} // namespace stormkit::core diff --git a/modules/stormkit/core/string.mpp b/modules/stormkit/core/string.cppm similarity index 97% rename from modules/stormkit/core/string.mpp rename to modules/stormkit/core/string.cppm index e2c65a7d9..e7655cd8a 100644 --- a/modules/stormkit/core/string.mpp +++ b/modules/stormkit/core/string.cppm @@ -1,11 +1,11 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -export module stormkit.core:string; - -export import :string.constexpr_string; -export import :string.czstring; -export import :string.encodings; -export import :string.format; -export import :string.operations; +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +export module stormkit.core:string; + +export import :string.constexpr_string; +export import :string.czstring; +export import :string.encodings; +export import :string.format; +export import :string.operations; diff --git a/modules/stormkit/core/string/constexpr_string.mpp b/modules/stormkit/core/string/constexpr_string.cppm similarity index 100% rename from modules/stormkit/core/string/constexpr_string.mpp rename to modules/stormkit/core/string/constexpr_string.cppm diff --git a/modules/stormkit/core/string/czstring.mpp b/modules/stormkit/core/string/czstring.cppm similarity index 97% rename from modules/stormkit/core/string/czstring.mpp rename to modules/stormkit/core/string/czstring.cppm index 173aaf483..934dfa94f 100644 --- a/modules/stormkit/core/string/czstring.mpp +++ b/modules/stormkit/core/string/czstring.cppm @@ -1,12 +1,12 @@ -// Copyright (C) 2023 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -export module stormkit.core:string.czstring; - -export namespace stormkit { inline namespace core { - using CZString = const char*; - using ZString = char*; - using CWZString = const wchar_t*; - using WZString = wchar_t*; -}} // namespace stormkit::core +// Copyright (C) 2023 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +export module stormkit.core:string.czstring; + +export namespace stormkit { inline namespace core { + using CZString = const char*; + using ZString = char*; + using CWZString = const wchar_t*; + using WZString = wchar_t*; +}} // namespace stormkit::core diff --git a/modules/stormkit/core/string/encodings.mpp b/modules/stormkit/core/string/encodings.cppm similarity index 100% rename from modules/stormkit/core/string/encodings.mpp rename to modules/stormkit/core/string/encodings.cppm diff --git a/modules/stormkit/core/string/format.mpp b/modules/stormkit/core/string/format.cppm similarity index 97% rename from modules/stormkit/core/string/format.mpp rename to modules/stormkit/core/string/format.cppm index 1704fd7c8..4d370bed9 100644 --- a/modules/stormkit/core/string/format.mpp +++ b/modules/stormkit/core/string/format.cppm @@ -1,188 +1,188 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -export module stormkit.core:string.format; - -import std; - -import :meta; -import :typesafe.integer; -import :typesafe.safecasts; -import :utils.time; -import :string.operations; - -export { - namespace stormkit { inline namespace core { - template - auto format_as(const T&, FormatContext& ctx) noexcept -> decltype(ctx.out()) = delete; - - namespace meta { - template - inline constexpr auto DISABLE_DEFAULT_FORMATTER_FOR_ENUM = false; - - template - concept IsDefaultFormattedEnumeration = IsEnumeration and not DISABLE_DEFAULT_FORMATTER_FOR_ENUM; - - template - concept HasFormatAs = requires(const T& val) { - { format_as(val, std::declval()) } -> Is; - }; - } // namespace meta - - inline constexpr struct FormatFN { - template - static constexpr auto operator()(const T& value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { - return format_as(value, ctx); - } - } format_fn = {}; - - template - auto format_as(std::byte, FormatContext& ctx) noexcept -> decltype(ctx.out()); - - template - auto format_as(stormkit::fsecond, FormatContext& ctx) noexcept -> decltype(ctx.out()); - }} // namespace stormkit::core - - template - struct std::formatter { - template - [[nodiscard]] - constexpr auto parse(ParseContext& ctx) noexcept -> decltype(ctx.begin()); - - template - [[nodiscard]] - auto format(const T&, FormatContext& ctx) const noexcept -> decltype(ctx.out()); - }; - - template - struct std::formatter { - template - [[nodiscard]] - constexpr auto parse(ParseContext& ctx) noexcept -> decltype(ctx.begin()); - - template - [[nodiscard]] - auto format(const T&, FormatContext& ctx) const -> decltype(ctx.out()); - }; - - template - struct std::formatter: public formatter { - template - [[nodiscard]] - auto format(const T&, FormatContext& ctx) const -> decltype(ctx.out()); - }; - - template - struct std::formatter: public formatter, CharT> { - template - [[nodiscard]] - auto format(const std::error_code&, FormatContext& ctx) const -> decltype(ctx.out()); - }; - - template - struct std::formatter: public formatter, CharT> { - template - [[nodiscard]] - auto format(const std::errc& code, FormatContext& ctx) const -> decltype(ctx.out()); - }; -} - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit { inline namespace core { - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto format_as(std::byte value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { - auto&& out = ctx.out(); - return std::format_to(out, "{}", narrow(value)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto format_as(fsecond value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { - auto&& out = ctx.out(); - return std::format_to(out, "{}", value.count()); - } -}} // namespace stormkit::core - -using namespace stormkit; - -///////////////////////////////////// -///////////////////////////////////// -template -template -constexpr auto std::formatter::parse(ParseContext& ctx) noexcept -> decltype(ctx.begin()) { - return ctx.begin(); -} - -///////////////////////////////////// -///////////////////////////////////// -template -template -auto std::formatter::format(const T& value, FormatContext& ctx) const noexcept -> decltype(ctx.out()) { - return core::format_fn(value, ctx); -} - -///////////////////////////////////// -///////////////////////////////////// -template -template -constexpr auto std::formatter::parse(ParseContext& ctx) noexcept -> decltype(ctx.begin()) { - return ctx.begin(); -} - -///////////////////////////////////// -///////////////////////////////////// -template -template -auto std::formatter::format(const T& value, FormatContext& ctx) const -> decltype(ctx.out()) { - auto&& out = ctx.out(); - if constexpr (requires { - { as_string(value) } -> meta::Is; - }) { - const auto strvalue = as_string(value); - return format_to(out, "{}", strvalue); - } else - return format_to(out, "{}", as(value)); -} - -///////////////////////////////////// -///////////////////////////////////// -template -template -auto std::formatter::format(const T& value, FormatContext& ctx) const -> decltype(ctx.out()) { - auto&& out = ctx.out(); - return format_to(out, "{:#0x}", std::bit_cast(std::to_address(value))); -} - -///////////////////////////////////// -///////////////////////////////////// -template -template -auto std::formatter::format(const std::error_code& code, FormatContext& ctx) const - -> decltype(ctx.out()) { - auto&& out = ctx.out(); - const auto message = code.message(); - return format_to(out, "{}", message); -} - -///////////////////////////////////// -///////////////////////////////////// -template -template -auto std::formatter::format(const std::errc& code, FormatContext& ctx) const -> decltype(ctx.out()) { - auto&& out = ctx.out(); - const auto message = make_error_code(code).message(); - return format_to(out, "{}", message); -} +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.core:string.format; + +import std; + +import :meta; +import :typesafe.integer; +import :typesafe.safecasts; +import :utils.time; +import :string.operations; + +export { + namespace stormkit { inline namespace core { + template + auto format_as(const T&, FormatContext& ctx) noexcept -> decltype(ctx.out()) = delete; + + namespace meta { + template + inline constexpr auto DISABLE_DEFAULT_FORMATTER_FOR_ENUM = false; + + template + concept IsDefaultFormattedEnumeration = IsEnumeration and not DISABLE_DEFAULT_FORMATTER_FOR_ENUM; + + template + concept HasFormatAs = requires(const T& val) { + { format_as(val, std::declval()) } -> Is; + }; + } // namespace meta + + inline constexpr struct FormatFN { + template + static constexpr auto operator()(const T& value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { + return format_as(value, ctx); + } + } format_fn = {}; + + template + auto format_as(std::byte, FormatContext& ctx) noexcept -> decltype(ctx.out()); + + template + auto format_as(stormkit::fsecond, FormatContext& ctx) noexcept -> decltype(ctx.out()); + }} // namespace stormkit::core + + template + struct std::formatter { + template + [[nodiscard]] + constexpr auto parse(ParseContext& ctx) noexcept -> decltype(ctx.begin()); + + template + [[nodiscard]] + auto format(const T&, FormatContext& ctx) const noexcept -> decltype(ctx.out()); + }; + + template + struct std::formatter { + template + [[nodiscard]] + constexpr auto parse(ParseContext& ctx) noexcept -> decltype(ctx.begin()); + + template + [[nodiscard]] + auto format(const T&, FormatContext& ctx) const -> decltype(ctx.out()); + }; + + template + struct std::formatter: public formatter { + template + [[nodiscard]] + auto format(const T&, FormatContext& ctx) const -> decltype(ctx.out()); + }; + + template + struct std::formatter: public formatter, CharT> { + template + [[nodiscard]] + auto format(const std::error_code&, FormatContext& ctx) const -> decltype(ctx.out()); + }; + + template + struct std::formatter: public formatter, CharT> { + template + [[nodiscard]] + auto format(const std::errc& code, FormatContext& ctx) const -> decltype(ctx.out()); + }; +} + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit { inline namespace core { + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto format_as(std::byte value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { + auto&& out = ctx.out(); + return std::format_to(out, "{}", narrow(value)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto format_as(fsecond value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { + auto&& out = ctx.out(); + return std::format_to(out, "{}", value.count()); + } +}} // namespace stormkit::core + +using namespace stormkit; + +///////////////////////////////////// +///////////////////////////////////// +template +template +constexpr auto std::formatter::parse(ParseContext& ctx) noexcept -> decltype(ctx.begin()) { + return ctx.begin(); +} + +///////////////////////////////////// +///////////////////////////////////// +template +template +auto std::formatter::format(const T& value, FormatContext& ctx) const noexcept -> decltype(ctx.out()) { + return core::format_fn(value, ctx); +} + +///////////////////////////////////// +///////////////////////////////////// +template +template +constexpr auto std::formatter::parse(ParseContext& ctx) noexcept -> decltype(ctx.begin()) { + return ctx.begin(); +} + +///////////////////////////////////// +///////////////////////////////////// +template +template +auto std::formatter::format(const T& value, FormatContext& ctx) const -> decltype(ctx.out()) { + auto&& out = ctx.out(); + if constexpr (requires { + { as_string(value) } -> meta::Is; + }) { + const auto strvalue = as_string(value); + return format_to(out, "{}", strvalue); + } else + return format_to(out, "{}", as(value)); +} + +///////////////////////////////////// +///////////////////////////////////// +template +template +auto std::formatter::format(const T& value, FormatContext& ctx) const -> decltype(ctx.out()) { + auto&& out = ctx.out(); + return format_to(out, "{:#0x}", std::bit_cast(std::to_address(value))); +} + +///////////////////////////////////// +///////////////////////////////////// +template +template +auto std::formatter::format(const std::error_code& code, FormatContext& ctx) const + -> decltype(ctx.out()) { + auto&& out = ctx.out(); + const auto message = code.message(); + return format_to(out, "{}", message); +} + +///////////////////////////////////// +///////////////////////////////////// +template +template +auto std::formatter::format(const std::errc& code, FormatContext& ctx) const -> decltype(ctx.out()) { + auto&& out = ctx.out(); + const auto message = make_error_code(code).message(); + return format_to(out, "{}", message); +} diff --git a/modules/stormkit/core/string/operations.mpp b/modules/stormkit/core/string/operations.cppm similarity index 100% rename from modules/stormkit/core/string/operations.mpp rename to modules/stormkit/core/string/operations.cppm diff --git a/modules/stormkit/core/typesafe.mpp b/modules/stormkit/core/typesafe.cppm similarity index 100% rename from modules/stormkit/core/typesafe.mpp rename to modules/stormkit/core/typesafe.cppm diff --git a/modules/stormkit/core/typesafe/boolean.mpp b/modules/stormkit/core/typesafe/boolean.cppm similarity index 100% rename from modules/stormkit/core/typesafe/boolean.mpp rename to modules/stormkit/core/typesafe/boolean.cppm diff --git a/modules/stormkit/core/typesafe/byte.mpp b/modules/stormkit/core/typesafe/byte.cppm similarity index 97% rename from modules/stormkit/core/typesafe/byte.mpp rename to modules/stormkit/core/typesafe/byte.cppm index 9724c1e9b..8011b7352 100644 --- a/modules/stormkit/core/typesafe/byte.mpp +++ b/modules/stormkit/core/typesafe/byte.cppm @@ -1,309 +1,309 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -#include - -export module stormkit.core:typesafe.byte; - -import std; - -import :meta; - -import :typesafe.integer; - -import :utils.contract; -import :utils.tags; - -namespace stdr = std::ranges; - -template -consteval auto get_byte_extent_value_of() { - if constexpr (EXTENT == std::dynamic_extent) return EXTENT; - else if constexpr (stormkit::meta::Is, void>) - return EXTENT; - else - return EXTENT * sizeof(T); -} - -export namespace stormkit { inline namespace core { - using std::byte; - using Byte = std::byte; - using ByteView = std::span; - template - using ByteArray = std::array; - using ByteDynArray = std::vector; - using MutableByteView = std::span; - - template - constexpr auto zero_bytes(T& value) noexcept -> void; - - template - constexpr auto zeroed() noexcept -> T; - - template - [[nodiscard]] - constexpr auto byte_swap(const T& value) noexcept -> T; - - // std::span - using std::as_bytes; - - template - [[nodiscard]] - constexpr auto as_bytes(const T* const ptr, usize size = 1) noexcept -> std::span; - - template - [[nodiscard]] - constexpr auto as_bytes(const Range& range) noexcept -> std::span; - - [[nodiscard]] - constexpr auto as_bytes(std::string_view string) noexcept -> std::span; - - template - [[nodiscard]] - constexpr auto as_bytes(const T& value) noexcept -> std::span; - - // std::span - template - [[nodiscard]] - constexpr auto as_bytes_mut(std::span container) noexcept - -> std::span()>; - - template - [[nodiscard]] - constexpr auto as_bytes_mut(Range& range) noexcept -> std::span; - - template - [[nodiscard]] - constexpr auto as_bytes_mut(T* const ptr, usize size = 1) noexcept -> std::span; - - template - [[nodiscard]] - constexpr auto as_bytes_mut(T& value) noexcept -> std::span; - - template - [[nodiscard]] - constexpr auto bytes_as(std::span bytes) noexcept -> const T&; - - template - [[nodiscard]] - constexpr auto bytes_mut_as(std::span bytes) noexcept -> T&; - - template - [[nodiscard]] - constexpr auto into_bytes(const T (&bytes)[N]) noexcept -> ByteArray; - - namespace literals { - [[nodiscard]] - constexpr auto operator""_b(unsigned long long value) noexcept -> byte; - - [[nodiscard]] - constexpr auto operator""_kb(unsigned long long x) noexcept -> u64; - - [[nodiscard]] - constexpr auto operator""_mb(unsigned long long x) noexcept -> u64; - - [[nodiscard]] - constexpr auto operator""_gb(unsigned long long x) noexcept -> u64; - - [[nodiscard]] - constexpr auto operator""_kib(unsigned long long x) noexcept -> u64; - - [[nodiscard]] - constexpr auto operator""_mib(unsigned long long x) noexcept -> u64; - - [[nodiscard]] - constexpr auto operator""_gib(unsigned long long x) noexcept -> u64; - - } // namespace literals -}} // namespace stormkit::core - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit { inline namespace core { - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto zero_bytes(T& value) noexcept -> void { - auto bytes = as_bytes_mut(value); - stdr::fill(bytes, byte { 0 }); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto zeroed() noexcept -> T { - auto data = T {}; - zero_bytes(data); - return data; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto byte_swap(const T& value) noexcept -> T { - if constexpr (meta::IsIntegral) return std::byteswap(value); - else { - auto repr = std::bit_cast>(value); - - stdr::reverse(repr); - - return std::bit_cast(repr); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto as_bytes(const T* const ptr, usize size) noexcept -> std::span { - return std::as_bytes(std::span { ptr, size }); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto as_bytes(const Range& range) noexcept -> std::span { - return as_bytes(std::span { range }); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - constexpr auto as_bytes(std::string_view value) noexcept -> std::span { - return std::as_bytes(std::span { stdr::data(value), stdr::size(value) }); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto as_bytes(const T& value) noexcept -> std::span { - return std::as_bytes(std::span { &value, 1 }); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - constexpr auto as_bytes_mut(std::span container) noexcept - -> std::span()> { - return std::as_writable_bytes(container); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto as_bytes_mut(Range& range) noexcept -> std::span { - return as_bytes_mut(std::span { range }); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto as_bytes_mut(T* const ptr, usize size) noexcept -> std::span { - return std::as_writable_bytes(std::span { ptr, size }); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto as_bytes_mut(T& value) noexcept -> std::span { - return std::as_writable_bytes(std::span { &value, 1 }); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto bytes_as(std::span bytes) noexcept -> const T& { - if constexpr (EXTENT != std::dynamic_extent) EXPECTS(EXTENT == sizeof(T)); - EXPECTS(stdr::size(bytes) == sizeof(T)); - return *std::bit_cast(stdr::data(bytes)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto bytes_mut_as(std::span bytes) noexcept -> T& { - if constexpr (EXTENT != std::dynamic_extent) EXPECTS(EXTENT == sizeof(T)); - EXPECTS(stdr::size(bytes) == sizeof(T)); - return *std::bit_cast(stdr::data(bytes)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto into_bytes(const T (&bytes)[N]) noexcept -> ByteArray { - EXPECTS(static_cast(static_cast(bytes[0])) == bytes[0]); - auto out = ByteArray {}; - auto i = 0_usize; - for (auto&& byte : bytes) out[i++] = static_cast(byte); - return out; - } - - namespace literals { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_CONST STORMKIT_INTRINSIC - constexpr auto operator""_b(unsigned long long value) noexcept -> byte { - return static_cast(value); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto operator""_kb(unsigned long long x) noexcept -> u64 { - return x * 1000ULL; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto operator""_mb(unsigned long long x) noexcept -> u64 { - return x * 1000_kb; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto operator""_gb(unsigned long long x) noexcept -> u64 { - return x * 1000_mb; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto operator""_kib(unsigned long long x) noexcept -> u64 { - return x * 1024; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto operator""_mib(unsigned long long x) noexcept -> u64 { - return x * 1024_kib; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto operator""_gib(unsigned long long x) noexcept -> u64 { - return x * 1024_mib; - } - } // namespace literals -}} // namespace stormkit::core +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +export module stormkit.core:typesafe.byte; + +import std; + +import :meta; + +import :typesafe.integer; + +import :utils.contract; +import :utils.tags; + +namespace stdr = std::ranges; + +template +consteval auto get_byte_extent_value_of() { + if constexpr (EXTENT == std::dynamic_extent) return EXTENT; + else if constexpr (stormkit::meta::Is, void>) + return EXTENT; + else + return EXTENT * sizeof(T); +} + +export namespace stormkit { inline namespace core { + using std::byte; + using Byte = std::byte; + using ByteView = std::span; + template + using ByteArray = std::array; + using ByteDynArray = std::vector; + using MutableByteView = std::span; + + template + constexpr auto zero_bytes(T& value) noexcept -> void; + + template + constexpr auto zeroed() noexcept -> T; + + template + [[nodiscard]] + constexpr auto byte_swap(const T& value) noexcept -> T; + + // std::span + using std::as_bytes; + + template + [[nodiscard]] + constexpr auto as_bytes(const T* const ptr, usize size = 1) noexcept -> std::span; + + template + [[nodiscard]] + constexpr auto as_bytes(const Range& range) noexcept -> std::span; + + [[nodiscard]] + constexpr auto as_bytes(std::string_view string) noexcept -> std::span; + + template + [[nodiscard]] + constexpr auto as_bytes(const T& value) noexcept -> std::span; + + // std::span + template + [[nodiscard]] + constexpr auto as_bytes_mut(std::span container) noexcept + -> std::span()>; + + template + [[nodiscard]] + constexpr auto as_bytes_mut(Range& range) noexcept -> std::span; + + template + [[nodiscard]] + constexpr auto as_bytes_mut(T* const ptr, usize size = 1) noexcept -> std::span; + + template + [[nodiscard]] + constexpr auto as_bytes_mut(T& value) noexcept -> std::span; + + template + [[nodiscard]] + constexpr auto bytes_as(std::span bytes) noexcept -> const T&; + + template + [[nodiscard]] + constexpr auto bytes_mut_as(std::span bytes) noexcept -> T&; + + template + [[nodiscard]] + constexpr auto into_bytes(const T (&bytes)[N]) noexcept -> ByteArray; + + namespace literals { + [[nodiscard]] + constexpr auto operator""_b(unsigned long long value) noexcept -> byte; + + [[nodiscard]] + constexpr auto operator""_kb(unsigned long long x) noexcept -> u64; + + [[nodiscard]] + constexpr auto operator""_mb(unsigned long long x) noexcept -> u64; + + [[nodiscard]] + constexpr auto operator""_gb(unsigned long long x) noexcept -> u64; + + [[nodiscard]] + constexpr auto operator""_kib(unsigned long long x) noexcept -> u64; + + [[nodiscard]] + constexpr auto operator""_mib(unsigned long long x) noexcept -> u64; + + [[nodiscard]] + constexpr auto operator""_gib(unsigned long long x) noexcept -> u64; + + } // namespace literals +}} // namespace stormkit::core + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit { inline namespace core { + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto zero_bytes(T& value) noexcept -> void { + auto bytes = as_bytes_mut(value); + stdr::fill(bytes, byte { 0 }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto zeroed() noexcept -> T { + auto data = T {}; + zero_bytes(data); + return data; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto byte_swap(const T& value) noexcept -> T { + if constexpr (meta::IsIntegral) return std::byteswap(value); + else { + auto repr = std::bit_cast>(value); + + stdr::reverse(repr); + + return std::bit_cast(repr); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto as_bytes(const T* const ptr, usize size) noexcept -> std::span { + return std::as_bytes(std::span { ptr, size }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto as_bytes(const Range& range) noexcept -> std::span { + return as_bytes(std::span { range }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto as_bytes(std::string_view value) noexcept -> std::span { + return std::as_bytes(std::span { stdr::data(value), stdr::size(value) }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto as_bytes(const T& value) noexcept -> std::span { + return std::as_bytes(std::span { &value, 1 }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + constexpr auto as_bytes_mut(std::span container) noexcept + -> std::span()> { + return std::as_writable_bytes(container); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto as_bytes_mut(Range& range) noexcept -> std::span { + return as_bytes_mut(std::span { range }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto as_bytes_mut(T* const ptr, usize size) noexcept -> std::span { + return std::as_writable_bytes(std::span { ptr, size }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto as_bytes_mut(T& value) noexcept -> std::span { + return std::as_writable_bytes(std::span { &value, 1 }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto bytes_as(std::span bytes) noexcept -> const T& { + if constexpr (EXTENT != std::dynamic_extent) EXPECTS(EXTENT == sizeof(T)); + EXPECTS(stdr::size(bytes) == sizeof(T)); + return *std::bit_cast(stdr::data(bytes)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto bytes_mut_as(std::span bytes) noexcept -> T& { + if constexpr (EXTENT != std::dynamic_extent) EXPECTS(EXTENT == sizeof(T)); + EXPECTS(stdr::size(bytes) == sizeof(T)); + return *std::bit_cast(stdr::data(bytes)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE STORMKIT_PURE + constexpr auto into_bytes(const T (&bytes)[N]) noexcept -> ByteArray { + EXPECTS(static_cast(static_cast(bytes[0])) == bytes[0]); + auto out = ByteArray {}; + auto i = 0_usize; + for (auto&& byte : bytes) out[i++] = static_cast(byte); + return out; + } + + namespace literals { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_CONST STORMKIT_INTRINSIC + constexpr auto operator""_b(unsigned long long value) noexcept -> byte { + return static_cast(value); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_CONST + constexpr auto operator""_kb(unsigned long long x) noexcept -> u64 { + return x * 1000ULL; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_CONST + constexpr auto operator""_mb(unsigned long long x) noexcept -> u64 { + return x * 1000_kb; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_CONST + constexpr auto operator""_gb(unsigned long long x) noexcept -> u64 { + return x * 1000_mb; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_CONST + constexpr auto operator""_kib(unsigned long long x) noexcept -> u64 { + return x * 1024; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_CONST + constexpr auto operator""_mib(unsigned long long x) noexcept -> u64 { + return x * 1024_kib; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_CONST + constexpr auto operator""_gib(unsigned long long x) noexcept -> u64 { + return x * 1024_mib; + } + } // namespace literals +}} // namespace stormkit::core diff --git a/modules/stormkit/core/typesafe/character.mpp b/modules/stormkit/core/typesafe/character.cppm similarity index 100% rename from modules/stormkit/core/typesafe/character.mpp rename to modules/stormkit/core/typesafe/character.cppm diff --git a/modules/stormkit/core/typesafe/checked_value.mpp b/modules/stormkit/core/typesafe/checked_value.cppm similarity index 100% rename from modules/stormkit/core/typesafe/checked_value.mpp rename to modules/stormkit/core/typesafe/checked_value.cppm diff --git a/modules/stormkit/core/typesafe/flags.mpp b/modules/stormkit/core/typesafe/flags.cppm similarity index 97% rename from modules/stormkit/core/typesafe/flags.mpp rename to modules/stormkit/core/typesafe/flags.cppm index 4db3b672c..4439f9983 100644 --- a/modules/stormkit/core/typesafe/flags.mpp +++ b/modules/stormkit/core/typesafe/flags.cppm @@ -1,300 +1,300 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -export module stormkit.core:typesafe.flags; - -import std; - -import :meta; - -import :string.constexpr_string; - -import :math.combinatoric; - -import :typesafe.integer; - -export { - namespace stormkit { inline namespace core { - namespace details { - template - struct EnableBitmaskOperators { - constexpr EnableBitmaskOperators() = default; - static constexpr auto enable = false; - }; - - template - inline constexpr auto BITMASK_OPERATORS_ENABLED = EnableBitmaskOperators::enable; - } // namespace details - - namespace meta { - template - concept IsFlag = (IsScopedEnumeration> and core::details::BITMASK_OPERATORS_ENABLED) - or IsPlainEnumeration>; - } - - /// \brief Check if a flag bit is enabled - /// \requires `Enum` to be an enumeration promoted static_cast a flag with `FLAG_ENUM` - /// macro - /// \returns true if the flag big is set and false if not - template - [[nodiscard]] - constexpr auto check_flag_bit(const T& value, const T& flag) noexcept -> bool; - - /// \exclude - template - [[nodiscard]] - constexpr auto next_value(const T& value) noexcept -> T; - - template - consteval auto generate_substitutions_as_string_for(std::string_view prefix, - const std::array, N>& mapping, - char separator = '|') noexcept -> decltype(auto); - - template - consteval auto generate_substitutions_as_string_for(std::string_view prefix, - const std::array, N>& mapping, - char separator = '|') noexcept -> decltype(auto); - }} // namespace stormkit::core - - template - [[nodiscard]] - constexpr auto operator|(const T& lhs, const T& rhs) noexcept -> decltype(auto); - - template - [[nodiscard]] - constexpr auto operator&(const T& lhs, const T& rhs) noexcept -> decltype(auto); - - template - [[nodiscard]] - constexpr auto operator^(const T& lhs, const T& rhs) noexcept -> decltype(auto); - - template - [[nodiscard]] - constexpr auto operator~(const T& lhs) noexcept -> decltype(auto); - - template - constexpr auto operator|=(T& lhs, const T& rhs) noexcept -> decltype(auto); - - template - constexpr auto operator&=(T& lhs, const T& rhs) noexcept -> decltype(auto); - - template - constexpr auto operator^=(T& lhs, const T& rhs) noexcept -> decltype(auto); -} - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit { inline namespace core { - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto check_flag_bit(const T& value, const T& flag) noexcept -> bool { - return (value & flag) == flag; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto next_value(const T& value) noexcept -> T { - using Underlying = meta::UnderlyingType; - return static_cast(static_cast(value) << 1); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - consteval auto generate_substitutions_as_string_for(std::string_view prefix, - const std::array, N>& mapping, - char separator) noexcept -> decltype(auto) { - constexpr auto OUT_SIZE = [] { - auto res = 0uz; - - constexpr auto n_fact = math::factoriel(N); - - if constexpr (static_cast(DEFAULT_VALUE) == 0) - for (auto R = 0uz; R < (N - 1); ++R) res += n_fact / (math::factoriel(N - R) * math::factoriel(R)); - else - for (auto R = 0uz; R < N; ++R) res += n_fact / (math::factoriel(N - R) * math::factoriel(R)); - - return res + 1; - }(); - - auto out = std::array>, OUT_SIZE> {}; - auto queue = std::vector> {}; - for (const auto& [k, v] : mapping) queue.emplace_back(k, std::string { v }, true); - - auto i = 0uz; - while (not stdr::empty(queue)) { - const auto [key, string, single_value] = queue.back(); - if (not stdr::any_of(out, [&key](auto& pair) noexcept { return pair.first == key; })) { - auto& [k, v] = out[i]; - k = key; - - auto out_string = std::string { prefix }; - if (single_value) out_string += string; - else { - out_string += "("; - out_string += string; - out_string += ")"; - } - - stdr::copy(out_string, stdr::begin(v)); - v.update_size(); - - i += 1; - } - if (key != DEFAULT_VALUE) { - for (const auto& [k, v] : mapping) { - const auto has_key = stdr::any_of(queue, ([_k = k | key](auto&& tuple) noexcept { - const auto& [_key, _, _] = tuple; - return _key == _k; - })); - - if (not has_key) { - auto str = string; - if (k != DEFAULT_VALUE) { - str += " "; - str += separator; - str += " "; - str += v; - } - queue.emplace(stdr::begin(queue), key | k, str, false); - } - } - } - queue.pop_back(); - } - return out; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - consteval auto generate_substitutions_as_string_for(std::string_view prefix, - const std::array, N>& mapping, - char separator) noexcept -> decltype(auto) { - constexpr auto OUT_SIZE = [] { - auto res = 0uz; - - constexpr auto n_fact = math::factoriel(N); - for (auto R = 0uz; R < N; ++R) res += n_fact / (math::factoriel(N - R) * math::factoriel(R)); - - return res; - }(); - - auto out = std::array>, OUT_SIZE> {}; - auto queue = std::vector> {}; - for (const auto& [k, v] : mapping) queue.emplace_back(k, std::string { v }, true); - - auto i = 0uz; - while (not stdr::empty(queue)) { - const auto [key, string, single_value] = queue.back(); - if (not stdr::any_of(out, [&key](auto& pair) noexcept { return pair.first == key; })) { - auto& [k, v] = out[i]; - k = key; - - auto out_string = std::string { prefix }; - if (single_value) out_string += string; - else { - out_string += "("; - out_string += string; - out_string += ")"; - } - - stdr::copy(out_string, stdr::begin(v)); - v.update_size(); - - i += 1; - } - for (const auto& [k, v] : mapping) { - const auto has_key = stdr::any_of(queue, [_k = k | key](auto tuple) noexcept { - const auto& [_key, _, _] = tuple; - return _key == _k; - }); - - if (not has_key) queue.emplace(stdr::begin(queue), key | k, string + " " + separator + " " + v, false); - } - queue.pop_back(); - } - return out; - } -}} // namespace stormkit::core - -///////////////////////////////////// -///////////////////////////////////// -template -STORMKIT_FORCE_INLINE -constexpr auto operator|(const T& lhs, const T& rhs) noexcept -> decltype(auto) { - using namespace stormkit; - using Underlying = meta::UnderlyingType; - return static_cast(static_cast(lhs) | static_cast(rhs)); -} - -///////////////////////////////////// -///////////////////////////////////// -template -STORMKIT_FORCE_INLINE -constexpr auto operator&(const T& lhs, const T& rhs) noexcept -> decltype(auto) { - using namespace stormkit; - using Underlying = meta::UnderlyingType; - return static_cast(static_cast(lhs) & static_cast(rhs)); -} - -///////////////////////////////////// -///////////////////////////////////// -template -STORMKIT_FORCE_INLINE -constexpr auto operator^(const T& lhs, const T& rhs) noexcept -> decltype(auto) { - using namespace stormkit; - using Underlying = meta::UnderlyingType; - return static_cast(static_cast(lhs) ^ static_cast(rhs)); -} - -///////////////////////////////////// -///////////////////////////////////// -template -STORMKIT_FORCE_INLINE -constexpr auto operator~(const T& lhs) noexcept -> decltype(auto) { - using namespace stormkit; - using Underlying = meta::UnderlyingType; - return static_cast(~static_cast(lhs)); -} - -///////////////////////////////////// -///////////////////////////////////// -template -STORMKIT_FORCE_INLINE -constexpr auto operator|=(T& lhs, const T& rhs) noexcept -> decltype(auto) { - using namespace stormkit; - lhs = lhs | rhs; - return lhs; -} - -///////////////////////////////////// -///////////////////////////////////// -template -STORMKIT_FORCE_INLINE -constexpr auto operator&=(T& lhs, const T& rhs) noexcept -> decltype(auto) { - using namespace stormkit; - lhs = lhs & rhs; - return lhs; -} - -///////////////////////////////////// -///////////////////////////////////// -template -STORMKIT_FORCE_INLINE -constexpr auto operator^=(T& lhs, const T& rhs) noexcept -> decltype(auto) { - using namespace stormkit; - lhs = lhs ^ rhs; - return lhs; -} +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.core:typesafe.flags; + +import std; + +import :meta; + +import :string.constexpr_string; + +import :math.combinatoric; + +import :typesafe.integer; + +export { + namespace stormkit { inline namespace core { + namespace details { + template + struct EnableBitmaskOperators { + constexpr EnableBitmaskOperators() = default; + static constexpr auto enable = false; + }; + + template + inline constexpr auto BITMASK_OPERATORS_ENABLED = EnableBitmaskOperators::enable; + } // namespace details + + namespace meta { + template + concept IsFlag = (IsScopedEnumeration> and core::details::BITMASK_OPERATORS_ENABLED) + or IsPlainEnumeration>; + } + + /// \brief Check if a flag bit is enabled + /// \requires `Enum` to be an enumeration promoted static_cast a flag with `FLAG_ENUM` + /// macro + /// \returns true if the flag big is set and false if not + template + [[nodiscard]] + constexpr auto check_flag_bit(const T& value, const T& flag) noexcept -> bool; + + /// \exclude + template + [[nodiscard]] + constexpr auto next_value(const T& value) noexcept -> T; + + template + consteval auto generate_substitutions_as_string_for(std::string_view prefix, + const std::array, N>& mapping, + char separator = '|') noexcept -> decltype(auto); + + template + consteval auto generate_substitutions_as_string_for(std::string_view prefix, + const std::array, N>& mapping, + char separator = '|') noexcept -> decltype(auto); + }} // namespace stormkit::core + + template + [[nodiscard]] + constexpr auto operator|(const T& lhs, const T& rhs) noexcept -> decltype(auto); + + template + [[nodiscard]] + constexpr auto operator&(const T& lhs, const T& rhs) noexcept -> decltype(auto); + + template + [[nodiscard]] + constexpr auto operator^(const T& lhs, const T& rhs) noexcept -> decltype(auto); + + template + [[nodiscard]] + constexpr auto operator~(const T& lhs) noexcept -> decltype(auto); + + template + constexpr auto operator|=(T& lhs, const T& rhs) noexcept -> decltype(auto); + + template + constexpr auto operator&=(T& lhs, const T& rhs) noexcept -> decltype(auto); + + template + constexpr auto operator^=(T& lhs, const T& rhs) noexcept -> decltype(auto); +} + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit { inline namespace core { + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto check_flag_bit(const T& value, const T& flag) noexcept -> bool { + return (value & flag) == flag; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto next_value(const T& value) noexcept -> T { + using Underlying = meta::UnderlyingType; + return static_cast(static_cast(value) << 1); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + consteval auto generate_substitutions_as_string_for(std::string_view prefix, + const std::array, N>& mapping, + char separator) noexcept -> decltype(auto) { + constexpr auto OUT_SIZE = [] { + auto res = 0uz; + + constexpr auto n_fact = math::factoriel(N); + + if constexpr (static_cast(DEFAULT_VALUE) == 0) + for (auto R = 0uz; R < (N - 1); ++R) res += n_fact / (math::factoriel(N - R) * math::factoriel(R)); + else + for (auto R = 0uz; R < N; ++R) res += n_fact / (math::factoriel(N - R) * math::factoriel(R)); + + return res + 1; + }(); + + auto out = std::array>, OUT_SIZE> {}; + auto queue = std::vector> {}; + for (const auto& [k, v] : mapping) queue.emplace_back(k, std::string { v }, true); + + auto i = 0uz; + while (not stdr::empty(queue)) { + const auto [key, string, single_value] = queue.back(); + if (not stdr::any_of(out, [&key](auto& pair) noexcept { return pair.first == key; })) { + auto& [k, v] = out[i]; + k = key; + + auto out_string = std::string { prefix }; + if (single_value) out_string += string; + else { + out_string += "("; + out_string += string; + out_string += ")"; + } + + stdr::copy(out_string, stdr::begin(v)); + v.update_size(); + + i += 1; + } + if (key != DEFAULT_VALUE) { + for (const auto& [k, v] : mapping) { + const auto has_key = stdr::any_of(queue, ([_k = k | key](auto&& tuple) noexcept { + const auto& [_key, _, _] = tuple; + return _key == _k; + })); + + if (not has_key) { + auto str = string; + if (k != DEFAULT_VALUE) { + str += " "; + str += separator; + str += " "; + str += v; + } + queue.emplace(stdr::begin(queue), key | k, str, false); + } + } + } + queue.pop_back(); + } + return out; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + consteval auto generate_substitutions_as_string_for(std::string_view prefix, + const std::array, N>& mapping, + char separator) noexcept -> decltype(auto) { + constexpr auto OUT_SIZE = [] { + auto res = 0uz; + + constexpr auto n_fact = math::factoriel(N); + for (auto R = 0uz; R < N; ++R) res += n_fact / (math::factoriel(N - R) * math::factoriel(R)); + + return res; + }(); + + auto out = std::array>, OUT_SIZE> {}; + auto queue = std::vector> {}; + for (const auto& [k, v] : mapping) queue.emplace_back(k, std::string { v }, true); + + auto i = 0uz; + while (not stdr::empty(queue)) { + const auto [key, string, single_value] = queue.back(); + if (not stdr::any_of(out, [&key](auto& pair) noexcept { return pair.first == key; })) { + auto& [k, v] = out[i]; + k = key; + + auto out_string = std::string { prefix }; + if (single_value) out_string += string; + else { + out_string += "("; + out_string += string; + out_string += ")"; + } + + stdr::copy(out_string, stdr::begin(v)); + v.update_size(); + + i += 1; + } + for (const auto& [k, v] : mapping) { + const auto has_key = stdr::any_of(queue, [_k = k | key](auto tuple) noexcept { + const auto& [_key, _, _] = tuple; + return _key == _k; + }); + + if (not has_key) queue.emplace(stdr::begin(queue), key | k, string + " " + separator + " " + v, false); + } + queue.pop_back(); + } + return out; + } +}} // namespace stormkit::core + +///////////////////////////////////// +///////////////////////////////////// +template +STORMKIT_FORCE_INLINE +constexpr auto operator|(const T& lhs, const T& rhs) noexcept -> decltype(auto) { + using namespace stormkit; + using Underlying = meta::UnderlyingType; + return static_cast(static_cast(lhs) | static_cast(rhs)); +} + +///////////////////////////////////// +///////////////////////////////////// +template +STORMKIT_FORCE_INLINE +constexpr auto operator&(const T& lhs, const T& rhs) noexcept -> decltype(auto) { + using namespace stormkit; + using Underlying = meta::UnderlyingType; + return static_cast(static_cast(lhs) & static_cast(rhs)); +} + +///////////////////////////////////// +///////////////////////////////////// +template +STORMKIT_FORCE_INLINE +constexpr auto operator^(const T& lhs, const T& rhs) noexcept -> decltype(auto) { + using namespace stormkit; + using Underlying = meta::UnderlyingType; + return static_cast(static_cast(lhs) ^ static_cast(rhs)); +} + +///////////////////////////////////// +///////////////////////////////////// +template +STORMKIT_FORCE_INLINE +constexpr auto operator~(const T& lhs) noexcept -> decltype(auto) { + using namespace stormkit; + using Underlying = meta::UnderlyingType; + return static_cast(~static_cast(lhs)); +} + +///////////////////////////////////// +///////////////////////////////////// +template +STORMKIT_FORCE_INLINE +constexpr auto operator|=(T& lhs, const T& rhs) noexcept -> decltype(auto) { + using namespace stormkit; + lhs = lhs | rhs; + return lhs; +} + +///////////////////////////////////// +///////////////////////////////////// +template +STORMKIT_FORCE_INLINE +constexpr auto operator&=(T& lhs, const T& rhs) noexcept -> decltype(auto) { + using namespace stormkit; + lhs = lhs & rhs; + return lhs; +} + +///////////////////////////////////// +///////////////////////////////////// +template +STORMKIT_FORCE_INLINE +constexpr auto operator^=(T& lhs, const T& rhs) noexcept -> decltype(auto) { + using namespace stormkit; + lhs = lhs ^ rhs; + return lhs; +} diff --git a/modules/stormkit/core/typesafe/float.mpp b/modules/stormkit/core/typesafe/float.cppm similarity index 100% rename from modules/stormkit/core/typesafe/float.mpp rename to modules/stormkit/core/typesafe/float.cppm diff --git a/modules/stormkit/core/typesafe/integer.mpp b/modules/stormkit/core/typesafe/integer.cppm similarity index 100% rename from modules/stormkit/core/typesafe/integer.mpp rename to modules/stormkit/core/typesafe/integer.cppm diff --git a/modules/stormkit/core/typesafe/ref.mpp b/modules/stormkit/core/typesafe/ref.cppm similarity index 100% rename from modules/stormkit/core/typesafe/ref.mpp rename to modules/stormkit/core/typesafe/ref.cppm diff --git a/modules/stormkit/core/typesafe/safecasts.mpp b/modules/stormkit/core/typesafe/safecasts.cppm similarity index 100% rename from modules/stormkit/core/typesafe/safecasts.mpp rename to modules/stormkit/core/typesafe/safecasts.cppm diff --git a/modules/stormkit/core/typesafe/strong_type.mpp b/modules/stormkit/core/typesafe/strong_type.cppm similarity index 100% rename from modules/stormkit/core/typesafe/strong_type.mpp rename to modules/stormkit/core/typesafe/strong_type.cppm diff --git a/modules/stormkit/core/utils.mpp b/modules/stormkit/core/utils.cppm similarity index 97% rename from modules/stormkit/core/utils.mpp rename to modules/stormkit/core/utils.cppm index c809d8ce7..0ebe7859d 100644 --- a/modules/stormkit/core/utils.mpp +++ b/modules/stormkit/core/utils.cppm @@ -1,24 +1,24 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -export module stormkit.core:utils; - -export import :utils.algorithms; -export import :utils.allocation; -export import :utils.app; -export import :utils.contract; -export import :utils.color; -export import :utils.deferinit; -export import :utils.dynamic_loader; -export import :utils.filesystem; -export import :utils.function_ref; -export import :utils.handle; -export import :utils.numeric_range; -export import :utils.pimpl; -export import :utils.random; -export import :utils.singleton; -export import :utils.stracktrace; -export import :utils.signal_handler; -export import :utils.tags; -export import :utils.time; +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +export module stormkit.core:utils; + +export import :utils.algorithms; +export import :utils.allocation; +export import :utils.app; +export import :utils.contract; +export import :utils.color; +export import :utils.deferinit; +export import :utils.dynamic_loader; +export import :utils.filesystem; +export import :utils.function_ref; +export import :utils.handle; +export import :utils.numeric_range; +export import :utils.pimpl; +export import :utils.random; +export import :utils.singleton; +export import :utils.stracktrace; +export import :utils.signal_handler; +export import :utils.tags; +export import :utils.time; diff --git a/modules/stormkit/core/utils/algorithms.mpp b/modules/stormkit/core/utils/algorithms.cppm similarity index 98% rename from modules/stormkit/core/utils/algorithms.mpp rename to modules/stormkit/core/utils/algorithms.cppm index 135a81cf8..4f6276093 100644 --- a/modules/stormkit/core/utils/algorithms.mpp +++ b/modules/stormkit/core/utils/algorithms.cppm @@ -1,94 +1,94 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -export module stormkit.core:utils.algorithms; - -import std; - -import :meta; - -export namespace stormkit { inline namespace core { - template::value_type> Predicate> - [[nodiscard]] - constexpr auto copy_if(Range&& input, Predicate&& predicate) noexcept; - - template::value_type&> Lambda> - [[nodiscard]] - constexpr auto transform(Range&& input, Lambda&& lambda) noexcept; - - template::value_type> Predicate, - std::invocable::value_type&> Lambda> - [[nodiscard]] - constexpr auto transform_if(Range&& input, Predicate&& predicate, Lambda&& lambda) noexcept; - - template::value_type> Predicate, - std::invocable::value_type&> Lambda, - std::output_iterator::value_type&>> Iterator> - constexpr auto transform_if(Range&& input, Iterator&& it, Predicate&& predicate, Lambda&& lambda) noexcept -> void; -}} // namespace stormkit::core - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit { inline namespace core { - ///////////////////////////////////// - ///////////////////////////////////// - template::value_type> Predicate> - constexpr auto copy_if(Range&& input, Predicate&& predicate) noexcept { - auto output = std::vector::value_type> {}; - - output.reserve(std::size(input)); - - std::ranges::copy_if(input, std::back_inserter(output), std::forward(predicate)); - - return output; - - } - - ///////////////////////////////////// - ///////////////////////////////////// - template::value_type&> Lambda> - constexpr auto transform(Range&& input, Lambda&& lambda) noexcept { - auto output = std::vector< - std::invoke_result_t, const typename std::remove_cvref_t::value_type&>> {}; - output.reserve(std::size(input)); - - std::ranges::transform(input, std::back_inserter(output), lambda); - - return output; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template::value_type> Predicate, - std::invocable::value_type&> Lambda> - constexpr auto transform_if(Range&& input, Predicate&& predicate, Lambda&& lambda) noexcept { - auto output = std::vector< - std::invoke_result_t, const typename std::remove_cvref_t::value_type&>> {}; - output.reserve(std::size(input)); - - std::ranges::for_each(input, [&](auto& elem) { - if (predicate(elem)) output.emplace_back(lambda(elem)); - }); - - return output; - - } - - ///////////////////////////////////// - ///////////////////////////////////// - template::value_type> Predicate, - std::invocable::value_type&> Lambda, - std::output_iterator::value_type&>> Iterator> - constexpr auto transform_if(Range&& input, Iterator&& it, Predicate&& predicate, Lambda&& lambda) noexcept -> void { - std::ranges::for_each(input, [&](auto& elem) { - if (predicate(elem)) *it++ = lambda(elem); - }); - } -}} // namespace stormkit::core +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +export module stormkit.core:utils.algorithms; + +import std; + +import :meta; + +export namespace stormkit { inline namespace core { + template::value_type> Predicate> + [[nodiscard]] + constexpr auto copy_if(Range&& input, Predicate&& predicate) noexcept; + + template::value_type&> Lambda> + [[nodiscard]] + constexpr auto transform(Range&& input, Lambda&& lambda) noexcept; + + template::value_type> Predicate, + std::invocable::value_type&> Lambda> + [[nodiscard]] + constexpr auto transform_if(Range&& input, Predicate&& predicate, Lambda&& lambda) noexcept; + + template::value_type> Predicate, + std::invocable::value_type&> Lambda, + std::output_iterator::value_type&>> Iterator> + constexpr auto transform_if(Range&& input, Iterator&& it, Predicate&& predicate, Lambda&& lambda) noexcept -> void; +}} // namespace stormkit::core + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit { inline namespace core { + ///////////////////////////////////// + ///////////////////////////////////// + template::value_type> Predicate> + constexpr auto copy_if(Range&& input, Predicate&& predicate) noexcept { + auto output = std::vector::value_type> {}; + + output.reserve(std::size(input)); + + std::ranges::copy_if(input, std::back_inserter(output), std::forward(predicate)); + + return output; + + } + + ///////////////////////////////////// + ///////////////////////////////////// + template::value_type&> Lambda> + constexpr auto transform(Range&& input, Lambda&& lambda) noexcept { + auto output = std::vector< + std::invoke_result_t, const typename std::remove_cvref_t::value_type&>> {}; + output.reserve(std::size(input)); + + std::ranges::transform(input, std::back_inserter(output), lambda); + + return output; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template::value_type> Predicate, + std::invocable::value_type&> Lambda> + constexpr auto transform_if(Range&& input, Predicate&& predicate, Lambda&& lambda) noexcept { + auto output = std::vector< + std::invoke_result_t, const typename std::remove_cvref_t::value_type&>> {}; + output.reserve(std::size(input)); + + std::ranges::for_each(input, [&](auto& elem) { + if (predicate(elem)) output.emplace_back(lambda(elem)); + }); + + return output; + + } + + ///////////////////////////////////// + ///////////////////////////////////// + template::value_type> Predicate, + std::invocable::value_type&> Lambda, + std::output_iterator::value_type&>> Iterator> + constexpr auto transform_if(Range&& input, Iterator&& it, Predicate&& predicate, Lambda&& lambda) noexcept -> void { + std::ranges::for_each(input, [&](auto& elem) { + if (predicate(elem)) *it++ = lambda(elem); + }); + } +}} // namespace stormkit::core diff --git a/modules/stormkit/core/utils/allocation.mpp b/modules/stormkit/core/utils/allocation.cppm similarity index 100% rename from modules/stormkit/core/utils/allocation.mpp rename to modules/stormkit/core/utils/allocation.cppm diff --git a/modules/stormkit/core/utils/app.mpp b/modules/stormkit/core/utils/app.cppm similarity index 96% rename from modules/stormkit/core/utils/app.mpp rename to modules/stormkit/core/utils/app.cppm index aecb718dc..c908ca5e3 100644 --- a/modules/stormkit/core/utils/app.mpp +++ b/modules/stormkit/core/utils/app.cppm @@ -1,31 +1,31 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -#include - -export module stormkit.core:utils.app; - -import std; - -import :typesafe.integer; - -export namespace stormkit { inline namespace core { - class STORMKIT_API App { - public: - App() noexcept = default; - virtual ~App() noexcept = default; - - App(App&&) noexcept = delete; - auto operator=(App&&) noexcept -> App& = delete; - - App(const App&) noexcept = delete; - auto operator=(const App&) noexcept -> App& = delete; - - virtual auto run(std::span args) -> i32 = 0; - }; -}} // namespace stormkit::core +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +export module stormkit.core:utils.app; + +import std; + +import :typesafe.integer; + +export namespace stormkit { inline namespace core { + class STORMKIT_API App { + public: + App() noexcept = default; + virtual ~App() noexcept = default; + + App(App&&) noexcept = delete; + auto operator=(App&&) noexcept -> App& = delete; + + App(const App&) noexcept = delete; + auto operator=(const App&) noexcept -> App& = delete; + + virtual auto run(std::span args) -> i32 = 0; + }; +}} // namespace stormkit::core diff --git a/modules/stormkit/core/utils/color.mpp b/modules/stormkit/core/utils/color.cppm similarity index 100% rename from modules/stormkit/core/utils/color.mpp rename to modules/stormkit/core/utils/color.cppm diff --git a/modules/stormkit/core/utils/contract.mpp b/modules/stormkit/core/utils/contract.cppm similarity index 97% rename from modules/stormkit/core/utils/contract.mpp rename to modules/stormkit/core/utils/contract.cppm index a50155259..212a7a3d2 100644 --- a/modules/stormkit/core/utils/contract.mpp +++ b/modules/stormkit/core/utils/contract.cppm @@ -1,192 +1,192 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -#ifndef STORMKIT_ASSERT - #define STORMKIT_ASSERT 1 -#endif - -export module stormkit.core:utils.contract; - -import std; -import frozen; - -import :utils.stracktrace; - -import :meta; - -namespace stdr = std::ranges; - -export namespace stormkit { inline namespace core { - enum class AssertType { - Assertion, - PreCondition, - PostCondition, - }; - - constexpr auto as_string(AssertType type) noexcept -> std::string_view; - constexpr auto to_string(AssertType type) noexcept -> std::string; - - STORMKIT_API - auto assert_base(bool cond, - AssertType type, - std::string_view message, - const std::source_location& location = std::source_location::current()) noexcept -> void; - - consteval auto consteval_assert_base(bool cond, AssertType type, std::string_view message) noexcept -> void; - - constexpr auto assert(bool cond, - std::string_view message, - const std::source_location& location = std::source_location::current()) noexcept -> void; - - constexpr auto assert(bool cond, const std::source_location& location = std::source_location::current()) noexcept -> void; - - constexpr auto expects(bool cond, - std::string_view message, - const std::source_location& location = std::source_location::current()) noexcept -> void; - - constexpr auto expects(bool cond, const std::source_location& location = std::source_location::current()) noexcept -> void; - - constexpr auto ensures(bool cond, - std::string_view message, - const std::source_location& location = std::source_location::current()) noexcept -> void; - - constexpr auto ensures(bool cond, const std::source_location& location = std::source_location::current()) noexcept -> void; - - namespace casts::core { - template To> - [[nodiscard]] - constexpr auto as(AssertType t) noexcept -> To; - } -}} // namespace stormkit::core - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -using namespace std::literals; -using namespace frozen::string_literals; - -namespace stormkit { inline namespace core { - namespace casts::core { - constexpr auto AssertTypeToContractName = frozen::make_unordered_map({ - { AssertType::Assertion, "Contract check"_s }, - { AssertType::PreCondition, "Pre condition check"_s }, - { AssertType::PostCondition, "Post condition check"_s }, - }); - - } // namespace casts::core - - struct StringLiteral { - std::array buff; - std::size_t size; - - consteval auto view() noexcept -> std::string_view { return { std::data(buff), size }; } - }; - - auto constevalFailure(StringLiteral) -> void; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto as_string(AssertType type) noexcept -> std::string_view { - const auto t = casts::core::AssertTypeToContractName.at(type); - return { stdr::data(t), stdr::size(t) }; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto to_string(AssertType type) noexcept -> std::string { - const auto t = casts::core::AssertTypeToContractName.at(type); - return { stdr::data(t), stdr::size(t) }; - } - - ///////////////////////////////////// - ///////////////////////////////////// - consteval auto generateConstevalMessage(AssertType type, std::string_view message) noexcept -> StringLiteral { - auto result = StringLiteral {}; - const auto str = "[Assertion]"s + to_string(type) + ": " + std::string { message }; - std::ranges::copy(str, std::begin(result.buff)); - result.size = std::size(str); - return result; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - consteval auto consteval_assert_base(bool cond, AssertType type, std::string_view message) noexcept -> void { - if (not cond) [[unlikely]] { constevalFailure(generateConstevalMessage(type, message)); } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - constexpr auto assert(bool cond, std::string_view message, [[maybe_unused]] const std::source_location& location) noexcept - -> void { -#ifdef STORMKIT_COMPILER_MSVC - if constexpr (std::is_constant_evaluated()) { -#else - if consteval { -#endif - consteval_assert_base(cond, AssertType::Assertion, message); - } else { - assert_base(cond, AssertType::Assertion, message, location); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - constexpr auto assert(bool cond, const std::source_location& location) noexcept -> void { - assert(cond, "", location); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - constexpr auto expects(bool cond, std::string_view message, const std::source_location& location) noexcept -> void { -#ifdef STORMKIT_COMPILER_MSVC - if constexpr (std::is_constant_evaluated()) { -#else - if consteval { -#endif - consteval_assert_base(cond, AssertType::PreCondition, message); - } else { - assert_base(cond, AssertType::PreCondition, message, location); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - constexpr auto expects(bool cond, const std::source_location& location) noexcept -> void { - expects(cond, "", location); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - constexpr auto ensures(bool cond, std::string_view message, const std::source_location& location) noexcept -> void { -#ifdef STORMKIT_COMPILER_MSVC - if constexpr (std::is_constant_evaluated()) { -#else - if consteval { -#endif - consteval_assert_base(cond, AssertType::PostCondition, message); - } else { - assert_base(cond, AssertType::PostCondition, message, location); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - constexpr auto ensures(bool cond, const std::source_location& location) noexcept -> void { - ensures(cond, "", location); - } -}} // namespace stormkit::core +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#ifndef STORMKIT_ASSERT + #define STORMKIT_ASSERT 1 +#endif + +export module stormkit.core:utils.contract; + +import std; +import frozen; + +import :utils.stracktrace; + +import :meta; + +namespace stdr = std::ranges; + +export namespace stormkit { inline namespace core { + enum class AssertType { + Assertion, + PreCondition, + PostCondition, + }; + + constexpr auto as_string(AssertType type) noexcept -> std::string_view; + constexpr auto to_string(AssertType type) noexcept -> std::string; + + STORMKIT_API + auto assert_base(bool cond, + AssertType type, + std::string_view message, + const std::source_location& location = std::source_location::current()) noexcept -> void; + + consteval auto consteval_assert_base(bool cond, AssertType type, std::string_view message) noexcept -> void; + + constexpr auto assert(bool cond, + std::string_view message, + const std::source_location& location = std::source_location::current()) noexcept -> void; + + constexpr auto assert(bool cond, const std::source_location& location = std::source_location::current()) noexcept -> void; + + constexpr auto expects(bool cond, + std::string_view message, + const std::source_location& location = std::source_location::current()) noexcept -> void; + + constexpr auto expects(bool cond, const std::source_location& location = std::source_location::current()) noexcept -> void; + + constexpr auto ensures(bool cond, + std::string_view message, + const std::source_location& location = std::source_location::current()) noexcept -> void; + + constexpr auto ensures(bool cond, const std::source_location& location = std::source_location::current()) noexcept -> void; + + namespace casts::core { + template To> + [[nodiscard]] + constexpr auto as(AssertType t) noexcept -> To; + } +}} // namespace stormkit::core + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +using namespace std::literals; +using namespace frozen::string_literals; + +namespace stormkit { inline namespace core { + namespace casts::core { + constexpr auto AssertTypeToContractName = frozen::make_unordered_map({ + { AssertType::Assertion, "Contract check"_s }, + { AssertType::PreCondition, "Pre condition check"_s }, + { AssertType::PostCondition, "Post condition check"_s }, + }); + + } // namespace casts::core + + struct StringLiteral { + std::array buff; + std::size_t size; + + consteval auto view() noexcept -> std::string_view { return { std::data(buff), size }; } + }; + + auto constevalFailure(StringLiteral) -> void; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_CONST + constexpr auto as_string(AssertType type) noexcept -> std::string_view { + const auto t = casts::core::AssertTypeToContractName.at(type); + return { stdr::data(t), stdr::size(t) }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_CONST + constexpr auto to_string(AssertType type) noexcept -> std::string { + const auto t = casts::core::AssertTypeToContractName.at(type); + return { stdr::data(t), stdr::size(t) }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + consteval auto generateConstevalMessage(AssertType type, std::string_view message) noexcept -> StringLiteral { + auto result = StringLiteral {}; + const auto str = "[Assertion]"s + to_string(type) + ": " + std::string { message }; + std::ranges::copy(str, std::begin(result.buff)); + result.size = std::size(str); + return result; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + consteval auto consteval_assert_base(bool cond, AssertType type, std::string_view message) noexcept -> void { + if (not cond) [[unlikely]] { constevalFailure(generateConstevalMessage(type, message)); } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto assert(bool cond, std::string_view message, [[maybe_unused]] const std::source_location& location) noexcept + -> void { +#ifdef STORMKIT_COMPILER_MSVC + if constexpr (std::is_constant_evaluated()) { +#else + if consteval { +#endif + consteval_assert_base(cond, AssertType::Assertion, message); + } else { + assert_base(cond, AssertType::Assertion, message, location); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto assert(bool cond, const std::source_location& location) noexcept -> void { + assert(cond, "", location); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto expects(bool cond, std::string_view message, const std::source_location& location) noexcept -> void { +#ifdef STORMKIT_COMPILER_MSVC + if constexpr (std::is_constant_evaluated()) { +#else + if consteval { +#endif + consteval_assert_base(cond, AssertType::PreCondition, message); + } else { + assert_base(cond, AssertType::PreCondition, message, location); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto expects(bool cond, const std::source_location& location) noexcept -> void { + expects(cond, "", location); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto ensures(bool cond, std::string_view message, const std::source_location& location) noexcept -> void { +#ifdef STORMKIT_COMPILER_MSVC + if constexpr (std::is_constant_evaluated()) { +#else + if consteval { +#endif + consteval_assert_base(cond, AssertType::PostCondition, message); + } else { + assert_base(cond, AssertType::PostCondition, message, location); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto ensures(bool cond, const std::source_location& location) noexcept -> void { + ensures(cond, "", location); + } +}} // namespace stormkit::core diff --git a/modules/stormkit/core/utils/deferinit.mpp b/modules/stormkit/core/utils/deferinit.cppm similarity index 100% rename from modules/stormkit/core/utils/deferinit.mpp rename to modules/stormkit/core/utils/deferinit.cppm diff --git a/modules/stormkit/core/utils/dynamic_loader.mpp b/modules/stormkit/core/utils/dynamic_loader.cppm similarity index 97% rename from modules/stormkit/core/utils/dynamic_loader.mpp rename to modules/stormkit/core/utils/dynamic_loader.cppm index f9a176d1d..2b909962f 100644 --- a/modules/stormkit/core/utils/dynamic_loader.mpp +++ b/modules/stormkit/core/utils/dynamic_loader.cppm @@ -1,133 +1,133 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -#include - -#include - -export module stormkit.core:utils.dynamic_loader; - -import std; - -import :utils.contract; -import :utils.pimpl; - -export namespace stormkit { inline namespace core { - class STORMKIT_API DynamicLoader { - public: - template - using Expected = std::expected; - - ~DynamicLoader(); - - DynamicLoader(const DynamicLoader&) = delete; - auto operator=(const DynamicLoader&) -> DynamicLoader& = delete; - - DynamicLoader(DynamicLoader&&) noexcept; - auto operator=(DynamicLoader&&) noexcept -> DynamicLoader&; - - [[nodiscard]] - static auto load(std::filesystem::path filepath) noexcept -> Expected; - - [[nodiscard]] - static auto allocate_and_load(std::filesystem::path filepath) noexcept -> Expected>; - - template - [[nodiscard]] - auto func(std::string_view name) const noexcept -> Expected>; - - template - [[nodiscard]] - auto c_func(std::string_view name) const noexcept -> Expected; - - [[nodiscard]] - auto filepath() const noexcept -> const std::filesystem::path&; - - private: - DynamicLoader() noexcept; - - auto do_load(std::filesystem::path filepath) -> Expected; - auto do_get_func(std::string_view name) const -> Expected; - - std::filesystem::path m_filepath; - void* m_library_handle = nullptr; - }; -}} // namespace stormkit::core - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit { inline namespace core { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline DynamicLoader::DynamicLoader() noexcept - = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline DynamicLoader::DynamicLoader(DynamicLoader&& other) noexcept - : m_filepath { std::move(other.m_filepath) }, m_library_handle { std::exchange(other.m_library_handle, nullptr) } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DynamicLoader::operator=(DynamicLoader&& other) noexcept -> DynamicLoader& { - if (&other == this) [[unlikely]] - return *this; - - m_filepath = std::move(other.m_filepath); - m_library_handle = std::exchange(other.m_library_handle, nullptr); - - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto DynamicLoader::load(std::filesystem::path filepath) noexcept -> Expected { - auto loader = DynamicLoader {}; - - return loader.do_load(std::move(filepath)).transform([&]() { return std::move(loader); }); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto DynamicLoader::allocate_and_load(std::filesystem::path filepath) noexcept - -> Expected> { - return load(std::move(filepath)) - .transform([](auto&& loader) { return std::make_unique(std::move(loader)); }); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - inline auto DynamicLoader::func(std::string_view name) const noexcept -> Expected> { - return c_func(name) - .transform([](T&& value) { return std::function { std::forward(value) }; }); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - inline auto DynamicLoader::c_func(std::string_view name) const noexcept -> Expected { - EXPECTS(not std::empty(name)); - - return do_get_func(name) - .transform([](T&& value) { return std::bit_cast(std::forward(value)); }); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DynamicLoader::filepath() const noexcept -> const std::filesystem::path& { - return m_filepath; - } -}} // namespace stormkit::core +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +#include + +export module stormkit.core:utils.dynamic_loader; + +import std; + +import :utils.contract; +import :utils.pimpl; + +export namespace stormkit { inline namespace core { + class STORMKIT_API DynamicLoader { + public: + template + using Expected = std::expected; + + ~DynamicLoader(); + + DynamicLoader(const DynamicLoader&) = delete; + auto operator=(const DynamicLoader&) -> DynamicLoader& = delete; + + DynamicLoader(DynamicLoader&&) noexcept; + auto operator=(DynamicLoader&&) noexcept -> DynamicLoader&; + + [[nodiscard]] + static auto load(std::filesystem::path filepath) noexcept -> Expected; + + [[nodiscard]] + static auto allocate_and_load(std::filesystem::path filepath) noexcept -> Expected>; + + template + [[nodiscard]] + auto func(std::string_view name) const noexcept -> Expected>; + + template + [[nodiscard]] + auto c_func(std::string_view name) const noexcept -> Expected; + + [[nodiscard]] + auto filepath() const noexcept -> const std::filesystem::path&; + + private: + DynamicLoader() noexcept; + + auto do_load(std::filesystem::path filepath) -> Expected; + auto do_get_func(std::string_view name) const -> Expected; + + std::filesystem::path m_filepath; + void* m_library_handle = nullptr; + }; +}} // namespace stormkit::core + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit { inline namespace core { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline DynamicLoader::DynamicLoader() noexcept + = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline DynamicLoader::DynamicLoader(DynamicLoader&& other) noexcept + : m_filepath { std::move(other.m_filepath) }, m_library_handle { std::exchange(other.m_library_handle, nullptr) } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto DynamicLoader::operator=(DynamicLoader&& other) noexcept -> DynamicLoader& { + if (&other == this) [[unlikely]] + return *this; + + m_filepath = std::move(other.m_filepath); + m_library_handle = std::exchange(other.m_library_handle, nullptr); + + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto DynamicLoader::load(std::filesystem::path filepath) noexcept -> Expected { + auto loader = DynamicLoader {}; + + return loader.do_load(std::move(filepath)).transform([&]() { return std::move(loader); }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto DynamicLoader::allocate_and_load(std::filesystem::path filepath) noexcept + -> Expected> { + return load(std::move(filepath)) + .transform([](auto&& loader) { return std::make_unique(std::move(loader)); }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + inline auto DynamicLoader::func(std::string_view name) const noexcept -> Expected> { + return c_func(name) + .transform([](T&& value) { return std::function { std::forward(value) }; }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + inline auto DynamicLoader::c_func(std::string_view name) const noexcept -> Expected { + EXPECTS(not std::empty(name)); + + return do_get_func(name) + .transform([](T&& value) { return std::bit_cast(std::forward(value)); }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto DynamicLoader::filepath() const noexcept -> const std::filesystem::path& { + return m_filepath; + } +}} // namespace stormkit::core diff --git a/modules/stormkit/core/utils/filesystem.mpp b/modules/stormkit/core/utils/filesystem.cppm similarity index 100% rename from modules/stormkit/core/utils/filesystem.mpp rename to modules/stormkit/core/utils/filesystem.cppm diff --git a/modules/stormkit/core/utils/function_ref.mpp b/modules/stormkit/core/utils/function_ref.cppm similarity index 100% rename from modules/stormkit/core/utils/function_ref.mpp rename to modules/stormkit/core/utils/function_ref.cppm diff --git a/modules/stormkit/core/utils/handle.mpp b/modules/stormkit/core/utils/handle.cppm similarity index 96% rename from modules/stormkit/core/utils/handle.mpp rename to modules/stormkit/core/utils/handle.cppm index de8c988b6..3486bd948 100644 --- a/modules/stormkit/core/utils/handle.mpp +++ b/modules/stormkit/core/utils/handle.cppm @@ -1,136 +1,136 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -#include - -export module stormkit.core:utils.handle; - -import std; - -import :hash; -import :typesafe.safecasts; -import :typesafe.integer; -import :meta; - -export namespace stormkit { inline namespace core { - template - struct Handle { - using ID = _ID; - - static constexpr auto INVALID_HANDLE_VALUE = std::numeric_limits::max(); - - [[nodiscard]] - constexpr auto operator<=>(const Handle&) const noexcept -> std::strong_ordering = default; - - template U> - constexpr operator Handle() const noexcept; - - constexpr auto& operator++() noexcept; - - constexpr auto operator++(int) noexcept; - - constexpr auto& operator--() noexcept; - - constexpr auto operator--(int) noexcept; - - constexpr operator ID() const noexcept; - - [[nodiscard]] - static constexpr auto invalid_handle() noexcept -> Handle; - - ID id = INVALID_HANDLE_VALUE; - }; - - template - using Handle32 = Handle; - - template - using Handle64 = Handle; - - template - constexpr auto hasher(const Handle& value) noexcept -> Ret; - - template - auto format_as(const Handle& value, FormatContext& ctx) noexcept -> decltype(ctx.out()); -}} // namespace stormkit::core - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit { inline namespace core { - ///////////////////////////////////// - ///////////////////////////////////// - template - template U> - constexpr Handle::operator Handle() const noexcept { - return Handle { id }; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - constexpr auto& Handle::operator++() noexcept { - ++id; - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - constexpr auto Handle::operator++(int) noexcept { - auto old = *this; - operator++(); - return old; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - constexpr auto& Handle::operator--() noexcept { - --id; - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - constexpr auto Handle::operator--(int) noexcept { - auto old = *this; - operator--(); - return old; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - constexpr Handle::operator ID() const noexcept { - return id; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - constexpr auto Handle::invalid_handle() noexcept -> Handle { - return Handle {}; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - constexpr auto hasher(const Handle& value) noexcept -> Ret { - return hash(value.id); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto format_as(const Handle& value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { - return std::format_to(ctx.out(), "[handle id: {}]", value.id); - } -}} // namespace stormkit::core +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +export module stormkit.core:utils.handle; + +import std; + +import :hash; +import :typesafe.safecasts; +import :typesafe.integer; +import :meta; + +export namespace stormkit { inline namespace core { + template + struct Handle { + using ID = _ID; + + static constexpr auto INVALID_HANDLE_VALUE = std::numeric_limits::max(); + + [[nodiscard]] + constexpr auto operator<=>(const Handle&) const noexcept -> std::strong_ordering = default; + + template U> + constexpr operator Handle() const noexcept; + + constexpr auto& operator++() noexcept; + + constexpr auto operator++(int) noexcept; + + constexpr auto& operator--() noexcept; + + constexpr auto operator--(int) noexcept; + + constexpr operator ID() const noexcept; + + [[nodiscard]] + static constexpr auto invalid_handle() noexcept -> Handle; + + ID id = INVALID_HANDLE_VALUE; + }; + + template + using Handle32 = Handle; + + template + using Handle64 = Handle; + + template + constexpr auto hasher(const Handle& value) noexcept -> Ret; + + template + auto format_as(const Handle& value, FormatContext& ctx) noexcept -> decltype(ctx.out()); +}} // namespace stormkit::core + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit { inline namespace core { + ///////////////////////////////////// + ///////////////////////////////////// + template + template U> + constexpr Handle::operator Handle() const noexcept { + return Handle { id }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + constexpr auto& Handle::operator++() noexcept { + ++id; + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + constexpr auto Handle::operator++(int) noexcept { + auto old = *this; + operator++(); + return old; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + constexpr auto& Handle::operator--() noexcept { + --id; + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + constexpr auto Handle::operator--(int) noexcept { + auto old = *this; + operator--(); + return old; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + constexpr Handle::operator ID() const noexcept { + return id; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + constexpr auto Handle::invalid_handle() noexcept -> Handle { + return Handle {}; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + constexpr auto hasher(const Handle& value) noexcept -> Ret { + return hash(value.id); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto format_as(const Handle& value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { + return std::format_to(ctx.out(), "[handle id: {}]", value.id); + } +}} // namespace stormkit::core diff --git a/modules/stormkit/core/utils/numeric_range.mpp b/modules/stormkit/core/utils/numeric_range.cppm similarity index 97% rename from modules/stormkit/core/utils/numeric_range.mpp rename to modules/stormkit/core/utils/numeric_range.cppm index e15dde211..082e8f477 100644 --- a/modules/stormkit/core/utils/numeric_range.mpp +++ b/modules/stormkit/core/utils/numeric_range.cppm @@ -1,308 +1,308 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -export module stormkit.core:utils.numeric_range; - -import std; - -import :meta; - -import :typesafe; - -import :coroutines; - -export namespace stormkit { inline namespace core { - template - struct NumericsRange { - using RangeType = T; - T begin; - T end; - T step = T { 1 }; - }; - - namespace meta { - template - concept IsNumericsRange = requires(const T& t) { - t.begin; - t.end; - t.step; - typename T::RangeType; - }; - - template - concept IsNumericsRangePure = IsNumericsRange>; - } // namespace meta - - template - [[nodiscard]] - constexpr auto range(const T& end) noexcept -> decltype(auto); - - template - [[nodiscard]] - constexpr auto range(const T& begin, const U& end) noexcept -> decltype(auto); - - template - [[nodiscard]] - constexpr auto range(const T& begin, const U& end, const V& step) noexcept -> decltype(auto); - - [[nodiscard]] - constexpr auto range(meta::IsNumericsRangePure auto&& range) noexcept -> decltype(auto); - - template - [[nodiscard]] - constexpr auto multi_range(const Args&... args) noexcept -> decltype(auto); - - template - [[nodiscard]] - constexpr auto multi_range(Args&&... args) noexcept -> decltype(auto); -}} // namespace stormkit::core - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stdr = std::ranges; -namespace stdv = std::views; - -namespace stormkit { inline namespace core { -#define FOR(a, b) for (auto a = b.begin; a < b.end; a += b.step) -#define YIELD(...) co_yield { __VA_ARGS__ }; - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto range_implementation(T a, U b) noexcept -> std::generator> { - FOR(i, a) - FOR(j, b) - YIELD(i, j) - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto range_implementation(T a, U b, V c) noexcept - -> std::generator> { - FOR(i, a) - FOR(j, b) - FOR(k, c) - YIELD(i, j, k) - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto range_implementation(T a, U b, V c, W d) noexcept - -> std::generator> { - FOR(i, a) - FOR(j, b) - FOR(k, c) - FOR(l, d) - YIELD(i, j, k, l) - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto range_implementation(T a, U b, V c, W d, X e) noexcept -> std::generator< - std::tuple> { - FOR(i, a) - FOR(j, b) - FOR(k, c) - FOR(l, d) - FOR(m, e) - YIELD(i, j, k, l, m) - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto range_implementation(T a, U b, V c, W d, X e, Y f) noexcept -> std::generator< - std:: - tuple> { - FOR(i, a) - FOR(j, b) - FOR(k, c) - FOR(l, d) - FOR(m, e) - FOR(n, f) - YIELD(i, j, k, l, m, n) - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto range_implementation(T a, U b, V c, W d, X e, Y f, Z g) noexcept - -> std::generator> { - FOR(i, a) - FOR(j, b) - FOR(k, c) - FOR(l, d) - FOR(m, e) - FOR(n, f) - FOR(o, g) - YIELD(i, j, k, l, m, n, g) - } - -#undef FOR -#undef YIELD - - template - struct Range { - using Type = typename T::RangeType; - - struct Sentinel { - Type val; - }; - - struct Iterator { - using value_type = T; - using difference_type = isize; - - constexpr Iterator(Type val, Type step) noexcept : m_val { val }, m_step { step } {} - - constexpr Iterator(const Iterator&) noexcept = default; - constexpr Iterator(Iterator&&) noexcept = default; - constexpr ~Iterator() noexcept = default; - - constexpr auto operator=(const Iterator&) noexcept -> Iterator& = default; - constexpr auto operator=(Iterator&&) noexcept -> Iterator& = default; - - constexpr auto operator=(const Sentinel& end) noexcept -> Iterator& { - m_val = end.val; - - return *this; - } - - constexpr auto operator+(std::size_t index) noexcept -> decltype(auto) { - auto cpy = clone(*this); - for (auto i = 0u; i < index; ++i) ++cpy; - return cpy; - } - - constexpr auto operator++() noexcept -> decltype(auto) { - m_val += m_step; - return *this; - } - - constexpr auto operator++(int) noexcept -> decltype(auto) { - auto old = clone(*this); - m_val += m_step; - return old; - } - - constexpr auto operator--() noexcept -> decltype(auto) { - m_val -= m_step; - return *this; - } - - constexpr auto operator--(int) noexcept -> decltype(auto) { - auto old = clone(*this); - m_val -= m_step; - return old; - } - - constexpr auto operator==(const Iterator& other) const noexcept { return m_val == other.m_val; } - - constexpr auto operator==(const Sentinel& end) const noexcept -> bool { - if (m_step > 0) return m_val >= end.val; - - return m_val <= end.val; - } - - constexpr auto operator!=(const Iterator& other) const noexcept { return m_val != other.m_val; } - - constexpr auto operator*() const noexcept -> const Type& { return m_val; } - - private: - Type m_val; - Type m_step; - }; - - constexpr explicit Range(meta::IsStrict auto&& range) : m_range { std::forward(range) } {} - - constexpr auto begin() const noexcept -> Iterator { return { m_range.begin, m_range.step }; } - - constexpr auto cbegin() const noexcept -> Iterator { return begin(); } - - constexpr auto end() const noexcept -> Sentinel { return { m_range.end }; } - - constexpr auto cend() const noexcept -> Sentinel { return end(); } - - private: - T m_range; - }; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - constexpr auto range(meta::IsNumericsRangePure auto&& range) noexcept -> decltype(auto) { - return Range> { std::forward(range) }; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto range(const T& begin, const U& end, const V& step) noexcept -> decltype(auto) { - using Type = meta::SafeNarrowHelperType, V>; - return range(NumericsRange { .begin = as(begin), .end = as(end), .step = as(step) }); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto range(const T& begin, const U& end) noexcept -> decltype(auto) { - return stdv::iota(begin, end); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto range(const T& end) noexcept -> decltype(auto) { - return range(T { 0 }, end); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto multi_range(const Args&... args) noexcept -> decltype(auto) { - return range_implementation(NumericsRange { .begin = 0, .end = args }...); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto multi_range(Args&&... args) noexcept -> decltype(auto) { - return range_implementation(std::forward(args)...); - } -}} // namespace stormkit::core +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.core:utils.numeric_range; + +import std; + +import :meta; + +import :typesafe; + +import :coroutines; + +export namespace stormkit { inline namespace core { + template + struct NumericsRange { + using RangeType = T; + T begin; + T end; + T step = T { 1 }; + }; + + namespace meta { + template + concept IsNumericsRange = requires(const T& t) { + t.begin; + t.end; + t.step; + typename T::RangeType; + }; + + template + concept IsNumericsRangePure = IsNumericsRange>; + } // namespace meta + + template + [[nodiscard]] + constexpr auto range(const T& end) noexcept -> decltype(auto); + + template + [[nodiscard]] + constexpr auto range(const T& begin, const U& end) noexcept -> decltype(auto); + + template + [[nodiscard]] + constexpr auto range(const T& begin, const U& end, const V& step) noexcept -> decltype(auto); + + [[nodiscard]] + constexpr auto range(meta::IsNumericsRangePure auto&& range) noexcept -> decltype(auto); + + template + [[nodiscard]] + constexpr auto multi_range(const Args&... args) noexcept -> decltype(auto); + + template + [[nodiscard]] + constexpr auto multi_range(Args&&... args) noexcept -> decltype(auto); +}} // namespace stormkit::core + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stdr = std::ranges; +namespace stdv = std::views; + +namespace stormkit { inline namespace core { +#define FOR(a, b) for (auto a = b.begin; a < b.end; a += b.step) +#define YIELD(...) co_yield { __VA_ARGS__ }; + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto range_implementation(T a, U b) noexcept -> std::generator> { + FOR(i, a) + FOR(j, b) + YIELD(i, j) + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto range_implementation(T a, U b, V c) noexcept + -> std::generator> { + FOR(i, a) + FOR(j, b) + FOR(k, c) + YIELD(i, j, k) + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto range_implementation(T a, U b, V c, W d) noexcept + -> std::generator> { + FOR(i, a) + FOR(j, b) + FOR(k, c) + FOR(l, d) + YIELD(i, j, k, l) + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto range_implementation(T a, U b, V c, W d, X e) noexcept -> std::generator< + std::tuple> { + FOR(i, a) + FOR(j, b) + FOR(k, c) + FOR(l, d) + FOR(m, e) + YIELD(i, j, k, l, m) + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto range_implementation(T a, U b, V c, W d, X e, Y f) noexcept -> std::generator< + std:: + tuple> { + FOR(i, a) + FOR(j, b) + FOR(k, c) + FOR(l, d) + FOR(m, e) + FOR(n, f) + YIELD(i, j, k, l, m, n) + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto range_implementation(T a, U b, V c, W d, X e, Y f, Z g) noexcept + -> std::generator> { + FOR(i, a) + FOR(j, b) + FOR(k, c) + FOR(l, d) + FOR(m, e) + FOR(n, f) + FOR(o, g) + YIELD(i, j, k, l, m, n, g) + } + +#undef FOR +#undef YIELD + + template + struct Range { + using Type = typename T::RangeType; + + struct Sentinel { + Type val; + }; + + struct Iterator { + using value_type = T; + using difference_type = isize; + + constexpr Iterator(Type val, Type step) noexcept : m_val { val }, m_step { step } {} + + constexpr Iterator(const Iterator&) noexcept = default; + constexpr Iterator(Iterator&&) noexcept = default; + constexpr ~Iterator() noexcept = default; + + constexpr auto operator=(const Iterator&) noexcept -> Iterator& = default; + constexpr auto operator=(Iterator&&) noexcept -> Iterator& = default; + + constexpr auto operator=(const Sentinel& end) noexcept -> Iterator& { + m_val = end.val; + + return *this; + } + + constexpr auto operator+(std::size_t index) noexcept -> decltype(auto) { + auto cpy = clone(*this); + for (auto i = 0u; i < index; ++i) ++cpy; + return cpy; + } + + constexpr auto operator++() noexcept -> decltype(auto) { + m_val += m_step; + return *this; + } + + constexpr auto operator++(int) noexcept -> decltype(auto) { + auto old = clone(*this); + m_val += m_step; + return old; + } + + constexpr auto operator--() noexcept -> decltype(auto) { + m_val -= m_step; + return *this; + } + + constexpr auto operator--(int) noexcept -> decltype(auto) { + auto old = clone(*this); + m_val -= m_step; + return old; + } + + constexpr auto operator==(const Iterator& other) const noexcept { return m_val == other.m_val; } + + constexpr auto operator==(const Sentinel& end) const noexcept -> bool { + if (m_step > 0) return m_val >= end.val; + + return m_val <= end.val; + } + + constexpr auto operator!=(const Iterator& other) const noexcept { return m_val != other.m_val; } + + constexpr auto operator*() const noexcept -> const Type& { return m_val; } + + private: + Type m_val; + Type m_step; + }; + + constexpr explicit Range(meta::IsStrict auto&& range) : m_range { std::forward(range) } {} + + constexpr auto begin() const noexcept -> Iterator { return { m_range.begin, m_range.step }; } + + constexpr auto cbegin() const noexcept -> Iterator { return begin(); } + + constexpr auto end() const noexcept -> Sentinel { return { m_range.end }; } + + constexpr auto cend() const noexcept -> Sentinel { return end(); } + + private: + T m_range; + }; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto range(meta::IsNumericsRangePure auto&& range) noexcept -> decltype(auto) { + return Range> { std::forward(range) }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto range(const T& begin, const U& end, const V& step) noexcept -> decltype(auto) { + using Type = meta::SafeNarrowHelperType, V>; + return range(NumericsRange { .begin = as(begin), .end = as(end), .step = as(step) }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto range(const T& begin, const U& end) noexcept -> decltype(auto) { + return stdv::iota(begin, end); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto range(const T& end) noexcept -> decltype(auto) { + return range(T { 0 }, end); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto multi_range(const Args&... args) noexcept -> decltype(auto) { + return range_implementation(NumericsRange { .begin = 0, .end = args }...); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto multi_range(Args&&... args) noexcept -> decltype(auto) { + return range_implementation(std::forward(args)...); + } +}} // namespace stormkit::core diff --git a/modules/stormkit/core/utils/pimpl.mpp b/modules/stormkit/core/utils/pimpl.cppm similarity index 96% rename from modules/stormkit/core/utils/pimpl.mpp rename to modules/stormkit/core/utils/pimpl.cppm index 1979024c5..6305c7c9a 100644 --- a/modules/stormkit/core/utils/pimpl.mpp +++ b/modules/stormkit/core/utils/pimpl.cppm @@ -1,164 +1,164 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -#include - -export module stormkit.core:utils.pimpl; - -import std; - -import :meta; -import :utils.contract; - -export namespace stormkit { inline namespace core { - template - class Pimpl { - public: - Pimpl() noexcept(not Defer); - ~Pimpl(); - -#if defined(STORMKIT_COMPILER_CLANG) and __clang_major__ < 21 - template - requires(meta::EnableCtor, Args...>) - Pimpl(Args&&... args); -#else - template - requires(meta::EnableCtor, Args...>) - explicit(sizeof...(Args) == 1) Pimpl(Args&&... args); -#endif - - Pimpl(Pimpl&&) noexcept; - auto operator=(Pimpl&&) noexcept -> Pimpl&; - - template - auto init(Args&&... args) -> void; - - auto operator->() noexcept -> T*; - auto operator->() const noexcept -> const T*; - - auto operator*() noexcept -> T&; - auto operator*() const noexcept -> const T&; - - auto get() noexcept -> T&; - auto get() const noexcept -> const T&; - - explicit operator bool() const noexcept; - - private: - std::unique_ptr m_data; - }; -}} // namespace stormkit::core - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit { inline namespace core { - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline Pimpl::Pimpl() noexcept(not Defer) { - if constexpr (not Defer) init(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline Pimpl::~Pimpl() = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - template - requires(meta::EnableCtor, Args...>) - STORMKIT_FORCE_INLINE - inline Pimpl::Pimpl(Args&&... args) { - init(std::forward(args)...); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline Pimpl::Pimpl(Pimpl&&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Pimpl::operator=(Pimpl&&) noexcept -> Pimpl& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - template - STORMKIT_FORCE_INLINE - inline auto Pimpl::init(Args&&... args) -> void { - m_data = std::make_unique(std::forward(args)...); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Pimpl::operator->() noexcept -> T* { - return &get(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Pimpl::operator->() const noexcept -> const T* { - return &get(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Pimpl::operator*() noexcept -> T& { - return get(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Pimpl::operator*() const noexcept -> const T& { - return get(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Pimpl::get() noexcept -> T& { - EXPECTS(m_data != nullptr); - return *m_data; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Pimpl::get() const noexcept -> const T& { - EXPECTS(m_data != nullptr); - return *m_data; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline Pimpl::operator bool() const noexcept { - return m_data != nullptr; - } -}} // namespace stormkit::core +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +export module stormkit.core:utils.pimpl; + +import std; + +import :meta; +import :utils.contract; + +export namespace stormkit { inline namespace core { + template + class Pimpl { + public: + Pimpl() noexcept(not Defer); + ~Pimpl(); + +#if defined(STORMKIT_COMPILER_CLANG) and __clang_major__ < 21 + template + requires(meta::EnableCtor, Args...>) + Pimpl(Args&&... args); +#else + template + requires(meta::EnableCtor, Args...>) + explicit(sizeof...(Args) == 1) Pimpl(Args&&... args); +#endif + + Pimpl(Pimpl&&) noexcept; + auto operator=(Pimpl&&) noexcept -> Pimpl&; + + template + auto init(Args&&... args) -> void; + + auto operator->() noexcept -> T*; + auto operator->() const noexcept -> const T*; + + auto operator*() noexcept -> T&; + auto operator*() const noexcept -> const T&; + + auto get() noexcept -> T&; + auto get() const noexcept -> const T&; + + explicit operator bool() const noexcept; + + private: + std::unique_ptr m_data; + }; +}} // namespace stormkit::core + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit { inline namespace core { + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline Pimpl::Pimpl() noexcept(not Defer) { + if constexpr (not Defer) init(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline Pimpl::~Pimpl() = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + template + requires(meta::EnableCtor, Args...>) + STORMKIT_FORCE_INLINE + inline Pimpl::Pimpl(Args&&... args) { + init(std::forward(args)...); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline Pimpl::Pimpl(Pimpl&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Pimpl::operator=(Pimpl&&) noexcept -> Pimpl& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + template + STORMKIT_FORCE_INLINE + inline auto Pimpl::init(Args&&... args) -> void { + m_data = std::make_unique(std::forward(args)...); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Pimpl::operator->() noexcept -> T* { + return &get(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Pimpl::operator->() const noexcept -> const T* { + return &get(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Pimpl::operator*() noexcept -> T& { + return get(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Pimpl::operator*() const noexcept -> const T& { + return get(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Pimpl::get() noexcept -> T& { + EXPECTS(m_data != nullptr); + return *m_data; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Pimpl::get() const noexcept -> const T& { + EXPECTS(m_data != nullptr); + return *m_data; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline Pimpl::operator bool() const noexcept { + return m_data != nullptr; + } +}} // namespace stormkit::core diff --git a/modules/stormkit/core/utils/random.mpp b/modules/stormkit/core/utils/random.cppm similarity index 96% rename from modules/stormkit/core/utils/random.mpp rename to modules/stormkit/core/utils/random.cppm index 846ea432e..8e2bba117 100644 --- a/modules/stormkit/core/utils/random.mpp +++ b/modules/stormkit/core/utils/random.cppm @@ -1,66 +1,66 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -export module stormkit.core:utils.random; - -import std; - -import :typesafe; - -import :meta; - -export namespace stormkit { inline namespace core { - auto seed(u32 seed) noexcept -> void; - - template - [[nodiscard]] - auto rand(T min, T max) noexcept -> T; - - template - [[nodiscard]] - auto rand(T min, T max) noexcept -> T; -}} // namespace stormkit::core - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit { inline namespace core { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto random_generator() noexcept -> std::default_random_engine& { - static auto generator = std::default_random_engine {}; - return generator; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto seed(u32 seed) noexcept -> void { - random_generator().seed(seed); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto rand(T min, T max) noexcept -> T { - std::uniform_real_distribution dis(min, max); - return dis(random_generator()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto rand(T min, T max) noexcept -> T { - std::uniform_int_distribution dis(min, max); - return dis(random_generator()); - } -}} // namespace stormkit::core +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.core:utils.random; + +import std; + +import :typesafe; + +import :meta; + +export namespace stormkit { inline namespace core { + auto seed(u32 seed) noexcept -> void; + + template + [[nodiscard]] + auto rand(T min, T max) noexcept -> T; + + template + [[nodiscard]] + auto rand(T min, T max) noexcept -> T; +}} // namespace stormkit::core + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit { inline namespace core { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto random_generator() noexcept -> std::default_random_engine& { + static auto generator = std::default_random_engine {}; + return generator; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto seed(u32 seed) noexcept -> void { + random_generator().seed(seed); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto rand(T min, T max) noexcept -> T { + std::uniform_real_distribution dis(min, max); + return dis(random_generator()); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto rand(T min, T max) noexcept -> T { + std::uniform_int_distribution dis(min, max); + return dis(random_generator()); + } +}} // namespace stormkit::core diff --git a/modules/stormkit/core/utils/signal_handler.mpp b/modules/stormkit/core/utils/signal_handler.cppm similarity index 100% rename from modules/stormkit/core/utils/signal_handler.mpp rename to modules/stormkit/core/utils/signal_handler.cppm diff --git a/modules/stormkit/core/utils/singleton.mpp b/modules/stormkit/core/utils/singleton.cppm similarity index 97% rename from modules/stormkit/core/utils/singleton.mpp rename to modules/stormkit/core/utils/singleton.cppm index d94f8076a..387b3e8a0 100644 --- a/modules/stormkit/core/utils/singleton.mpp +++ b/modules/stormkit/core/utils/singleton.cppm @@ -1,57 +1,57 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -export module stormkit.core:utils.singleton; - -import std; - -export namespace stormkit { inline namespace core { - template - class Singleton { - public: - template - static auto instance(Args&&... args) noexcept(std::is_nothrow_constructible_v) -> T&; - - Singleton(Singleton&&) = delete; - Singleton(const Singleton&) = delete; - - auto operator=(Singleton&&) -> Singleton& = delete; - auto operator=(const Singleton&) -> Singleton& = delete; - - protected: - Singleton() noexcept = default; - ~Singleton() noexcept = default; - - private: - static auto once_flag() noexcept -> std::once_flag&; - - static inline std::unique_ptr m_instance = nullptr; - }; -}} // namespace stormkit::core - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit { inline namespace core { - ///////////////////////////////////// - ///////////////////////////////////// - template - template - auto Singleton::instance(Args&&... args) noexcept(std::is_nothrow_constructible_v) -> T& { - auto lambdas = [](Args&&... args) mutable { m_instance = std::make_unique(std::forward(args)...); }; - - std::call_once(once_flag(), lambdas, std::forward(args)...); - - return *m_instance; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto Singleton::once_flag() noexcept -> std::once_flag& { - static auto once_flag = std::once_flag {}; - return once_flag; - } -}} // namespace stormkit::core +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +export module stormkit.core:utils.singleton; + +import std; + +export namespace stormkit { inline namespace core { + template + class Singleton { + public: + template + static auto instance(Args&&... args) noexcept(std::is_nothrow_constructible_v) -> T&; + + Singleton(Singleton&&) = delete; + Singleton(const Singleton&) = delete; + + auto operator=(Singleton&&) -> Singleton& = delete; + auto operator=(const Singleton&) -> Singleton& = delete; + + protected: + Singleton() noexcept = default; + ~Singleton() noexcept = default; + + private: + static auto once_flag() noexcept -> std::once_flag&; + + static inline std::unique_ptr m_instance = nullptr; + }; +}} // namespace stormkit::core + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit { inline namespace core { + ///////////////////////////////////// + ///////////////////////////////////// + template + template + auto Singleton::instance(Args&&... args) noexcept(std::is_nothrow_constructible_v) -> T& { + auto lambdas = [](Args&&... args) mutable { m_instance = std::make_unique(std::forward(args)...); }; + + std::call_once(once_flag(), lambdas, std::forward(args)...); + + return *m_instance; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto Singleton::once_flag() noexcept -> std::once_flag& { + static auto once_flag = std::once_flag {}; + return once_flag; + } +}} // namespace stormkit::core diff --git a/modules/stormkit/core/utils/stacktrace.mpp b/modules/stormkit/core/utils/stacktrace.cppm similarity index 100% rename from modules/stormkit/core/utils/stacktrace.mpp rename to modules/stormkit/core/utils/stacktrace.cppm diff --git a/modules/stormkit/core/utils/tags.mpp b/modules/stormkit/core/utils/tags.cppm similarity index 100% rename from modules/stormkit/core/utils/tags.mpp rename to modules/stormkit/core/utils/tags.cppm diff --git a/modules/stormkit/core/utils/time.mpp b/modules/stormkit/core/utils/time.cppm similarity index 100% rename from modules/stormkit/core/utils/time.mpp rename to modules/stormkit/core/utils/time.cppm diff --git a/modules/stormkit/entities.mpp b/modules/stormkit/entities.cppm similarity index 97% rename from modules/stormkit/entities.mpp rename to modules/stormkit/entities.cppm index 4b25ee496..fedc6f015 100644 --- a/modules/stormkit/entities.mpp +++ b/modules/stormkit/entities.cppm @@ -1,463 +1,463 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -#include - -#include - -export module stormkit.entities; - -import std; - -import stormkit.core; - -#ifdef STORMKIT_LUA_BINDING -export import :lua; -#endif - -namespace stdr = std::ranges; -namespace stdv = std::views; - -export namespace stormkit::entities { - using Entity = u32; - inline constexpr auto INVALID_ENTITY = Entity { 0 }; - class System; - - struct EntityHashFunc { -#ifdef STORMKIT_COMPILER_MSVC - [[nodiscard]] - auto operator()(Entity k) const noexcept -> hash64; -#else - [[nodiscard]] - static auto operator()(Entity k) noexcept -> hash64; -#endif - }; - - struct Component { - using Type = u64; - - static constexpr Type INVALID_TYPE = 0; - static constexpr Type TYPE = INVALID_TYPE; - }; - - namespace meta { - template - concept IsComponentType = core::meta::Is and requires(T&& component) { T::TYPE; }; - - template - concept IsSystem = core::meta::Is; - } // namespace meta - - template - constexpr auto component_hash(std::string_view str) noexcept -> Result; - - constexpr auto component_hash(CZString str, usize size) noexcept -> Component::Type; - - constexpr auto component_hash(std::string_view str) noexcept -> Component::Type; - - namespace literals { - constexpr auto operator""_component_type(CZString str, usize size) -> Component::Type; - } // namespace literals - - struct Message { - u32 id; - std::vector entities; - }; - - class STORMKIT_API MessageBus { - public: - MessageBus(); - ~MessageBus(); - - MessageBus(const MessageBus&) = delete; - auto operator=(const MessageBus&) -> MessageBus& = delete; - - MessageBus(MessageBus&&); - auto operator=(MessageBus&&) -> MessageBus&; - - auto push(Message&& message) -> void; - [[nodiscard]] - auto top() const -> const Message&; - auto pop() -> void; - - [[nodiscard]] - auto empty() const noexcept -> bool; - - private: - std::queue m_messages; - }; - - class EntityManager; - - class STORMKIT_API System { - public: - using ComponentTypes = HashSet; - - System(EntityManager& manager, u32 priority, ComponentTypes types); - - System(const System&) = delete; - auto operator=(const System&) -> System& = delete; - - System(System&&) noexcept; - auto operator=(System&&) noexcept -> System&; - - virtual ~System(); - - virtual auto pre_update() -> void; - virtual auto update(fsecond delta) -> void = 0; - virtual auto post_update() -> void; - - [[nodiscard]] - auto priority() const noexcept -> u32; - [[nodiscard]] - auto components_used() const noexcept -> const ComponentTypes&; - - auto add_entity(Entity e) -> void; - auto remove_entity(Entity e) -> void; - - struct Predicate { -#ifdef STORMKIT_COMPILER_MSVC - [[nodiscard]] - auto operator()(const std::unique_ptr& s1, const std::unique_ptr& s2) const noexcept -#else - [[nodiscard]] - static auto operator()(const std::unique_ptr& s1, const std::unique_ptr& s2) noexcept -#endif - -> bool { - return s1->priority() < s2->priority(); - } - }; - - protected: - virtual auto on_message_received(const Message& message) -> void = 0; - - Ref m_manager; - HashSet m_entities; - - friend class EntityManager; - - private: - u32 m_priority; - ComponentTypes m_types; - }; - - class STORMKIT_API EntityManager { - public: - static constexpr auto ADDED_ENTITY_MESSAGE_ID = 1; - static constexpr auto REMOVED_ENTITY_MESSAGE_ID = 2; - - explicit EntityManager(); - ~EntityManager(); - - EntityManager(const EntityManager&) = delete; - auto operator=(const EntityManager&) -> EntityManager& = delete; - - EntityManager(EntityManager&&); - auto operator=(EntityManager&&) -> EntityManager&; - - auto make_entity() -> Entity; - auto destroy_entity(Entity entity) -> void; - auto destroy_all_entities() -> void; - auto has_entity(Entity entity) const -> bool; - - template - auto add_component(Entity entity, Args&&... args) -> T&; - - template - auto destroy_component(Entity entity) -> void; - - template - auto has_component(Entity entity) const -> bool; - - auto has_component(Entity entity, Component::Type type) const -> bool; - - auto entities() const noexcept -> const std::vector&; - - template - auto entities_with_component() const -> std::vector; - - template - auto getComponent(this Self& self, Entity entity) -> core::meta::ForwardConst; - - template - auto components(this Self& self, Entity entity) -> std::vector>>; - - template - auto components_of_type(this Self& self) noexcept -> std::vector>>; - - template - auto add_system(Args&&... args) -> T&; - - template - auto has_system() const noexcept -> bool; - - template - auto systems(this Self& self) noexcept -> std::vector>>; - - template - auto get_system(this Self& self) noexcept -> core::meta::ForwardConst; - - auto step(fsecond delta) -> void; - - auto entity_count() const noexcept -> usize; - - // void commit(Entity e); - - private: - using ComponentKey = u64; - - static constexpr auto component_key_for(Entity e, Component::Type type) noexcept -> ComponentKey; - static constexpr auto is_key_entity(Entity e, ComponentKey key) noexcept -> bool; - - auto purpose_to_systems(Entity e) -> void; - auto remove_from_systems(Entity e) -> void; - auto get_needed_entities(System& system) -> void; - - Entity m_next_valid_entity = 1; - std::queue m_free_entities; - - HashSet m_entities; - - HashSet m_added_entities; - HashSet m_updated_entities; - HashSet m_removed_entities; - - HashMap> m_registered_components_for_entities; - std::set, System::Predicate> m_systems; - HashMap> m_components; - - MessageBus m_message_bus; - }; -} // namespace stormkit::entities - -namespace stormkit::entities { - ///////////////////////////////////// - ///////////////////////////////////// -#ifdef STORMKIT_COMPILER_MSVC - inline auto EntityHashFunc::operator()(Entity k) const noexcept -> hash64 { -#else - inline auto EntityHashFunc::operator()(Entity k) noexcept -> hash64 { -#endif - return as(k); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - constexpr auto component_hash(std::string_view str) noexcept -> Result { - return std::empty(str) - ? 0xcbf29ce484222325UL - : (as(str[0]) ^ component_hash(str.substr(1, std::size(str) - 1))) * 0x100000001b3UL; - } - - ///////////////////////////////////// - ///////////////////////////////////// - constexpr auto component_hash(CZString str, usize size) noexcept -> Component::Type { - return size == 0 ? 0xcbf29ce484222325UL - : (as(str[0]) ^ component_hash(std::string_view { str + 1, size - 1 })) * 0x100000001b3UL; - } - - ///////////////////////////////////// - ///////////////////////////////////// - constexpr auto component_hash(std::string_view str) noexcept -> Component::Type { - return component_hash(std::data(str), std::size(str)); - } - - namespace literals { - ///////////////////////////////////// - ///////////////////////////////////// - constexpr auto operator""_component_type(CZString str, usize size) -> Component::Type { - return stormkit::entities::component_hash(str, size); - } - } // namespace literals - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto MessageBus::empty() const noexcept -> bool { - return std::empty(m_messages); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto System::priority() const noexcept -> u32 { - return m_priority; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto System::components_used() const noexcept -> const ComponentTypes& { - return m_types; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto EntityManager::add_component(Entity entity, Args&&... args) -> T& { - static_assert(T::TYPE != Component::INVALID_TYPE, "T must have T::type defined"); - - EXPECTS(has_entity(entity)); - EXPECTS(not has_component(entity)); - - auto component = std::make_unique(std::forward(args)...); - - auto type = T::TYPE; - m_components[component_key_for(entity, type)] = std::move(component); - m_registered_components_for_entities.at(entity).emplace_back(type); - - m_updated_entities.emplace(entity); - - return getComponent(entity); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto EntityManager::destroy_component(Entity entity) -> void { - static_assert(T::TYPE != Component::INVALID_TYPE, "T must have T::type defined"); - - EXPECTS(has_entity(entity)); - EXPECTS(has_component(entity)); - - const auto key = component_key_for(entity, T::TYPE); - - if (m_components.find(key) != stdr::cend(m_components)) m_components.erase(key); - - m_updated_entities.emplace(entity); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto EntityManager::has_component(Entity entity) const -> bool { - static_assert(T::TYPE != Component::INVALID_TYPE, "T must have T::type defined"); - - return has_component(entity, T::TYPE); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto EntityManager::entities() const noexcept -> const std::vector& { - return m_entities.values(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto EntityManager::entities_with_component() const -> std::vector { - // clang-format off - return entities() - | stdv::filter([](auto&& entity) static noexcept { return stdr::any_of(entity, T::TYPE); }) - | stdr::to(); - // clang-format on - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto EntityManager::getComponent(this Self& self, Entity entity) -> core::meta::ForwardConst { - EXPECTS(self.template has_component(entity)); - EXPECTS(self.has_entity(entity)); - - const auto key = component_key_for(entity, T::TYPE); - return *std::bit_cast(self.m_components.at(key).get()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto EntityManager::components(this Self& self, Entity entity) - -> std::vector>> { - if (not self.has_entity(entity)) [[unlikely]] - return {}; - // clang-format off - return self.m_components - | stdv::filter([entity](auto&& pair) noexcept { - return EntityManager::is_key_entity(entity, pair.first); - }) - | stdv::values - | stdv::transform(monadic::as_ref()) - | stdr::to(); - // clang-format on - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto EntityManager::components_of_type(this Self& self) noexcept -> std::vector>> { - // clang-format off - return self.m_entities - | stdv::filter(bind_front(&EntityManager::has_component, &self)) - | stdv::transform(bind_front(&EntityManager::getComponent, &self)) - | stdv::transform(monadic::forward_like()) - | stdv::transform(monadic::as_ref()) - | stdr::to(); - // clang-format on - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto EntityManager::add_system(Args&&... args) -> T& { - m_systems.emplace(std::make_unique(std::forward(args)..., *this)); - - auto& system = get_system(); - - get_needed_entities(system); - - return system; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto EntityManager::has_system() const noexcept -> bool { - return stdr::any_of(m_systems, monadic::is()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto EntityManager::systems(this Self& self) noexcept -> std::vector>> { - constexpr auto as_refer = [] { - if constexpr (core::meta::IsConst) return monadic::as_ref(); - else - return monadic::as_ref_mut(); - }(); - - return self.m_systems | stdv::transform(as_refer) | stdr::to(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto EntityManager::get_system(this Self& self) noexcept -> core::meta::ForwardConst { - EXPECTS(self.template has_system()); - - auto it = stdr::find_if(self.m_systems, monadic::is()); - - return as>(*it->get()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto EntityManager::entity_count() const noexcept -> usize { - return std::size(m_entities); - } - - ///////////////////////////////////// - ///////////////////////////////////// - constexpr auto EntityManager::component_key_for(Entity e, Component::Type type) noexcept -> ComponentKey { - return (static_cast(e) << 32) | static_cast(type); - } - - ///////////////////////////////////// - ///////////////////////////////////// - constexpr auto EntityManager::is_key_entity(Entity e, ComponentKey type) noexcept -> bool { - return static_cast(e) == (type >> 32); - } -} // namespace stormkit::entities +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +#include + +export module stormkit.entities; + +import std; + +import stormkit.core; + +#ifdef STORMKIT_LUA_BINDING +export import :lua; +#endif + +namespace stdr = std::ranges; +namespace stdv = std::views; + +export namespace stormkit::entities { + using Entity = u32; + inline constexpr auto INVALID_ENTITY = Entity { 0 }; + class System; + + struct EntityHashFunc { +#ifdef STORMKIT_COMPILER_MSVC + [[nodiscard]] + auto operator()(Entity k) const noexcept -> hash64; +#else + [[nodiscard]] + static auto operator()(Entity k) noexcept -> hash64; +#endif + }; + + struct Component { + using Type = u64; + + static constexpr Type INVALID_TYPE = 0; + static constexpr Type TYPE = INVALID_TYPE; + }; + + namespace meta { + template + concept IsComponentType = core::meta::Is and requires(T&& component) { T::TYPE; }; + + template + concept IsSystem = core::meta::Is; + } // namespace meta + + template + constexpr auto component_hash(std::string_view str) noexcept -> Result; + + constexpr auto component_hash(CZString str, usize size) noexcept -> Component::Type; + + constexpr auto component_hash(std::string_view str) noexcept -> Component::Type; + + namespace literals { + constexpr auto operator""_component_type(CZString str, usize size) -> Component::Type; + } // namespace literals + + struct Message { + u32 id; + std::vector entities; + }; + + class STORMKIT_API MessageBus { + public: + MessageBus(); + ~MessageBus(); + + MessageBus(const MessageBus&) = delete; + auto operator=(const MessageBus&) -> MessageBus& = delete; + + MessageBus(MessageBus&&); + auto operator=(MessageBus&&) -> MessageBus&; + + auto push(Message&& message) -> void; + [[nodiscard]] + auto top() const -> const Message&; + auto pop() -> void; + + [[nodiscard]] + auto empty() const noexcept -> bool; + + private: + std::queue m_messages; + }; + + class EntityManager; + + class STORMKIT_API System { + public: + using ComponentTypes = HashSet; + + System(EntityManager& manager, u32 priority, ComponentTypes types); + + System(const System&) = delete; + auto operator=(const System&) -> System& = delete; + + System(System&&) noexcept; + auto operator=(System&&) noexcept -> System&; + + virtual ~System(); + + virtual auto pre_update() -> void; + virtual auto update(fsecond delta) -> void = 0; + virtual auto post_update() -> void; + + [[nodiscard]] + auto priority() const noexcept -> u32; + [[nodiscard]] + auto components_used() const noexcept -> const ComponentTypes&; + + auto add_entity(Entity e) -> void; + auto remove_entity(Entity e) -> void; + + struct Predicate { +#ifdef STORMKIT_COMPILER_MSVC + [[nodiscard]] + auto operator()(const std::unique_ptr& s1, const std::unique_ptr& s2) const noexcept +#else + [[nodiscard]] + static auto operator()(const std::unique_ptr& s1, const std::unique_ptr& s2) noexcept +#endif + -> bool { + return s1->priority() < s2->priority(); + } + }; + + protected: + virtual auto on_message_received(const Message& message) -> void = 0; + + Ref m_manager; + HashSet m_entities; + + friend class EntityManager; + + private: + u32 m_priority; + ComponentTypes m_types; + }; + + class STORMKIT_API EntityManager { + public: + static constexpr auto ADDED_ENTITY_MESSAGE_ID = 1; + static constexpr auto REMOVED_ENTITY_MESSAGE_ID = 2; + + explicit EntityManager(); + ~EntityManager(); + + EntityManager(const EntityManager&) = delete; + auto operator=(const EntityManager&) -> EntityManager& = delete; + + EntityManager(EntityManager&&); + auto operator=(EntityManager&&) -> EntityManager&; + + auto make_entity() -> Entity; + auto destroy_entity(Entity entity) -> void; + auto destroy_all_entities() -> void; + auto has_entity(Entity entity) const -> bool; + + template + auto add_component(Entity entity, Args&&... args) -> T&; + + template + auto destroy_component(Entity entity) -> void; + + template + auto has_component(Entity entity) const -> bool; + + auto has_component(Entity entity, Component::Type type) const -> bool; + + auto entities() const noexcept -> const std::vector&; + + template + auto entities_with_component() const -> std::vector; + + template + auto getComponent(this Self& self, Entity entity) -> core::meta::ForwardConst; + + template + auto components(this Self& self, Entity entity) -> std::vector>>; + + template + auto components_of_type(this Self& self) noexcept -> std::vector>>; + + template + auto add_system(Args&&... args) -> T&; + + template + auto has_system() const noexcept -> bool; + + template + auto systems(this Self& self) noexcept -> std::vector>>; + + template + auto get_system(this Self& self) noexcept -> core::meta::ForwardConst; + + auto step(fsecond delta) -> void; + + auto entity_count() const noexcept -> usize; + + // void commit(Entity e); + + private: + using ComponentKey = u64; + + static constexpr auto component_key_for(Entity e, Component::Type type) noexcept -> ComponentKey; + static constexpr auto is_key_entity(Entity e, ComponentKey key) noexcept -> bool; + + auto purpose_to_systems(Entity e) -> void; + auto remove_from_systems(Entity e) -> void; + auto get_needed_entities(System& system) -> void; + + Entity m_next_valid_entity = 1; + std::queue m_free_entities; + + HashSet m_entities; + + HashSet m_added_entities; + HashSet m_updated_entities; + HashSet m_removed_entities; + + HashMap> m_registered_components_for_entities; + std::set, System::Predicate> m_systems; + HashMap> m_components; + + MessageBus m_message_bus; + }; +} // namespace stormkit::entities + +namespace stormkit::entities { + ///////////////////////////////////// + ///////////////////////////////////// +#ifdef STORMKIT_COMPILER_MSVC + inline auto EntityHashFunc::operator()(Entity k) const noexcept -> hash64 { +#else + inline auto EntityHashFunc::operator()(Entity k) noexcept -> hash64 { +#endif + return as(k); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + constexpr auto component_hash(std::string_view str) noexcept -> Result { + return std::empty(str) + ? 0xcbf29ce484222325UL + : (as(str[0]) ^ component_hash(str.substr(1, std::size(str) - 1))) * 0x100000001b3UL; + } + + ///////////////////////////////////// + ///////////////////////////////////// + constexpr auto component_hash(CZString str, usize size) noexcept -> Component::Type { + return size == 0 ? 0xcbf29ce484222325UL + : (as(str[0]) ^ component_hash(std::string_view { str + 1, size - 1 })) * 0x100000001b3UL; + } + + ///////////////////////////////////// + ///////////////////////////////////// + constexpr auto component_hash(std::string_view str) noexcept -> Component::Type { + return component_hash(std::data(str), std::size(str)); + } + + namespace literals { + ///////////////////////////////////// + ///////////////////////////////////// + constexpr auto operator""_component_type(CZString str, usize size) -> Component::Type { + return stormkit::entities::component_hash(str, size); + } + } // namespace literals + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto MessageBus::empty() const noexcept -> bool { + return std::empty(m_messages); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto System::priority() const noexcept -> u32 { + return m_priority; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto System::components_used() const noexcept -> const ComponentTypes& { + return m_types; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto EntityManager::add_component(Entity entity, Args&&... args) -> T& { + static_assert(T::TYPE != Component::INVALID_TYPE, "T must have T::type defined"); + + EXPECTS(has_entity(entity)); + EXPECTS(not has_component(entity)); + + auto component = std::make_unique(std::forward(args)...); + + auto type = T::TYPE; + m_components[component_key_for(entity, type)] = std::move(component); + m_registered_components_for_entities.at(entity).emplace_back(type); + + m_updated_entities.emplace(entity); + + return getComponent(entity); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto EntityManager::destroy_component(Entity entity) -> void { + static_assert(T::TYPE != Component::INVALID_TYPE, "T must have T::type defined"); + + EXPECTS(has_entity(entity)); + EXPECTS(has_component(entity)); + + const auto key = component_key_for(entity, T::TYPE); + + if (m_components.find(key) != stdr::cend(m_components)) m_components.erase(key); + + m_updated_entities.emplace(entity); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto EntityManager::has_component(Entity entity) const -> bool { + static_assert(T::TYPE != Component::INVALID_TYPE, "T must have T::type defined"); + + return has_component(entity, T::TYPE); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto EntityManager::entities() const noexcept -> const std::vector& { + return m_entities.values(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto EntityManager::entities_with_component() const -> std::vector { + // clang-format off + return entities() + | stdv::filter([](auto&& entity) static noexcept { return stdr::any_of(entity, T::TYPE); }) + | stdr::to(); + // clang-format on + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto EntityManager::getComponent(this Self& self, Entity entity) -> core::meta::ForwardConst { + EXPECTS(self.template has_component(entity)); + EXPECTS(self.has_entity(entity)); + + const auto key = component_key_for(entity, T::TYPE); + return *std::bit_cast(self.m_components.at(key).get()); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto EntityManager::components(this Self& self, Entity entity) + -> std::vector>> { + if (not self.has_entity(entity)) [[unlikely]] + return {}; + // clang-format off + return self.m_components + | stdv::filter([entity](auto&& pair) noexcept { + return EntityManager::is_key_entity(entity, pair.first); + }) + | stdv::values + | stdv::transform(monadic::as_ref()) + | stdr::to(); + // clang-format on + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto EntityManager::components_of_type(this Self& self) noexcept -> std::vector>> { + // clang-format off + return self.m_entities + | stdv::filter(bind_front(&EntityManager::has_component, &self)) + | stdv::transform(bind_front(&EntityManager::getComponent, &self)) + | stdv::transform(monadic::forward_like()) + | stdv::transform(monadic::as_ref()) + | stdr::to(); + // clang-format on + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto EntityManager::add_system(Args&&... args) -> T& { + m_systems.emplace(std::make_unique(std::forward(args)..., *this)); + + auto& system = get_system(); + + get_needed_entities(system); + + return system; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto EntityManager::has_system() const noexcept -> bool { + return stdr::any_of(m_systems, monadic::is()); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto EntityManager::systems(this Self& self) noexcept -> std::vector>> { + constexpr auto as_refer = [] { + if constexpr (core::meta::IsConst) return monadic::as_ref(); + else + return monadic::as_ref_mut(); + }(); + + return self.m_systems | stdv::transform(as_refer) | stdr::to(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto EntityManager::get_system(this Self& self) noexcept -> core::meta::ForwardConst { + EXPECTS(self.template has_system()); + + auto it = stdr::find_if(self.m_systems, monadic::is()); + + return as>(*it->get()); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto EntityManager::entity_count() const noexcept -> usize { + return std::size(m_entities); + } + + ///////////////////////////////////// + ///////////////////////////////////// + constexpr auto EntityManager::component_key_for(Entity e, Component::Type type) noexcept -> ComponentKey { + return (static_cast(e) << 32) | static_cast(type); + } + + ///////////////////////////////////// + ///////////////////////////////////// + constexpr auto EntityManager::is_key_entity(Entity e, ComponentKey type) noexcept -> bool { + return static_cast(e) == (type >> 32); + } +} // namespace stormkit::entities diff --git a/modules/stormkit/entities/lua.mpp b/modules/stormkit/entities/lua.cppm similarity index 100% rename from modules/stormkit/entities/lua.mpp rename to modules/stormkit/entities/lua.cppm diff --git a/modules/stormkit/gpu.mpp b/modules/stormkit/gpu.cppm similarity index 96% rename from modules/stormkit/gpu.mpp rename to modules/stormkit/gpu.cppm index b3ccf97c7..b62d527bf 100644 --- a/modules/stormkit/gpu.mpp +++ b/modules/stormkit/gpu.cppm @@ -1,14 +1,14 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -export module stormkit.gpu; - -// export import stormkit.gpu:Core.Compute; -export import stormkit.gpu.core; -export import stormkit.gpu.execution; -export import stormkit.gpu.resource; - -#ifdef STORMKIT_LUA_BINDING -export import :lua; -#endif +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +export module stormkit.gpu; + +// export import stormkit.gpu:Core.Compute; +export import stormkit.gpu.core; +export import stormkit.gpu.execution; +export import stormkit.gpu.resource; + +#ifdef STORMKIT_LUA_BINDING +export import :lua; +#endif diff --git a/modules/stormkit/gpu/core.mpp b/modules/stormkit/gpu/core.cppm similarity index 96% rename from modules/stormkit/gpu/core.mpp rename to modules/stormkit/gpu/core.cppm index dda5cd765..51b782769 100644 --- a/modules/stormkit/gpu/core.mpp +++ b/modules/stormkit/gpu/core.cppm @@ -1,12 +1,12 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -export module stormkit.gpu.core; - -export import :loader; -export import :device; -export import :instance; -export import :structs; -export import :sync; -export import :vulkan; +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +export module stormkit.gpu.core; + +export import :loader; +export import :device; +export import :instance; +export import :structs; +export import :sync; +export import :vulkan; diff --git a/modules/stormkit/gpu/core/device.mpp b/modules/stormkit/gpu/core/device.cppm similarity index 100% rename from modules/stormkit/gpu/core/device.mpp rename to modules/stormkit/gpu/core/device.cppm diff --git a/modules/stormkit/gpu/core/instance.mpp b/modules/stormkit/gpu/core/instance.cppm similarity index 100% rename from modules/stormkit/gpu/core/instance.mpp rename to modules/stormkit/gpu/core/instance.cppm diff --git a/modules/stormkit/gpu/core/loader.mpp b/modules/stormkit/gpu/core/loader.cppm similarity index 100% rename from modules/stormkit/gpu/core/loader.mpp rename to modules/stormkit/gpu/core/loader.cppm diff --git a/modules/stormkit/gpu/core/structs.mpp b/modules/stormkit/gpu/core/structs.cppm similarity index 100% rename from modules/stormkit/gpu/core/structs.mpp rename to modules/stormkit/gpu/core/structs.cppm diff --git a/modules/stormkit/gpu/core/sync.mpp b/modules/stormkit/gpu/core/sync.cppm similarity index 100% rename from modules/stormkit/gpu/core/sync.mpp rename to modules/stormkit/gpu/core/sync.cppm diff --git a/modules/stormkit/gpu/core/vulkan.mpp b/modules/stormkit/gpu/core/vulkan.cppm similarity index 100% rename from modules/stormkit/gpu/core/vulkan.mpp rename to modules/stormkit/gpu/core/vulkan.cppm diff --git a/modules/stormkit/gpu/core/vulkan/enums.mpp b/modules/stormkit/gpu/core/vulkan/enums.cppm similarity index 100% rename from modules/stormkit/gpu/core/vulkan/enums.mpp rename to modules/stormkit/gpu/core/vulkan/enums.cppm diff --git a/modules/stormkit/gpu/core/vulkan/structs.mpp b/modules/stormkit/gpu/core/vulkan/structs.cppm similarity index 100% rename from modules/stormkit/gpu/core/vulkan/structs.mpp rename to modules/stormkit/gpu/core/vulkan/structs.cppm diff --git a/modules/stormkit/gpu/core/vulkan/utils.mpp b/modules/stormkit/gpu/core/vulkan/utils.cppm similarity index 100% rename from modules/stormkit/gpu/core/vulkan/utils.mpp rename to modules/stormkit/gpu/core/vulkan/utils.cppm diff --git a/modules/stormkit/gpu/core/vulkan/vma.mpp b/modules/stormkit/gpu/core/vulkan/vma.cppm similarity index 100% rename from modules/stormkit/gpu/core/vulkan/vma.mpp rename to modules/stormkit/gpu/core/vulkan/vma.cppm diff --git a/modules/stormkit/gpu/core/vulkan/volk.mpp b/modules/stormkit/gpu/core/vulkan/volk.cppm similarity index 100% rename from modules/stormkit/gpu/core/vulkan/volk.mpp rename to modules/stormkit/gpu/core/vulkan/volk.cppm diff --git a/modules/stormkit/gpu/execution.mpp b/modules/stormkit/gpu/execution.cppm similarity index 100% rename from modules/stormkit/gpu/execution.mpp rename to modules/stormkit/gpu/execution.cppm diff --git a/modules/stormkit/gpu/execution/command_buffer.mpp b/modules/stormkit/gpu/execution/command_buffer.cppm similarity index 100% rename from modules/stormkit/gpu/execution/command_buffer.mpp rename to modules/stormkit/gpu/execution/command_buffer.cppm diff --git a/modules/stormkit/gpu/execution/descriptors.mpp b/modules/stormkit/gpu/execution/descriptors.cppm similarity index 100% rename from modules/stormkit/gpu/execution/descriptors.mpp rename to modules/stormkit/gpu/execution/descriptors.cppm diff --git a/modules/stormkit/gpu/execution/pipeline.mpp b/modules/stormkit/gpu/execution/pipeline.cppm similarity index 100% rename from modules/stormkit/gpu/execution/pipeline.mpp rename to modules/stormkit/gpu/execution/pipeline.cppm diff --git a/modules/stormkit/gpu/execution/raster_pipeline.mpp b/modules/stormkit/gpu/execution/raster_pipeline.cppm similarity index 100% rename from modules/stormkit/gpu/execution/raster_pipeline.mpp rename to modules/stormkit/gpu/execution/raster_pipeline.cppm diff --git a/modules/stormkit/gpu/execution/render_pass.mpp b/modules/stormkit/gpu/execution/render_pass.cppm similarity index 100% rename from modules/stormkit/gpu/execution/render_pass.mpp rename to modules/stormkit/gpu/execution/render_pass.cppm diff --git a/modules/stormkit/gpu/execution/swapchain.mpp b/modules/stormkit/gpu/execution/swapchain.cppm similarity index 100% rename from modules/stormkit/gpu/execution/swapchain.mpp rename to modules/stormkit/gpu/execution/swapchain.cppm diff --git a/modules/stormkit/gpu/lua.mpp b/modules/stormkit/gpu/lua.cppm similarity index 100% rename from modules/stormkit/gpu/lua.mpp rename to modules/stormkit/gpu/lua.cppm diff --git a/modules/stormkit/gpu/resource.mpp b/modules/stormkit/gpu/resource.cppm similarity index 100% rename from modules/stormkit/gpu/resource.mpp rename to modules/stormkit/gpu/resource.cppm diff --git a/modules/stormkit/gpu/resource/buffer.mpp b/modules/stormkit/gpu/resource/buffer.cppm similarity index 97% rename from modules/stormkit/gpu/resource/buffer.mpp rename to modules/stormkit/gpu/resource/buffer.cppm index 18cc04fc5..1e70bd574 100644 --- a/modules/stormkit/gpu/resource/buffer.mpp +++ b/modules/stormkit/gpu/resource/buffer.cppm @@ -1,330 +1,330 @@ -// Copyright (C) 2023 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include -#include - -#include - -export module stormkit.gpu.resource:buffer; - -import std; - -import stormkit.core; -import stormkit.gpu.core; - -namespace stdr = std::ranges; - -export namespace stormkit::gpu { - class STORMKIT_API Buffer { - struct PrivateFuncTag {}; - - public: - struct CreateInfo { - BufferUsageFlag usages; - usize size; - MemoryPropertyFlag property = MemoryPropertyFlag::HOST_VISIBLE | MemoryPropertyFlag::HOST_COHERENT; - }; - - static constexpr auto DEBUG_TYPE = DebugObjectType::BUFFER; - - ~Buffer(); - - Buffer(const Buffer&) = delete; - auto operator=(const Buffer&) -> Buffer& = delete; - - Buffer(Buffer&&) noexcept; - auto operator=(Buffer&&) noexcept -> Buffer&; - - static auto create(const Device& device, const CreateInfo& info, bool persistently_mapped = false) noexcept - -> Expected; - static auto allocate(const Device& device, const CreateInfo& info, bool persistently_mapped = false) noexcept - -> Expected>; - - [[nodiscard]] - auto usages() const noexcept -> BufferUsageFlag; - [[nodiscard]] - auto size() const noexcept -> usize; - [[nodiscard]] - auto memory_property() const noexcept -> MemoryPropertyFlag; - - auto map(ioffset offset) noexcept -> Expected; - auto map(ioffset offset, usize size) noexcept -> Expected>; - - template - auto map_as(ioffset offset) noexcept -> Expected>; - - template - [[nodiscard]] - auto data(this Self& self) noexcept -> core::meta::ForwardConst*; - template - [[nodiscard]] - auto data(this Self& self, usize size) noexcept - -> core::meta::If, std::span, std::span>; - - template - [[nodiscard]] - auto data_as(this auto& self) noexcept -> Ref; - - auto flush(ioffset offset, usize size) noexcept -> Expected; - auto unmap() noexcept -> void; - - [[nodiscard]] - auto is_persistently_mapped() const noexcept -> bool; - - auto upload(std::span data, ioffset offset = 0) noexcept -> Expected; - - template - requires(not stormkit::meta::IsSpecializationWithNTTPOf) - auto upload(const T& data, ioffset offset = 0) noexcept -> Expected; - - [[nodiscard]] - auto native_handle() const noexcept -> VkBuffer; - - Buffer(const Device& device, const CreateInfo& info, bool persistently_mapping, PrivateFuncTag) noexcept; - - private: - static auto find_memory_type(u32, - VkMemoryPropertyFlagBits, - const VkPhysicalDeviceMemoryProperties&, - const VkMemoryRequirements&) noexcept -> u32; - - auto do_init(MemoryPropertyFlag memory_properties) noexcept -> Expected; - - BufferUsageFlag m_usages = {}; - usize m_size = 0; - MemoryPropertyFlag m_memory_property = {}; - - bool m_is_persistently_mapped = false; - byte* m_mapped_pointer = nullptr; - - VkDevice m_vk_device; - Ref m_vk_device_table; - VmaAllocator m_vma_allocator; - VkRAIIHandle m_vma_allocation = { [](auto) static noexcept {} }; - VkRAIIHandle m_vk_handle; - }; - - struct BufferMemoryBarrier { - AccessFlag src; - AccessFlag dst; - - u32 src_queue_family_index = QUEUE_FAMILY_IGNORED; - u32 dst_queue_family_index = QUEUE_FAMILY_IGNORED; - - const Buffer& buffer; - usize size; - u64 offset = 0; - }; -} // namespace stormkit::gpu - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit::gpu { - ///////////////////////////////////// - ///////////////////////////////////// - inline Buffer::Buffer(const Device& device, const CreateInfo& info, bool persistently_mapped, PrivateFuncTag) noexcept - : m_usages { info.usages }, - m_size { info.size }, - m_memory_property { info.property }, - m_is_persistently_mapped { persistently_mapped }, - m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vma_allocator { device.allocator() }, - m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { - vk_device_table.vkDestroyBuffer(vk_device, handle, nullptr); - } } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Buffer::~Buffer() { - if (m_vma_allocation and m_mapped_pointer) { - vk_call(vmaUnmapMemory, m_vma_allocator, m_vma_allocation); - - m_mapped_pointer = nullptr; - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Buffer::Buffer(Buffer&& other) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Buffer::operator=(Buffer&& other) noexcept -> Buffer& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Buffer::create(const Device& device, const CreateInfo& info, bool persistently_mapped) noexcept - -> Expected { - auto buffer = Buffer { device, info, persistently_mapped, PrivateFuncTag {} }; - return buffer.do_init(info.property).transform(core::monadic::consume(buffer)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Buffer::allocate(const Device& device, const CreateInfo& info, bool persistently_mapped) noexcept - -> Expected> { - auto buffer = std::make_unique(device, info, persistently_mapped, PrivateFuncTag {}); - return buffer->do_init(info.property).transform(core::monadic::consume(buffer)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Buffer::usages() const noexcept -> BufferUsageFlag { - EXPECTS(m_vma_allocation and m_vk_handle); - return m_usages; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Buffer::size() const noexcept -> usize { - EXPECTS(m_vma_allocation and m_vk_handle); - return m_size; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Buffer::map(ioffset offset) noexcept -> Expected { - EXPECTS(m_vma_allocation and m_vk_handle); - EXPECTS(offset < as(m_size)); - - return vk_call(vmaMapMemory, m_vma_allocator, m_vma_allocation) - .transform([this, &offset](auto&& ptr) noexcept { - m_mapped_pointer = std::bit_cast(ptr); - m_mapped_pointer += offset; - return m_mapped_pointer; - }) - .transform_error(monadic::from_vk()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Buffer::map(ioffset offset, usize size) noexcept -> Expected> { - EXPECTS(m_vma_allocation and m_vk_handle); - return map(offset).transform([&size](auto&& ptr) noexcept { return as_bytes_mut(ptr, size); }); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Buffer::map_as(ioffset offset) noexcept -> Expected> { - EXPECTS(m_vma_allocation and m_vk_handle); - - return map(offset) - .transform([](auto&& ptr) static noexcept { return std::bit_cast(ptr); }) - .transform(core::monadic::as_ref_mut); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Buffer::data(this Self& self) noexcept -> core::meta::ForwardConst* { - EXPECTS(self.m_vma_allocation and self.m_vk_handle); - EXPECTS(self.m_mapped_pointer); - - using Out = core::meta::ForwardConst*; - return std::bit_cast(self.m_mapped_pointer); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Buffer::data(this Self& self, usize size) noexcept - -> core::meta::If, std::span, std::span> { - EXPECTS(self.m_vma_allocation and self.m_vk_handle); - EXPECTS(self.m_mapped_pointer); - - using Out = core::meta::If, std::span, std::span>; - return Out { std::bit_cast(self.m_mapped_pointer), size }; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Buffer::data_as(this Self& self) noexcept -> Ref { - EXPECTS(self.m_vma_allocation and self.m_vk_handle); - EXPECTS(self.m_mapped_pointer); - - using Type = core::meta::ForwardConst*; - return as_ref_like(std::bit_cast(self.data())); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Buffer::flush(ioffset offset, usize size) noexcept -> Expected { - EXPECTS(m_vma_allocation and m_vk_handle); - EXPECTS(offset <= as(m_size)); - EXPECTS(size <= m_size); - - return vk_call(vmaFlushAllocation, m_vma_allocator, m_vma_allocation, offset, size) - .transform_error(monadic::from_vk()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Buffer::unmap() noexcept -> void { - EXPECTS(m_vma_allocation and m_vk_handle); - expects(not m_is_persistently_mapped, "unmapping persistent buffer !"); - - vk_call(vmaUnmapMemory, m_vma_allocator, m_vma_allocation); - - m_mapped_pointer = nullptr; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Buffer::upload(std::span data, ioffset offset) noexcept -> Expected { - EXPECTS(stdr::size(data) <= m_size); - - if (m_is_persistently_mapped) { - stdr::copy(data, m_mapped_pointer); - return {}; - } - - return map(offset, stdr::size(data)).transform([this, &data](auto&& out) noexcept -> void { - stdr::copy(data, stdr::begin(out)); - unmap(); - }); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - requires(not stormkit::meta::IsSpecializationWithNTTPOf) - STORMKIT_FORCE_INLINE - inline auto Buffer::upload(const T& data, ioffset offset) noexcept -> Expected { - const auto bytes = as_bytes(data); - return upload(bytes, offset); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Buffer::native_handle() const noexcept -> VkBuffer { - EXPECTS(m_vk_handle); - return m_vk_handle; - } -} // namespace stormkit::gpu +// Copyright (C) 2023 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include +#include + +#include + +export module stormkit.gpu.resource:buffer; + +import std; + +import stormkit.core; +import stormkit.gpu.core; + +namespace stdr = std::ranges; + +export namespace stormkit::gpu { + class STORMKIT_API Buffer { + struct PrivateFuncTag {}; + + public: + struct CreateInfo { + BufferUsageFlag usages; + usize size; + MemoryPropertyFlag property = MemoryPropertyFlag::HOST_VISIBLE | MemoryPropertyFlag::HOST_COHERENT; + }; + + static constexpr auto DEBUG_TYPE = DebugObjectType::BUFFER; + + ~Buffer(); + + Buffer(const Buffer&) = delete; + auto operator=(const Buffer&) -> Buffer& = delete; + + Buffer(Buffer&&) noexcept; + auto operator=(Buffer&&) noexcept -> Buffer&; + + static auto create(const Device& device, const CreateInfo& info, bool persistently_mapped = false) noexcept + -> Expected; + static auto allocate(const Device& device, const CreateInfo& info, bool persistently_mapped = false) noexcept + -> Expected>; + + [[nodiscard]] + auto usages() const noexcept -> BufferUsageFlag; + [[nodiscard]] + auto size() const noexcept -> usize; + [[nodiscard]] + auto memory_property() const noexcept -> MemoryPropertyFlag; + + auto map(ioffset offset) noexcept -> Expected; + auto map(ioffset offset, usize size) noexcept -> Expected>; + + template + auto map_as(ioffset offset) noexcept -> Expected>; + + template + [[nodiscard]] + auto data(this Self& self) noexcept -> core::meta::ForwardConst*; + template + [[nodiscard]] + auto data(this Self& self, usize size) noexcept + -> core::meta::If, std::span, std::span>; + + template + [[nodiscard]] + auto data_as(this auto& self) noexcept -> Ref; + + auto flush(ioffset offset, usize size) noexcept -> Expected; + auto unmap() noexcept -> void; + + [[nodiscard]] + auto is_persistently_mapped() const noexcept -> bool; + + auto upload(std::span data, ioffset offset = 0) noexcept -> Expected; + + template + requires(not stormkit::meta::IsSpecializationWithNTTPOf) + auto upload(const T& data, ioffset offset = 0) noexcept -> Expected; + + [[nodiscard]] + auto native_handle() const noexcept -> VkBuffer; + + Buffer(const Device& device, const CreateInfo& info, bool persistently_mapping, PrivateFuncTag) noexcept; + + private: + static auto find_memory_type(u32, + VkMemoryPropertyFlagBits, + const VkPhysicalDeviceMemoryProperties&, + const VkMemoryRequirements&) noexcept -> u32; + + auto do_init(MemoryPropertyFlag memory_properties) noexcept -> Expected; + + BufferUsageFlag m_usages = {}; + usize m_size = 0; + MemoryPropertyFlag m_memory_property = {}; + + bool m_is_persistently_mapped = false; + byte* m_mapped_pointer = nullptr; + + VkDevice m_vk_device; + Ref m_vk_device_table; + VmaAllocator m_vma_allocator; + VkRAIIHandle m_vma_allocation = { [](auto) static noexcept {} }; + VkRAIIHandle m_vk_handle; + }; + + struct BufferMemoryBarrier { + AccessFlag src; + AccessFlag dst; + + u32 src_queue_family_index = QUEUE_FAMILY_IGNORED; + u32 dst_queue_family_index = QUEUE_FAMILY_IGNORED; + + const Buffer& buffer; + usize size; + u64 offset = 0; + }; +} // namespace stormkit::gpu + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit::gpu { + ///////////////////////////////////// + ///////////////////////////////////// + inline Buffer::Buffer(const Device& device, const CreateInfo& info, bool persistently_mapped, PrivateFuncTag) noexcept + : m_usages { info.usages }, + m_size { info.size }, + m_memory_property { info.property }, + m_is_persistently_mapped { persistently_mapped }, + m_vk_device { device.native_handle() }, + m_vk_device_table { as_ref(device.device_table()) }, + m_vma_allocator { device.allocator() }, + m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { + vk_device_table.vkDestroyBuffer(vk_device, handle, nullptr); + } } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Buffer::~Buffer() { + if (m_vma_allocation and m_mapped_pointer) { + vk_call(vmaUnmapMemory, m_vma_allocator, m_vma_allocation); + + m_mapped_pointer = nullptr; + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Buffer::Buffer(Buffer&& other) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::operator=(Buffer&& other) noexcept -> Buffer& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::create(const Device& device, const CreateInfo& info, bool persistently_mapped) noexcept + -> Expected { + auto buffer = Buffer { device, info, persistently_mapped, PrivateFuncTag {} }; + return buffer.do_init(info.property).transform(core::monadic::consume(buffer)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::allocate(const Device& device, const CreateInfo& info, bool persistently_mapped) noexcept + -> Expected> { + auto buffer = std::make_unique(device, info, persistently_mapped, PrivateFuncTag {}); + return buffer->do_init(info.property).transform(core::monadic::consume(buffer)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::usages() const noexcept -> BufferUsageFlag { + EXPECTS(m_vma_allocation and m_vk_handle); + return m_usages; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::size() const noexcept -> usize { + EXPECTS(m_vma_allocation and m_vk_handle); + return m_size; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::map(ioffset offset) noexcept -> Expected { + EXPECTS(m_vma_allocation and m_vk_handle); + EXPECTS(offset < as(m_size)); + + return vk_call(vmaMapMemory, m_vma_allocator, m_vma_allocation) + .transform([this, &offset](auto&& ptr) noexcept { + m_mapped_pointer = std::bit_cast(ptr); + m_mapped_pointer += offset; + return m_mapped_pointer; + }) + .transform_error(monadic::from_vk()); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::map(ioffset offset, usize size) noexcept -> Expected> { + EXPECTS(m_vma_allocation and m_vk_handle); + return map(offset).transform([&size](auto&& ptr) noexcept { return as_bytes_mut(ptr, size); }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Buffer::map_as(ioffset offset) noexcept -> Expected> { + EXPECTS(m_vma_allocation and m_vk_handle); + + return map(offset) + .transform([](auto&& ptr) static noexcept { return std::bit_cast(ptr); }) + .transform(core::monadic::as_ref_mut); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Buffer::data(this Self& self) noexcept -> core::meta::ForwardConst* { + EXPECTS(self.m_vma_allocation and self.m_vk_handle); + EXPECTS(self.m_mapped_pointer); + + using Out = core::meta::ForwardConst*; + return std::bit_cast(self.m_mapped_pointer); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Buffer::data(this Self& self, usize size) noexcept + -> core::meta::If, std::span, std::span> { + EXPECTS(self.m_vma_allocation and self.m_vk_handle); + EXPECTS(self.m_mapped_pointer); + + using Out = core::meta::If, std::span, std::span>; + return Out { std::bit_cast(self.m_mapped_pointer), size }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Buffer::data_as(this Self& self) noexcept -> Ref { + EXPECTS(self.m_vma_allocation and self.m_vk_handle); + EXPECTS(self.m_mapped_pointer); + + using Type = core::meta::ForwardConst*; + return as_ref_like(std::bit_cast(self.data())); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::flush(ioffset offset, usize size) noexcept -> Expected { + EXPECTS(m_vma_allocation and m_vk_handle); + EXPECTS(offset <= as(m_size)); + EXPECTS(size <= m_size); + + return vk_call(vmaFlushAllocation, m_vma_allocator, m_vma_allocation, offset, size) + .transform_error(monadic::from_vk()); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::unmap() noexcept -> void { + EXPECTS(m_vma_allocation and m_vk_handle); + expects(not m_is_persistently_mapped, "unmapping persistent buffer !"); + + vk_call(vmaUnmapMemory, m_vma_allocator, m_vma_allocation); + + m_mapped_pointer = nullptr; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::upload(std::span data, ioffset offset) noexcept -> Expected { + EXPECTS(stdr::size(data) <= m_size); + + if (m_is_persistently_mapped) { + stdr::copy(data, m_mapped_pointer); + return {}; + } + + return map(offset, stdr::size(data)).transform([this, &data](auto&& out) noexcept -> void { + stdr::copy(data, stdr::begin(out)); + unmap(); + }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(not stormkit::meta::IsSpecializationWithNTTPOf) + STORMKIT_FORCE_INLINE + inline auto Buffer::upload(const T& data, ioffset offset) noexcept -> Expected { + const auto bytes = as_bytes(data); + return upload(bytes, offset); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::native_handle() const noexcept -> VkBuffer { + EXPECTS(m_vk_handle); + return m_vk_handle; + } +} // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/resource/image.mpp b/modules/stormkit/gpu/resource/image.cppm similarity index 97% rename from modules/stormkit/gpu/resource/image.mpp rename to modules/stormkit/gpu/resource/image.cppm index d810cae77..a78502386 100644 --- a/modules/stormkit/gpu/resource/image.mpp +++ b/modules/stormkit/gpu/resource/image.cppm @@ -1,570 +1,570 @@ -// Copyright (C) 2023 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include -#include - -#include - -export module stormkit.gpu.resource:image; - -import std; - -import stormkit.core; -import stormkit.image; -import stormkit.gpu.core; - -export namespace stormkit::gpu { - class STORMKIT_API Sampler { - struct PrivateFuncTag {}; - - public: - struct Settings { - Filter mag_filter = Filter::LINEAR; - Filter min_filter = Filter::LINEAR; - - SamplerAddressMode address_mode_u = SamplerAddressMode::REPEAT; - SamplerAddressMode address_mode_v = SamplerAddressMode::REPEAT; - SamplerAddressMode address_mode_w = SamplerAddressMode::REPEAT; - - bool enable_anisotropy = false; - f32 max_anisotropy = 0.f; - - BorderColor border_color = BorderColor::INT_OPAQUE_BLACK; - - bool unnormalized_coordinates = false; - - bool compare_enable = false; - CompareOperation compare_operation = CompareOperation::ALWAYS; - - SamplerMipmapMode mipmap_mode = SamplerMipmapMode::LINEAR; - f32 mip_lod_bias = 0.f; - - f32 min_lod = 0.f; - f32 max_lod = 0.f; - }; - - static constexpr auto DEBUG_TYPE = DebugObjectType::SAMPLER; - - static auto create(const Device& device, const Settings& settings) noexcept -> Expected; - static auto allocate(const Device& device, const Settings& settings) noexcept -> Expected>; - ~Sampler(); - - Sampler(const Sampler&) = delete; - auto operator=(const Sampler&) -> Sampler& = delete; - - Sampler(Sampler&&) noexcept; - auto operator=(Sampler&&) noexcept -> Sampler&; - - [[nodiscard]] - auto settings() const noexcept -> const Settings&; - - [[nodiscard]] - auto native_handle() const noexcept -> VkSampler; - - Sampler(const Device& device, const Settings& settings, PrivateFuncTag) noexcept; - - private: - auto do_init() noexcept -> Expected; - - Settings m_settings = {}; - - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; - }; - - class Image; - - class STORMKIT_API ImageView { - struct PrivateFuncTag {}; - - public: - static constexpr auto DEBUG_TYPE = DebugObjectType::IMAGE_VIEW; - - static auto create(const Device& device, - const Image& image, - ImageViewType type = ImageViewType::T2D, - const ImageSubresourceRange& subresource_range = {}) noexcept -> Expected; - static auto allocate(const Device& device, - const Image& image, - ImageViewType type = ImageViewType::T2D, - const ImageSubresourceRange& subresource_range = {}) noexcept -> Expected>; - ~ImageView(); - - ImageView(const ImageView&) = delete; - auto operator=(const ImageView&) -> ImageView& = delete; - - ImageView(ImageView&&) noexcept; - auto operator=(ImageView&&) noexcept -> ImageView&; - - [[nodiscard]] - auto type() const noexcept -> ImageViewType; - [[nodiscard]] - auto subresource_range() const noexcept -> const ImageSubresourceRange&; - - [[nodiscard]] - auto native_handle() const noexcept -> VkImageView; - - ImageView(const Device&, ImageViewType, const ImageSubresourceRange&, PrivateFuncTag) noexcept; - - private: - auto do_init(const Image&) noexcept -> Expected; - - ImageViewType m_type = {}; - ImageSubresourceRange m_subresource_range = {}; - - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; - }; - - class STORMKIT_API Image { - struct PrivateFuncTag {}; - - public: - struct CreateInfo { - math::uextent3 extent; - PixelFormat format = PixelFormat::RGBA8_UNORM; - u32 layers = 1u; - u32 mip_levels = 1u; - ImageType type = ImageType::T2D; - ImageCreateFlag flags = ImageCreateFlag::NONE; - SampleCountFlag samples = SampleCountFlag::C1; - ImageUsageFlag usages = ImageUsageFlag::SAMPLED | ImageUsageFlag::TRANSFER_DST | ImageUsageFlag::TRANSFER_SRC; - ImageTiling tiling = ImageTiling::OPTIMAL; - MemoryPropertyFlag property = MemoryPropertyFlag::DEVICE_LOCAL; - }; - - static constexpr auto DEBUG_TYPE = DebugObjectType::IMAGE; - - static auto create(const Device& device, const CreateInfo& info) noexcept -> Expected; - static auto allocate(const Device& device, const CreateInfo& create_info) noexcept -> Expected>; - ~Image(); - - Image(const Image&) = delete; - auto operator=(const Image&) -> Image& = delete; - - Image(Image&&) noexcept; - auto operator=(Image&&) noexcept -> Image&; - - [[nodiscard]] - auto extent() const noexcept -> const math::uextent3&; - [[nodiscard]] - auto format() const noexcept -> PixelFormat; - [[nodiscard]] - auto type() const noexcept -> ImageType; - [[nodiscard]] - auto samples() const noexcept -> SampleCountFlag; - [[nodiscard]] - auto layers() const noexcept -> u32; - [[nodiscard]] - auto faces() const noexcept -> u32; - [[nodiscard]] - auto mip_levels() const noexcept -> u32; - [[nodiscard]] - auto usages() const noexcept -> ImageUsageFlag; - - [[nodiscard]] - auto native_handle() const noexcept -> VkImage; - - Image(const Device&, const CreateInfo&, PrivateFuncTag) noexcept; - - [[nodiscard]] - static auto create(const Device&, const CreateInfo&, VkImage&&) noexcept -> Image; - - private: - auto do_init(const CreateInfo&) noexcept -> Expected; - auto do_init(const VkImageCreateInfo&, MemoryPropertyFlag) noexcept -> Expected; - - math::uextent3 m_extent = { 0, 0, 0 }; - PixelFormat m_format = {}; - u32 m_layers = 0; - u32 m_faces = 0; - u32 m_mip_levels = 0; - ImageType m_type = {}; - ImageCreateFlag m_flags = {}; - SampleCountFlag m_samples = {}; - ImageUsageFlag m_usages = {}; - - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VmaAllocator m_vma_allocator = nullptr; - VkRAIIHandle m_vma_allocation = { [](auto) static noexcept {} }; - VkRAIIHandle m_vk_handle; - }; - - struct ImageMemoryBarrier { - AccessFlag src; - AccessFlag dst; - - ImageLayout old_layout; - ImageLayout new_layout; - - u32 src_queue_family_index = QUEUE_FAMILY_IGNORED; - u32 dst_queue_family_index = QUEUE_FAMILY_IGNORED; - - const Image& image; - ImageSubresourceRange range; - }; -} // namespace stormkit::gpu - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit::gpu { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Sampler::do_init() noexcept -> Expected { - const auto create_info = VkSamplerCreateInfo { - .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .magFilter = to_vk(m_settings.mag_filter), - .minFilter = to_vk(m_settings.min_filter), - .mipmapMode = to_vk(m_settings.mipmap_mode), - .addressModeU = to_vk(m_settings.address_mode_u), - .addressModeV = to_vk(m_settings.address_mode_v), - .addressModeW = to_vk(m_settings.address_mode_w), - .mipLodBias = m_settings.mip_lod_bias, - .anisotropyEnable = m_settings.enable_anisotropy, - .maxAnisotropy = m_settings.max_anisotropy, - .compareEnable = m_settings.compare_enable, - .compareOp = to_vk(m_settings.compare_operation), - .minLod = m_settings.min_lod, - .maxLod = m_settings.max_lod, - .borderColor = to_vk(m_settings.border_color), - .unnormalizedCoordinates = m_settings.unnormalized_coordinates - }; - return vk_call(m_vk_device_table->vkCreateSampler, m_vk_device, &create_info, nullptr) - .transform(core::monadic::set(m_vk_handle)) - .transform_error(monadic::from_vk()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Sampler::Sampler(const Device& device, const Settings& settings, PrivateFuncTag) noexcept - : m_settings { settings }, - m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto&& handle) noexcept { - vk_device_table.vkDestroySampler(vk_device, handle, nullptr); - } } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Sampler::~Sampler() - = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Sampler::Sampler(Sampler&&) noexcept - = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Sampler::operator=(Sampler&&) noexcept -> Sampler& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Sampler::create(const Device& device, const Settings& settings) noexcept -> Expected { - auto sampler = Sampler { device, settings, PrivateFuncTag {} }; - return sampler.do_init().transform(core::monadic::consume(sampler)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Sampler::allocate(const Device& device, const Settings& settings) noexcept -> Expected> { - auto sampler = std::make_unique(device, settings, PrivateFuncTag {}); - return sampler->do_init().transform(core::monadic::consume(sampler)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Sampler::settings() const noexcept -> const Settings& { - return m_settings; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Sampler::native_handle() const noexcept -> VkSampler { - EXPECTS(m_vk_handle); - return m_vk_handle; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto ImageView::do_init(const Image& image) noexcept -> Expected { - const auto vk_subresource_range = VkImageSubresourceRange { - .aspectMask = to_vk(m_subresource_range.aspect_mask), - .baseMipLevel = m_subresource_range.base_mip_level, - .levelCount = m_subresource_range.level_count, - .baseArrayLayer = m_subresource_range.base_array_layer, - .layerCount = m_subresource_range.layer_count, - }; - - const auto create_info = VkImageViewCreateInfo { - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .image = image.native_handle(), - .viewType = to_vk(m_type), - .format = to_vk(image.format()), - .components = { .r = VK_COMPONENT_SWIZZLE_R, - .g = VK_COMPONENT_SWIZZLE_G, - .b = VK_COMPONENT_SWIZZLE_B, - .a = VK_COMPONENT_SWIZZLE_A }, - .subresourceRange = vk_subresource_range, - }; - - return vk_call(m_vk_device_table->vkCreateImageView, m_vk_device, &create_info, nullptr) - .transform(core::monadic::set(m_vk_handle)) - .transform_error(monadic::from_vk()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline ImageView::ImageView(const Device& device, - ImageViewType type, - const ImageSubresourceRange& subresource_range, - PrivateFuncTag) noexcept - : m_type { type }, - m_subresource_range { subresource_range }, - m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto&& handle) noexcept { - vk_device_table.vkDestroyImageView(vk_device, handle, nullptr); - } } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline ImageView::~ImageView() - = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline ImageView::ImageView(ImageView&&) noexcept - = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto ImageView::operator=(ImageView&&) noexcept -> ImageView& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto ImageView::create(const Device& device, - const Image& image, - ImageViewType type, - const ImageSubresourceRange& subresource_range) noexcept -> Expected { - auto image_view = ImageView { device, type, subresource_range, PrivateFuncTag {} }; - return image_view.do_init(image).transform(core::monadic::consume(image_view)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto ImageView::allocate(const Device& device, - const Image& image, - ImageViewType type, - const ImageSubresourceRange& subresource_range) noexcept -> Expected> { - auto image_view = std::make_unique(device, type, subresource_range, PrivateFuncTag {}); - return image_view->do_init(image).transform(core::monadic::consume(image_view)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto ImageView::type() const noexcept -> ImageViewType { - return m_type; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto ImageView::subresource_range() const noexcept -> const ImageSubresourceRange& { - return m_subresource_range; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto ImageView::native_handle() const noexcept -> VkImageView { - EXPECTS(m_vk_handle); - return m_vk_handle; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Image::Image(const Device& device, const CreateInfo& info, PrivateFuncTag) noexcept - : m_extent { info.extent }, - m_format { info.format }, - m_layers { info.layers }, - m_faces { 1 }, - m_mip_levels { info.mip_levels }, - m_type { info.type }, - m_flags { info.flags }, - m_samples { info.samples }, - m_usages { info.usages }, - m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vma_allocator { device.allocator() }, - m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { - vk_device_table.vkDestroyImage(vk_device, handle, nullptr); - } } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Image::~Image() - = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Image::Image(Image&&) noexcept - = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::operator=(Image&&) noexcept -> Image& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::create(const Device& device, const CreateInfo& create_info) noexcept -> Expected { - auto image = Image { device, create_info, PrivateFuncTag {} }; - return image.do_init(create_info).transform(core::monadic::consume(image)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::allocate(const Device& device, const CreateInfo& create_info) noexcept -> Expected> { - auto image = std::make_unique(device, create_info, PrivateFuncTag {}); - return image->do_init(create_info).transform(core::monadic::consume(image)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::extent() const noexcept -> const math::uextent3& { - return m_extent; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::format() const noexcept -> PixelFormat { - return m_format; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::type() const noexcept -> ImageType { - return m_type; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::samples() const noexcept -> SampleCountFlag { - return m_samples; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::layers() const noexcept -> u32 { - return m_layers; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::faces() const noexcept -> u32 { - return m_faces; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::mip_levels() const noexcept -> u32 { - return m_mip_levels; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::usages() const noexcept -> ImageUsageFlag { - return m_usages; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::native_handle() const noexcept -> VkImage { - EXPECTS(m_vk_handle); - return m_vk_handle; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::create(const Device& device, const CreateInfo& info, VkImage&& vk_image) noexcept -> Image { - auto image = Image { device, info, PrivateFuncTag {} }; - image.m_vma_allocation = { core::monadic::noop() }; - image.m_vk_handle = { core::monadic::noop() }; - image.m_vk_handle = std::move(vk_image); - return image; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::do_init(const CreateInfo& info) noexcept -> Expected { - if (core::check_flag_bit(m_flags, gpu::ImageCreateFlag::CUBE_COMPATIBLE)) m_faces = 6u; - const auto create_info = VkImageCreateInfo { - .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, - .pNext = nullptr, - .flags = to_vk(m_flags), - .imageType = to_vk(m_type), - .format = to_vk(m_format), - .extent = { m_extent.width, m_extent.height, m_extent.depth }, - .mipLevels = m_mip_levels, - .arrayLayers = m_layers * m_faces, - .samples = to_vk(m_samples), - .tiling = to_vk(info.tiling), - .usage = to_vk(m_usages), - .sharingMode = VK_SHARING_MODE_EXCLUSIVE, - .queueFamilyIndexCount = 0, // TODO CHECK IF VALID VALUE - .pQueueFamilyIndices = nullptr, - .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, - }; - - return do_init(create_info, info.property); - } -} // namespace stormkit::gpu +// Copyright (C) 2023 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include +#include + +#include + +export module stormkit.gpu.resource:image; + +import std; + +import stormkit.core; +import stormkit.image; +import stormkit.gpu.core; + +export namespace stormkit::gpu { + class STORMKIT_API Sampler { + struct PrivateFuncTag {}; + + public: + struct Settings { + Filter mag_filter = Filter::LINEAR; + Filter min_filter = Filter::LINEAR; + + SamplerAddressMode address_mode_u = SamplerAddressMode::REPEAT; + SamplerAddressMode address_mode_v = SamplerAddressMode::REPEAT; + SamplerAddressMode address_mode_w = SamplerAddressMode::REPEAT; + + bool enable_anisotropy = false; + f32 max_anisotropy = 0.f; + + BorderColor border_color = BorderColor::INT_OPAQUE_BLACK; + + bool unnormalized_coordinates = false; + + bool compare_enable = false; + CompareOperation compare_operation = CompareOperation::ALWAYS; + + SamplerMipmapMode mipmap_mode = SamplerMipmapMode::LINEAR; + f32 mip_lod_bias = 0.f; + + f32 min_lod = 0.f; + f32 max_lod = 0.f; + }; + + static constexpr auto DEBUG_TYPE = DebugObjectType::SAMPLER; + + static auto create(const Device& device, const Settings& settings) noexcept -> Expected; + static auto allocate(const Device& device, const Settings& settings) noexcept -> Expected>; + ~Sampler(); + + Sampler(const Sampler&) = delete; + auto operator=(const Sampler&) -> Sampler& = delete; + + Sampler(Sampler&&) noexcept; + auto operator=(Sampler&&) noexcept -> Sampler&; + + [[nodiscard]] + auto settings() const noexcept -> const Settings&; + + [[nodiscard]] + auto native_handle() const noexcept -> VkSampler; + + Sampler(const Device& device, const Settings& settings, PrivateFuncTag) noexcept; + + private: + auto do_init() noexcept -> Expected; + + Settings m_settings = {}; + + VkDevice m_vk_device = nullptr; + Ref m_vk_device_table; + VkRAIIHandle m_vk_handle; + }; + + class Image; + + class STORMKIT_API ImageView { + struct PrivateFuncTag {}; + + public: + static constexpr auto DEBUG_TYPE = DebugObjectType::IMAGE_VIEW; + + static auto create(const Device& device, + const Image& image, + ImageViewType type = ImageViewType::T2D, + const ImageSubresourceRange& subresource_range = {}) noexcept -> Expected; + static auto allocate(const Device& device, + const Image& image, + ImageViewType type = ImageViewType::T2D, + const ImageSubresourceRange& subresource_range = {}) noexcept -> Expected>; + ~ImageView(); + + ImageView(const ImageView&) = delete; + auto operator=(const ImageView&) -> ImageView& = delete; + + ImageView(ImageView&&) noexcept; + auto operator=(ImageView&&) noexcept -> ImageView&; + + [[nodiscard]] + auto type() const noexcept -> ImageViewType; + [[nodiscard]] + auto subresource_range() const noexcept -> const ImageSubresourceRange&; + + [[nodiscard]] + auto native_handle() const noexcept -> VkImageView; + + ImageView(const Device&, ImageViewType, const ImageSubresourceRange&, PrivateFuncTag) noexcept; + + private: + auto do_init(const Image&) noexcept -> Expected; + + ImageViewType m_type = {}; + ImageSubresourceRange m_subresource_range = {}; + + VkDevice m_vk_device = nullptr; + Ref m_vk_device_table; + VkRAIIHandle m_vk_handle; + }; + + class STORMKIT_API Image { + struct PrivateFuncTag {}; + + public: + struct CreateInfo { + math::uextent3 extent; + PixelFormat format = PixelFormat::RGBA8_UNORM; + u32 layers = 1u; + u32 mip_levels = 1u; + ImageType type = ImageType::T2D; + ImageCreateFlag flags = ImageCreateFlag::NONE; + SampleCountFlag samples = SampleCountFlag::C1; + ImageUsageFlag usages = ImageUsageFlag::SAMPLED | ImageUsageFlag::TRANSFER_DST | ImageUsageFlag::TRANSFER_SRC; + ImageTiling tiling = ImageTiling::OPTIMAL; + MemoryPropertyFlag property = MemoryPropertyFlag::DEVICE_LOCAL; + }; + + static constexpr auto DEBUG_TYPE = DebugObjectType::IMAGE; + + static auto create(const Device& device, const CreateInfo& info) noexcept -> Expected; + static auto allocate(const Device& device, const CreateInfo& create_info) noexcept -> Expected>; + ~Image(); + + Image(const Image&) = delete; + auto operator=(const Image&) -> Image& = delete; + + Image(Image&&) noexcept; + auto operator=(Image&&) noexcept -> Image&; + + [[nodiscard]] + auto extent() const noexcept -> const math::uextent3&; + [[nodiscard]] + auto format() const noexcept -> PixelFormat; + [[nodiscard]] + auto type() const noexcept -> ImageType; + [[nodiscard]] + auto samples() const noexcept -> SampleCountFlag; + [[nodiscard]] + auto layers() const noexcept -> u32; + [[nodiscard]] + auto faces() const noexcept -> u32; + [[nodiscard]] + auto mip_levels() const noexcept -> u32; + [[nodiscard]] + auto usages() const noexcept -> ImageUsageFlag; + + [[nodiscard]] + auto native_handle() const noexcept -> VkImage; + + Image(const Device&, const CreateInfo&, PrivateFuncTag) noexcept; + + [[nodiscard]] + static auto create(const Device&, const CreateInfo&, VkImage&&) noexcept -> Image; + + private: + auto do_init(const CreateInfo&) noexcept -> Expected; + auto do_init(const VkImageCreateInfo&, MemoryPropertyFlag) noexcept -> Expected; + + math::uextent3 m_extent = { 0, 0, 0 }; + PixelFormat m_format = {}; + u32 m_layers = 0; + u32 m_faces = 0; + u32 m_mip_levels = 0; + ImageType m_type = {}; + ImageCreateFlag m_flags = {}; + SampleCountFlag m_samples = {}; + ImageUsageFlag m_usages = {}; + + VkDevice m_vk_device = nullptr; + Ref m_vk_device_table; + VmaAllocator m_vma_allocator = nullptr; + VkRAIIHandle m_vma_allocation = { [](auto) static noexcept {} }; + VkRAIIHandle m_vk_handle; + }; + + struct ImageMemoryBarrier { + AccessFlag src; + AccessFlag dst; + + ImageLayout old_layout; + ImageLayout new_layout; + + u32 src_queue_family_index = QUEUE_FAMILY_IGNORED; + u32 dst_queue_family_index = QUEUE_FAMILY_IGNORED; + + const Image& image; + ImageSubresourceRange range; + }; +} // namespace stormkit::gpu + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit::gpu { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Sampler::do_init() noexcept -> Expected { + const auto create_info = VkSamplerCreateInfo { + .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .magFilter = to_vk(m_settings.mag_filter), + .minFilter = to_vk(m_settings.min_filter), + .mipmapMode = to_vk(m_settings.mipmap_mode), + .addressModeU = to_vk(m_settings.address_mode_u), + .addressModeV = to_vk(m_settings.address_mode_v), + .addressModeW = to_vk(m_settings.address_mode_w), + .mipLodBias = m_settings.mip_lod_bias, + .anisotropyEnable = m_settings.enable_anisotropy, + .maxAnisotropy = m_settings.max_anisotropy, + .compareEnable = m_settings.compare_enable, + .compareOp = to_vk(m_settings.compare_operation), + .minLod = m_settings.min_lod, + .maxLod = m_settings.max_lod, + .borderColor = to_vk(m_settings.border_color), + .unnormalizedCoordinates = m_settings.unnormalized_coordinates + }; + return vk_call(m_vk_device_table->vkCreateSampler, m_vk_device, &create_info, nullptr) + .transform(core::monadic::set(m_vk_handle)) + .transform_error(monadic::from_vk()); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Sampler::Sampler(const Device& device, const Settings& settings, PrivateFuncTag) noexcept + : m_settings { settings }, + m_vk_device { device.native_handle() }, + m_vk_device_table { as_ref(device.device_table()) }, + m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto&& handle) noexcept { + vk_device_table.vkDestroySampler(vk_device, handle, nullptr); + } } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Sampler::~Sampler() + = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Sampler::Sampler(Sampler&&) noexcept + = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Sampler::operator=(Sampler&&) noexcept -> Sampler& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Sampler::create(const Device& device, const Settings& settings) noexcept -> Expected { + auto sampler = Sampler { device, settings, PrivateFuncTag {} }; + return sampler.do_init().transform(core::monadic::consume(sampler)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Sampler::allocate(const Device& device, const Settings& settings) noexcept -> Expected> { + auto sampler = std::make_unique(device, settings, PrivateFuncTag {}); + return sampler->do_init().transform(core::monadic::consume(sampler)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Sampler::settings() const noexcept -> const Settings& { + return m_settings; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Sampler::native_handle() const noexcept -> VkSampler { + EXPECTS(m_vk_handle); + return m_vk_handle; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto ImageView::do_init(const Image& image) noexcept -> Expected { + const auto vk_subresource_range = VkImageSubresourceRange { + .aspectMask = to_vk(m_subresource_range.aspect_mask), + .baseMipLevel = m_subresource_range.base_mip_level, + .levelCount = m_subresource_range.level_count, + .baseArrayLayer = m_subresource_range.base_array_layer, + .layerCount = m_subresource_range.layer_count, + }; + + const auto create_info = VkImageViewCreateInfo { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .image = image.native_handle(), + .viewType = to_vk(m_type), + .format = to_vk(image.format()), + .components = { .r = VK_COMPONENT_SWIZZLE_R, + .g = VK_COMPONENT_SWIZZLE_G, + .b = VK_COMPONENT_SWIZZLE_B, + .a = VK_COMPONENT_SWIZZLE_A }, + .subresourceRange = vk_subresource_range, + }; + + return vk_call(m_vk_device_table->vkCreateImageView, m_vk_device, &create_info, nullptr) + .transform(core::monadic::set(m_vk_handle)) + .transform_error(monadic::from_vk()); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline ImageView::ImageView(const Device& device, + ImageViewType type, + const ImageSubresourceRange& subresource_range, + PrivateFuncTag) noexcept + : m_type { type }, + m_subresource_range { subresource_range }, + m_vk_device { device.native_handle() }, + m_vk_device_table { as_ref(device.device_table()) }, + m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto&& handle) noexcept { + vk_device_table.vkDestroyImageView(vk_device, handle, nullptr); + } } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline ImageView::~ImageView() + = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline ImageView::ImageView(ImageView&&) noexcept + = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto ImageView::operator=(ImageView&&) noexcept -> ImageView& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto ImageView::create(const Device& device, + const Image& image, + ImageViewType type, + const ImageSubresourceRange& subresource_range) noexcept -> Expected { + auto image_view = ImageView { device, type, subresource_range, PrivateFuncTag {} }; + return image_view.do_init(image).transform(core::monadic::consume(image_view)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto ImageView::allocate(const Device& device, + const Image& image, + ImageViewType type, + const ImageSubresourceRange& subresource_range) noexcept -> Expected> { + auto image_view = std::make_unique(device, type, subresource_range, PrivateFuncTag {}); + return image_view->do_init(image).transform(core::monadic::consume(image_view)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto ImageView::type() const noexcept -> ImageViewType { + return m_type; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto ImageView::subresource_range() const noexcept -> const ImageSubresourceRange& { + return m_subresource_range; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto ImageView::native_handle() const noexcept -> VkImageView { + EXPECTS(m_vk_handle); + return m_vk_handle; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Image::Image(const Device& device, const CreateInfo& info, PrivateFuncTag) noexcept + : m_extent { info.extent }, + m_format { info.format }, + m_layers { info.layers }, + m_faces { 1 }, + m_mip_levels { info.mip_levels }, + m_type { info.type }, + m_flags { info.flags }, + m_samples { info.samples }, + m_usages { info.usages }, + m_vk_device { device.native_handle() }, + m_vk_device_table { as_ref(device.device_table()) }, + m_vma_allocator { device.allocator() }, + m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { + vk_device_table.vkDestroyImage(vk_device, handle, nullptr); + } } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Image::~Image() + = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Image::Image(Image&&) noexcept + = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::operator=(Image&&) noexcept -> Image& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::create(const Device& device, const CreateInfo& create_info) noexcept -> Expected { + auto image = Image { device, create_info, PrivateFuncTag {} }; + return image.do_init(create_info).transform(core::monadic::consume(image)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::allocate(const Device& device, const CreateInfo& create_info) noexcept -> Expected> { + auto image = std::make_unique(device, create_info, PrivateFuncTag {}); + return image->do_init(create_info).transform(core::monadic::consume(image)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::extent() const noexcept -> const math::uextent3& { + return m_extent; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::format() const noexcept -> PixelFormat { + return m_format; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::type() const noexcept -> ImageType { + return m_type; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::samples() const noexcept -> SampleCountFlag { + return m_samples; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::layers() const noexcept -> u32 { + return m_layers; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::faces() const noexcept -> u32 { + return m_faces; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::mip_levels() const noexcept -> u32 { + return m_mip_levels; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::usages() const noexcept -> ImageUsageFlag { + return m_usages; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::native_handle() const noexcept -> VkImage { + EXPECTS(m_vk_handle); + return m_vk_handle; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::create(const Device& device, const CreateInfo& info, VkImage&& vk_image) noexcept -> Image { + auto image = Image { device, info, PrivateFuncTag {} }; + image.m_vma_allocation = { core::monadic::noop() }; + image.m_vk_handle = { core::monadic::noop() }; + image.m_vk_handle = std::move(vk_image); + return image; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::do_init(const CreateInfo& info) noexcept -> Expected { + if (core::check_flag_bit(m_flags, gpu::ImageCreateFlag::CUBE_COMPATIBLE)) m_faces = 6u; + const auto create_info = VkImageCreateInfo { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .pNext = nullptr, + .flags = to_vk(m_flags), + .imageType = to_vk(m_type), + .format = to_vk(m_format), + .extent = { m_extent.width, m_extent.height, m_extent.depth }, + .mipLevels = m_mip_levels, + .arrayLayers = m_layers * m_faces, + .samples = to_vk(m_samples), + .tiling = to_vk(info.tiling), + .usage = to_vk(m_usages), + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .queueFamilyIndexCount = 0, // TODO CHECK IF VALID VALUE + .pQueueFamilyIndices = nullptr, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + }; + + return do_init(create_info, info.property); + } +} // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/resource/shader.mpp b/modules/stormkit/gpu/resource/shader.cppm similarity index 97% rename from modules/stormkit/gpu/resource/shader.mpp rename to modules/stormkit/gpu/resource/shader.cppm index 71827d0f3..60aa1e563 100644 --- a/modules/stormkit/gpu/resource/shader.mpp +++ b/modules/stormkit/gpu/resource/shader.cppm @@ -1,262 +1,262 @@ -// Copyright (C) 2023 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include -#include - -#include - -export module stormkit.gpu.resource:shader; - -import std; - -import stormkit.core; -import stormkit.gpu.core; - -namespace stdr = std::ranges; - -export namespace stormkit::gpu { - class STORMKIT_API Shader { - struct PrivateFuncTag {}; - - public: - enum class Error { - INVALID_SPIRV, - }; - using LoadError = std::variant; - template - using LoadExpected = std::expected; - static constexpr auto DEBUG_TYPE = DebugObjectType::SHADER_MODULE; - - static auto load_from_file(const Device& device, const std::filesystem::path& filepath, ShaderStageFlag type) noexcept - -> LoadExpected; - static auto load_from_bytes(const Device& device, std::span data, ShaderStageFlag type) noexcept - -> Expected; - static auto load_from_spirvid(const Device& device, std::span data, ShaderStageFlag type) noexcept - -> Expected; - - static auto allocate_and_load_from_file(const Device& device, - const std::filesystem::path& filepath, - ShaderStageFlag type) noexcept -> LoadExpected>; - static auto allocate_and_load_from_bytes(const Device& device, std::span data, ShaderStageFlag type) noexcept - -> Expected>; - static auto allocate_and_load_from_spirvid(const Device& device, - std::span data, - ShaderStageFlag type) noexcept -> Expected>; - ~Shader(); - - Shader(const Shader&) = delete; - auto operator=(const Shader&) -> Shader& = delete; - - Shader(Shader&&) noexcept; - auto operator=(Shader&&) noexcept -> Shader&; - - [[nodiscard]] - auto type() const noexcept -> ShaderStageFlag; - [[nodiscard]] - auto source() const noexcept -> const std::vector&; - [[nodiscard]] - auto source_as_bytes() const noexcept -> std::span; - - [[nodiscard]] - auto native_handle() const noexcept -> VkShaderModule; - - Shader(const Device&, std::vector, ShaderStageFlag, PrivateFuncTag) noexcept; - - private: - auto do_init() -> Expected; - auto reflect() noexcept -> void; - - ShaderStageFlag m_type = ShaderStageFlag::NONE; - std::vector m_source = {}; - - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; - }; -} // namespace stormkit::gpu - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit::gpu { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto sys_to_load_error(SystemError&& error) noexcept -> Shader::LoadError { - return Shader::LoadError { std::move(error) }; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto result_to_load_error(gpu::Result&& error) noexcept -> Shader::LoadError { - return Shader::LoadError { std::move(error) }; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Shader::do_init() -> Expected { - const auto create_info = VkShaderModuleCreateInfo { - .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .codeSize = stdr::size(m_source) * sizeof(SpirvID), - .pCode = stdr::data(m_source) - }; - - return vk_call(m_vk_device_table->vkCreateShaderModule, m_vk_device, &create_info, nullptr) - .transform(core::monadic::set(m_vk_handle)) - .transform_error(monadic::from_vk()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Shader::Shader(const Device& device, std::vector data, ShaderStageFlag type, PrivateFuncTag) noexcept - : m_type { type }, - m_source { std::move(data) }, - m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto&& handle) noexcept { - vk_device_table.vkDestroyShaderModule(vk_device, handle, nullptr); - } } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Shader::~Shader() = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Shader::Shader(Shader&&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Shader::operator=(Shader&&) noexcept -> Shader& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Shader::load_from_file(const Device& device, const std::filesystem::path& filepath, ShaderStageFlag type) noexcept - -> LoadExpected { - return io::File::open(filepath, io::Access::READ) - .transform_error(sys_to_load_error) - .and_then([](auto&& file) static noexcept -> LoadExpected> { - const auto size = file.size(); - if (size % sizeof(SpirvID) != 0) return std::unexpected { LoadError { Error::INVALID_SPIRV } }; - auto spirv = std::vector(size / sizeof(SpirvID)); - return file.read_to(as_bytes_mut(spirv)) - .transform(core::monadic::consume(spirv)) - .transform_error(sys_to_load_error); - }) - .and_then([&type, &device](auto&& spirv) noexcept { - auto shader = Shader { device, std::move(spirv), type, PrivateFuncTag {} }; - return shader.do_init().transform_error(result_to_load_error).transform(core::monadic::consume(shader)); - }); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Shader::load_from_bytes(const Device& device, std::span data, ShaderStageFlag type) noexcept - -> Expected { - auto shader = Shader { device, - bytes_as>(data) | stdr::to(), - type, - PrivateFuncTag {} }; - return shader.do_init().transform(core::monadic::consume(shader)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Shader::load_from_spirvid(const Device& device, std::span data, ShaderStageFlag type) noexcept - -> Expected { - auto shader = Shader { device, data | stdr::to(), type, PrivateFuncTag {} }; - return shader.do_init().transform(core::monadic::consume(shader)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Shader::allocate_and_load_from_file(const Device& device, - const std::filesystem::path& filepath, - ShaderStageFlag type) noexcept -> LoadExpected> { - expects(std::filesystem::is_regular_file(filepath), std::format("{} is not a file", filepath.string())); - - return io::File::open(filepath, io::Access::READ) - .transform_error(sys_to_load_error) - .and_then([](auto&& file) static noexcept { - const auto size = file.size(); - - auto spirv = std::vector(size / sizeof(SpirvID)); - return file.read_to(as_bytes_mut(spirv)) - .transform(core::monadic::consume(spirv)) - .transform_error(sys_to_load_error); - }) - .and_then([&type, &device](auto&& spirv) noexcept { - auto shader = std::make_unique(device, std::move(spirv), type, PrivateFuncTag {}); - return shader->do_init().transform(core::monadic::consume(shader)).transform_error(result_to_load_error); - }); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Shader::allocate_and_load_from_bytes(const Device& device, - std::span data, - ShaderStageFlag type) noexcept -> Expected> { - auto shader = std::make_unique(device, - bytes_as>(data) | stdr::to(), - type, - PrivateFuncTag {}); - return shader->do_init().transform(core::monadic::consume(shader)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Shader::allocate_and_load_from_spirvid(const Device& device, - std::span data, - ShaderStageFlag type) noexcept -> Expected> { - auto shader = std::make_unique(device, data | stdr::to(), type, PrivateFuncTag {}); - return shader->do_init().transform(core::monadic::consume(shader)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Shader::type() const noexcept -> ShaderStageFlag { - return m_type; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Shader::source() const noexcept -> const std::vector& { - return m_source; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Shader::source_as_bytes() const noexcept -> std::span { - return as_bytes(m_source); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Shader::native_handle() const noexcept -> VkShaderModule { - return m_vk_handle; - } -} // namespace stormkit::gpu +// Copyright (C) 2023 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include +#include + +#include + +export module stormkit.gpu.resource:shader; + +import std; + +import stormkit.core; +import stormkit.gpu.core; + +namespace stdr = std::ranges; + +export namespace stormkit::gpu { + class STORMKIT_API Shader { + struct PrivateFuncTag {}; + + public: + enum class Error { + INVALID_SPIRV, + }; + using LoadError = std::variant; + template + using LoadExpected = std::expected; + static constexpr auto DEBUG_TYPE = DebugObjectType::SHADER_MODULE; + + static auto load_from_file(const Device& device, const std::filesystem::path& filepath, ShaderStageFlag type) noexcept + -> LoadExpected; + static auto load_from_bytes(const Device& device, std::span data, ShaderStageFlag type) noexcept + -> Expected; + static auto load_from_spirvid(const Device& device, std::span data, ShaderStageFlag type) noexcept + -> Expected; + + static auto allocate_and_load_from_file(const Device& device, + const std::filesystem::path& filepath, + ShaderStageFlag type) noexcept -> LoadExpected>; + static auto allocate_and_load_from_bytes(const Device& device, std::span data, ShaderStageFlag type) noexcept + -> Expected>; + static auto allocate_and_load_from_spirvid(const Device& device, + std::span data, + ShaderStageFlag type) noexcept -> Expected>; + ~Shader(); + + Shader(const Shader&) = delete; + auto operator=(const Shader&) -> Shader& = delete; + + Shader(Shader&&) noexcept; + auto operator=(Shader&&) noexcept -> Shader&; + + [[nodiscard]] + auto type() const noexcept -> ShaderStageFlag; + [[nodiscard]] + auto source() const noexcept -> const std::vector&; + [[nodiscard]] + auto source_as_bytes() const noexcept -> std::span; + + [[nodiscard]] + auto native_handle() const noexcept -> VkShaderModule; + + Shader(const Device&, std::vector, ShaderStageFlag, PrivateFuncTag) noexcept; + + private: + auto do_init() -> Expected; + auto reflect() noexcept -> void; + + ShaderStageFlag m_type = ShaderStageFlag::NONE; + std::vector m_source = {}; + + VkDevice m_vk_device = nullptr; + Ref m_vk_device_table; + VkRAIIHandle m_vk_handle; + }; +} // namespace stormkit::gpu + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit::gpu { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + inline auto sys_to_load_error(SystemError&& error) noexcept -> Shader::LoadError { + return Shader::LoadError { std::move(error) }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + inline auto result_to_load_error(gpu::Result&& error) noexcept -> Shader::LoadError { + return Shader::LoadError { std::move(error) }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Shader::do_init() -> Expected { + const auto create_info = VkShaderModuleCreateInfo { + .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .codeSize = stdr::size(m_source) * sizeof(SpirvID), + .pCode = stdr::data(m_source) + }; + + return vk_call(m_vk_device_table->vkCreateShaderModule, m_vk_device, &create_info, nullptr) + .transform(core::monadic::set(m_vk_handle)) + .transform_error(monadic::from_vk()); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Shader::Shader(const Device& device, std::vector data, ShaderStageFlag type, PrivateFuncTag) noexcept + : m_type { type }, + m_source { std::move(data) }, + m_vk_device { device.native_handle() }, + m_vk_device_table { as_ref(device.device_table()) }, + m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto&& handle) noexcept { + vk_device_table.vkDestroyShaderModule(vk_device, handle, nullptr); + } } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Shader::~Shader() = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Shader::Shader(Shader&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Shader::operator=(Shader&&) noexcept -> Shader& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Shader::load_from_file(const Device& device, const std::filesystem::path& filepath, ShaderStageFlag type) noexcept + -> LoadExpected { + return io::File::open(filepath, io::Access::READ) + .transform_error(sys_to_load_error) + .and_then([](auto&& file) static noexcept -> LoadExpected> { + const auto size = file.size(); + if (size % sizeof(SpirvID) != 0) return std::unexpected { LoadError { Error::INVALID_SPIRV } }; + auto spirv = std::vector(size / sizeof(SpirvID)); + return file.read_to(as_bytes_mut(spirv)) + .transform(core::monadic::consume(spirv)) + .transform_error(sys_to_load_error); + }) + .and_then([&type, &device](auto&& spirv) noexcept { + auto shader = Shader { device, std::move(spirv), type, PrivateFuncTag {} }; + return shader.do_init().transform_error(result_to_load_error).transform(core::monadic::consume(shader)); + }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Shader::load_from_bytes(const Device& device, std::span data, ShaderStageFlag type) noexcept + -> Expected { + auto shader = Shader { device, + bytes_as>(data) | stdr::to(), + type, + PrivateFuncTag {} }; + return shader.do_init().transform(core::monadic::consume(shader)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Shader::load_from_spirvid(const Device& device, std::span data, ShaderStageFlag type) noexcept + -> Expected { + auto shader = Shader { device, data | stdr::to(), type, PrivateFuncTag {} }; + return shader.do_init().transform(core::monadic::consume(shader)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Shader::allocate_and_load_from_file(const Device& device, + const std::filesystem::path& filepath, + ShaderStageFlag type) noexcept -> LoadExpected> { + expects(std::filesystem::is_regular_file(filepath), std::format("{} is not a file", filepath.string())); + + return io::File::open(filepath, io::Access::READ) + .transform_error(sys_to_load_error) + .and_then([](auto&& file) static noexcept { + const auto size = file.size(); + + auto spirv = std::vector(size / sizeof(SpirvID)); + return file.read_to(as_bytes_mut(spirv)) + .transform(core::monadic::consume(spirv)) + .transform_error(sys_to_load_error); + }) + .and_then([&type, &device](auto&& spirv) noexcept { + auto shader = std::make_unique(device, std::move(spirv), type, PrivateFuncTag {}); + return shader->do_init().transform(core::monadic::consume(shader)).transform_error(result_to_load_error); + }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Shader::allocate_and_load_from_bytes(const Device& device, + std::span data, + ShaderStageFlag type) noexcept -> Expected> { + auto shader = std::make_unique(device, + bytes_as>(data) | stdr::to(), + type, + PrivateFuncTag {}); + return shader->do_init().transform(core::monadic::consume(shader)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Shader::allocate_and_load_from_spirvid(const Device& device, + std::span data, + ShaderStageFlag type) noexcept -> Expected> { + auto shader = std::make_unique(device, data | stdr::to(), type, PrivateFuncTag {}); + return shader->do_init().transform(core::monadic::consume(shader)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Shader::type() const noexcept -> ShaderStageFlag { + return m_type; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Shader::source() const noexcept -> const std::vector& { + return m_source; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Shader::source_as_bytes() const noexcept -> std::span { + return as_bytes(m_source); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Shader::native_handle() const noexcept -> VkShaderModule { + return m_vk_handle; + } +} // namespace stormkit::gpu diff --git a/modules/stormkit/image.mpp b/modules/stormkit/image.cppm similarity index 97% rename from modules/stormkit/image.mpp rename to modules/stormkit/image.cppm index a7b07466f..00ad1a73d 100644 --- a/modules/stormkit/image.mpp +++ b/modules/stormkit/image.cppm @@ -1,692 +1,692 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -#include - -export module stormkit.image; - -import std; - -import stormkit.core; - -#ifdef STORMKIT_LUA_BINDING -export import :lua; -#endif - -export namespace stormkit::image { - class STORMKIT_API Image { - public: - enum class Format : u8 { - R8_SNORM = 0, - RG8_SNORM = 1, - RGB8_SNORM = 2, - RGBA8_SNORM = 3, - R8_UNORM = 4, - RG8_UNORM = 5, - RGB8_UNORM = 6, - RGBA8_UNORM = 7, - R16_SNORM = 8, - RG16_SNORM = 9, - RGB16_SNORM = 10, - RGBA16_SNORM = 11, - R16_UNORM = 12, - RG16_UNORM = 13, - RGB16_UNORM = 14, - RGBA16_UNORM = 15, - RGBA4_UNORM = 17, - BGR8_UNORM = 20, - BGRA8_UNORM = 21, - R8I = 22, - RG8I = 23, - RGB8I = 24, - RGBA8I = 25, - R8U = 26, - RG8U = 27, - RGB8U = 28, - RGBA8U = 29, - R16I = 30, - RG16I = 31, - RGB16I = 32, - RGBA16I = 33, - R16U = 34, - RG16U = 35, - RGB16U = 36, - RGBA16U = 37, - R32I = 38, - RG32I = 39, - RGB32I = 40, - RGBA32I = 41, - R32U = 42, - RG32U = 43, - RGB32U = 44, - RGBA32U = 45, - R16F = 47, - RG16F = 48, - RGB16F = 49, - RGBA16F = 50, - R32F = 51, - RG32F = 52, - RGB32F = 53, - RGBA32F = 54, - SRGB8 = 56, - SRGBA8 = 57, - SBGR8 = 58, - SBGRA8 = 59, - UNDEFINED = 254, - }; - - enum class Codec : u8 { - AUTODETECT = 0, - JPEG = 1, - PNG = 2, - TARGA = 3, - PPM = 4, - HDR = 5, - KTX = 6, - QOI = 7, - UNKNOWN = 255, - }; - - enum class CodecArgs : u8 { - BINARY = 0, - ASCII = 1, - }; - - struct Error { - enum class Reason { - NOT_IMPLEMENTED, - FAILED_TO_PARSE, - FAILED_TO_SAVE, - FILE_NOT_FOUND, - INVALID_FORMAT, - UNKNOWN, - } reason; - - std::string str_error; - }; - - struct ImageData { - math::uextent3 extent = { .width = 0u, .height = 0u }; - u32 channel_count = 0u; - u32 bytes_per_channel = 0u; - u32 layers = 1u; - u32 faces = 1u; - u32 mip_levels = 1u; - Format format = Format::UNDEFINED; - - std::vector data = {}; - }; - - Image() noexcept; - explicit Image(ImageData&& data) noexcept; - Image(const math::uextent3& extent, Format format) noexcept; - Image(const std::filesystem::path& filepath, Codec codec = Codec::AUTODETECT) noexcept; - Image(std::span data, Codec codec = Codec::AUTODETECT) noexcept; - ~Image() noexcept; - - Image(const Image& rhs) noexcept; - auto operator=(const Image& rhs) noexcept -> Image&; - - Image(Image&& rhs) noexcept; - auto operator=(Image&& rhs) noexcept -> Image&; - - [[nodiscard]] - auto load_from_file(std::filesystem::path filepath, Codec codec = Codec::AUTODETECT) noexcept - -> std::expected; - [[nodiscard]] - auto load_from_memory(std::span data, Codec codec = Codec::AUTODETECT) noexcept -> std::expected; - [[nodiscard]] - auto save_to_file(std::filesystem::path filename, Codec codec, CodecArgs args = CodecArgs::BINARY) const noexcept - -> std::expected; - - [[nodiscard]] - auto save_to_memory(Codec codec, CodecArgs args = CodecArgs::BINARY) const noexcept - -> std::expected, Error>; - - auto create(math::uextent3 extent, Format format) noexcept -> void; - - [[nodiscard]] - auto convert_to(Format format) const noexcept -> Image; - [[nodiscard]] - auto scale(const math::uextent3& scale_to) const noexcept -> Image; - [[nodiscard]] - auto flip_x() const noexcept -> Image; - [[nodiscard]] - auto flip_y() const noexcept -> Image; - [[nodiscard]] - auto flip_z() const noexcept -> Image; - [[nodiscard]] - auto rotate_90() const noexcept -> Image; - [[nodiscard]] - auto rotate_180() const noexcept -> Image; - [[nodiscard]] - auto rotate_270() const noexcept -> Image; - - [[nodiscard]] - auto pixel(usize id, u32 layer = 0u, u32 face = 0u, u32 level = 0u) noexcept -> std::span; - [[nodiscard]] - auto pixel(usize id, u32 layer = 0u, u32 face = 0u, u32 level = 0u) const noexcept -> std::span; - [[nodiscard]] - auto pixel(math::uvec3 position, u32 layer = 0u, u32 face = 0u, u32 level = 0u) noexcept -> std::span; - [[nodiscard]] - auto pixel(math::uvec3 position, u32 layer = 0u, u32 face = 0u, u32 level = 0u) const noexcept -> std::span; - - [[nodiscard]] - auto extent(u32 level = 0u) const noexcept -> math::uextent3; - - [[nodiscard]] - auto channelCount() const noexcept -> u32; - - [[nodiscard]] - auto bytesPerChannel() const noexcept -> u32; - - [[nodiscard]] - auto layers() const noexcept -> u32; - - [[nodiscard]] - auto faces() const noexcept -> u32; - - [[nodiscard]] - auto mip_levels() const noexcept -> u32; - - [[nodiscard]] - auto format() const noexcept -> Format; - - [[nodiscard]] - auto size() const noexcept -> usize; - [[nodiscard]] - auto size(u32 layer, u32 face, u32 level) const noexcept -> usize; - [[nodiscard]] - auto size(u32 layer, u32 face) const noexcept -> usize; - [[nodiscard]] - auto size(u32 layer) const noexcept -> usize; - - [[nodiscard]] - auto data() noexcept -> std::span; - [[nodiscard]] - auto data(u32 layer, u32 face, u32 level) noexcept -> std::span; - [[nodiscard]] - auto data() const noexcept -> std::span; - [[nodiscard]] - auto data(u32 layer, u32 face, u32 level) const noexcept -> std::span; - - [[nodiscard]] - auto begin() noexcept; - [[nodiscard]] - auto begin(u32 layer, u32 face, u32 level) noexcept; - [[nodiscard]] - auto begin() const noexcept; - [[nodiscard]] - auto begin(u32 layer, u32 face, u32 level) const noexcept; - - [[nodiscard]] - auto cbegin() const noexcept; - [[nodiscard]] - auto cbegin(u32 layer, u32 face, u32 level) const noexcept; - - [[nodiscard]] - auto end() noexcept; - [[nodiscard]] - auto end(u32 layer, u32 face, u32 level) noexcept; - [[nodiscard]] - auto end() const noexcept; - [[nodiscard]] - auto end(u32 layer, u32 face, u32 level) const noexcept; - - [[nodiscard]] - auto cend() const noexcept; - [[nodiscard]] - auto cend(u32 layer, u32 face, u32 level) const noexcept; - - [[nodiscard]] - auto image_data() const noexcept -> const ImageData&; - - private: - ImageData m_data; - }; - - constexpr auto get_format_channel_count(Image::Format format) noexcept -> u8; - constexpr auto getSizeof(Image::Format format) noexcept -> u8; - -} // namespace stormkit::image - -export { - template - struct std::formatter: std::formatter, CharT> { - template - [[nodiscard]] - auto format(const stormkit::image::Image::Error& error, FormatContext& ctx) const noexcept -> decltype(ctx.out()); - }; -} - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit::image { - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::pixel(usize index, u32 layer, u32 face, u32 level) noexcept -> std::span { - EXPECTS(m_data.mip_levels > level); - EXPECTS(m_data.faces > face); - EXPECTS(m_data.layers > layer); - - auto _data = data(layer, face, level); - - EXPECTS(index < m_data.extent.width * m_data.extent.height * m_data.extent.depth); - - const auto block_size = m_data.channel_count * m_data.bytes_per_channel; - - return { std::data(_data) + index * block_size, block_size }; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::pixel(usize index, u32 layer, u32 face, u32 level) const noexcept -> std::span { - EXPECTS(m_data.mip_levels > level); - EXPECTS(m_data.faces > face); - EXPECTS(m_data.layers > layer); - - auto _data = data(layer, face, level); - - const auto mip_extent = extent(level); - EXPECTS(index < mip_extent.width * mip_extent.height * mip_extent.depth); - - const auto block_size = m_data.channel_count * m_data.bytes_per_channel; - - return { std::data(_data) + index * block_size, block_size }; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::pixel(math::uvec3 position, u32 layer, u32 face, u32 level) noexcept -> std::span { - const auto mip_extent = extent(level); - - const auto id = position.x + (position.y * mip_extent.width) + (mip_extent.width * mip_extent.height * position.z); - - return pixel(id, layer, face, level); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::pixel(math::uvec3 position, u32 layer, u32 face, u32 level) const noexcept -> std::span { - const auto mip_extent = extent(level); - - const auto id = position.x + (position.y * mip_extent.width) + (mip_extent.width * mip_extent.height * position.z); - - return pixel(id, layer, face, level); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::extent(u32 level) const noexcept -> math::uextent3 { - EXPECTS(m_data.mip_levels > level); - - return { .width = std::max(1u, m_data.extent.width >> level), - .height = std::max(1u, m_data.extent.height >> level), - .depth = std::max(1u, m_data.extent.depth >> level) }; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::channelCount() const noexcept -> u32 { - return m_data.channel_count; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::bytesPerChannel() const noexcept -> u32 { - return m_data.bytes_per_channel; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::layers() const noexcept -> u32 { - return m_data.layers; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::faces() const noexcept -> u32 { - return m_data.faces; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::mip_levels() const noexcept -> u32 { - return m_data.mip_levels; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::format() const noexcept -> Format { - return m_data.format; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::size() const noexcept -> usize { - return std::size(m_data.data); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::size(u32 layer, // TODO Use layer and face to get correct size - u32 face, - u32 level) const noexcept -> usize { - EXPECTS(m_data.mip_levels > level); - EXPECTS(m_data.faces > face); - EXPECTS(m_data.layers > layer); - - const auto mip_extent = extent(level); - - return mip_extent.width * mip_extent.height * mip_extent.depth * m_data.channel_count * m_data.bytes_per_channel; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::size(u32 layer, u32 face) const noexcept -> usize { - auto _size = usize { 0u }; - for (auto i : range(m_data.mip_levels)) _size += size(layer, face, i); - - return _size; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::size(u32 layer) const noexcept -> usize { - auto _size = usize { 0u }; - for (auto i : range(m_data.faces)) _size += size(layer, i); - - return _size; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::data() noexcept -> std::span { - return m_data.data; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::data(u32 layer, u32 face, u32 level) noexcept -> std::span { - const auto mip_size = size(layer, face, level); - - auto offset = usize { 0 }; - - for (auto i : range(layer)) offset += size(i); - - for (auto j : range(face)) offset += size(layer, j); - - for (auto k : range(level)) offset += size(layer, face, k); - - return { std::data(m_data.data) + offset, mip_size }; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::data() const noexcept -> std::span { - return m_data.data; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::data(u32 layer, u32 face, u32 level) const noexcept -> std::span { - const auto mip_size = size(layer, face, level); - - auto offset = usize { 0 }; - - for (auto i : range(layer)) offset += size(i); - - for (auto j : range(face)) offset += size(layer, j); - - for (auto k : range(level)) offset += size(layer, face, k); - - return { std::data(m_data.data) + offset, mip_size }; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::begin() noexcept { - return std::begin(m_data.data); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::begin(u32 layer, u32 face, u32 level) noexcept { - EXPECTS(m_data.mip_levels > level); - EXPECTS(m_data.faces > face); - EXPECTS(m_data.layers > layer); - - return std::begin(data(layer, face, level)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::begin() const noexcept { - return std::begin(m_data.data); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::begin(u32 layer, u32 face, u32 level) const noexcept { - return std::begin(data(layer, face, level)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::cbegin() const noexcept { - return std::cbegin(m_data.data); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::cbegin(u32 layer, u32 face, u32 level) const noexcept { - EXPECTS(m_data.mip_levels > level); - EXPECTS(m_data.faces > face); - EXPECTS(m_data.layers > layer); - - return std::cbegin(data(layer, face, level)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::end() noexcept { - return std::end(m_data.data); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::end(u32 layer, u32 face, u32 level) noexcept { - EXPECTS(m_data.mip_levels > level); - EXPECTS(m_data.faces > face); - EXPECTS(m_data.layers > layer); - - return std::end(data(layer, face, level)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::end() const noexcept { - return std::end(m_data.data); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::end(u32 layer, u32 face, u32 level) const noexcept { - EXPECTS(m_data.mip_levels > level); - EXPECTS(m_data.faces > face); - EXPECTS(m_data.layers > layer); - - return std::end(data(layer, face, level)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::cend() const noexcept { - return std::cend(m_data.data); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::cend(u32 layer, u32 face, u32 level) const noexcept { - EXPECTS(m_data.mip_levels > level); - EXPECTS(m_data.faces > face); - EXPECTS(m_data.layers > layer); - - return std::cend(data(layer, face, level)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::image_data() const noexcept -> const ImageData& { - return m_data; - } - - ///////////////////////////////////// - ///////////////////////////////////// - constexpr auto get_format_channel_count(Image::Format format) noexcept -> u8 { - switch (format) { - case Image::Format::R8_SNORM: - case Image::Format::R8_UNORM: - case Image::Format::R16_SNORM: - case Image::Format::R16_UNORM: - case Image::Format::R8I: - case Image::Format::R8U: - case Image::Format::R16I: - case Image::Format::R16U: - case Image::Format::R32I: - case Image::Format::R32U: - case Image::Format::R16F: - case Image::Format::R32F: return 1; - - case Image::Format::RG8_SNORM: - case Image::Format::RG8_UNORM: - case Image::Format::RG16_SNORM: - case Image::Format::RG16_UNORM: - case Image::Format::RG8I: - case Image::Format::RG8U: - case Image::Format::RG16I: - case Image::Format::RG16U: - case Image::Format::RG32I: - case Image::Format::RG32U: - case Image::Format::RG16F: - case Image::Format::RG32F: return 2; - - case Image::Format::RGB8_SNORM: - case Image::Format::RGB8_UNORM: - case Image::Format::RGB16_SNORM: - case Image::Format::RGB16_UNORM: - case Image::Format::BGR8_UNORM: - case Image::Format::RGB8I: - case Image::Format::RGB8U: - case Image::Format::RGB16I: - case Image::Format::RGB16U: - case Image::Format::RGB32I: - case Image::Format::RGB32U: - case Image::Format::RGB16F: - case Image::Format::RGB32F: - case Image::Format::SRGB8: - case Image::Format::SBGR8: return 3; - - case Image::Format::RGBA8_SNORM: - case Image::Format::RGBA8_UNORM: - case Image::Format::RGBA16_SNORM: - case Image::Format::RGBA16_UNORM: - case Image::Format::BGRA8_UNORM: - case Image::Format::RGBA8I: - case Image::Format::RGBA8U: - case Image::Format::RGBA16I: - case Image::Format::RGBA16U: - case Image::Format::RGBA32I: - case Image::Format::RGBA32U: - case Image::Format::RGBA16F: - case Image::Format::RGBA32F: - case Image::Format::SRGBA8: - case Image::Format::SBGRA8: return 4; - - default: break; - } - - return 0u; - } - - ///////////////////////////////////// - ///////////////////////////////////// - constexpr auto getSizeof(Image::Format format) noexcept -> u8 { - switch (format) { - case Image::Format::R8_SNORM: - case Image::Format::R8_UNORM: - case Image::Format::RG8_SNORM: - case Image::Format::RG8_UNORM: - case Image::Format::R8I: - case Image::Format::R8U: - case Image::Format::RG8I: - case Image::Format::RG8U: - case Image::Format::RGB8_SNORM: - case Image::Format::RGB8_UNORM: - case Image::Format::BGR8_UNORM: - case Image::Format::RGB8I: - case Image::Format::RGB8U: - case Image::Format::RGBA8_SNORM: - case Image::Format::RGBA8_UNORM: - case Image::Format::RGBA16_SNORM: - case Image::Format::BGRA8_UNORM: - case Image::Format::SRGB8: - case Image::Format::SBGR8: - case Image::Format::SRGBA8: - case Image::Format::SBGRA8: return 1u; - - case Image::Format::R16_SNORM: - case Image::Format::R16_UNORM: - case Image::Format::R16I: - case Image::Format::R16U: - case Image::Format::RG16_SNORM: - case Image::Format::RG16_UNORM: - case Image::Format::RG16I: - case Image::Format::RG16U: - case Image::Format::RG16F: - case Image::Format::RGB16I: - case Image::Format::RGB16U: - case Image::Format::RGB16F: - case Image::Format::RGBA16I: - case Image::Format::RGBA16U: - case Image::Format::RGBA16F: - case Image::Format::R16F: return 2u; - - case Image::Format::R32I: - case Image::Format::R32U: - case Image::Format::R32F: - case Image::Format::RG32I: - case Image::Format::RG32U: - case Image::Format::RG32F: - case Image::Format::RGB16_SNORM: - case Image::Format::RGB32I: - case Image::Format::RGB32U: - case Image::Format::RGB32F: - case Image::Format::RGBA8I: - case Image::Format::RGBA8U: - case Image::Format::RGBA32I: - case Image::Format::RGBA32U: - case Image::Format::RGBA32F: return 4u; - - default: break; - } - - return 0u; - } - -} // namespace stormkit::image - -template -template -auto std::formatter::format(const stormkit::image::Image::Error& error, - FormatContext& ctx) const noexcept -> decltype(ctx.out()) { - auto&& out = ctx.out(); - return format_to(out, "{}", error.str_error); -} +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +export module stormkit.image; + +import std; + +import stormkit.core; + +#ifdef STORMKIT_LUA_BINDING +export import :lua; +#endif + +export namespace stormkit::image { + class STORMKIT_API Image { + public: + enum class Format : u8 { + R8_SNORM = 0, + RG8_SNORM = 1, + RGB8_SNORM = 2, + RGBA8_SNORM = 3, + R8_UNORM = 4, + RG8_UNORM = 5, + RGB8_UNORM = 6, + RGBA8_UNORM = 7, + R16_SNORM = 8, + RG16_SNORM = 9, + RGB16_SNORM = 10, + RGBA16_SNORM = 11, + R16_UNORM = 12, + RG16_UNORM = 13, + RGB16_UNORM = 14, + RGBA16_UNORM = 15, + RGBA4_UNORM = 17, + BGR8_UNORM = 20, + BGRA8_UNORM = 21, + R8I = 22, + RG8I = 23, + RGB8I = 24, + RGBA8I = 25, + R8U = 26, + RG8U = 27, + RGB8U = 28, + RGBA8U = 29, + R16I = 30, + RG16I = 31, + RGB16I = 32, + RGBA16I = 33, + R16U = 34, + RG16U = 35, + RGB16U = 36, + RGBA16U = 37, + R32I = 38, + RG32I = 39, + RGB32I = 40, + RGBA32I = 41, + R32U = 42, + RG32U = 43, + RGB32U = 44, + RGBA32U = 45, + R16F = 47, + RG16F = 48, + RGB16F = 49, + RGBA16F = 50, + R32F = 51, + RG32F = 52, + RGB32F = 53, + RGBA32F = 54, + SRGB8 = 56, + SRGBA8 = 57, + SBGR8 = 58, + SBGRA8 = 59, + UNDEFINED = 254, + }; + + enum class Codec : u8 { + AUTODETECT = 0, + JPEG = 1, + PNG = 2, + TARGA = 3, + PPM = 4, + HDR = 5, + KTX = 6, + QOI = 7, + UNKNOWN = 255, + }; + + enum class CodecArgs : u8 { + BINARY = 0, + ASCII = 1, + }; + + struct Error { + enum class Reason { + NOT_IMPLEMENTED, + FAILED_TO_PARSE, + FAILED_TO_SAVE, + FILE_NOT_FOUND, + INVALID_FORMAT, + UNKNOWN, + } reason; + + std::string str_error; + }; + + struct ImageData { + math::uextent3 extent = { .width = 0u, .height = 0u }; + u32 channel_count = 0u; + u32 bytes_per_channel = 0u; + u32 layers = 1u; + u32 faces = 1u; + u32 mip_levels = 1u; + Format format = Format::UNDEFINED; + + std::vector data = {}; + }; + + Image() noexcept; + explicit Image(ImageData&& data) noexcept; + Image(const math::uextent3& extent, Format format) noexcept; + Image(const std::filesystem::path& filepath, Codec codec = Codec::AUTODETECT) noexcept; + Image(std::span data, Codec codec = Codec::AUTODETECT) noexcept; + ~Image() noexcept; + + Image(const Image& rhs) noexcept; + auto operator=(const Image& rhs) noexcept -> Image&; + + Image(Image&& rhs) noexcept; + auto operator=(Image&& rhs) noexcept -> Image&; + + [[nodiscard]] + auto load_from_file(std::filesystem::path filepath, Codec codec = Codec::AUTODETECT) noexcept + -> std::expected; + [[nodiscard]] + auto load_from_memory(std::span data, Codec codec = Codec::AUTODETECT) noexcept -> std::expected; + [[nodiscard]] + auto save_to_file(std::filesystem::path filename, Codec codec, CodecArgs args = CodecArgs::BINARY) const noexcept + -> std::expected; + + [[nodiscard]] + auto save_to_memory(Codec codec, CodecArgs args = CodecArgs::BINARY) const noexcept + -> std::expected, Error>; + + auto create(math::uextent3 extent, Format format) noexcept -> void; + + [[nodiscard]] + auto convert_to(Format format) const noexcept -> Image; + [[nodiscard]] + auto scale(const math::uextent3& scale_to) const noexcept -> Image; + [[nodiscard]] + auto flip_x() const noexcept -> Image; + [[nodiscard]] + auto flip_y() const noexcept -> Image; + [[nodiscard]] + auto flip_z() const noexcept -> Image; + [[nodiscard]] + auto rotate_90() const noexcept -> Image; + [[nodiscard]] + auto rotate_180() const noexcept -> Image; + [[nodiscard]] + auto rotate_270() const noexcept -> Image; + + [[nodiscard]] + auto pixel(usize id, u32 layer = 0u, u32 face = 0u, u32 level = 0u) noexcept -> std::span; + [[nodiscard]] + auto pixel(usize id, u32 layer = 0u, u32 face = 0u, u32 level = 0u) const noexcept -> std::span; + [[nodiscard]] + auto pixel(math::uvec3 position, u32 layer = 0u, u32 face = 0u, u32 level = 0u) noexcept -> std::span; + [[nodiscard]] + auto pixel(math::uvec3 position, u32 layer = 0u, u32 face = 0u, u32 level = 0u) const noexcept -> std::span; + + [[nodiscard]] + auto extent(u32 level = 0u) const noexcept -> math::uextent3; + + [[nodiscard]] + auto channelCount() const noexcept -> u32; + + [[nodiscard]] + auto bytesPerChannel() const noexcept -> u32; + + [[nodiscard]] + auto layers() const noexcept -> u32; + + [[nodiscard]] + auto faces() const noexcept -> u32; + + [[nodiscard]] + auto mip_levels() const noexcept -> u32; + + [[nodiscard]] + auto format() const noexcept -> Format; + + [[nodiscard]] + auto size() const noexcept -> usize; + [[nodiscard]] + auto size(u32 layer, u32 face, u32 level) const noexcept -> usize; + [[nodiscard]] + auto size(u32 layer, u32 face) const noexcept -> usize; + [[nodiscard]] + auto size(u32 layer) const noexcept -> usize; + + [[nodiscard]] + auto data() noexcept -> std::span; + [[nodiscard]] + auto data(u32 layer, u32 face, u32 level) noexcept -> std::span; + [[nodiscard]] + auto data() const noexcept -> std::span; + [[nodiscard]] + auto data(u32 layer, u32 face, u32 level) const noexcept -> std::span; + + [[nodiscard]] + auto begin() noexcept; + [[nodiscard]] + auto begin(u32 layer, u32 face, u32 level) noexcept; + [[nodiscard]] + auto begin() const noexcept; + [[nodiscard]] + auto begin(u32 layer, u32 face, u32 level) const noexcept; + + [[nodiscard]] + auto cbegin() const noexcept; + [[nodiscard]] + auto cbegin(u32 layer, u32 face, u32 level) const noexcept; + + [[nodiscard]] + auto end() noexcept; + [[nodiscard]] + auto end(u32 layer, u32 face, u32 level) noexcept; + [[nodiscard]] + auto end() const noexcept; + [[nodiscard]] + auto end(u32 layer, u32 face, u32 level) const noexcept; + + [[nodiscard]] + auto cend() const noexcept; + [[nodiscard]] + auto cend(u32 layer, u32 face, u32 level) const noexcept; + + [[nodiscard]] + auto image_data() const noexcept -> const ImageData&; + + private: + ImageData m_data; + }; + + constexpr auto get_format_channel_count(Image::Format format) noexcept -> u8; + constexpr auto getSizeof(Image::Format format) noexcept -> u8; + +} // namespace stormkit::image + +export { + template + struct std::formatter: std::formatter, CharT> { + template + [[nodiscard]] + auto format(const stormkit::image::Image::Error& error, FormatContext& ctx) const noexcept -> decltype(ctx.out()); + }; +} + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit::image { + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::pixel(usize index, u32 layer, u32 face, u32 level) noexcept -> std::span { + EXPECTS(m_data.mip_levels > level); + EXPECTS(m_data.faces > face); + EXPECTS(m_data.layers > layer); + + auto _data = data(layer, face, level); + + EXPECTS(index < m_data.extent.width * m_data.extent.height * m_data.extent.depth); + + const auto block_size = m_data.channel_count * m_data.bytes_per_channel; + + return { std::data(_data) + index * block_size, block_size }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::pixel(usize index, u32 layer, u32 face, u32 level) const noexcept -> std::span { + EXPECTS(m_data.mip_levels > level); + EXPECTS(m_data.faces > face); + EXPECTS(m_data.layers > layer); + + auto _data = data(layer, face, level); + + const auto mip_extent = extent(level); + EXPECTS(index < mip_extent.width * mip_extent.height * mip_extent.depth); + + const auto block_size = m_data.channel_count * m_data.bytes_per_channel; + + return { std::data(_data) + index * block_size, block_size }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::pixel(math::uvec3 position, u32 layer, u32 face, u32 level) noexcept -> std::span { + const auto mip_extent = extent(level); + + const auto id = position.x + (position.y * mip_extent.width) + (mip_extent.width * mip_extent.height * position.z); + + return pixel(id, layer, face, level); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::pixel(math::uvec3 position, u32 layer, u32 face, u32 level) const noexcept -> std::span { + const auto mip_extent = extent(level); + + const auto id = position.x + (position.y * mip_extent.width) + (mip_extent.width * mip_extent.height * position.z); + + return pixel(id, layer, face, level); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::extent(u32 level) const noexcept -> math::uextent3 { + EXPECTS(m_data.mip_levels > level); + + return { .width = std::max(1u, m_data.extent.width >> level), + .height = std::max(1u, m_data.extent.height >> level), + .depth = std::max(1u, m_data.extent.depth >> level) }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::channelCount() const noexcept -> u32 { + return m_data.channel_count; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::bytesPerChannel() const noexcept -> u32 { + return m_data.bytes_per_channel; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::layers() const noexcept -> u32 { + return m_data.layers; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::faces() const noexcept -> u32 { + return m_data.faces; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::mip_levels() const noexcept -> u32 { + return m_data.mip_levels; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::format() const noexcept -> Format { + return m_data.format; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::size() const noexcept -> usize { + return std::size(m_data.data); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::size(u32 layer, // TODO Use layer and face to get correct size + u32 face, + u32 level) const noexcept -> usize { + EXPECTS(m_data.mip_levels > level); + EXPECTS(m_data.faces > face); + EXPECTS(m_data.layers > layer); + + const auto mip_extent = extent(level); + + return mip_extent.width * mip_extent.height * mip_extent.depth * m_data.channel_count * m_data.bytes_per_channel; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::size(u32 layer, u32 face) const noexcept -> usize { + auto _size = usize { 0u }; + for (auto i : range(m_data.mip_levels)) _size += size(layer, face, i); + + return _size; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::size(u32 layer) const noexcept -> usize { + auto _size = usize { 0u }; + for (auto i : range(m_data.faces)) _size += size(layer, i); + + return _size; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::data() noexcept -> std::span { + return m_data.data; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::data(u32 layer, u32 face, u32 level) noexcept -> std::span { + const auto mip_size = size(layer, face, level); + + auto offset = usize { 0 }; + + for (auto i : range(layer)) offset += size(i); + + for (auto j : range(face)) offset += size(layer, j); + + for (auto k : range(level)) offset += size(layer, face, k); + + return { std::data(m_data.data) + offset, mip_size }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::data() const noexcept -> std::span { + return m_data.data; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::data(u32 layer, u32 face, u32 level) const noexcept -> std::span { + const auto mip_size = size(layer, face, level); + + auto offset = usize { 0 }; + + for (auto i : range(layer)) offset += size(i); + + for (auto j : range(face)) offset += size(layer, j); + + for (auto k : range(level)) offset += size(layer, face, k); + + return { std::data(m_data.data) + offset, mip_size }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::begin() noexcept { + return std::begin(m_data.data); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::begin(u32 layer, u32 face, u32 level) noexcept { + EXPECTS(m_data.mip_levels > level); + EXPECTS(m_data.faces > face); + EXPECTS(m_data.layers > layer); + + return std::begin(data(layer, face, level)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::begin() const noexcept { + return std::begin(m_data.data); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::begin(u32 layer, u32 face, u32 level) const noexcept { + return std::begin(data(layer, face, level)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::cbegin() const noexcept { + return std::cbegin(m_data.data); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::cbegin(u32 layer, u32 face, u32 level) const noexcept { + EXPECTS(m_data.mip_levels > level); + EXPECTS(m_data.faces > face); + EXPECTS(m_data.layers > layer); + + return std::cbegin(data(layer, face, level)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::end() noexcept { + return std::end(m_data.data); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::end(u32 layer, u32 face, u32 level) noexcept { + EXPECTS(m_data.mip_levels > level); + EXPECTS(m_data.faces > face); + EXPECTS(m_data.layers > layer); + + return std::end(data(layer, face, level)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::end() const noexcept { + return std::end(m_data.data); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::end(u32 layer, u32 face, u32 level) const noexcept { + EXPECTS(m_data.mip_levels > level); + EXPECTS(m_data.faces > face); + EXPECTS(m_data.layers > layer); + + return std::end(data(layer, face, level)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::cend() const noexcept { + return std::cend(m_data.data); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::cend(u32 layer, u32 face, u32 level) const noexcept { + EXPECTS(m_data.mip_levels > level); + EXPECTS(m_data.faces > face); + EXPECTS(m_data.layers > layer); + + return std::cend(data(layer, face, level)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto Image::image_data() const noexcept -> const ImageData& { + return m_data; + } + + ///////////////////////////////////// + ///////////////////////////////////// + constexpr auto get_format_channel_count(Image::Format format) noexcept -> u8 { + switch (format) { + case Image::Format::R8_SNORM: + case Image::Format::R8_UNORM: + case Image::Format::R16_SNORM: + case Image::Format::R16_UNORM: + case Image::Format::R8I: + case Image::Format::R8U: + case Image::Format::R16I: + case Image::Format::R16U: + case Image::Format::R32I: + case Image::Format::R32U: + case Image::Format::R16F: + case Image::Format::R32F: return 1; + + case Image::Format::RG8_SNORM: + case Image::Format::RG8_UNORM: + case Image::Format::RG16_SNORM: + case Image::Format::RG16_UNORM: + case Image::Format::RG8I: + case Image::Format::RG8U: + case Image::Format::RG16I: + case Image::Format::RG16U: + case Image::Format::RG32I: + case Image::Format::RG32U: + case Image::Format::RG16F: + case Image::Format::RG32F: return 2; + + case Image::Format::RGB8_SNORM: + case Image::Format::RGB8_UNORM: + case Image::Format::RGB16_SNORM: + case Image::Format::RGB16_UNORM: + case Image::Format::BGR8_UNORM: + case Image::Format::RGB8I: + case Image::Format::RGB8U: + case Image::Format::RGB16I: + case Image::Format::RGB16U: + case Image::Format::RGB32I: + case Image::Format::RGB32U: + case Image::Format::RGB16F: + case Image::Format::RGB32F: + case Image::Format::SRGB8: + case Image::Format::SBGR8: return 3; + + case Image::Format::RGBA8_SNORM: + case Image::Format::RGBA8_UNORM: + case Image::Format::RGBA16_SNORM: + case Image::Format::RGBA16_UNORM: + case Image::Format::BGRA8_UNORM: + case Image::Format::RGBA8I: + case Image::Format::RGBA8U: + case Image::Format::RGBA16I: + case Image::Format::RGBA16U: + case Image::Format::RGBA32I: + case Image::Format::RGBA32U: + case Image::Format::RGBA16F: + case Image::Format::RGBA32F: + case Image::Format::SRGBA8: + case Image::Format::SBGRA8: return 4; + + default: break; + } + + return 0u; + } + + ///////////////////////////////////// + ///////////////////////////////////// + constexpr auto getSizeof(Image::Format format) noexcept -> u8 { + switch (format) { + case Image::Format::R8_SNORM: + case Image::Format::R8_UNORM: + case Image::Format::RG8_SNORM: + case Image::Format::RG8_UNORM: + case Image::Format::R8I: + case Image::Format::R8U: + case Image::Format::RG8I: + case Image::Format::RG8U: + case Image::Format::RGB8_SNORM: + case Image::Format::RGB8_UNORM: + case Image::Format::BGR8_UNORM: + case Image::Format::RGB8I: + case Image::Format::RGB8U: + case Image::Format::RGBA8_SNORM: + case Image::Format::RGBA8_UNORM: + case Image::Format::RGBA16_SNORM: + case Image::Format::BGRA8_UNORM: + case Image::Format::SRGB8: + case Image::Format::SBGR8: + case Image::Format::SRGBA8: + case Image::Format::SBGRA8: return 1u; + + case Image::Format::R16_SNORM: + case Image::Format::R16_UNORM: + case Image::Format::R16I: + case Image::Format::R16U: + case Image::Format::RG16_SNORM: + case Image::Format::RG16_UNORM: + case Image::Format::RG16I: + case Image::Format::RG16U: + case Image::Format::RG16F: + case Image::Format::RGB16I: + case Image::Format::RGB16U: + case Image::Format::RGB16F: + case Image::Format::RGBA16I: + case Image::Format::RGBA16U: + case Image::Format::RGBA16F: + case Image::Format::R16F: return 2u; + + case Image::Format::R32I: + case Image::Format::R32U: + case Image::Format::R32F: + case Image::Format::RG32I: + case Image::Format::RG32U: + case Image::Format::RG32F: + case Image::Format::RGB16_SNORM: + case Image::Format::RGB32I: + case Image::Format::RGB32U: + case Image::Format::RGB32F: + case Image::Format::RGBA8I: + case Image::Format::RGBA8U: + case Image::Format::RGBA32I: + case Image::Format::RGBA32U: + case Image::Format::RGBA32F: return 4u; + + default: break; + } + + return 0u; + } + +} // namespace stormkit::image + +template +template +auto std::formatter::format(const stormkit::image::Image::Error& error, + FormatContext& ctx) const noexcept -> decltype(ctx.out()) { + auto&& out = ctx.out(); + return format_to(out, "{}", error.str_error); +} diff --git a/modules/stormkit/image/lua.mpp b/modules/stormkit/image/lua.cppm similarity index 100% rename from modules/stormkit/image/lua.mpp rename to modules/stormkit/image/lua.cppm diff --git a/modules/stormkit/log.mpp b/modules/stormkit/log.cppm similarity index 97% rename from modules/stormkit/log.mpp rename to modules/stormkit/log.cppm index f0e59d33a..cc5baff81 100644 --- a/modules/stormkit/log.mpp +++ b/modules/stormkit/log.cppm @@ -1,383 +1,383 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include -#include -#include - -export module stormkit.log; - -import std; -import frozen; - -import stormkit.core; - -#ifdef STORMKIT_LUA_BINDING -export import :lua; -#endif - -export { - namespace stormkit::log { - struct Module; - enum class Severity : u8 { - INFO = 1, - WARNING = 2, - ERROR = 4, - FATAL = 8, - DEBUG = 16, - }; - - [[nodiscard]] - constexpr auto as_string(Severity severity) noexcept -> std::string_view; - [[nodiscard]] - constexpr auto to_string(Severity severity) noexcept -> std::string; - - STORMKIT_API - auto parse_args(std::span args) noexcept -> void; - - class STORMKIT_API Logger { - public: - using LogClock = std::chrono::high_resolution_clock; - - explicit Logger(LogClock::time_point start) noexcept; - Logger(LogClock::time_point start, Severity log_level) noexcept; - virtual ~Logger() noexcept; - - virtual auto write(Severity severity, const Module& module, CZString string) noexcept -> void = 0; - virtual auto flush() noexcept -> void = 0; - - auto set_log_level(Severity log_level) noexcept -> void; - - [[nodiscard]] - auto start_time() const noexcept -> const LogClock::time_point&; - [[nodiscard]] - auto log_level() const noexcept -> const Severity&; - - [[nodiscard]] - auto mutex() noexcept -> std::mutex&; - - template - [[nodiscard]] - static auto create_logger_instance(Args&&... param_args) noexcept -> T; - - template - [[nodiscard]] - static auto allocate_logger_instance(Args&&... param_args) noexcept -> Heap; - - template - static auto log(Severity severity, - const Module& module, - std::string_view format_string, - Args&&... param_args) noexcept -> void; - - template - static auto log(Severity severity, std::string_view format_string, Args&&... param_args) noexcept -> void; - - template - static auto dlog(Args&&... param_args) noexcept -> void; - - template - static auto ilog(Args&&... param_args) noexcept -> void; - - template - static auto wlog(Args&&... param_args) noexcept -> void; - - template - static auto elog(Args&&... param_args) noexcept -> void; - - template - static auto flog(Args&&... param_args) noexcept -> void; - - [[nodiscard]] - static auto has_logger() noexcept -> bool; - [[nodiscard]] - static auto instance() noexcept -> Logger&; - - protected: - LogClock::time_point m_start_time; - Severity m_log_level; - - std::mutex m_mutex; - }; - - struct Module { - template - auto dlog(Args&&... args) const noexcept -> void; - - template - auto ilog(Args&&... args) const noexcept -> void; - - template - auto wlog(Args&&... args) const noexcept -> void; - - template - auto elog(Args&&... args) const noexcept -> void; - - template - auto flog(Args&&... args) const noexcept -> void; - - auto flush() const noexcept -> void; - - std::string_view name = ""; - }; - - template - [[nodiscard]] - constexpr auto operator""_module() noexcept -> stormkit::log::Module; - - class STORMKIT_API FileLogger final: public Logger { - public: - FileLogger(LogClock::time_point start, std::filesystem::path path) noexcept; - FileLogger(LogClock::time_point start, std::filesystem::path path, Severity log_level) noexcept; - ~FileLogger() noexcept override; - - FileLogger(const FileLogger&) noexcept = delete; - auto operator=(const FileLogger&) noexcept -> FileLogger& = delete; - - FileLogger(FileLogger&&) noexcept = delete; - auto operator=(FileLogger&&) noexcept -> FileLogger& = delete; - - auto write(Severity severity, const Module& module, CZString string) noexcept -> void override; - auto flush() noexcept -> void override; - - private: - StringHashMap m_streams; - - std::filesystem::path m_base_path; - }; - - class STORMKIT_API ConsoleLogger final: public Logger { - public: - explicit ConsoleLogger(LogClock::time_point start) noexcept; - ConsoleLogger(LogClock::time_point start, Severity log_level) noexcept; - - ConsoleLogger(const ConsoleLogger&) noexcept = delete; - auto operator=(const ConsoleLogger&) noexcept -> ConsoleLogger& = delete; - - ConsoleLogger(ConsoleLogger&&) noexcept = delete; - auto operator=(ConsoleLogger&&) noexcept -> ConsoleLogger& = delete; - - ~ConsoleLogger() noexcept override; - - auto write(Severity severity, const Module& module, CZString string) noexcept -> void override; - auto flush() noexcept -> void override; - }; - } // namespace stormkit::log - FLAG_ENUM(stormkit::log::Severity) -} - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -using namespace std::literals; - -namespace stormkit::log { - //////////////////////////////////////// - //////////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto as_string(Severity severity) noexcept -> std::string_view { - switch (severity) { - case Severity::INFO: return "Severity::INFO"; - case Severity::WARNING: return "Severity::WARNING"; - case Severity::ERROR: return "Severity::ERROR"; - case Severity::FATAL: return "Severity::FATAL"; - case Severity::DEBUG: return "Severity::DEBUG"; - default: break; - } - - std::unreachable(); - } - - //////////////////////////////////////// - //////////////////////////////////////// - STORMKIT_FORCE_INLINE - constexpr auto to_string(Severity severity) noexcept -> std::string { - return std::string { as_string(severity) }; - } - - //////////////////////////////////////// - //////////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Logger::set_log_level(Severity log_level) noexcept -> void { - m_log_level = log_level; - } - - //////////////////////////////////////// - //////////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Logger::start_time() const noexcept -> const LogClock::time_point& { - return m_start_time; - } - - //////////////////////////////////////// - //////////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Logger::log_level() const noexcept -> const Severity& { - return m_log_level; - } - - //////////////////////////////////////// - //////////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Logger::mutex() noexcept -> std::mutex& { - return m_mutex; - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - inline auto Logger::create_logger_instance(Args&&... param_args) noexcept -> T { - static_assert(std::is_base_of::value, "T must inherit Logger"); - - auto time_point = LogClock::now(); - - return T { std::move(time_point), std::forward(param_args)... }; - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - inline auto Logger::allocate_logger_instance(Args&&... param_args) noexcept -> Heap { - static_assert(std::is_base_of::value, "T must inherit Logger"); - - auto time_point = LogClock::now(); - - return allocate(std::move(time_point), std::forward(param_args)...) - .transform_error(core::monadic::assert("Failed to allocate logger instance")); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - inline auto Logger::log(Severity severity, const Module& m, std::string_view format_string, Args&&... param_args) noexcept - -> void { - EXPECTS(has_logger()); - - const auto log_level = instance().log_level(); - if (not check_flag_bit(log_level, severity)) return; - - auto memory_buffer = std::string {}; - memory_buffer.reserve(std::size(format_string)); - std::vformat_to(std::back_inserter(memory_buffer), format_string, std::make_format_args(param_args...)); - - auto _ = std::unique_lock(instance().mutex()); - instance().write(severity, m, std::data(memory_buffer)); - } - - //////////////////////////////////////// - //////////////////////////////////////// - STORMKIT_FORCE_INLINE - inline ConsoleLogger::~ConsoleLogger() noexcept = default; - - //////////////////////////////////////// - //////////////////////////////////////// - STORMKIT_FORCE_INLINE - inline FileLogger::~FileLogger() noexcept = default; - - //////////////////////////////////////// - //////////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Logger::log(Severity severity, std::string_view format_string, Args&&... param_args) noexcept -> void { - log(severity, Module {}, format_string, std::forward(param_args)...); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Logger::dlog(Args&&... param_args) noexcept -> void { - log(Severity::DEBUG, std::forward(param_args)...); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Logger::ilog(Args&&... param_args) noexcept -> void { - log(Severity::INFO, std::forward(param_args)...); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Logger::wlog(Args&&... param_args) noexcept -> void { - log(Severity::WARNING, std::forward(param_args)...); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Logger::elog(Args&&... param_args) noexcept -> void { - log(Severity::ERROR, std::forward(param_args)...); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Logger::flog(Args&&... param_args) noexcept -> void { - log(Severity::FATAL, std::forward(param_args)...); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Module::dlog(Args&&... args) const noexcept -> void { - Logger::dlog(*this, std::forward(args)...); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Module::ilog(Args&&... args) const noexcept -> void { - Logger::ilog(*this, std::forward(args)...); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Module::wlog(Args&&... args) const noexcept -> void { - Logger::wlog(*this, std::forward(args)...); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Module::elog(Args&&... args) const noexcept -> void { - Logger::elog(*this, std::forward(args)...); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Module::flog(Args&&... args) const noexcept -> void { - Logger::flog(*this, std::forward(args)...); - } - - //////////////////////////////////////// - //////////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Module::flush() const noexcept -> void { - Logger::instance().flush(); - } - - //////////////////////////////////////// - //////////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto operator""_module() noexcept -> stormkit::log::Module { - return Module { str.view() }; - } -} // namespace stormkit::log +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include +#include +#include + +export module stormkit.log; + +import std; +import frozen; + +import stormkit.core; + +#ifdef STORMKIT_LUA_BINDING +export import :lua; +#endif + +export { + namespace stormkit::log { + struct Module; + enum class Severity : u8 { + INFO = 1, + WARNING = 2, + ERROR = 4, + FATAL = 8, + DEBUG = 16, + }; + + [[nodiscard]] + constexpr auto as_string(Severity severity) noexcept -> std::string_view; + [[nodiscard]] + constexpr auto to_string(Severity severity) noexcept -> std::string; + + STORMKIT_API + auto parse_args(std::span args) noexcept -> void; + + class STORMKIT_API Logger { + public: + using LogClock = std::chrono::high_resolution_clock; + + explicit Logger(LogClock::time_point start) noexcept; + Logger(LogClock::time_point start, Severity log_level) noexcept; + virtual ~Logger() noexcept; + + virtual auto write(Severity severity, const Module& module, CZString string) noexcept -> void = 0; + virtual auto flush() noexcept -> void = 0; + + auto set_log_level(Severity log_level) noexcept -> void; + + [[nodiscard]] + auto start_time() const noexcept -> const LogClock::time_point&; + [[nodiscard]] + auto log_level() const noexcept -> const Severity&; + + [[nodiscard]] + auto mutex() noexcept -> std::mutex&; + + template + [[nodiscard]] + static auto create_logger_instance(Args&&... param_args) noexcept -> T; + + template + [[nodiscard]] + static auto allocate_logger_instance(Args&&... param_args) noexcept -> Heap; + + template + static auto log(Severity severity, + const Module& module, + std::string_view format_string, + Args&&... param_args) noexcept -> void; + + template + static auto log(Severity severity, std::string_view format_string, Args&&... param_args) noexcept -> void; + + template + static auto dlog(Args&&... param_args) noexcept -> void; + + template + static auto ilog(Args&&... param_args) noexcept -> void; + + template + static auto wlog(Args&&... param_args) noexcept -> void; + + template + static auto elog(Args&&... param_args) noexcept -> void; + + template + static auto flog(Args&&... param_args) noexcept -> void; + + [[nodiscard]] + static auto has_logger() noexcept -> bool; + [[nodiscard]] + static auto instance() noexcept -> Logger&; + + protected: + LogClock::time_point m_start_time; + Severity m_log_level; + + std::mutex m_mutex; + }; + + struct Module { + template + auto dlog(Args&&... args) const noexcept -> void; + + template + auto ilog(Args&&... args) const noexcept -> void; + + template + auto wlog(Args&&... args) const noexcept -> void; + + template + auto elog(Args&&... args) const noexcept -> void; + + template + auto flog(Args&&... args) const noexcept -> void; + + auto flush() const noexcept -> void; + + std::string_view name = ""; + }; + + template + [[nodiscard]] + constexpr auto operator""_module() noexcept -> stormkit::log::Module; + + class STORMKIT_API FileLogger final: public Logger { + public: + FileLogger(LogClock::time_point start, std::filesystem::path path) noexcept; + FileLogger(LogClock::time_point start, std::filesystem::path path, Severity log_level) noexcept; + ~FileLogger() noexcept override; + + FileLogger(const FileLogger&) noexcept = delete; + auto operator=(const FileLogger&) noexcept -> FileLogger& = delete; + + FileLogger(FileLogger&&) noexcept = delete; + auto operator=(FileLogger&&) noexcept -> FileLogger& = delete; + + auto write(Severity severity, const Module& module, CZString string) noexcept -> void override; + auto flush() noexcept -> void override; + + private: + StringHashMap m_streams; + + std::filesystem::path m_base_path; + }; + + class STORMKIT_API ConsoleLogger final: public Logger { + public: + explicit ConsoleLogger(LogClock::time_point start) noexcept; + ConsoleLogger(LogClock::time_point start, Severity log_level) noexcept; + + ConsoleLogger(const ConsoleLogger&) noexcept = delete; + auto operator=(const ConsoleLogger&) noexcept -> ConsoleLogger& = delete; + + ConsoleLogger(ConsoleLogger&&) noexcept = delete; + auto operator=(ConsoleLogger&&) noexcept -> ConsoleLogger& = delete; + + ~ConsoleLogger() noexcept override; + + auto write(Severity severity, const Module& module, CZString string) noexcept -> void override; + auto flush() noexcept -> void override; + }; + } // namespace stormkit::log + FLAG_ENUM(stormkit::log::Severity) +} + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +using namespace std::literals; + +namespace stormkit::log { + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_CONST + constexpr auto as_string(Severity severity) noexcept -> std::string_view { + switch (severity) { + case Severity::INFO: return "Severity::INFO"; + case Severity::WARNING: return "Severity::WARNING"; + case Severity::ERROR: return "Severity::ERROR"; + case Severity::FATAL: return "Severity::FATAL"; + case Severity::DEBUG: return "Severity::DEBUG"; + default: break; + } + + std::unreachable(); + } + + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto to_string(Severity severity) noexcept -> std::string { + return std::string { as_string(severity) }; + } + + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Logger::set_log_level(Severity log_level) noexcept -> void { + m_log_level = log_level; + } + + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Logger::start_time() const noexcept -> const LogClock::time_point& { + return m_start_time; + } + + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Logger::log_level() const noexcept -> const Severity& { + return m_log_level; + } + + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Logger::mutex() noexcept -> std::mutex& { + return m_mutex; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + inline auto Logger::create_logger_instance(Args&&... param_args) noexcept -> T { + static_assert(std::is_base_of::value, "T must inherit Logger"); + + auto time_point = LogClock::now(); + + return T { std::move(time_point), std::forward(param_args)... }; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + inline auto Logger::allocate_logger_instance(Args&&... param_args) noexcept -> Heap { + static_assert(std::is_base_of::value, "T must inherit Logger"); + + auto time_point = LogClock::now(); + + return allocate(std::move(time_point), std::forward(param_args)...) + .transform_error(core::monadic::assert("Failed to allocate logger instance")); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + inline auto Logger::log(Severity severity, const Module& m, std::string_view format_string, Args&&... param_args) noexcept + -> void { + EXPECTS(has_logger()); + + const auto log_level = instance().log_level(); + if (not check_flag_bit(log_level, severity)) return; + + auto memory_buffer = std::string {}; + memory_buffer.reserve(std::size(format_string)); + std::vformat_to(std::back_inserter(memory_buffer), format_string, std::make_format_args(param_args...)); + + auto _ = std::unique_lock(instance().mutex()); + instance().write(severity, m, std::data(memory_buffer)); + } + + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE + inline ConsoleLogger::~ConsoleLogger() noexcept = default; + + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE + inline FileLogger::~FileLogger() noexcept = default; + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::log(Severity severity, std::string_view format_string, Args&&... param_args) noexcept -> void { + log(severity, Module {}, format_string, std::forward(param_args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::dlog(Args&&... param_args) noexcept -> void { + log(Severity::DEBUG, std::forward(param_args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::ilog(Args&&... param_args) noexcept -> void { + log(Severity::INFO, std::forward(param_args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::wlog(Args&&... param_args) noexcept -> void { + log(Severity::WARNING, std::forward(param_args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::elog(Args&&... param_args) noexcept -> void { + log(Severity::ERROR, std::forward(param_args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::flog(Args&&... param_args) noexcept -> void { + log(Severity::FATAL, std::forward(param_args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Module::dlog(Args&&... args) const noexcept -> void { + Logger::dlog(*this, std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Module::ilog(Args&&... args) const noexcept -> void { + Logger::ilog(*this, std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Module::wlog(Args&&... args) const noexcept -> void { + Logger::wlog(*this, std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Module::elog(Args&&... args) const noexcept -> void { + Logger::elog(*this, std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Module::flog(Args&&... args) const noexcept -> void { + Logger::flog(*this, std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Module::flush() const noexcept -> void { + Logger::instance().flush(); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto operator""_module() noexcept -> stormkit::log::Module { + return Module { str.view() }; + } +} // namespace stormkit::log diff --git a/modules/stormkit/log/lua.mpp b/modules/stormkit/log/lua.cppm similarity index 100% rename from modules/stormkit/log/lua.mpp rename to modules/stormkit/log/lua.cppm diff --git a/modules/stormkit/luau.mpp b/modules/stormkit/luau.cppm similarity index 100% rename from modules/stormkit/luau.mpp rename to modules/stormkit/luau.cppm diff --git a/modules/stormkit/luau/core.mpp b/modules/stormkit/luau/core.cppm similarity index 100% rename from modules/stormkit/luau/core.mpp rename to modules/stormkit/luau/core.cppm diff --git a/modules/stormkit/main.mpp b/modules/stormkit/main.cppm similarity index 96% rename from modules/stormkit/main.mpp rename to modules/stormkit/main.cppm index c0a353901..339576753 100644 --- a/modules/stormkit/main.mpp +++ b/modules/stormkit/main.cppm @@ -1,9 +1,9 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -export module stormkit.main; - -// clang-format off - -// clang-format on +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +export module stormkit.main; + +// clang-format off + +// clang-format on diff --git a/modules/stormkit/test.mpp b/modules/stormkit/test.cppm similarity index 100% rename from modules/stormkit/test.mpp rename to modules/stormkit/test.cppm diff --git a/modules/stormkit/wsi.mpp b/modules/stormkit/wsi.cppm similarity index 96% rename from modules/stormkit/wsi.mpp rename to modules/stormkit/wsi.cppm index 5f52b05f9..6190aca02 100644 --- a/modules/stormkit/wsi.mpp +++ b/modules/stormkit/wsi.cppm @@ -1,16 +1,16 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -export module stormkit.wsi; - -export import :core; -export import :monitor; -export import :window; -// export import :event_handler; -export import :keyboard; -export import :mouse; - -#ifdef STORMKIT_LUA_BINDING -export import :lua; -#endif +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +export module stormkit.wsi; + +export import :core; +export import :monitor; +export import :window; +// export import :event_handler; +export import :keyboard; +export import :mouse; + +#ifdef STORMKIT_LUA_BINDING +export import :lua; +#endif diff --git a/modules/stormkit/wsi/core.mpp b/modules/stormkit/wsi/core.cppm similarity index 100% rename from modules/stormkit/wsi/core.mpp rename to modules/stormkit/wsi/core.cppm diff --git a/modules/stormkit/wsi/keyboard.mpp b/modules/stormkit/wsi/keyboard.cppm similarity index 100% rename from modules/stormkit/wsi/keyboard.mpp rename to modules/stormkit/wsi/keyboard.cppm diff --git a/modules/stormkit/wsi/lua.mpp b/modules/stormkit/wsi/lua.cppm similarity index 100% rename from modules/stormkit/wsi/lua.mpp rename to modules/stormkit/wsi/lua.cppm diff --git a/modules/stormkit/wsi/monitor.mpp b/modules/stormkit/wsi/monitor.cppm similarity index 100% rename from modules/stormkit/wsi/monitor.mpp rename to modules/stormkit/wsi/monitor.cppm diff --git a/modules/stormkit/wsi/mouse.mpp b/modules/stormkit/wsi/mouse.cppm similarity index 100% rename from modules/stormkit/wsi/mouse.mpp rename to modules/stormkit/wsi/mouse.cppm diff --git a/modules/stormkit/wsi/window.mpp b/modules/stormkit/wsi/window.cppm similarity index 100% rename from modules/stormkit/wsi/window.mpp rename to modules/stormkit/wsi/window.cppm diff --git a/src/core/contract.mpp b/src/core/contract.cppm similarity index 100% rename from src/core/contract.mpp rename to src/core/contract.cppm diff --git a/src/image/hdr.mpp b/src/image/hdr.cppm similarity index 97% rename from src/image/hdr.mpp rename to src/image/hdr.cppm index dfe398aa0..2069b8393 100644 --- a/src/image/hdr.mpp +++ b/src/image/hdr.cppm @@ -1,50 +1,50 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -export module stormkit.image:hdr; - -import std; - -import stormkit.core; -import stormkit.image; - -export namespace stormkit::image::details { - [[nodiscard]] - auto load_hdr(std::span data) noexcept -> std::expected; - - [[nodiscard]] - auto save_hdr(const image::Image& image, const std::filesystem::path& filepath) noexcept - -> std::expected; - - [[nodiscard]] - auto save_hdr(const image::Image& image) noexcept -> std::expected, image::Image::Error>; -} // namespace stormkit::image::details - -namespace stormkit::image::details { - template - using Unexpected = std::unexpected; - using Error = image::Image::Error; - using Reason = image::Image::Error::Reason; - - ///////////////////////////////////// - ///////////////////////////////////// - auto load_hdr(std::span) noexcept -> std::expected { - assert(false, "Not implemented yet !"); - return {}; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto save_hdr(const image::Image&, const std::filesystem::path&) noexcept -> std::expected { - assert(false, "Not implemented yet !"); - return {}; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto save_hdr(const image::Image&) noexcept -> std::expected, image::Image::Error> { - assert(false, "Not implemented yet !"); - return {}; - } -} // namespace stormkit::image::details +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +export module stormkit.image:hdr; + +import std; + +import stormkit.core; +import stormkit.image; + +export namespace stormkit::image::details { + [[nodiscard]] + auto load_hdr(std::span data) noexcept -> std::expected; + + [[nodiscard]] + auto save_hdr(const image::Image& image, const std::filesystem::path& filepath) noexcept + -> std::expected; + + [[nodiscard]] + auto save_hdr(const image::Image& image) noexcept -> std::expected, image::Image::Error>; +} // namespace stormkit::image::details + +namespace stormkit::image::details { + template + using Unexpected = std::unexpected; + using Error = image::Image::Error; + using Reason = image::Image::Error::Reason; + + ///////////////////////////////////// + ///////////////////////////////////// + auto load_hdr(std::span) noexcept -> std::expected { + assert(false, "Not implemented yet !"); + return {}; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto save_hdr(const image::Image&, const std::filesystem::path&) noexcept -> std::expected { + assert(false, "Not implemented yet !"); + return {}; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto save_hdr(const image::Image&) noexcept -> std::expected, image::Image::Error> { + assert(false, "Not implemented yet !"); + return {}; + } +} // namespace stormkit::image::details diff --git a/src/image/jpg.mpp b/src/image/jpg.cppm similarity index 97% rename from src/image/jpg.mpp rename to src/image/jpg.cppm index 39736ac2a..882969839 100644 --- a/src/image/jpg.mpp +++ b/src/image/jpg.cppm @@ -1,261 +1,261 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include -#include -#include - -#include - -#include -#include -#include - -#include - -export module stormkit.image:jpg; - -import std; - -import stormkit.core; -import stormkit.image; - -namespace stdr = std::ranges; - -export namespace stormkit::image::details { - [[nodiscard]] - auto load_jpg(std::span data) noexcept -> std::expected; - - [[nodiscard]] - auto save_jpg(const image::Image& image, const std::filesystem::path& filepath) noexcept - -> std::expected; - - [[nodiscard]] - auto save_jpg(const image::Image& image) noexcept -> std::expected, image::Image::Error>; -} // namespace stormkit::image::details - -namespace stormkit::image::details { - template - using Unexpected = std::unexpected; - using Error = image::Image::Error; - using Reason = image::Image::Error::Reason; - using Format = image::Image::Format; - - namespace jpg { - struct ErrorData { - std::jmp_buf setjmp_buffer; - std::string msg; - }; - - ///////////////////////////////////// - ///////////////////////////////////// - auto error_callback(jpeg_common_struct* st) noexcept -> void { - EXPECTS(st != nullptr); - - auto error_data = reinterpret_cast(st->client_data); - - auto message = std::string {}; - message.resize(JMSG_STR_PARM_MAX); - (*st->err->format_message)(st, stdr::data(message)); - - error_data->msg = message; - - std::longjmp(error_data->setjmp_buffer, 1); - } - } // namespace jpg - - ///////////////////////////////////// - ///////////////////////////////////// - auto load_jpg(std::span data) noexcept -> std::expected { - auto image_memory = std::vector {}; - volatile auto format = Format {}; // NOTE volatile for error: variable ‘format’ might be - // clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered] - auto extent = math::uextent3 {}; - auto info = jpeg_decompress_struct {}; - auto error_mgr = jpeg_error_mgr {}; - - auto error_data = jpg::ErrorData {}; - - info.err = jpeg_std_error(&error_mgr); - info.client_data = &error_data; - error_mgr.error_exit = jpg::error_callback; - - jpeg_create_decompress(&info); - if (setjmp(error_data.setjmp_buffer)) { - return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, .str_error = error_data.msg }); - } - - jpeg_mem_src(&info, reinterpret_cast(stdr::data(data)), as(stdr::size(data))); - jpeg_read_header(&info, TRUE); - - jpeg_start_decompress(&info); - extent.width = info.output_width; - extent.height = info.output_height; - extent.depth = 1; - if (info.output_components == 1) format = Format::R8_UNORM; - if (info.output_components == 2) format = Format::RG8_UNORM; - if (info.output_components == 3) format = Format::RGB8_UNORM; - - image_memory.resize(as(extent.width * extent.height * extent.depth * as(info.out_color_components))); - - auto row_ptr = std::array { nullptr }; - while (info.output_scanline < info.output_height) { - const auto index = as(extent.width * as(info.output_components) * info.output_scanline); - row_ptr[0] = stdr::data(image_memory) + index; - jpeg_read_scanlines(&info, reinterpret_cast(stdr::data(row_ptr)), as(stdr::size(row_ptr))); - } - - jpeg_finish_decompress(&info); - jpeg_destroy_decompress(&info); - - if (setjmp(error_data.setjmp_buffer)) { - jpeg_destroy_decompress(&info); - return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, .str_error = error_data.msg }); - } - - auto image_data = image::Image::ImageData {}; - - image_data.extent = extent; - image_data.channel_count = get_format_channel_count(format); - image_data.bytes_per_channel = 1u; - image_data.mip_levels = 1u; - image_data.faces = 1u; - image_data.layers = 1u; - image_data.data = std::move(image_memory); - image_data.format = format; - - return Image { std::move(image_data) }; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto save_jpg(const image::Image& image, const std::filesystem::path& filepath) noexcept - -> std::expected { - auto _filename = filepath; - - auto image_rgb = image.convert_to(Format::RGB8_UNORM); - - auto info = jpeg_compress_struct {}; - auto error_mgr = jpeg_error_mgr {}; - - auto error_data = jpg::ErrorData {}; - - info.err = jpeg_std_error(&error_mgr); - info.client_data = &error_data; - error_mgr.error_exit = jpg::error_callback; - - for (auto i : range(image_rgb.mip_levels())) { - if (i >= 1u) _filename += to_native_encoding(std::format("_mip{}", i)); - - auto file = io::File::open(_filename, io::Access::WRITE); - if (not file) return std::unexpected(Error { .reason = Reason::FAILED_TO_SAVE, .str_error = error_data.msg }); - - auto data = image_rgb.data(0, 0, 0); - const auto& extent = image_rgb.extent(0); - - auto out = -#ifdef STORMKIT_OS_WINDOWS - _fdopen -#else - fdopen -#endif - (file->native_descriptor(), "w"); - - jpeg_create_compress(&info); - jpeg_stdio_dest(&info, out); - - info.image_width = extent.width; - info.image_height = extent.height; - info.input_components = get_format_channel_count(Format::RGB8_UNORM); - info.in_color_space = JCS_RGB; - jpeg_set_defaults(&info); - jpeg_set_quality(&info, 75, TRUE); - - jpeg_start_compress(&info, TRUE); - - auto row_ptr = std::array { nullptr }; - while (info.next_scanline < info.image_height) { - const auto index = info.next_scanline * 3u * info.image_width; - row_ptr[0] = stdr::data(data) + index; - - jpeg_write_scanlines(&info, reinterpret_cast(stdr::data(row_ptr)), 1); - } - - jpeg_finish_compress(&info); - jpeg_destroy_compress(&info); - - file->flush(); - } - - if (setjmp(error_data.setjmp_buffer)) { - jpeg_destroy_compress(&info); - return std::unexpected(Error { .reason = Reason::FAILED_TO_SAVE, .str_error = error_data.msg }); - } - - return {}; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto save_jpg(const image::Image& image) noexcept -> std::expected, image::Image::Error> { - using uchar_ptr = unsigned char*; - - auto output_ptr = uchar_ptr { nullptr }; - - auto image_rgb = image.convert_to(Format::RGB8_UNORM); - - auto info = jpeg_compress_struct {}; - auto error_mgr = jpeg_error_mgr {}; - - auto error_data = jpg::ErrorData {}; - - info.err = jpeg_std_error(&error_mgr); - info.client_data = &error_data; - error_mgr.error_exit = jpg::error_callback; - - auto data = image_rgb.data(0, 0, 0); - const auto& extent = image_rgb.extent(0); - - jpeg_create_compress(&info); - - using ulong = unsigned long; - auto out_size = ulong { 0 }; - jpeg_mem_dest(&info, &output_ptr, &out_size); - - info.image_width = extent.width; - info.image_height = extent.height; - info.input_components = get_format_channel_count(Format::RGB8_UNORM); - info.in_color_space = JCS_RGB; - jpeg_set_defaults(&info); - jpeg_set_quality(&info, 75, TRUE); - - jpeg_start_compress(&info, TRUE); - - auto row_ptr = std::array { nullptr }; - while (info.next_scanline < info.image_height) { - const auto index = info.next_scanline * 3u * info.image_width; - row_ptr[0] = stdr::data(data) + index; - - jpeg_write_scanlines(&info, reinterpret_cast(stdr::data(row_ptr)), 1); - } - - jpeg_finish_compress(&info); - jpeg_destroy_compress(&info); - - if (setjmp(error_data.setjmp_buffer)) { - jpeg_destroy_compress(&info); - return std::unexpected(Error { .reason = Reason::FAILED_TO_SAVE, .str_error = error_data.msg }); - } - - auto output = std::vector {}; - output.reserve((out_size)); - - std::ranges::copy(as_bytes(output_ptr, out_size), std::back_inserter(output)); - if (output_ptr != nullptr) std::free(output_ptr); - - return output; - } -} // namespace stormkit::image::details +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include +#include +#include + +#include + +#include +#include +#include + +#include + +export module stormkit.image:jpg; + +import std; + +import stormkit.core; +import stormkit.image; + +namespace stdr = std::ranges; + +export namespace stormkit::image::details { + [[nodiscard]] + auto load_jpg(std::span data) noexcept -> std::expected; + + [[nodiscard]] + auto save_jpg(const image::Image& image, const std::filesystem::path& filepath) noexcept + -> std::expected; + + [[nodiscard]] + auto save_jpg(const image::Image& image) noexcept -> std::expected, image::Image::Error>; +} // namespace stormkit::image::details + +namespace stormkit::image::details { + template + using Unexpected = std::unexpected; + using Error = image::Image::Error; + using Reason = image::Image::Error::Reason; + using Format = image::Image::Format; + + namespace jpg { + struct ErrorData { + std::jmp_buf setjmp_buffer; + std::string msg; + }; + + ///////////////////////////////////// + ///////////////////////////////////// + auto error_callback(jpeg_common_struct* st) noexcept -> void { + EXPECTS(st != nullptr); + + auto error_data = reinterpret_cast(st->client_data); + + auto message = std::string {}; + message.resize(JMSG_STR_PARM_MAX); + (*st->err->format_message)(st, stdr::data(message)); + + error_data->msg = message; + + std::longjmp(error_data->setjmp_buffer, 1); + } + } // namespace jpg + + ///////////////////////////////////// + ///////////////////////////////////// + auto load_jpg(std::span data) noexcept -> std::expected { + auto image_memory = std::vector {}; + volatile auto format = Format {}; // NOTE volatile for error: variable ‘format’ might be + // clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered] + auto extent = math::uextent3 {}; + auto info = jpeg_decompress_struct {}; + auto error_mgr = jpeg_error_mgr {}; + + auto error_data = jpg::ErrorData {}; + + info.err = jpeg_std_error(&error_mgr); + info.client_data = &error_data; + error_mgr.error_exit = jpg::error_callback; + + jpeg_create_decompress(&info); + if (setjmp(error_data.setjmp_buffer)) { + return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, .str_error = error_data.msg }); + } + + jpeg_mem_src(&info, reinterpret_cast(stdr::data(data)), as(stdr::size(data))); + jpeg_read_header(&info, TRUE); + + jpeg_start_decompress(&info); + extent.width = info.output_width; + extent.height = info.output_height; + extent.depth = 1; + if (info.output_components == 1) format = Format::R8_UNORM; + if (info.output_components == 2) format = Format::RG8_UNORM; + if (info.output_components == 3) format = Format::RGB8_UNORM; + + image_memory.resize(as(extent.width * extent.height * extent.depth * as(info.out_color_components))); + + auto row_ptr = std::array { nullptr }; + while (info.output_scanline < info.output_height) { + const auto index = as(extent.width * as(info.output_components) * info.output_scanline); + row_ptr[0] = stdr::data(image_memory) + index; + jpeg_read_scanlines(&info, reinterpret_cast(stdr::data(row_ptr)), as(stdr::size(row_ptr))); + } + + jpeg_finish_decompress(&info); + jpeg_destroy_decompress(&info); + + if (setjmp(error_data.setjmp_buffer)) { + jpeg_destroy_decompress(&info); + return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, .str_error = error_data.msg }); + } + + auto image_data = image::Image::ImageData {}; + + image_data.extent = extent; + image_data.channel_count = get_format_channel_count(format); + image_data.bytes_per_channel = 1u; + image_data.mip_levels = 1u; + image_data.faces = 1u; + image_data.layers = 1u; + image_data.data = std::move(image_memory); + image_data.format = format; + + return Image { std::move(image_data) }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto save_jpg(const image::Image& image, const std::filesystem::path& filepath) noexcept + -> std::expected { + auto _filename = filepath; + + auto image_rgb = image.convert_to(Format::RGB8_UNORM); + + auto info = jpeg_compress_struct {}; + auto error_mgr = jpeg_error_mgr {}; + + auto error_data = jpg::ErrorData {}; + + info.err = jpeg_std_error(&error_mgr); + info.client_data = &error_data; + error_mgr.error_exit = jpg::error_callback; + + for (auto i : range(image_rgb.mip_levels())) { + if (i >= 1u) _filename += to_native_encoding(std::format("_mip{}", i)); + + auto file = io::File::open(_filename, io::Access::WRITE); + if (not file) return std::unexpected(Error { .reason = Reason::FAILED_TO_SAVE, .str_error = error_data.msg }); + + auto data = image_rgb.data(0, 0, 0); + const auto& extent = image_rgb.extent(0); + + auto out = +#ifdef STORMKIT_OS_WINDOWS + _fdopen +#else + fdopen +#endif + (file->native_descriptor(), "w"); + + jpeg_create_compress(&info); + jpeg_stdio_dest(&info, out); + + info.image_width = extent.width; + info.image_height = extent.height; + info.input_components = get_format_channel_count(Format::RGB8_UNORM); + info.in_color_space = JCS_RGB; + jpeg_set_defaults(&info); + jpeg_set_quality(&info, 75, TRUE); + + jpeg_start_compress(&info, TRUE); + + auto row_ptr = std::array { nullptr }; + while (info.next_scanline < info.image_height) { + const auto index = info.next_scanline * 3u * info.image_width; + row_ptr[0] = stdr::data(data) + index; + + jpeg_write_scanlines(&info, reinterpret_cast(stdr::data(row_ptr)), 1); + } + + jpeg_finish_compress(&info); + jpeg_destroy_compress(&info); + + file->flush(); + } + + if (setjmp(error_data.setjmp_buffer)) { + jpeg_destroy_compress(&info); + return std::unexpected(Error { .reason = Reason::FAILED_TO_SAVE, .str_error = error_data.msg }); + } + + return {}; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto save_jpg(const image::Image& image) noexcept -> std::expected, image::Image::Error> { + using uchar_ptr = unsigned char*; + + auto output_ptr = uchar_ptr { nullptr }; + + auto image_rgb = image.convert_to(Format::RGB8_UNORM); + + auto info = jpeg_compress_struct {}; + auto error_mgr = jpeg_error_mgr {}; + + auto error_data = jpg::ErrorData {}; + + info.err = jpeg_std_error(&error_mgr); + info.client_data = &error_data; + error_mgr.error_exit = jpg::error_callback; + + auto data = image_rgb.data(0, 0, 0); + const auto& extent = image_rgb.extent(0); + + jpeg_create_compress(&info); + + using ulong = unsigned long; + auto out_size = ulong { 0 }; + jpeg_mem_dest(&info, &output_ptr, &out_size); + + info.image_width = extent.width; + info.image_height = extent.height; + info.input_components = get_format_channel_count(Format::RGB8_UNORM); + info.in_color_space = JCS_RGB; + jpeg_set_defaults(&info); + jpeg_set_quality(&info, 75, TRUE); + + jpeg_start_compress(&info, TRUE); + + auto row_ptr = std::array { nullptr }; + while (info.next_scanline < info.image_height) { + const auto index = info.next_scanline * 3u * info.image_width; + row_ptr[0] = stdr::data(data) + index; + + jpeg_write_scanlines(&info, reinterpret_cast(stdr::data(row_ptr)), 1); + } + + jpeg_finish_compress(&info); + jpeg_destroy_compress(&info); + + if (setjmp(error_data.setjmp_buffer)) { + jpeg_destroy_compress(&info); + return std::unexpected(Error { .reason = Reason::FAILED_TO_SAVE, .str_error = error_data.msg }); + } + + auto output = std::vector {}; + output.reserve((out_size)); + + std::ranges::copy(as_bytes(output_ptr, out_size), std::back_inserter(output)); + if (output_ptr != nullptr) std::free(output_ptr); + + return output; + } +} // namespace stormkit::image::details diff --git a/src/image/ktx.mpp b/src/image/ktx.cppm similarity index 98% rename from src/image/ktx.mpp rename to src/image/ktx.cppm index 7e320f838..64f3125b9 100644 --- a/src/image/ktx.mpp +++ b/src/image/ktx.cppm @@ -1,151 +1,151 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; -#include - -export module stormkit.image:ktx; - -import std; - -import stormkit.core; -import stormkit.image; - -export namespace stormkit::image::details { - [[nodiscard]] - auto load_ktx(std::span data) noexcept -> std::expected; - - [[nodiscard]] - auto save_ktx(const image::Image& image, const std::filesystem::path& filepath) noexcept - -> std::expected; - - [[nodiscard]] - auto save_ktx(const image::Image& image) noexcept -> std::expected, image::Image::Error>; -} // namespace stormkit::image::details - -namespace stormkit::image::details { - template - using Unexpected = std::unexpected; - using Error = image::Image::Error; - using Reason = image::Image::Error::Reason; - using Format = image::Image::Format; - - ///////////////////////////////////// - ///////////////////////////////////// - /*constexpr auto toStormFormat(gli::format format) noexcept {*/ - /*switch (format) {*/ - /* case gli::format_R8_SNORM_PACK8: return Format::R8_SNORM;*/ - /* case gli::format_R8_UNORM_PACK8: return Format::R8_UNORM;*/ - /* case gli::format_R16_SNORM_PACK16: return Format::R16_SNORM;*/ - /* case gli::format_R16_UNORM_PACK16: return Format::R16_UNORM;*/ - /* case gli::format_R8_SINT_PACK8: return Format::R8I;*/ - /* case gli::format_R8_UINT_PACK8: return Format::R8U;*/ - /* case gli::format_R16_SINT_PACK16: return Format::R16I;*/ - /* case gli::format_R16_UINT_PACK16: return Format::R16U;*/ - /* case gli::format_R32_SINT_PACK32: return Format::R32I;*/ - /* case gli::format_R32_UINT_PACK32: return Format::R32U;*/ - /* case gli::format_R16_SFLOAT_PACK16: return Format::R16F;*/ - /* case gli::format_R32_SFLOAT_PACK32: return Format::R32F;*/ - /**/ - /* case gli::format_RG8_SNORM_PACK8: return Format::RG8_SNORM;*/ - /* case gli::format_RG8_UNORM_PACK8: return Format::RG8_UNORM;*/ - /* case gli::format_RG16_SNORM_PACK16: return Format::RG16_SNORM;*/ - /* case gli::format_RG16_UNORM_PACK16: return Format::RG16_UNORM;*/ - /* case gli::format_RG8_SINT_PACK8: return Format::RG8I;*/ - /* case gli::format_RG8_UINT_PACK8: return Format::RG8U;*/ - /* case gli::format_RG16_SINT_PACK16: return Format::RG16I;*/ - /* case gli::format_RG16_UINT_PACK16: return Format::RG16U;*/ - /* case gli::format_RG32_SINT_PACK32: return Format::RG32I;*/ - /* case gli::format_RG32_UINT_PACK32: return Format::RG32U;*/ - /* case gli::format_RG16_SFLOAT_PACK16: return Format::RG16F;*/ - /* case gli::format_RG32_SFLOAT_PACK32: return Format::RG32F;*/ - /**/ - /* case gli::format_RGB8_SNORM_PACK8: return Format::RGB8_SNORM;*/ - /* case gli::format_RGB8_UNORM_PACK8: return Format::RGB8_UNORM;*/ - /* case gli::format_RGB16_SNORM_PACK16: return Format::RGB16_SNORM;*/ - /* case gli::format_RGB16_UNORM_PACK16: return Format::RGB16_UNORM;*/ - /* case gli::format_BGR8_UNORM_PACK8: return Format::RGB16_UNORM;*/ - /* case gli::format_RGB8_SINT_PACK8: return Format::RGB8I;*/ - /* case gli::format_RGB8_UINT_PACK8: return Format::RGB8U;*/ - /* case gli::format_RGB16_SINT_PACK16: return Format::RGB16I;*/ - /* case gli::format_RGB16_UINT_PACK16: return Format::RGB16U;*/ - /* case gli::format_RGB32_SINT_PACK32: return Format::RGB32I;*/ - /* case gli::format_RGB32_UINT_PACK32: return Format::RGB32U;*/ - /* case gli::format_RGB16_SFLOAT_PACK16: return Format::RGB16F;*/ - /* case gli::format_RGB32_SFLOAT_PACK32: return Format::RGB32F;*/ - /* case gli::format_RGB8_SRGB_PACK8: return Format::SRGB8;*/ - /* case gli::format_BGR8_SRGB_PACK8: return Format::SBGR8;*/ - /**/ - /* case gli::format_RGBA8_SNORM_PACK8: return Format::RGBA8_SNORM;*/ - /* case gli::format_RGBA8_UNORM_PACK8: return Format::RGBA8_UNORM;*/ - /* case gli::format_RGBA16_SNORM_PACK16: return Format::RGBA16_SNORM;*/ - /* case gli::format_RGBA16_UNORM_PACK16: return Format::RGBA16_UNORM;*/ - /* case gli::format_BGRA8_UNORM_PACK8: return Format::RGBA16_UNORM;*/ - /* case gli::format_RGBA8_SINT_PACK8: return Format::RGBA8I;*/ - /* case gli::format_RGBA8_UINT_PACK8: return Format::RGBA8U;*/ - /* case gli::format_RGBA16_SINT_PACK16: return Format::RGBA16I;*/ - /* case gli::format_RGBA16_UINT_PACK16: return Format::RGBA16U;*/ - /* case gli::format_RGBA32_SINT_PACK32: return Format::RGBA32I;*/ - /* case gli::format_RGBA32_UINT_PACK32: return Format::RGBA32U;*/ - /* case gli::format_RGBA16_SFLOAT_PACK16: return Format::RGBA16F;*/ - /* case gli::format_RGBA32_SFLOAT_PACK32: return Format::RGBA32F;*/ - /* case gli::format_RGBA8_SRGB_PACK8: return Format::SRGBA8;*/ - /* case gli::format_BGRA8_SRGB_PACK8: return Format::SBGRA8;*/ - /* default: break;*/ - /*}*/ - /**/ - /* return Format::UNDEFINED;*/ - /*}*/ - - ///////////////////////////////////// - ///////////////////////////////////// - auto load_ktx([[maybe_unused]] std::span data) noexcept -> std::expected { - /*auto image = gli::load_ktx(reinterpret_cast(std::data(data)), - * std::size(data));*/ - /**/ - /*const auto faces = as(image.faces());*/ - /*const auto layers = as(image.layers());*/ - /*const auto mip_levels = as(image.levels());*/ - /*const auto format = toStormFormat(image.format());*/ - /**/ - /*if (format == Format::UNDEFINED)*/ - /* return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE,*/ - /* .str_error = "Unsupported pixel format" });*/ - /**/ - /*auto image_memory = std::vector {};*/ - /*image_memory.resize(image.size());*/ - /**/ - /*std::ranges::copy(as_bytes(image.data(), image.size()), std::begin(image_memory));*/ - /**/ - /*auto image_data = image::Image::ImageData {};*/ - /**/ - /*image_data.extent = math::extentI { image.extent().x, image.extent().y, image.extent().z - * };*/ - /*image_data.channel_count = get_format_channel_count(format);*/ - /*image_data.bytes_per_channel = getSizeof(format);*/ - /*image_data.mip_levels = mip_levels;*/ - /*image_data.faces = faces;*/ - /*image_data.layers = layers;*/ - /*image_data.data = std::move(image_memory);*/ - /*image_data.format = format;*/ - /**/ - /*return Image { std::move(image_data) };*/ - assert(false, "Not implemented yet !"); - return {}; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto save_ktx(const image::Image&, const std::filesystem::path&) noexcept -> std::expected { - assert(false, "Not implemented yet !"); - return {}; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto save_ktx(const image::Image&) noexcept -> std::expected, image::Image::Error> { - assert(false, "Not implemented yet !"); - return {}; - } -} // namespace stormkit::image::details +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; +#include + +export module stormkit.image:ktx; + +import std; + +import stormkit.core; +import stormkit.image; + +export namespace stormkit::image::details { + [[nodiscard]] + auto load_ktx(std::span data) noexcept -> std::expected; + + [[nodiscard]] + auto save_ktx(const image::Image& image, const std::filesystem::path& filepath) noexcept + -> std::expected; + + [[nodiscard]] + auto save_ktx(const image::Image& image) noexcept -> std::expected, image::Image::Error>; +} // namespace stormkit::image::details + +namespace stormkit::image::details { + template + using Unexpected = std::unexpected; + using Error = image::Image::Error; + using Reason = image::Image::Error::Reason; + using Format = image::Image::Format; + + ///////////////////////////////////// + ///////////////////////////////////// + /*constexpr auto toStormFormat(gli::format format) noexcept {*/ + /*switch (format) {*/ + /* case gli::format_R8_SNORM_PACK8: return Format::R8_SNORM;*/ + /* case gli::format_R8_UNORM_PACK8: return Format::R8_UNORM;*/ + /* case gli::format_R16_SNORM_PACK16: return Format::R16_SNORM;*/ + /* case gli::format_R16_UNORM_PACK16: return Format::R16_UNORM;*/ + /* case gli::format_R8_SINT_PACK8: return Format::R8I;*/ + /* case gli::format_R8_UINT_PACK8: return Format::R8U;*/ + /* case gli::format_R16_SINT_PACK16: return Format::R16I;*/ + /* case gli::format_R16_UINT_PACK16: return Format::R16U;*/ + /* case gli::format_R32_SINT_PACK32: return Format::R32I;*/ + /* case gli::format_R32_UINT_PACK32: return Format::R32U;*/ + /* case gli::format_R16_SFLOAT_PACK16: return Format::R16F;*/ + /* case gli::format_R32_SFLOAT_PACK32: return Format::R32F;*/ + /**/ + /* case gli::format_RG8_SNORM_PACK8: return Format::RG8_SNORM;*/ + /* case gli::format_RG8_UNORM_PACK8: return Format::RG8_UNORM;*/ + /* case gli::format_RG16_SNORM_PACK16: return Format::RG16_SNORM;*/ + /* case gli::format_RG16_UNORM_PACK16: return Format::RG16_UNORM;*/ + /* case gli::format_RG8_SINT_PACK8: return Format::RG8I;*/ + /* case gli::format_RG8_UINT_PACK8: return Format::RG8U;*/ + /* case gli::format_RG16_SINT_PACK16: return Format::RG16I;*/ + /* case gli::format_RG16_UINT_PACK16: return Format::RG16U;*/ + /* case gli::format_RG32_SINT_PACK32: return Format::RG32I;*/ + /* case gli::format_RG32_UINT_PACK32: return Format::RG32U;*/ + /* case gli::format_RG16_SFLOAT_PACK16: return Format::RG16F;*/ + /* case gli::format_RG32_SFLOAT_PACK32: return Format::RG32F;*/ + /**/ + /* case gli::format_RGB8_SNORM_PACK8: return Format::RGB8_SNORM;*/ + /* case gli::format_RGB8_UNORM_PACK8: return Format::RGB8_UNORM;*/ + /* case gli::format_RGB16_SNORM_PACK16: return Format::RGB16_SNORM;*/ + /* case gli::format_RGB16_UNORM_PACK16: return Format::RGB16_UNORM;*/ + /* case gli::format_BGR8_UNORM_PACK8: return Format::RGB16_UNORM;*/ + /* case gli::format_RGB8_SINT_PACK8: return Format::RGB8I;*/ + /* case gli::format_RGB8_UINT_PACK8: return Format::RGB8U;*/ + /* case gli::format_RGB16_SINT_PACK16: return Format::RGB16I;*/ + /* case gli::format_RGB16_UINT_PACK16: return Format::RGB16U;*/ + /* case gli::format_RGB32_SINT_PACK32: return Format::RGB32I;*/ + /* case gli::format_RGB32_UINT_PACK32: return Format::RGB32U;*/ + /* case gli::format_RGB16_SFLOAT_PACK16: return Format::RGB16F;*/ + /* case gli::format_RGB32_SFLOAT_PACK32: return Format::RGB32F;*/ + /* case gli::format_RGB8_SRGB_PACK8: return Format::SRGB8;*/ + /* case gli::format_BGR8_SRGB_PACK8: return Format::SBGR8;*/ + /**/ + /* case gli::format_RGBA8_SNORM_PACK8: return Format::RGBA8_SNORM;*/ + /* case gli::format_RGBA8_UNORM_PACK8: return Format::RGBA8_UNORM;*/ + /* case gli::format_RGBA16_SNORM_PACK16: return Format::RGBA16_SNORM;*/ + /* case gli::format_RGBA16_UNORM_PACK16: return Format::RGBA16_UNORM;*/ + /* case gli::format_BGRA8_UNORM_PACK8: return Format::RGBA16_UNORM;*/ + /* case gli::format_RGBA8_SINT_PACK8: return Format::RGBA8I;*/ + /* case gli::format_RGBA8_UINT_PACK8: return Format::RGBA8U;*/ + /* case gli::format_RGBA16_SINT_PACK16: return Format::RGBA16I;*/ + /* case gli::format_RGBA16_UINT_PACK16: return Format::RGBA16U;*/ + /* case gli::format_RGBA32_SINT_PACK32: return Format::RGBA32I;*/ + /* case gli::format_RGBA32_UINT_PACK32: return Format::RGBA32U;*/ + /* case gli::format_RGBA16_SFLOAT_PACK16: return Format::RGBA16F;*/ + /* case gli::format_RGBA32_SFLOAT_PACK32: return Format::RGBA32F;*/ + /* case gli::format_RGBA8_SRGB_PACK8: return Format::SRGBA8;*/ + /* case gli::format_BGRA8_SRGB_PACK8: return Format::SBGRA8;*/ + /* default: break;*/ + /*}*/ + /**/ + /* return Format::UNDEFINED;*/ + /*}*/ + + ///////////////////////////////////// + ///////////////////////////////////// + auto load_ktx([[maybe_unused]] std::span data) noexcept -> std::expected { + /*auto image = gli::load_ktx(reinterpret_cast(std::data(data)), + * std::size(data));*/ + /**/ + /*const auto faces = as(image.faces());*/ + /*const auto layers = as(image.layers());*/ + /*const auto mip_levels = as(image.levels());*/ + /*const auto format = toStormFormat(image.format());*/ + /**/ + /*if (format == Format::UNDEFINED)*/ + /* return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE,*/ + /* .str_error = "Unsupported pixel format" });*/ + /**/ + /*auto image_memory = std::vector {};*/ + /*image_memory.resize(image.size());*/ + /**/ + /*std::ranges::copy(as_bytes(image.data(), image.size()), std::begin(image_memory));*/ + /**/ + /*auto image_data = image::Image::ImageData {};*/ + /**/ + /*image_data.extent = math::extentI { image.extent().x, image.extent().y, image.extent().z + * };*/ + /*image_data.channel_count = get_format_channel_count(format);*/ + /*image_data.bytes_per_channel = getSizeof(format);*/ + /*image_data.mip_levels = mip_levels;*/ + /*image_data.faces = faces;*/ + /*image_data.layers = layers;*/ + /*image_data.data = std::move(image_memory);*/ + /*image_data.format = format;*/ + /**/ + /*return Image { std::move(image_data) };*/ + assert(false, "Not implemented yet !"); + return {}; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto save_ktx(const image::Image&, const std::filesystem::path&) noexcept -> std::expected { + assert(false, "Not implemented yet !"); + return {}; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto save_ktx(const image::Image&) noexcept -> std::expected, image::Image::Error> { + assert(false, "Not implemented yet !"); + return {}; + } +} // namespace stormkit::image::details diff --git a/src/image/png.mpp b/src/image/png.cppm similarity index 97% rename from src/image/png.mpp rename to src/image/png.cppm index 08ca567a6..814aea850 100644 --- a/src/image/png.mpp +++ b/src/image/png.cppm @@ -1,254 +1,254 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include -#include - -#include - -export module stormkit.image:png; - -import std; - -import stormkit.core; -import stormkit.image; - -export namespace stormkit::image::details { - [[nodiscard]] - auto load_png(std::span data) noexcept -> std::expected; - - [[nodiscard]] - auto save_png(const image::Image& image, const std::filesystem::path& filepath) noexcept - -> std::expected; - - [[nodiscard]] - auto save_png(const image::Image& image) noexcept -> std::expected, image::Image::Error>; -} // namespace stormkit::image::details - -namespace stdr = std::ranges; - -namespace stormkit::image::details { - template - using Unexpected = std::unexpected; - using Error = image::Image::Error; - using Reason = image::Image::Error::Reason; - using Format = image::Image::Format; - - namespace png { - struct ReadParam { - usize readed; - std::span& data; - }; - - struct WriteParam { - std::vector& data; - }; - - ///////////////////////////////////// - ///////////////////////////////////// - static auto read_func(png_struct* ps, png_byte* d, png_size_t length) noexcept -> void { - auto& param = *std::bit_cast(png_get_io_ptr(ps)); - - auto _d = as_bytes_mut(d, length); - auto data = param.data.subspan(param.readed, length); - - stdr::copy(data, stdr::begin(_d)); - - param.readed += length; - } - - ///////////////////////////////////// - ///////////////////////////////////// - static auto write_func(png_struct* ps, png_byte* d, png_size_t length) -> void { - auto& param = *std::bit_cast(png_get_io_ptr(ps)); - - auto _d = as_bytes(d, length); - param.data.reserve(std::size(param.data) + length); - - stdr::copy(_d, std::back_inserter(param.data)); - } - } // namespace png - - ///////////////////////////////////// - ///////////////////////////////////// - auto load_png(std::span data) noexcept -> std::expected { - auto image_memory = std::vector {}; - auto format = Format {}; - auto extent = math::uextent3 {}; - - auto read_param = png::ReadParam { 8u, data }; - - auto sig = std::bit_cast(std::data(data)); - if (!png_check_sig(sig, 8u)) - return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, - .str_error = "[libpng] Failed to validate PNG signature" }); - - auto png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - if (!png_ptr) - return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, - .str_error = "[libpng] Failed to init (png_create_read_struct)" }); - - auto info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_read_struct(&png_ptr, nullptr, nullptr); - return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, - .str_error = "[libpng] Failed to init (png_create_info_struct)" }); - } - - png_set_read_fn(png_ptr, &read_param, png::read_func); - png_set_sig_bytes(png_ptr, 8); - png_read_info(png_ptr, info_ptr); - - auto bit_depth = 0; - auto color_type = 0; - - png_get_IHDR(png_ptr, info_ptr, &extent.width, &extent.height, &bit_depth, &color_type, nullptr, nullptr, nullptr); - - if (color_type == PNG_COLOR_TYPE_GRAY) png_set_expand_gray_1_2_4_to_8(png_ptr); - else if (color_type == PNG_COLOR_TYPE_PALETTE) { - png_set_palette_to_rgb(png_ptr); - png_set_filler(png_ptr, 0xFF, PNG_FILLER_AFTER); - } - if (bit_depth < 8) png_set_packing(png_ptr); - if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); - - png_get_IHDR(png_ptr, info_ptr, &extent.width, &extent.height, &bit_depth, &color_type, nullptr, nullptr, nullptr); - - switch (color_type) { - case PNG_COLOR_TYPE_GRAY: { - if (bit_depth == 8) format = Format::R8_UNORM; - else if (bit_depth == 16) - format = Format::R16_UNORM; - - break; - } - case PNG_COLOR_TYPE_GRAY_ALPHA: { - if (bit_depth == 8) format = Format::RG8_UNORM; - else if (bit_depth == 16) - format = Format::RG16_UNORM; - - break; - } - case PNG_COLOR_TYPE_RGB: { - if (bit_depth == 8) format = Format::RGB8_UNORM; - else if (bit_depth == 16) - format = Format::RGB16_UNORM; - - break; - } - case PNG_COLOR_TYPE_RGB_ALPHA: { - if (bit_depth == 8) format = Format::RGBA8_UNORM; - else if (bit_depth == 16) - format = Format::RGBA16_UNORM; - - break; - } - case PNG_COLOR_TYPE_PALETTE: { - if (bit_depth == 8) format = Format::RGBA8_UNORM; - else if (bit_depth == 16) - format = Format::RGBA16_UNORM; - - break; - } - - default: break; - } - - png_read_update_info(png_ptr, info_ptr); - - const auto row_bytes = png_get_rowbytes(png_ptr, info_ptr); - image_memory.resize(extent.height * row_bytes); - - auto row_pointers = std::vector { extent.height, nullptr }; - - auto buff_pos = std::data(image_memory); - - for (auto i : range(extent.height)) row_pointers[i] = &buff_pos[row_bytes * i]; - - png_read_image(png_ptr, std::bit_cast(std::data(row_pointers))); - png_read_end(png_ptr, info_ptr); - - png_destroy_info_struct(png_ptr, &info_ptr); - png_destroy_read_struct(&png_ptr, nullptr, nullptr); - - auto image_data = image::Image::ImageData { - .extent = std::move(extent), - .channel_count = get_format_channel_count(format), - .bytes_per_channel = getSizeof(format), - .layers = 1u, - .faces = 1u, - .mip_levels = 1u, - .format = format, - .data = std::move(image_memory) - }; - - return Image { std::move(image_data) }; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto save_png(const image::Image&, const std::filesystem::path&) noexcept -> std::expected { - assert(false, "Not implemented yet !"); - return {}; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto save_png(const image::Image& image) noexcept -> std::expected, image::Image::Error> { - auto output = std::vector {}; - - auto write_param = png::WriteParam { output }; - - auto png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - if (!png_ptr) - return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, - .str_error = "[libpng] Failed to init (png_create_write_struct)" }); - - auto info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) { - png_destroy_write_struct(&png_ptr, nullptr); - return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, - .str_error = "[libpng] Failed to init (png_create_info_struct)" }); - } - - if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_info_struct(png_ptr, &info_ptr); - png_destroy_write_struct(&png_ptr, nullptr); - return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, - .str_error = "[libpng] Unkown error during png creation" }); - } - - png_set_write_fn(png_ptr, &write_param, png::write_func, nullptr); - - const auto& data = image.image_data(); - - png_set_IHDR(png_ptr, - info_ptr, - data.extent.width, - data.extent.height, - 8, - PNG_COLOR_TYPE_RGB_ALPHA, - PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - png_write_info(png_ptr, info_ptr); - - auto rows = std::vector { data.extent.height, nullptr }; - for (auto i : range(data.extent.height)) - rows[i] = const_cast< - Byte*>(&data.data[i * data.extent.width * data.channel_count * data.bytes_per_channel]); // TODO Fix this shit - - png_set_rows(png_ptr, info_ptr, std::bit_cast(std::data(rows))); - png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, nullptr); - png_write_end(png_ptr, info_ptr); - - png_destroy_info_struct(png_ptr, &info_ptr); - png_destroy_write_struct(&png_ptr, nullptr); - - return output; - ; - } -} // namespace stormkit::image::details +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include +#include + +#include + +export module stormkit.image:png; + +import std; + +import stormkit.core; +import stormkit.image; + +export namespace stormkit::image::details { + [[nodiscard]] + auto load_png(std::span data) noexcept -> std::expected; + + [[nodiscard]] + auto save_png(const image::Image& image, const std::filesystem::path& filepath) noexcept + -> std::expected; + + [[nodiscard]] + auto save_png(const image::Image& image) noexcept -> std::expected, image::Image::Error>; +} // namespace stormkit::image::details + +namespace stdr = std::ranges; + +namespace stormkit::image::details { + template + using Unexpected = std::unexpected; + using Error = image::Image::Error; + using Reason = image::Image::Error::Reason; + using Format = image::Image::Format; + + namespace png { + struct ReadParam { + usize readed; + std::span& data; + }; + + struct WriteParam { + std::vector& data; + }; + + ///////////////////////////////////// + ///////////////////////////////////// + static auto read_func(png_struct* ps, png_byte* d, png_size_t length) noexcept -> void { + auto& param = *std::bit_cast(png_get_io_ptr(ps)); + + auto _d = as_bytes_mut(d, length); + auto data = param.data.subspan(param.readed, length); + + stdr::copy(data, stdr::begin(_d)); + + param.readed += length; + } + + ///////////////////////////////////// + ///////////////////////////////////// + static auto write_func(png_struct* ps, png_byte* d, png_size_t length) -> void { + auto& param = *std::bit_cast(png_get_io_ptr(ps)); + + auto _d = as_bytes(d, length); + param.data.reserve(std::size(param.data) + length); + + stdr::copy(_d, std::back_inserter(param.data)); + } + } // namespace png + + ///////////////////////////////////// + ///////////////////////////////////// + auto load_png(std::span data) noexcept -> std::expected { + auto image_memory = std::vector {}; + auto format = Format {}; + auto extent = math::uextent3 {}; + + auto read_param = png::ReadParam { 8u, data }; + + auto sig = std::bit_cast(std::data(data)); + if (!png_check_sig(sig, 8u)) + return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, + .str_error = "[libpng] Failed to validate PNG signature" }); + + auto png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); + if (!png_ptr) + return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, + .str_error = "[libpng] Failed to init (png_create_read_struct)" }); + + auto info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_read_struct(&png_ptr, nullptr, nullptr); + return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, + .str_error = "[libpng] Failed to init (png_create_info_struct)" }); + } + + png_set_read_fn(png_ptr, &read_param, png::read_func); + png_set_sig_bytes(png_ptr, 8); + png_read_info(png_ptr, info_ptr); + + auto bit_depth = 0; + auto color_type = 0; + + png_get_IHDR(png_ptr, info_ptr, &extent.width, &extent.height, &bit_depth, &color_type, nullptr, nullptr, nullptr); + + if (color_type == PNG_COLOR_TYPE_GRAY) png_set_expand_gray_1_2_4_to_8(png_ptr); + else if (color_type == PNG_COLOR_TYPE_PALETTE) { + png_set_palette_to_rgb(png_ptr); + png_set_filler(png_ptr, 0xFF, PNG_FILLER_AFTER); + } + if (bit_depth < 8) png_set_packing(png_ptr); + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr); + + png_get_IHDR(png_ptr, info_ptr, &extent.width, &extent.height, &bit_depth, &color_type, nullptr, nullptr, nullptr); + + switch (color_type) { + case PNG_COLOR_TYPE_GRAY: { + if (bit_depth == 8) format = Format::R8_UNORM; + else if (bit_depth == 16) + format = Format::R16_UNORM; + + break; + } + case PNG_COLOR_TYPE_GRAY_ALPHA: { + if (bit_depth == 8) format = Format::RG8_UNORM; + else if (bit_depth == 16) + format = Format::RG16_UNORM; + + break; + } + case PNG_COLOR_TYPE_RGB: { + if (bit_depth == 8) format = Format::RGB8_UNORM; + else if (bit_depth == 16) + format = Format::RGB16_UNORM; + + break; + } + case PNG_COLOR_TYPE_RGB_ALPHA: { + if (bit_depth == 8) format = Format::RGBA8_UNORM; + else if (bit_depth == 16) + format = Format::RGBA16_UNORM; + + break; + } + case PNG_COLOR_TYPE_PALETTE: { + if (bit_depth == 8) format = Format::RGBA8_UNORM; + else if (bit_depth == 16) + format = Format::RGBA16_UNORM; + + break; + } + + default: break; + } + + png_read_update_info(png_ptr, info_ptr); + + const auto row_bytes = png_get_rowbytes(png_ptr, info_ptr); + image_memory.resize(extent.height * row_bytes); + + auto row_pointers = std::vector { extent.height, nullptr }; + + auto buff_pos = std::data(image_memory); + + for (auto i : range(extent.height)) row_pointers[i] = &buff_pos[row_bytes * i]; + + png_read_image(png_ptr, std::bit_cast(std::data(row_pointers))); + png_read_end(png_ptr, info_ptr); + + png_destroy_info_struct(png_ptr, &info_ptr); + png_destroy_read_struct(&png_ptr, nullptr, nullptr); + + auto image_data = image::Image::ImageData { + .extent = std::move(extent), + .channel_count = get_format_channel_count(format), + .bytes_per_channel = getSizeof(format), + .layers = 1u, + .faces = 1u, + .mip_levels = 1u, + .format = format, + .data = std::move(image_memory) + }; + + return Image { std::move(image_data) }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto save_png(const image::Image&, const std::filesystem::path&) noexcept -> std::expected { + assert(false, "Not implemented yet !"); + return {}; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto save_png(const image::Image& image) noexcept -> std::expected, image::Image::Error> { + auto output = std::vector {}; + + auto write_param = png::WriteParam { output }; + + auto png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); + if (!png_ptr) + return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, + .str_error = "[libpng] Failed to init (png_create_write_struct)" }); + + auto info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + png_destroy_write_struct(&png_ptr, nullptr); + return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, + .str_error = "[libpng] Failed to init (png_create_info_struct)" }); + } + + if (setjmp(png_jmpbuf(png_ptr))) { + png_destroy_info_struct(png_ptr, &info_ptr); + png_destroy_write_struct(&png_ptr, nullptr); + return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE, + .str_error = "[libpng] Unkown error during png creation" }); + } + + png_set_write_fn(png_ptr, &write_param, png::write_func, nullptr); + + const auto& data = image.image_data(); + + png_set_IHDR(png_ptr, + info_ptr, + data.extent.width, + data.extent.height, + 8, + PNG_COLOR_TYPE_RGB_ALPHA, + PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + png_write_info(png_ptr, info_ptr); + + auto rows = std::vector { data.extent.height, nullptr }; + for (auto i : range(data.extent.height)) + rows[i] = const_cast< + Byte*>(&data.data[i * data.extent.width * data.channel_count * data.bytes_per_channel]); // TODO Fix this shit + + png_set_rows(png_ptr, info_ptr, std::bit_cast(std::data(rows))); + png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, nullptr); + png_write_end(png_ptr, info_ptr); + + png_destroy_info_struct(png_ptr, &info_ptr); + png_destroy_write_struct(&png_ptr, nullptr); + + return output; + ; + } +} // namespace stormkit::image::details diff --git a/src/image/ppm.mpp b/src/image/ppm.cppm similarity index 97% rename from src/image/ppm.mpp rename to src/image/ppm.cppm index a0284c21b..c7b92ecc1 100644 --- a/src/image/ppm.mpp +++ b/src/image/ppm.cppm @@ -1,90 +1,90 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -export module stormkit.image:ppm; - -import std; - -import stormkit.core; -import stormkit.image; - -export namespace stormkit::image::details { - [[nodiscard]] - auto load_ppm(std::span data) noexcept -> std::expected; - - [[nodiscard]] - auto save_ppm(const image::Image& image, image::Image::CodecArgs args, const std::filesystem::path& filepath) noexcept - -> std::expected; - - [[nodiscard]] - auto save_ppm(const image::Image& image, image::Image::CodecArgs args) noexcept - -> std::expected, image::Image::Error>; -} // namespace stormkit::image::details - -using namespace std::literals; - -namespace stormkit::image::details { - template - using Unexpected = std::unexpected; - using Error = image::Image::Error; - using Reason = image::Image::Error::Reason; - using Format = image::Image::Format; - - ///////////////////////////////////// - ///////////////////////////////////// - auto load_ppm(std::span) noexcept -> std::expected { - assert(false, "Not implemented yet !"); - return {}; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto save_ppm(const image::Image& image, image::Image::CodecArgs args, const std::filesystem::path& filepath) noexcept - -> std::expected { - return save_ppm(image, args) - .and_then([&filepath](auto&& val) noexcept { - return io::write(filepath, val).transform_error([](auto&&) static noexcept { - return Error { .reason = Error::Reason::FAILED_TO_SAVE, .str_error = "" }; - }); - }) - .transform(monadic::discard()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto save_ppm(const image::Image& image, image::Image::CodecArgs args) noexcept - -> std::expected, image::Image::Error> { - const auto output_image = image.convert_to(Format::RGB8_UNORM); - const auto& data = output_image.image_data(); - - auto output = std::vector {}; - if (args == image::Image::CodecArgs::ASCII) { - auto result = std::format("P3\n{}\n{}\n255\n"sv, data.extent.width, data.extent.height); - - const auto& extent = output_image.extent(); - for (auto [i, j] : multi_range(extent.height, extent.width)) { - const auto pixel = output_image.pixel(i * output_image.extent().width + j); - - result += std::format("{} {} {}\n"sv, as(pixel[0]), as(pixel[1]), as(pixel[2])); - - if (j == extent.width) result += '\n'; - } - - output.reserve(std::size(result)); - std::ranges::copy(as_bytes(result), std::back_inserter(output)); - } else if (args == image::Image::CodecArgs::BINARY) { - auto header = std::format("P3\n{}\n{}\n255\n"sv, data.extent.width, data.extent.height); - output.reserve(std::size(output) + std::size(output_image)); - - std::ranges::copy(as_bytes(header), std::back_inserter(output)); - std::ranges::copy(output_image, std::back_inserter(output)); - } - - return output; - } -} // namespace stormkit::image::details +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.image:ppm; + +import std; + +import stormkit.core; +import stormkit.image; + +export namespace stormkit::image::details { + [[nodiscard]] + auto load_ppm(std::span data) noexcept -> std::expected; + + [[nodiscard]] + auto save_ppm(const image::Image& image, image::Image::CodecArgs args, const std::filesystem::path& filepath) noexcept + -> std::expected; + + [[nodiscard]] + auto save_ppm(const image::Image& image, image::Image::CodecArgs args) noexcept + -> std::expected, image::Image::Error>; +} // namespace stormkit::image::details + +using namespace std::literals; + +namespace stormkit::image::details { + template + using Unexpected = std::unexpected; + using Error = image::Image::Error; + using Reason = image::Image::Error::Reason; + using Format = image::Image::Format; + + ///////////////////////////////////// + ///////////////////////////////////// + auto load_ppm(std::span) noexcept -> std::expected { + assert(false, "Not implemented yet !"); + return {}; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto save_ppm(const image::Image& image, image::Image::CodecArgs args, const std::filesystem::path& filepath) noexcept + -> std::expected { + return save_ppm(image, args) + .and_then([&filepath](auto&& val) noexcept { + return io::write(filepath, val).transform_error([](auto&&) static noexcept { + return Error { .reason = Error::Reason::FAILED_TO_SAVE, .str_error = "" }; + }); + }) + .transform(monadic::discard()); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto save_ppm(const image::Image& image, image::Image::CodecArgs args) noexcept + -> std::expected, image::Image::Error> { + const auto output_image = image.convert_to(Format::RGB8_UNORM); + const auto& data = output_image.image_data(); + + auto output = std::vector {}; + if (args == image::Image::CodecArgs::ASCII) { + auto result = std::format("P3\n{}\n{}\n255\n"sv, data.extent.width, data.extent.height); + + const auto& extent = output_image.extent(); + for (auto [i, j] : multi_range(extent.height, extent.width)) { + const auto pixel = output_image.pixel(i * output_image.extent().width + j); + + result += std::format("{} {} {}\n"sv, as(pixel[0]), as(pixel[1]), as(pixel[2])); + + if (j == extent.width) result += '\n'; + } + + output.reserve(std::size(result)); + std::ranges::copy(as_bytes(result), std::back_inserter(output)); + } else if (args == image::Image::CodecArgs::BINARY) { + auto header = std::format("P3\n{}\n{}\n255\n"sv, data.extent.width, data.extent.height); + output.reserve(std::size(output) + std::size(output_image)); + + std::ranges::copy(as_bytes(header), std::back_inserter(output)); + std::ranges::copy(output_image, std::back_inserter(output)); + } + + return output; + } +} // namespace stormkit::image::details diff --git a/src/image/qoi.mpp b/src/image/qoi.cppm similarity index 97% rename from src/image/qoi.mpp rename to src/image/qoi.cppm index df023038f..693cf1bc6 100644 --- a/src/image/qoi.mpp +++ b/src/image/qoi.cppm @@ -1,209 +1,209 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -export module stormkit.image:qoi; - -import std; - -import frozen; - -import stormkit.core; -import stormkit.image; - -export namespace stormkit::image::details { - [[nodiscard]] - auto load_qoi(std::span data) noexcept -> std::expected; - - [[nodiscard]] - auto save_qoi(const image::Image& image, const std::filesystem::path& filepath) noexcept - -> std::expected; - - [[nodiscard]] - auto save_qoi(const image::Image& image) noexcept -> std::expected, image::Image::Error>; -} // namespace stormkit::image::details - -using namespace std::literals; - -namespace stdr = std::ranges; - -namespace stormkit::image::details { - template - using Unexpected = std::unexpected; - using Error = image::Image::Error; - using Reason = image::Image::Error::Reason; - - struct QOIHeader { - std::array magic; - u32 width; - u32 height; - u8 channels; - u8 colorspace; - }; - - namespace { - constexpr auto SIZE_OF_HEADER = 14; - - constexpr auto CHANNELS_TO_FORMAT = frozen::make_unordered_map>({ - { 3, std::array { image::Image::Format::SRGB8, image::Image::Format::RGB8_UNORM } }, - { 4, std::array { image::Image::Format::SRGBA8, image::Image::Format::RGBA8_UNORM } } - }); - - constexpr auto END_OF_FILE = into_bytes({ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }); - - constexpr auto PIXEL_CACHE_SIZE = 64u; - } // namespace - - enum class QOI_OPERATION : u8 { - RGB = 0b11111110, - RGBA = 0b11111111, - INDEX = 0b00000000, - DIFF = 0b01000000, - LUMA = 0b10000000, - RUN = 0b11000000, - }; - - union Pixel { - struct { - u8 r = 0; - u8 g = 0; - u8 b = 0; - u8 a = 0; - } rgba; - - std::array data; - }; - - ///////////////////////////////////// - ///////////////////////////////////// - constexpr auto indexHash(const Pixel& pixel) noexcept { - return (pixel.rgba.r * 3u + pixel.rgba.g * 5u + pixel.rgba.b * 7u + pixel.rgba.a * 11u) % PIXEL_CACHE_SIZE; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto load_qoi(std::span data) noexcept -> std::expected { - const auto raw_header = data.subspan(SIZE_OF_HEADER); - const auto* header = std::bit_cast(stdr::data(raw_header)); - - const auto extent = math::uextent3 { .width = byte_swap(header->width), .height = byte_swap(header->height) }; - const auto channels = header->channels; - const auto format = CHANNELS_TO_FORMAT.at(header->channels)[header->colorspace]; - - auto pixel_cache = std::array {}; - - const auto chunks = std::span { std::bit_cast(stdr::data(data)) + SIZE_OF_HEADER, - stdr::size(data) - SIZE_OF_HEADER }; - - const auto output_size = extent.width * extent.height * channels; - - auto output = std::vector {}; - output.reserve(output_size); - - auto previous_pixel = Pixel { .rgba = { .a = 255 } }; - - auto run = 0; - - const auto diff = 4 - channels; - auto it = stdr::begin(chunks); - - const auto chunks_size = output_size - stdr::size(END_OF_FILE); - for (auto _ : range(output_size, channels)) { - const auto tag = *it; - - const auto position = as(std::distance(stdr::begin(chunks), it)); - - if (run > 0) --run; - else if (std::memcmp(&*it, std::data(END_OF_FILE), stdr::size(END_OF_FILE)) == 0) [[unlikely]] { - it = stdr::cend(chunks); - } else if (position < chunks_size) { - ++it; - if (static_cast(tag) == QOI_OPERATION::RGB) { - previous_pixel.rgba.r = *it; - previous_pixel.rgba.g = *(it + 1); - previous_pixel.rgba.b = *(it + 2); - - it += 3; - } else if (static_cast(tag) == QOI_OPERATION::RGBA) { - previous_pixel.rgba.r = *it; - previous_pixel.rgba.g = *(it + 1); - previous_pixel.rgba.b = *(it + 2); - previous_pixel.rgba.a = *(it + 3); - - it += 4; - } else { -#define CHECK(op) (tag & 0b11000000) == static_cast(op) - if (CHECK(QOI_OPERATION::INDEX)) { - const auto index = tag; - - previous_pixel = pixel_cache[index]; - } else if (CHECK(QOI_OPERATION::DIFF)) { - const auto r_diff = as(((tag >> 4) & 0x03) - 2); - const auto g_diff = as(((tag >> 2) & 0x03) - 2); - const auto b_diff = as((tag & 0x03) - 2); - - previous_pixel.rgba.r += r_diff; - previous_pixel.rgba.g += g_diff; - previous_pixel.rgba.b += b_diff; - - } else if (CHECK(QOI_OPERATION::LUMA)) { - const auto g_diff = (tag & 0x3f) - 32; - - const auto current_r = ((*it) >> 4) & 0x0f; - const auto current_b = (*it) & 0x0f; - - previous_pixel.rgba.r += as(g_diff - 8 + current_r); - previous_pixel.rgba.g += as(g_diff); - previous_pixel.rgba.b += as(g_diff - 8 + current_b); - - ++it; - } else if (CHECK(QOI_OPERATION::RUN)) { - run = (tag & 0x3f); - } -#undef CHECK - } - - auto& cached = pixel_cache[indexHash(previous_pixel)]; - cached = previous_pixel; - } - - stdr::transform(stdr::begin(previous_pixel.data), - stdr::end(previous_pixel.data) - diff, - std::back_inserter(output), - monadic::as()); - } - - auto image_data = image::Image::ImageData { - .extent = extent, - .channel_count = channels, - .bytes_per_channel = getSizeof(format), - .layers = 1u, - .faces = 1u, - .mip_levels = 1u, - .format = format, - .data = std::move(output) - - }; - - return image::Image { std::move(image_data) }; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto save_qoi(const image::Image&, const std::filesystem::path&) noexcept -> std::expected { - assert(false, "Not implemented yet !"); - return {}; - } - - ///////////////////////////////////// - ///////////////////////////////////// - [[nodiscard]] - auto save_qoi(const image::Image&) noexcept -> std::expected, image::Image::Error> { - assert(false, "Not implemented yet !"); - return {}; - } -} // namespace stormkit::image::details +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.image:qoi; + +import std; + +import frozen; + +import stormkit.core; +import stormkit.image; + +export namespace stormkit::image::details { + [[nodiscard]] + auto load_qoi(std::span data) noexcept -> std::expected; + + [[nodiscard]] + auto save_qoi(const image::Image& image, const std::filesystem::path& filepath) noexcept + -> std::expected; + + [[nodiscard]] + auto save_qoi(const image::Image& image) noexcept -> std::expected, image::Image::Error>; +} // namespace stormkit::image::details + +using namespace std::literals; + +namespace stdr = std::ranges; + +namespace stormkit::image::details { + template + using Unexpected = std::unexpected; + using Error = image::Image::Error; + using Reason = image::Image::Error::Reason; + + struct QOIHeader { + std::array magic; + u32 width; + u32 height; + u8 channels; + u8 colorspace; + }; + + namespace { + constexpr auto SIZE_OF_HEADER = 14; + + constexpr auto CHANNELS_TO_FORMAT = frozen::make_unordered_map>({ + { 3, std::array { image::Image::Format::SRGB8, image::Image::Format::RGB8_UNORM } }, + { 4, std::array { image::Image::Format::SRGBA8, image::Image::Format::RGBA8_UNORM } } + }); + + constexpr auto END_OF_FILE = into_bytes({ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }); + + constexpr auto PIXEL_CACHE_SIZE = 64u; + } // namespace + + enum class QOI_OPERATION : u8 { + RGB = 0b11111110, + RGBA = 0b11111111, + INDEX = 0b00000000, + DIFF = 0b01000000, + LUMA = 0b10000000, + RUN = 0b11000000, + }; + + union Pixel { + struct { + u8 r = 0; + u8 g = 0; + u8 b = 0; + u8 a = 0; + } rgba; + + std::array data; + }; + + ///////////////////////////////////// + ///////////////////////////////////// + constexpr auto indexHash(const Pixel& pixel) noexcept { + return (pixel.rgba.r * 3u + pixel.rgba.g * 5u + pixel.rgba.b * 7u + pixel.rgba.a * 11u) % PIXEL_CACHE_SIZE; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto load_qoi(std::span data) noexcept -> std::expected { + const auto raw_header = data.subspan(SIZE_OF_HEADER); + const auto* header = std::bit_cast(stdr::data(raw_header)); + + const auto extent = math::uextent3 { .width = byte_swap(header->width), .height = byte_swap(header->height) }; + const auto channels = header->channels; + const auto format = CHANNELS_TO_FORMAT.at(header->channels)[header->colorspace]; + + auto pixel_cache = std::array {}; + + const auto chunks = std::span { std::bit_cast(stdr::data(data)) + SIZE_OF_HEADER, + stdr::size(data) - SIZE_OF_HEADER }; + + const auto output_size = extent.width * extent.height * channels; + + auto output = std::vector {}; + output.reserve(output_size); + + auto previous_pixel = Pixel { .rgba = { .a = 255 } }; + + auto run = 0; + + const auto diff = 4 - channels; + auto it = stdr::begin(chunks); + + const auto chunks_size = output_size - stdr::size(END_OF_FILE); + for (auto _ : range(output_size, channels)) { + const auto tag = *it; + + const auto position = as(std::distance(stdr::begin(chunks), it)); + + if (run > 0) --run; + else if (std::memcmp(&*it, std::data(END_OF_FILE), stdr::size(END_OF_FILE)) == 0) [[unlikely]] { + it = stdr::cend(chunks); + } else if (position < chunks_size) { + ++it; + if (static_cast(tag) == QOI_OPERATION::RGB) { + previous_pixel.rgba.r = *it; + previous_pixel.rgba.g = *(it + 1); + previous_pixel.rgba.b = *(it + 2); + + it += 3; + } else if (static_cast(tag) == QOI_OPERATION::RGBA) { + previous_pixel.rgba.r = *it; + previous_pixel.rgba.g = *(it + 1); + previous_pixel.rgba.b = *(it + 2); + previous_pixel.rgba.a = *(it + 3); + + it += 4; + } else { +#define CHECK(op) (tag & 0b11000000) == static_cast(op) + if (CHECK(QOI_OPERATION::INDEX)) { + const auto index = tag; + + previous_pixel = pixel_cache[index]; + } else if (CHECK(QOI_OPERATION::DIFF)) { + const auto r_diff = as(((tag >> 4) & 0x03) - 2); + const auto g_diff = as(((tag >> 2) & 0x03) - 2); + const auto b_diff = as((tag & 0x03) - 2); + + previous_pixel.rgba.r += r_diff; + previous_pixel.rgba.g += g_diff; + previous_pixel.rgba.b += b_diff; + + } else if (CHECK(QOI_OPERATION::LUMA)) { + const auto g_diff = (tag & 0x3f) - 32; + + const auto current_r = ((*it) >> 4) & 0x0f; + const auto current_b = (*it) & 0x0f; + + previous_pixel.rgba.r += as(g_diff - 8 + current_r); + previous_pixel.rgba.g += as(g_diff); + previous_pixel.rgba.b += as(g_diff - 8 + current_b); + + ++it; + } else if (CHECK(QOI_OPERATION::RUN)) { + run = (tag & 0x3f); + } +#undef CHECK + } + + auto& cached = pixel_cache[indexHash(previous_pixel)]; + cached = previous_pixel; + } + + stdr::transform(stdr::begin(previous_pixel.data), + stdr::end(previous_pixel.data) - diff, + std::back_inserter(output), + monadic::as()); + } + + auto image_data = image::Image::ImageData { + .extent = extent, + .channel_count = channels, + .bytes_per_channel = getSizeof(format), + .layers = 1u, + .faces = 1u, + .mip_levels = 1u, + .format = format, + .data = std::move(output) + + }; + + return image::Image { std::move(image_data) }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto save_qoi(const image::Image&, const std::filesystem::path&) noexcept -> std::expected { + assert(false, "Not implemented yet !"); + return {}; + } + + ///////////////////////////////////// + ///////////////////////////////////// + [[nodiscard]] + auto save_qoi(const image::Image&) noexcept -> std::expected, image::Image::Error> { + assert(false, "Not implemented yet !"); + return {}; + } +} // namespace stormkit::image::details diff --git a/src/image/tga.mpp b/src/image/tga.cppm similarity index 97% rename from src/image/tga.mpp rename to src/image/tga.cppm index 279156350..d0e6cd2a3 100644 --- a/src/image/tga.mpp +++ b/src/image/tga.cppm @@ -1,55 +1,55 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -export module stormkit.image:tga; - -import std; - -import stormkit.core; - -import stormkit.image; - -export namespace stormkit::image::details { - [[nodiscard]] - auto load_tga(std::span data) noexcept -> std::expected; - - [[nodiscard]] - auto save_tga(const image::Image& image, const std::filesystem::path& filepath) noexcept - -> std::expected; - - [[nodiscard]] - auto save_tga(const image::Image& image) noexcept -> std::expected, image::Image::Error>; -} // namespace stormkit::image::details - -namespace stormkit::image::details { - template - using Unexpected = std::unexpected; - using Error = image::Image::Error; - using Reason = image::Image::Error::Reason; - - ///////////////////////////////////// - ///////////////////////////////////// - auto load_tga(std::span) noexcept -> std::expected { - assert(false, "Not implemented yet !"); - return {}; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto save_tga(const image::Image&, const std::filesystem::path&) noexcept -> std::expected { - assert(false, "Not implemented yet !"); - return {}; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto save_tga(const image::Image&) noexcept -> std::expected, image::Image::Error> { - assert(false, "Not implemented yet !"); - return {}; - } -} // namespace stormkit::image::details +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.image:tga; + +import std; + +import stormkit.core; + +import stormkit.image; + +export namespace stormkit::image::details { + [[nodiscard]] + auto load_tga(std::span data) noexcept -> std::expected; + + [[nodiscard]] + auto save_tga(const image::Image& image, const std::filesystem::path& filepath) noexcept + -> std::expected; + + [[nodiscard]] + auto save_tga(const image::Image& image) noexcept -> std::expected, image::Image::Error>; +} // namespace stormkit::image::details + +namespace stormkit::image::details { + template + using Unexpected = std::unexpected; + using Error = image::Image::Error; + using Reason = image::Image::Error::Reason; + + ///////////////////////////////////// + ///////////////////////////////////// + auto load_tga(std::span) noexcept -> std::expected { + assert(false, "Not implemented yet !"); + return {}; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto save_tga(const image::Image&, const std::filesystem::path&) noexcept -> std::expected { + assert(false, "Not implemented yet !"); + return {}; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto save_tga(const image::Image&) noexcept -> std::expected, image::Image::Error> { + assert(false, "Not implemented yet !"); + return {}; + } +} // namespace stormkit::image::details diff --git a/src/wsi/common/input_base.mpp b/src/wsi/common/input_base.cppm similarity index 100% rename from src/wsi/common/input_base.mpp rename to src/wsi/common/input_base.cppm diff --git a/src/wsi/common/monitor_base.mpp b/src/wsi/common/monitor_base.cppm similarity index 100% rename from src/wsi/common/monitor_base.mpp rename to src/wsi/common/monitor_base.cppm diff --git a/src/wsi/common/window_base.mpp b/src/wsi/common/window_base.cppm similarity index 100% rename from src/wsi/common/window_base.mpp rename to src/wsi/common/window_base.cppm diff --git a/src/wsi/linux/common/fd.mpp b/src/wsi/linux/common/fd.cppm similarity index 100% rename from src/wsi/linux/common/fd.mpp rename to src/wsi/linux/common/fd.cppm diff --git a/src/wsi/linux/common/xkb.mpp b/src/wsi/linux/common/xkb.cppm similarity index 97% rename from src/wsi/linux/common/xkb.mpp rename to src/wsi/linux/common/xkb.cppm index 8eb19e52a..d1c340568 100644 --- a/src/wsi/linux/common/xkb.mpp +++ b/src/wsi/linux/common/xkb.cppm @@ -1,206 +1,206 @@ -// Copyright (C) 2021 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -#include -#include - -export module stormkit.wsi:linux.common.xkb; - -import std; -import frozen; - -import stormkit.core; -import stormkit.log; -import stormkit.wsi; - -export namespace stormkit::wsi::linux::common { - namespace xkb { - using Keymap = RAIICapsule; - using State = RAIICapsule; - using Context = RAIICapsule; - - struct Mods { - xkb_mod_index_t shift; - xkb_mod_index_t lock; - xkb_mod_index_t control; - xkb_mod_index_t mod1; - xkb_mod_index_t mod2; - xkb_mod_index_t mod3; - xkb_mod_index_t mod4; - xkb_mod_index_t mod5; - }; - } // namespace xkb - - auto stormkit_key_to_xkb(Key key) noexcept -> xkb_keysym_t; - auto xkb_key_to_stormkit(xkb_keysym_t key) noexcept -> Key; -} // namespace stormkit::wsi::linux::common - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stdr = std::ranges; -namespace stdv = std::views; - -namespace stormkit::wsi::linux::common { - namespace { - constexpr auto SCANCODE_AS_KEY = frozen::make_map({ - { XKB_KEY_a, Key::A }, - { XKB_KEY_b, Key::B }, - { XKB_KEY_c, Key::C }, - { XKB_KEY_d, Key::D }, - { XKB_KEY_e, Key::E }, - { XKB_KEY_f, Key::F }, - { XKB_KEY_g, Key::G }, - { XKB_KEY_h, Key::H }, - { XKB_KEY_i, Key::I }, - { XKB_KEY_j, Key::J }, - { XKB_KEY_k, Key::K }, - { XKB_KEY_l, Key::L }, - { XKB_KEY_m, Key::M }, - { XKB_KEY_n, Key::N }, - { XKB_KEY_o, Key::O }, - { XKB_KEY_p, Key::P }, - { XKB_KEY_q, Key::Q }, - { XKB_KEY_r, Key::R }, - { XKB_KEY_s, Key::S }, - { XKB_KEY_t, Key::T }, - { XKB_KEY_u, Key::U }, - { XKB_KEY_v, Key::V }, - { XKB_KEY_w, Key::W }, - { XKB_KEY_x, Key::X }, - { XKB_KEY_y, Key::Y }, - { XKB_KEY_z, Key::Z }, - - { XKB_KEY_0, Key::NUM_0 }, - { XKB_KEY_1, Key::NUM_1 }, - { XKB_KEY_2, Key::NUM_2 }, - { XKB_KEY_3, Key::NUM_3 }, - { XKB_KEY_4, Key::NUM_4 }, - { XKB_KEY_5, Key::NUM_5 }, - { XKB_KEY_6, Key::NUM_6 }, - { XKB_KEY_7, Key::NUM_7 }, - { XKB_KEY_8, Key::NUM_8 }, - { XKB_KEY_9, Key::NUM_9 }, - - { XKB_KEY_Left, Key::LEFT }, - { XKB_KEY_Right, Key::RIGHT }, - { XKB_KEY_Up, Key::UP }, - { XKB_KEY_Down, Key::DOWN }, - - { XKB_KEY_Control_L, Key::L_CONTROL }, - { XKB_KEY_Shift_L, Key::L_SHIFT }, - { XKB_KEY_Alt_L, Key::L_ALT }, - { XKB_KEY_Super_L, Key::L_META }, - { XKB_KEY_Control_R, Key::R_CONTROL }, - { XKB_KEY_Shift_R, Key::R_SHIFT }, - { XKB_KEY_Alt_R, Key::R_ALT }, - { XKB_KEY_Super_R, Key::R_META }, - - { XKB_KEY_Escape, Key::ESCAPE }, - { XKB_KEY_Tab, Key::TAB }, - { XKB_KEY_Menu, Key::MENU }, - - { XKB_KEY_apostrophe, Key::QUOTE }, - { XKB_KEY_backslash, Key::BACK_SLASH }, - { XKB_KEY_comma, Key::COMMA }, - { XKB_KEY_equal, Key::EQUAL }, - - { XKB_KEY_grave, Key::GRAVE_ACCENT }, - { XKB_KEY_bracketleft, Key::L_BRACKET }, - { XKB_KEY_minus, Key::MINUS }, - { XKB_KEY_period, Key::PERIOD }, - { XKB_KEY_bracketright, Key::R_BRACKET }, - { XKB_KEY_semicolon, Key::SEMI_COLON }, - { XKB_KEY_slash, Key::SLASH }, - - { XKB_KEY_less, Key::ISO }, - - { XKB_KEY_BackSpace, Key::BACK_SPACE }, - { XKB_KEY_Caps_Lock, Key::CAPS_LOCK }, - { XKB_KEY_Return, Key::ENTER }, - { XKB_KEY_space, Key::SPACE }, - - { XKB_KEY_F1, Key::F1 }, - { XKB_KEY_F2, Key::F2 }, - { XKB_KEY_F3, Key::F3 }, - { XKB_KEY_F4, Key::F4 }, - { XKB_KEY_F5, Key::F5 }, - { XKB_KEY_F6, Key::F6 }, - { XKB_KEY_F7, Key::F7 }, - { XKB_KEY_F8, Key::F8 }, - { XKB_KEY_F9, Key::F9 }, - { XKB_KEY_F10, Key::F10 }, - { XKB_KEY_F11, Key::F11 }, - { XKB_KEY_F12, Key::F12 }, - { XKB_KEY_F14, Key::F14 }, - { XKB_KEY_F15, Key::F15 }, - { XKB_KEY_F16, Key::F16 }, - { XKB_KEY_F17, Key::F17 }, - { XKB_KEY_F18, Key::F18 }, - { XKB_KEY_F19, Key::F19 }, - { XKB_KEY_F20, Key::F20 }, - - { XKB_KEY_Print, Key::PRINT_SCREEN }, - - { XKB_KEY_Insert, Key::INSERT }, - { XKB_KEY_Delete, Key::DELETE }, - { XKB_KEY_Home, Key::HOME }, - { XKB_KEY_End, Key::END }, - { XKB_KEY_Page_Down, Key::PAGE_DOWN }, - { XKB_KEY_Page_Up, Key::PAGE_UP }, - - { XKB_KEY_Num_Lock, Key::NUMPAD_LOCK }, - { XKB_KEY_KP_Add, Key::NUMPAD_ADD }, - { XKB_KEY_KP_Decimal, Key::NUMPAD_DECIMAL }, - { XKB_KEY_KP_Divide, Key::NUMPAD_DIVIDE }, - { XKB_KEY_KP_Enter, Key::NUMPAD_ENTER }, - { XKB_KEY_KP_Equal, Key::NUMPAD_EQUAL }, - { XKB_KEY_KP_Multiply, Key::NUMPAD_MULTIPLY }, - { XKB_KEY_KP_Subtract, Key::NUMPAD_SUBTRACT }, - { XKB_KEY_KP_0, Key::NUMPAD_0 }, - { XKB_KEY_KP_1, Key::NUMPAD_1 }, - { XKB_KEY_KP_2, Key::NUMPAD_2 }, - { XKB_KEY_KP_3, Key::NUMPAD_3 }, - { XKB_KEY_KP_4, Key::NUMPAD_4 }, - { XKB_KEY_KP_5, Key::NUMPAD_5 }, - { XKB_KEY_KP_6, Key::NUMPAD_6 }, - { XKB_KEY_KP_7, Key::NUMPAD_7 }, - { XKB_KEY_KP_8, Key::NUMPAD_8 }, - { XKB_KEY_KP_9, Key::NUMPAD_9 }, - }); - - constexpr auto KEY_AS_SCANCODE = [] static noexcept -> decltype(auto) { - auto out = std::array, 111> {}; - auto i = 0_usize; - for (const auto& [key, value] : SCANCODE_AS_KEY) out[i++] = std::make_pair(value, key); - - return frozen::make_map(out); - }(); - } // namespace - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_CONST - inline auto xkb_key_to_stormkit(xkb_keysym_t scancode) noexcept -> Key { - const auto it = SCANCODE_AS_KEY.find(scancode); - if (it == stdr::cend(SCANCODE_AS_KEY)) return Key::UNKNOWN; - return it->second; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_CONST - inline auto stormkit_key_to_xkb(Key key) noexcept -> xkb_keysym_t { - ENSURES(key != Key::UNKNOWN); - const auto it = KEY_AS_SCANCODE.find(key); - return it->second; - } -} // namespace stormkit::wsi::linux::common - -#undef STORMKIT_XKB_SCOPED +// Copyright (C) 2021 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include +#include + +export module stormkit.wsi:linux.common.xkb; + +import std; +import frozen; + +import stormkit.core; +import stormkit.log; +import stormkit.wsi; + +export namespace stormkit::wsi::linux::common { + namespace xkb { + using Keymap = RAIICapsule; + using State = RAIICapsule; + using Context = RAIICapsule; + + struct Mods { + xkb_mod_index_t shift; + xkb_mod_index_t lock; + xkb_mod_index_t control; + xkb_mod_index_t mod1; + xkb_mod_index_t mod2; + xkb_mod_index_t mod3; + xkb_mod_index_t mod4; + xkb_mod_index_t mod5; + }; + } // namespace xkb + + auto stormkit_key_to_xkb(Key key) noexcept -> xkb_keysym_t; + auto xkb_key_to_stormkit(xkb_keysym_t key) noexcept -> Key; +} // namespace stormkit::wsi::linux::common + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stdr = std::ranges; +namespace stdv = std::views; + +namespace stormkit::wsi::linux::common { + namespace { + constexpr auto SCANCODE_AS_KEY = frozen::make_map({ + { XKB_KEY_a, Key::A }, + { XKB_KEY_b, Key::B }, + { XKB_KEY_c, Key::C }, + { XKB_KEY_d, Key::D }, + { XKB_KEY_e, Key::E }, + { XKB_KEY_f, Key::F }, + { XKB_KEY_g, Key::G }, + { XKB_KEY_h, Key::H }, + { XKB_KEY_i, Key::I }, + { XKB_KEY_j, Key::J }, + { XKB_KEY_k, Key::K }, + { XKB_KEY_l, Key::L }, + { XKB_KEY_m, Key::M }, + { XKB_KEY_n, Key::N }, + { XKB_KEY_o, Key::O }, + { XKB_KEY_p, Key::P }, + { XKB_KEY_q, Key::Q }, + { XKB_KEY_r, Key::R }, + { XKB_KEY_s, Key::S }, + { XKB_KEY_t, Key::T }, + { XKB_KEY_u, Key::U }, + { XKB_KEY_v, Key::V }, + { XKB_KEY_w, Key::W }, + { XKB_KEY_x, Key::X }, + { XKB_KEY_y, Key::Y }, + { XKB_KEY_z, Key::Z }, + + { XKB_KEY_0, Key::NUM_0 }, + { XKB_KEY_1, Key::NUM_1 }, + { XKB_KEY_2, Key::NUM_2 }, + { XKB_KEY_3, Key::NUM_3 }, + { XKB_KEY_4, Key::NUM_4 }, + { XKB_KEY_5, Key::NUM_5 }, + { XKB_KEY_6, Key::NUM_6 }, + { XKB_KEY_7, Key::NUM_7 }, + { XKB_KEY_8, Key::NUM_8 }, + { XKB_KEY_9, Key::NUM_9 }, + + { XKB_KEY_Left, Key::LEFT }, + { XKB_KEY_Right, Key::RIGHT }, + { XKB_KEY_Up, Key::UP }, + { XKB_KEY_Down, Key::DOWN }, + + { XKB_KEY_Control_L, Key::L_CONTROL }, + { XKB_KEY_Shift_L, Key::L_SHIFT }, + { XKB_KEY_Alt_L, Key::L_ALT }, + { XKB_KEY_Super_L, Key::L_META }, + { XKB_KEY_Control_R, Key::R_CONTROL }, + { XKB_KEY_Shift_R, Key::R_SHIFT }, + { XKB_KEY_Alt_R, Key::R_ALT }, + { XKB_KEY_Super_R, Key::R_META }, + + { XKB_KEY_Escape, Key::ESCAPE }, + { XKB_KEY_Tab, Key::TAB }, + { XKB_KEY_Menu, Key::MENU }, + + { XKB_KEY_apostrophe, Key::QUOTE }, + { XKB_KEY_backslash, Key::BACK_SLASH }, + { XKB_KEY_comma, Key::COMMA }, + { XKB_KEY_equal, Key::EQUAL }, + + { XKB_KEY_grave, Key::GRAVE_ACCENT }, + { XKB_KEY_bracketleft, Key::L_BRACKET }, + { XKB_KEY_minus, Key::MINUS }, + { XKB_KEY_period, Key::PERIOD }, + { XKB_KEY_bracketright, Key::R_BRACKET }, + { XKB_KEY_semicolon, Key::SEMI_COLON }, + { XKB_KEY_slash, Key::SLASH }, + + { XKB_KEY_less, Key::ISO }, + + { XKB_KEY_BackSpace, Key::BACK_SPACE }, + { XKB_KEY_Caps_Lock, Key::CAPS_LOCK }, + { XKB_KEY_Return, Key::ENTER }, + { XKB_KEY_space, Key::SPACE }, + + { XKB_KEY_F1, Key::F1 }, + { XKB_KEY_F2, Key::F2 }, + { XKB_KEY_F3, Key::F3 }, + { XKB_KEY_F4, Key::F4 }, + { XKB_KEY_F5, Key::F5 }, + { XKB_KEY_F6, Key::F6 }, + { XKB_KEY_F7, Key::F7 }, + { XKB_KEY_F8, Key::F8 }, + { XKB_KEY_F9, Key::F9 }, + { XKB_KEY_F10, Key::F10 }, + { XKB_KEY_F11, Key::F11 }, + { XKB_KEY_F12, Key::F12 }, + { XKB_KEY_F14, Key::F14 }, + { XKB_KEY_F15, Key::F15 }, + { XKB_KEY_F16, Key::F16 }, + { XKB_KEY_F17, Key::F17 }, + { XKB_KEY_F18, Key::F18 }, + { XKB_KEY_F19, Key::F19 }, + { XKB_KEY_F20, Key::F20 }, + + { XKB_KEY_Print, Key::PRINT_SCREEN }, + + { XKB_KEY_Insert, Key::INSERT }, + { XKB_KEY_Delete, Key::DELETE }, + { XKB_KEY_Home, Key::HOME }, + { XKB_KEY_End, Key::END }, + { XKB_KEY_Page_Down, Key::PAGE_DOWN }, + { XKB_KEY_Page_Up, Key::PAGE_UP }, + + { XKB_KEY_Num_Lock, Key::NUMPAD_LOCK }, + { XKB_KEY_KP_Add, Key::NUMPAD_ADD }, + { XKB_KEY_KP_Decimal, Key::NUMPAD_DECIMAL }, + { XKB_KEY_KP_Divide, Key::NUMPAD_DIVIDE }, + { XKB_KEY_KP_Enter, Key::NUMPAD_ENTER }, + { XKB_KEY_KP_Equal, Key::NUMPAD_EQUAL }, + { XKB_KEY_KP_Multiply, Key::NUMPAD_MULTIPLY }, + { XKB_KEY_KP_Subtract, Key::NUMPAD_SUBTRACT }, + { XKB_KEY_KP_0, Key::NUMPAD_0 }, + { XKB_KEY_KP_1, Key::NUMPAD_1 }, + { XKB_KEY_KP_2, Key::NUMPAD_2 }, + { XKB_KEY_KP_3, Key::NUMPAD_3 }, + { XKB_KEY_KP_4, Key::NUMPAD_4 }, + { XKB_KEY_KP_5, Key::NUMPAD_5 }, + { XKB_KEY_KP_6, Key::NUMPAD_6 }, + { XKB_KEY_KP_7, Key::NUMPAD_7 }, + { XKB_KEY_KP_8, Key::NUMPAD_8 }, + { XKB_KEY_KP_9, Key::NUMPAD_9 }, + }); + + constexpr auto KEY_AS_SCANCODE = [] static noexcept -> decltype(auto) { + auto out = std::array, 111> {}; + auto i = 0_usize; + for (const auto& [key, value] : SCANCODE_AS_KEY) out[i++] = std::make_pair(value, key); + + return frozen::make_map(out); + }(); + } // namespace + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_CONST + inline auto xkb_key_to_stormkit(xkb_keysym_t scancode) noexcept -> Key { + const auto it = SCANCODE_AS_KEY.find(scancode); + if (it == stdr::cend(SCANCODE_AS_KEY)) return Key::UNKNOWN; + return it->second; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_CONST + inline auto stormkit_key_to_xkb(Key key) noexcept -> xkb_keysym_t { + ENSURES(key != Key::UNKNOWN); + const auto it = KEY_AS_SCANCODE.find(key); + return it->second; + } +} // namespace stormkit::wsi::linux::common + +#undef STORMKIT_XKB_SCOPED diff --git a/src/wsi/linux/monitor.mpp b/src/wsi/linux/monitor.cppm similarity index 100% rename from src/wsi/linux/monitor.mpp rename to src/wsi/linux/monitor.cppm diff --git a/src/wsi/linux/mouse.mpp b/src/wsi/linux/mouse.cppm similarity index 100% rename from src/wsi/linux/mouse.mpp rename to src/wsi/linux/mouse.cppm diff --git a/src/wsi/linux/wayland/context.mpp b/src/wsi/linux/wayland/context.cppm similarity index 100% rename from src/wsi/linux/wayland/context.mpp rename to src/wsi/linux/wayland/context.cppm diff --git a/src/wsi/linux/wayland/inputs.mpp b/src/wsi/linux/wayland/inputs.cppm similarity index 100% rename from src/wsi/linux/wayland/inputs.mpp rename to src/wsi/linux/wayland/inputs.cppm diff --git a/src/wsi/linux/wayland/log.mpp b/src/wsi/linux/wayland/log.cppm similarity index 96% rename from src/wsi/linux/wayland/log.mpp rename to src/wsi/linux/wayland/log.cppm index 51602908f..fa340748f 100644 --- a/src/wsi/linux/wayland/log.mpp +++ b/src/wsi/linux/wayland/log.cppm @@ -1,18 +1,18 @@ -// Copyright (C) 2021 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -export module stormkit.wsi:linux.wayland.log; - -import std; - -import stormkit.core; -import stormkit.log; - -export namespace stormkit::wsi::linux::wayland { - IN_MODULE_LOGGER("StormKit.Wsi.Linux.Wayland") -} // namespace stormkit::wsi::linux::wayland +// Copyright (C) 2021 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.wsi:linux.wayland.log; + +import std; + +import stormkit.core; +import stormkit.log; + +export namespace stormkit::wsi::linux::wayland { + IN_MODULE_LOGGER("StormKit.Wsi.Linux.Wayland") +} // namespace stormkit::wsi::linux::wayland diff --git a/src/wsi/linux/wayland/monitor.mpp b/src/wsi/linux/wayland/monitor.cppm similarity index 100% rename from src/wsi/linux/wayland/monitor.mpp rename to src/wsi/linux/wayland/monitor.cppm diff --git a/src/wsi/linux/wayland/wayland.mpp b/src/wsi/linux/wayland/wayland.cppm similarity index 98% rename from src/wsi/linux/wayland/wayland.mpp rename to src/wsi/linux/wayland/wayland.cppm index 9b851888a..6dc0b8898 100644 --- a/src/wsi/linux/wayland/wayland.mpp +++ b/src/wsi/linux/wayland/wayland.cppm @@ -1,119 +1,119 @@ -// Copyright (C) 2021 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -export module stormkit.wsi:linux.wayland; - -import std; - -import stormkit.core; - -import stormkit.wsi; - -export namespace stormkit::wsi::linux::wayland::wl { - using Display = stormkit::RAIICapsule; - using Registry = stormkit:: - RAIICapsule; - using Compositor = stormkit:: - RAIICapsule; - using Output = stormkit::RAIICapsule; - using XDGWmBase = stormkit::RAIICapsule; - using XDGDecorationManager = stormkit::RAIICapsule; - using Buffer = stormkit::RAIICapsule; - using Keyboard = stormkit::RAIICapsule; - using Pointer = stormkit::RAIICapsule; - using Touch = stormkit::RAIICapsule; - using Shm = stormkit::RAIICapsule; - using Seat = stormkit::RAIICapsule; - using SinglePixelBufferManager = stormkit::RAIICapsule; - using Viewporter = stormkit:: - RAIICapsule; - using ContentTypeManager = stormkit::RAIICapsule; - - using ShmPool = stormkit::RAIICapsule; - using CursorTheme = stormkit:: - RAIICapsule; - using CursorShapeManager = stormkit::RAIICapsule; - using CursorShapeDevice = stormkit::RAIICapsule; - using PointerConstraints = stormkit::RAIICapsule; - using PointerWarp = stormkit:: - RAIICapsule; - using RelativePointerManager = stormkit::RAIICapsule; - - using Surface = stormkit:: - RAIICapsule; - using XDGSurface = stormkit:: - RAIICapsule; - using XDGTopLevel = stormkit:: - RAIICapsule; - using XDGTopLevelDecoration = stormkit::RAIICapsule; - using LockedPointer = stormkit::RAIICapsule; - using ConfinedPointer = stormkit::RAIICapsule; - using RelativePointer = stormkit::RAIICapsule; - using Viewport = stormkit:: - RAIICapsule; - using ContentType = stormkit::RAIICapsule; -} // namespace stormkit::wsi::linux::wayland::wl +// Copyright (C) 2021 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +export module stormkit.wsi:linux.wayland; + +import std; + +import stormkit.core; + +import stormkit.wsi; + +export namespace stormkit::wsi::linux::wayland::wl { + using Display = stormkit::RAIICapsule; + using Registry = stormkit:: + RAIICapsule; + using Compositor = stormkit:: + RAIICapsule; + using Output = stormkit::RAIICapsule; + using XDGWmBase = stormkit::RAIICapsule; + using XDGDecorationManager = stormkit::RAIICapsule; + using Buffer = stormkit::RAIICapsule; + using Keyboard = stormkit::RAIICapsule; + using Pointer = stormkit::RAIICapsule; + using Touch = stormkit::RAIICapsule; + using Shm = stormkit::RAIICapsule; + using Seat = stormkit::RAIICapsule; + using SinglePixelBufferManager = stormkit::RAIICapsule; + using Viewporter = stormkit:: + RAIICapsule; + using ContentTypeManager = stormkit::RAIICapsule; + + using ShmPool = stormkit::RAIICapsule; + using CursorTheme = stormkit:: + RAIICapsule; + using CursorShapeManager = stormkit::RAIICapsule; + using CursorShapeDevice = stormkit::RAIICapsule; + using PointerConstraints = stormkit::RAIICapsule; + using PointerWarp = stormkit:: + RAIICapsule; + using RelativePointerManager = stormkit::RAIICapsule; + + using Surface = stormkit:: + RAIICapsule; + using XDGSurface = stormkit:: + RAIICapsule; + using XDGTopLevel = stormkit:: + RAIICapsule; + using XDGTopLevelDecoration = stormkit::RAIICapsule; + using LockedPointer = stormkit::RAIICapsule; + using ConfinedPointer = stormkit::RAIICapsule; + using RelativePointer = stormkit::RAIICapsule; + using Viewport = stormkit:: + RAIICapsule; + using ContentType = stormkit::RAIICapsule; +} // namespace stormkit::wsi::linux::wayland::wl diff --git a/src/wsi/linux/wayland/window.mpp b/src/wsi/linux/wayland/window.cppm similarity index 97% rename from src/wsi/linux/wayland/window.mpp rename to src/wsi/linux/wayland/window.cppm index 739d184ff..97bf79191 100644 --- a/src/wsi/linux/wayland/window.mpp +++ b/src/wsi/linux/wayland/window.cppm @@ -1,153 +1,153 @@ -// Copyright (C) 2021 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include -#include - -#include - -#include -#include -#include - -export module stormkit.wsi:linux.wayland.window; - -import std; - -import stormkit.core; -import stormkit.wsi; - -import :common.window_base; - -import :linux.wayland; -import :linux.wayland.context; - -export { - namespace stormkit::wsi::linux::wayland { - class Window: public stormkit::wsi::common::WindowBase { - public: - struct Handles { - wl_display* display; - wl_surface* surface; - }; - - Window() noexcept; - ~Window() noexcept; - - Window(const Window&) noexcept = delete; - auto operator=(const Window&) noexcept -> Window& = delete; - - Window(Window&&) noexcept; - auto operator=(Window&&) noexcept -> Window&; - - auto open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> void; - auto close() noexcept -> void; - - auto handle_events() noexcept -> void; - - auto clear(const rgbcolor& color) noexcept -> void; - auto fill_framebuffer(std::span> colors) noexcept -> void; - - auto set_title(std::string title) noexcept -> void; - auto set_extent(const math::uextent2& extent) noexcept -> void; - auto set_fullscreen(bool fullscreen) noexcept -> void; - - auto confine_mouse(bool confined, u8 id) noexcept -> void; - [[nodiscard]] - auto is_mouse_confined(u8 id) const noexcept -> bool; - - auto lock_mouse(bool locked, u8 id) noexcept -> void; - [[nodiscard]] - auto is_mouse_locked(u8 id) const noexcept -> bool; - - auto hide_mouse(bool hidden, u8 id) noexcept -> void; - [[nodiscard]] - auto is_mouse_hidden(u8 id) const noexcept -> bool; - - auto set_relative_mouse(bool enabled, u8 id) noexcept -> void; - [[nodiscard]] - auto is_mouse_relative(u8 id) const noexcept -> bool; - - auto set_key_repeat(bool enabled, u8 id) noexcept -> void; - [[nodiscard]] - auto is_key_repeat_enabled(u8 id) const noexcept -> bool; - - auto show_virtual_keyboard(bool visible) noexcept -> void; - [[nodiscard]] - auto is_virtual_keyboard_visible() const noexcept -> bool; - - auto set_mouse_position(const math::ivec2& position, u8 id) noexcept -> void; - - [[nodiscard]] - auto native_handle() const noexcept -> NativeHandle; - - auto handle_xdg_surface_configure(u32) noexcept -> void; - auto handle_xdg_surface_close() noexcept -> void; - - auto handle_xdg_top_level_configure(u32, u32, std::span) noexcept -> void; - auto handle_surface_enter(wl_surface*, wl_output*) noexcept -> void; - - auto handle_keyboard_key(Key, char, bool) noexcept -> void; - - auto handle_pointer_enter(wl_pointer*, wl::PointerState&) noexcept -> void; - auto handle_pointer_leave() noexcept -> void; - auto handle_pointer_motion(wl_fixed_t, wl_fixed_t) noexcept -> void; - auto handle_pointer_button(u32, u32, wl_fixed_t, wl_fixed_t) noexcept -> void; - - private: - auto reallocate_pixel_buffer() noexcept -> void; - - auto hide_mouse(bool hidden, wl_pointer*, wl::PointerState&) noexcept -> void; - auto set_cursor(std::string_view, wl_pointer*, wl::PointerState&) noexcept -> void; - - auto handle_key_repeat() noexcept -> void; - - u8 m_scale = 2u; - - bool m_configured = false; - bool m_scale_content = false; - WindowFlag m_flags; - wl_output* m_current_output = nullptr; - - std::string m_title; - - Handles m_handles; - - wl::Surface m_surface = wl::Surface::empty(); - wl::XDGSurface m_xdg_surface = wl::XDGSurface::empty(); - wl::XDGTopLevel m_xdg_top_level = wl::XDGTopLevel::empty(); - wl::XDGTopLevelDecoration m_xdg_top_level_decoration = wl::XDGTopLevelDecoration::empty(); - wl::ContentType m_content_type = wl::ContentType::empty(); - wl::Viewport m_viewport = wl::Viewport::empty(); - - DeferInit m_shm_buffer; - wl::ShmPool m_shm_pool = wl::ShmPool::empty(); - wl::Buffer m_pixel_buffer = wl::Buffer::empty(); - - struct { - bool restored = false; - bool activated = false; - bool suspended = false; - bool fullscreen = false; - - std::optional resizing; - } m_pending_state; - }; - } // namespace stormkit::wsi::linux::wayland -} - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit::wsi::linux::wayland { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_CONST - inline auto Window::is_virtual_keyboard_visible() const noexcept -> bool { - return false; - } -} // namespace stormkit::wsi::linux::wayland +// Copyright (C) 2021 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include +#include + +#include + +#include +#include +#include + +export module stormkit.wsi:linux.wayland.window; + +import std; + +import stormkit.core; +import stormkit.wsi; + +import :common.window_base; + +import :linux.wayland; +import :linux.wayland.context; + +export { + namespace stormkit::wsi::linux::wayland { + class Window: public stormkit::wsi::common::WindowBase { + public: + struct Handles { + wl_display* display; + wl_surface* surface; + }; + + Window() noexcept; + ~Window() noexcept; + + Window(const Window&) noexcept = delete; + auto operator=(const Window&) noexcept -> Window& = delete; + + Window(Window&&) noexcept; + auto operator=(Window&&) noexcept -> Window&; + + auto open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> void; + auto close() noexcept -> void; + + auto handle_events() noexcept -> void; + + auto clear(const rgbcolor& color) noexcept -> void; + auto fill_framebuffer(std::span> colors) noexcept -> void; + + auto set_title(std::string title) noexcept -> void; + auto set_extent(const math::uextent2& extent) noexcept -> void; + auto set_fullscreen(bool fullscreen) noexcept -> void; + + auto confine_mouse(bool confined, u8 id) noexcept -> void; + [[nodiscard]] + auto is_mouse_confined(u8 id) const noexcept -> bool; + + auto lock_mouse(bool locked, u8 id) noexcept -> void; + [[nodiscard]] + auto is_mouse_locked(u8 id) const noexcept -> bool; + + auto hide_mouse(bool hidden, u8 id) noexcept -> void; + [[nodiscard]] + auto is_mouse_hidden(u8 id) const noexcept -> bool; + + auto set_relative_mouse(bool enabled, u8 id) noexcept -> void; + [[nodiscard]] + auto is_mouse_relative(u8 id) const noexcept -> bool; + + auto set_key_repeat(bool enabled, u8 id) noexcept -> void; + [[nodiscard]] + auto is_key_repeat_enabled(u8 id) const noexcept -> bool; + + auto show_virtual_keyboard(bool visible) noexcept -> void; + [[nodiscard]] + auto is_virtual_keyboard_visible() const noexcept -> bool; + + auto set_mouse_position(const math::ivec2& position, u8 id) noexcept -> void; + + [[nodiscard]] + auto native_handle() const noexcept -> NativeHandle; + + auto handle_xdg_surface_configure(u32) noexcept -> void; + auto handle_xdg_surface_close() noexcept -> void; + + auto handle_xdg_top_level_configure(u32, u32, std::span) noexcept -> void; + auto handle_surface_enter(wl_surface*, wl_output*) noexcept -> void; + + auto handle_keyboard_key(Key, char, bool) noexcept -> void; + + auto handle_pointer_enter(wl_pointer*, wl::PointerState&) noexcept -> void; + auto handle_pointer_leave() noexcept -> void; + auto handle_pointer_motion(wl_fixed_t, wl_fixed_t) noexcept -> void; + auto handle_pointer_button(u32, u32, wl_fixed_t, wl_fixed_t) noexcept -> void; + + private: + auto reallocate_pixel_buffer() noexcept -> void; + + auto hide_mouse(bool hidden, wl_pointer*, wl::PointerState&) noexcept -> void; + auto set_cursor(std::string_view, wl_pointer*, wl::PointerState&) noexcept -> void; + + auto handle_key_repeat() noexcept -> void; + + u8 m_scale = 2u; + + bool m_configured = false; + bool m_scale_content = false; + WindowFlag m_flags; + wl_output* m_current_output = nullptr; + + std::string m_title; + + Handles m_handles; + + wl::Surface m_surface = wl::Surface::empty(); + wl::XDGSurface m_xdg_surface = wl::XDGSurface::empty(); + wl::XDGTopLevel m_xdg_top_level = wl::XDGTopLevel::empty(); + wl::XDGTopLevelDecoration m_xdg_top_level_decoration = wl::XDGTopLevelDecoration::empty(); + wl::ContentType m_content_type = wl::ContentType::empty(); + wl::Viewport m_viewport = wl::Viewport::empty(); + + DeferInit m_shm_buffer; + wl::ShmPool m_shm_pool = wl::ShmPool::empty(); + wl::Buffer m_pixel_buffer = wl::Buffer::empty(); + + struct { + bool restored = false; + bool activated = false; + bool suspended = false; + bool fullscreen = false; + + std::optional resizing; + } m_pending_state; + }; + } // namespace stormkit::wsi::linux::wayland +} + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit::wsi::linux::wayland { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_CONST + inline auto Window::is_virtual_keyboard_visible() const noexcept -> bool { + return false; + } +} // namespace stormkit::wsi::linux::wayland diff --git a/src/wsi/linux/window.mpp b/src/wsi/linux/window.cppm similarity index 97% rename from src/wsi/linux/window.mpp rename to src/wsi/linux/window.cppm index a4b7bc87f..3f0fd87a1 100644 --- a/src/wsi/linux/window.mpp +++ b/src/wsi/linux/window.cppm @@ -1,637 +1,637 @@ -// Copyright (C) 2021 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -export module stormkit.wsi:linux.window; - -import std; - -import stormkit.core; -import stormkit.wsi; - -import :common.window_base; -import :linux.x11.window; -import :linux.wayland.window; - -export namespace stormkit::wsi::linux { - class Window { - using BackendWindow = std::variant; - - WM m_wm; - - BackendWindow m_impl = std::monostate {}; - - public: - explicit Window(WM wm) noexcept; - ~Window() noexcept; - - Window(const Window&) noexcept = delete; - auto operator=(const Window&) noexcept -> Window& = delete; - - Window(Window&&) noexcept; - auto operator=(Window&&) noexcept -> Window&; - - auto open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> void; - auto close() noexcept -> void; - - [[nodiscard]] - auto is_open() const noexcept -> bool; - - [[nodiscard]] - auto visible() const noexcept -> bool; - - [[nodiscard]] - auto current_monitor() const noexcept -> const Monitor&; - - auto handle_events() noexcept -> void; - - auto clear(const rgbcolor& color) noexcept -> void; - auto fill_framebuffer(std::span> colors) noexcept -> void; - - auto set_title(std::string title) noexcept -> void; - [[nodiscard]] - auto title() const noexcept -> const std::string&; - - auto set_extent(const math::uextent2& extent) noexcept -> void; - [[nodiscard]] - auto extent() const noexcept -> const math::uextent2&; - - auto set_fullscreen(bool fullscreen) noexcept -> void; - [[nodiscard]] - auto fullscreen() const noexcept -> bool; - - auto confine_mouse(bool confined = true, u8 mouse_id = 0) noexcept -> void; - [[nodiscard]] - auto is_mouse_confined(u8 mouse_id) const noexcept -> bool; - - auto lock_mouse(bool locked = true, u8 mouse_id = 0) noexcept -> void; - [[nodiscard]] - auto is_mouse_locked(u8 mouse_id) const noexcept -> bool; - - auto hide_mouse(bool hidden = true, u8 mouse_id = 0) noexcept -> void; - [[nodiscard]] - auto is_mouse_hidden(u8 mouse_id) const noexcept -> bool; - - auto set_relative_mouse(bool enabled, u8 mouse_id = 0) noexcept -> void; - [[nodiscard]] - auto is_mouse_relative(u8 mouse_id = 0) const noexcept -> bool; - - auto set_key_repeat(bool enabled, u8 keyboard_id = 0) noexcept -> void; - [[nodiscard]] - auto is_key_repeat_enabled(u8 keyboard_id = 0) const noexcept -> bool; - - auto show_virtual_keyboard(bool visible = true) noexcept -> void; - [[nodiscard]] - auto is_virtual_keyboard_visible() const noexcept -> bool; - - auto set_mouse_position(const math::ivec2& position, u8 mouse_id = 0) noexcept -> void; - - [[nodiscard]] - auto native_handle() const noexcept -> NativeHandle; - - auto set_closed_event(ClosedEventFunc&& func) noexcept -> void; - auto set_monitor_changed_event(MonitorChangedEventFunc&& func) noexcept -> void; - auto set_resized_event(ResizedEventFunc&& func) noexcept -> void; - auto set_restored_event(RestoredEventFunc&& func) noexcept -> void; - auto set_minimized_event(MinimizedEventFunc&& func) noexcept -> void; - auto set_key_down_event(KeyDownEventFunc&& func) noexcept -> void; - auto set_key_up_event(KeyUpEventFunc&& func) noexcept -> void; - auto set_mouse_button_down_event(MouseButtonDownEventFunc&& func) noexcept -> void; - auto set_mouse_button_up_event(MouseButtonUpEventFunc&& func) noexcept -> void; - auto set_mouse_moved_event(MouseMovedEventFunc&& func) noexcept -> void; - auto set_deactivate_event(DeactivateEventFunc&& func) noexcept -> void; - auto set_activate_event(ActivateEventFunc&& func) noexcept -> void; - }; -} // namespace stormkit::wsi::linux - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit::wsi::linux { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Window::Window(WM wm) noexcept - : m_wm { wm } { - if (m_wm == WM::X11) m_impl = x11::Window {}; - else if (m_wm == WM::WAYLAND) - m_impl = wayland::Window {}; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Window::~Window() noexcept - = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Window::Window(Window&&) noexcept - = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::operator=(Window&&) noexcept -> Window& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::open(std::string title, const math::uextent2& extent, WindowFlag flags) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).open(std::move(title), extent, flags); break; - case WM::WAYLAND: as(m_impl).open(std::move(title), extent, flags); break; - - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::close() noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).close(); break; - case WM::WAYLAND: as(m_impl).close(); break; - - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto Window::is_open() const noexcept -> bool { - switch (m_wm) { - case WM::X11: return as(m_impl).is_open(); - case WM::WAYLAND: return as(m_impl).is_open(); - - default: break; - } - - std::unreachable(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto Window::visible() const noexcept -> bool { - switch (m_wm) { - case WM::X11: return as(m_impl).visible(); - case WM::WAYLAND: return as(m_impl).visible(); - - default: break; - } - - std::unreachable(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto Window::current_monitor() const noexcept -> const Monitor& { - switch (m_wm) { - case WM::X11: return as(m_impl).current_monitor(); - case WM::WAYLAND: return as(m_impl).current_monitor(); - - default: break; - } - - std::unreachable(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::handle_events() noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).handle_events(); break; - case WM::WAYLAND: as(m_impl).handle_events(); break; - - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::clear(const rgbcolor& color) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).clear(color); break; - case WM::WAYLAND: as(m_impl).clear(color); break; - - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::fill_framebuffer(std::span> colors) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).fill_framebuffer(colors); break; - case WM::WAYLAND: as(m_impl).fill_framebuffer(colors); break; - - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::set_title(std::string title) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).set_title(std::move(title)); break; - case WM::WAYLAND: as(m_impl).set_title(std::move(title)); break; - - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto Window::title() const noexcept -> const std::string& { - switch (m_wm) { - case WM::X11: return as(m_impl).title(); - case WM::WAYLAND: return as(m_impl).title(); - - default: break; - } - - std::unreachable(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::set_extent(const math::uextent2& extent) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).set_extent(extent); break; - case WM::WAYLAND: as(m_impl).set_extent(extent); break; - - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto Window::extent() const noexcept -> const math::uextent2& { - switch (m_wm) { - case WM::X11: return as(m_impl).extent(); - case WM::WAYLAND: return as(m_impl).extent(); - - default: break; - } - - std::unreachable(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::set_fullscreen(bool enabled) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).set_fullscreen(enabled); break; - case WM::WAYLAND: as(m_impl).set_fullscreen(enabled); break; - - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto Window::fullscreen() const noexcept -> bool { - switch (m_wm) { - case WM::X11: return as(m_impl).fullscreen(); - case WM::WAYLAND: return as(m_impl).fullscreen(); - - default: break; - } - - std::unreachable(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::confine_mouse(bool confined, u8 mouse_id) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).confine_mouse(confined, mouse_id); break; - case WM::WAYLAND: as(m_impl).confine_mouse(confined, mouse_id); break; - - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto Window::is_mouse_confined(u8 mouse_id) const noexcept -> bool { - switch (m_wm) { - case WM::X11: return as(m_impl).is_mouse_confined(mouse_id); - case WM::WAYLAND: return as(m_impl).is_mouse_confined(mouse_id); - - default: break; - } - - std::unreachable(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::lock_mouse(bool locked, u8 mouse_id) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).lock_mouse(locked, mouse_id); break; - case WM::WAYLAND: as(m_impl).lock_mouse(locked, mouse_id); break; - - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto Window::is_mouse_locked(u8 mouse_id) const noexcept -> bool { - switch (m_wm) { - case WM::X11: return as(m_impl).is_mouse_locked(mouse_id); - case WM::WAYLAND: return as(m_impl).is_mouse_locked(mouse_id); - - default: break; - } - - std::unreachable(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::hide_mouse(bool hidden, u8 mouse_id) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).hide_mouse(hidden, mouse_id); break; - case WM::WAYLAND: as(m_impl).hide_mouse(hidden, mouse_id); break; - - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto Window::is_mouse_hidden(u8 mouse_id) const noexcept -> bool { - switch (m_wm) { - case WM::X11: return as(m_impl).is_mouse_hidden(mouse_id); - case WM::WAYLAND: return as(m_impl).is_mouse_hidden(mouse_id); - - default: break; - } - - std::unreachable(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::set_relative_mouse(bool enabled, u8 mouse_id) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).set_relative_mouse(enabled, mouse_id); break; - case WM::WAYLAND: as(m_impl).set_relative_mouse(enabled, mouse_id); break; - - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto Window::is_mouse_relative(u8 mouse_id) const noexcept -> bool { - switch (m_wm) { - case WM::X11: return as(m_impl).is_mouse_relative(mouse_id); - case WM::WAYLAND: return as(m_impl).is_mouse_relative(mouse_id); - - default: break; - } - - std::unreachable(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::set_key_repeat(bool enabled, u8 keyboard_id) noexcept -> void { - switch (m_wm) { - case WM::X11: return as(m_impl).set_key_repeat(enabled, keyboard_id); - case WM::WAYLAND: return as(m_impl).set_key_repeat(enabled, keyboard_id); - - default: break; - } - - std::unreachable(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto Window::is_key_repeat_enabled(u8 keyboard_id) const noexcept -> bool { - switch (m_wm) { - case WM::X11: return as(m_impl).is_key_repeat_enabled(keyboard_id); - case WM::WAYLAND: return as(m_impl).is_key_repeat_enabled(keyboard_id); - - default: break; - } - - std::unreachable(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::show_virtual_keyboard(bool visible) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).show_virtual_keyboard(visible); break; - case WM::WAYLAND: as(m_impl).show_virtual_keyboard(visible); break; - - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto Window::is_virtual_keyboard_visible() const noexcept -> bool { - switch (m_wm) { - case WM::X11: return as(m_impl).is_virtual_keyboard_visible(); - case WM::WAYLAND: return as(m_impl).is_virtual_keyboard_visible(); - - default: break; - } - - std::unreachable(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::set_mouse_position(const math::ivec2& position, u8 mouse_id) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).set_mouse_position(position, mouse_id); break; - case WM::WAYLAND: as(m_impl).set_mouse_position(position, mouse_id); break; - - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto Window::native_handle() const noexcept -> NativeHandle { - switch (m_wm) { - case WM::X11: return as(m_impl).native_handle(); - case WM::WAYLAND: return as(m_impl).native_handle(); - default: break; - } - - std::unreachable(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::set_closed_event(ClosedEventFunc&& func) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).closed_event = std::move(func); break; - case WM::WAYLAND: as(m_impl).closed_event = std::move(func); break; - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::set_monitor_changed_event(MonitorChangedEventFunc&& func) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).monitor_changed_event = std::move(func); break; - case WM::WAYLAND: as(m_impl).monitor_changed_event = std::move(func); break; - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::set_resized_event(ResizedEventFunc&& func) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).resized_event = std::move(func); break; - case WM::WAYLAND: as(m_impl).resized_event = std::move(func); break; - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::set_restored_event(RestoredEventFunc&& func) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).restored_event = std::move(func); break; - case WM::WAYLAND: as(m_impl).restored_event = std::move(func); break; - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::set_minimized_event(MinimizedEventFunc&& func) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).minimized_event = std::move(func); break; - case WM::WAYLAND: as(m_impl).minimized_event = std::move(func); break; - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::set_key_down_event(KeyDownEventFunc&& func) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).key_down_event = std::move(func); break; - case WM::WAYLAND: as(m_impl).key_down_event = std::move(func); break; - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::set_key_up_event(KeyUpEventFunc&& func) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).key_up_event = std::move(func); break; - case WM::WAYLAND: as(m_impl).key_up_event = std::move(func); break; - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::set_mouse_button_down_event(MouseButtonDownEventFunc&& func) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).mouse_button_down_event = std::move(func); break; - case WM::WAYLAND: as(m_impl).mouse_button_down_event = std::move(func); break; - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::set_mouse_button_up_event(MouseButtonUpEventFunc&& func) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).mouse_button_up_event = std::move(func); break; - case WM::WAYLAND: as(m_impl).mouse_button_up_event = std::move(func); break; - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::set_mouse_moved_event(MouseMovedEventFunc&& func) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).mouse_moved_event = std::move(func); break; - case WM::WAYLAND: as(m_impl).mouse_moved_event = std::move(func); break; - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::set_deactivate_event(DeactivateEventFunc&& func) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).deactivate_event = std::move(func); break; - case WM::WAYLAND: as(m_impl).deactivate_event = std::move(func); break; - default: std::unreachable(); - } - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::set_activate_event(ActivateEventFunc&& func) noexcept -> void { - switch (m_wm) { - case WM::X11: as(m_impl).activate_event = std::move(func); break; - case WM::WAYLAND: as(m_impl).activate_event = std::move(func); break; - default: std::unreachable(); - } - } -} // namespace stormkit::wsi::linux +// Copyright (C) 2021 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.wsi:linux.window; + +import std; + +import stormkit.core; +import stormkit.wsi; + +import :common.window_base; +import :linux.x11.window; +import :linux.wayland.window; + +export namespace stormkit::wsi::linux { + class Window { + using BackendWindow = std::variant; + + WM m_wm; + + BackendWindow m_impl = std::monostate {}; + + public: + explicit Window(WM wm) noexcept; + ~Window() noexcept; + + Window(const Window&) noexcept = delete; + auto operator=(const Window&) noexcept -> Window& = delete; + + Window(Window&&) noexcept; + auto operator=(Window&&) noexcept -> Window&; + + auto open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> void; + auto close() noexcept -> void; + + [[nodiscard]] + auto is_open() const noexcept -> bool; + + [[nodiscard]] + auto visible() const noexcept -> bool; + + [[nodiscard]] + auto current_monitor() const noexcept -> const Monitor&; + + auto handle_events() noexcept -> void; + + auto clear(const rgbcolor& color) noexcept -> void; + auto fill_framebuffer(std::span> colors) noexcept -> void; + + auto set_title(std::string title) noexcept -> void; + [[nodiscard]] + auto title() const noexcept -> const std::string&; + + auto set_extent(const math::uextent2& extent) noexcept -> void; + [[nodiscard]] + auto extent() const noexcept -> const math::uextent2&; + + auto set_fullscreen(bool fullscreen) noexcept -> void; + [[nodiscard]] + auto fullscreen() const noexcept -> bool; + + auto confine_mouse(bool confined = true, u8 mouse_id = 0) noexcept -> void; + [[nodiscard]] + auto is_mouse_confined(u8 mouse_id) const noexcept -> bool; + + auto lock_mouse(bool locked = true, u8 mouse_id = 0) noexcept -> void; + [[nodiscard]] + auto is_mouse_locked(u8 mouse_id) const noexcept -> bool; + + auto hide_mouse(bool hidden = true, u8 mouse_id = 0) noexcept -> void; + [[nodiscard]] + auto is_mouse_hidden(u8 mouse_id) const noexcept -> bool; + + auto set_relative_mouse(bool enabled, u8 mouse_id = 0) noexcept -> void; + [[nodiscard]] + auto is_mouse_relative(u8 mouse_id = 0) const noexcept -> bool; + + auto set_key_repeat(bool enabled, u8 keyboard_id = 0) noexcept -> void; + [[nodiscard]] + auto is_key_repeat_enabled(u8 keyboard_id = 0) const noexcept -> bool; + + auto show_virtual_keyboard(bool visible = true) noexcept -> void; + [[nodiscard]] + auto is_virtual_keyboard_visible() const noexcept -> bool; + + auto set_mouse_position(const math::ivec2& position, u8 mouse_id = 0) noexcept -> void; + + [[nodiscard]] + auto native_handle() const noexcept -> NativeHandle; + + auto set_closed_event(ClosedEventFunc&& func) noexcept -> void; + auto set_monitor_changed_event(MonitorChangedEventFunc&& func) noexcept -> void; + auto set_resized_event(ResizedEventFunc&& func) noexcept -> void; + auto set_restored_event(RestoredEventFunc&& func) noexcept -> void; + auto set_minimized_event(MinimizedEventFunc&& func) noexcept -> void; + auto set_key_down_event(KeyDownEventFunc&& func) noexcept -> void; + auto set_key_up_event(KeyUpEventFunc&& func) noexcept -> void; + auto set_mouse_button_down_event(MouseButtonDownEventFunc&& func) noexcept -> void; + auto set_mouse_button_up_event(MouseButtonUpEventFunc&& func) noexcept -> void; + auto set_mouse_moved_event(MouseMovedEventFunc&& func) noexcept -> void; + auto set_deactivate_event(DeactivateEventFunc&& func) noexcept -> void; + auto set_activate_event(ActivateEventFunc&& func) noexcept -> void; + }; +} // namespace stormkit::wsi::linux + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit::wsi::linux { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Window::Window(WM wm) noexcept + : m_wm { wm } { + if (m_wm == WM::X11) m_impl = x11::Window {}; + else if (m_wm == WM::WAYLAND) + m_impl = wayland::Window {}; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Window::~Window() noexcept + = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Window::Window(Window&&) noexcept + = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::operator=(Window&&) noexcept -> Window& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::open(std::string title, const math::uextent2& extent, WindowFlag flags) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).open(std::move(title), extent, flags); break; + case WM::WAYLAND: as(m_impl).open(std::move(title), extent, flags); break; + + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::close() noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).close(); break; + case WM::WAYLAND: as(m_impl).close(); break; + + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + inline auto Window::is_open() const noexcept -> bool { + switch (m_wm) { + case WM::X11: return as(m_impl).is_open(); + case WM::WAYLAND: return as(m_impl).is_open(); + + default: break; + } + + std::unreachable(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + inline auto Window::visible() const noexcept -> bool { + switch (m_wm) { + case WM::X11: return as(m_impl).visible(); + case WM::WAYLAND: return as(m_impl).visible(); + + default: break; + } + + std::unreachable(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + inline auto Window::current_monitor() const noexcept -> const Monitor& { + switch (m_wm) { + case WM::X11: return as(m_impl).current_monitor(); + case WM::WAYLAND: return as(m_impl).current_monitor(); + + default: break; + } + + std::unreachable(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::handle_events() noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).handle_events(); break; + case WM::WAYLAND: as(m_impl).handle_events(); break; + + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::clear(const rgbcolor& color) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).clear(color); break; + case WM::WAYLAND: as(m_impl).clear(color); break; + + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::fill_framebuffer(std::span> colors) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).fill_framebuffer(colors); break; + case WM::WAYLAND: as(m_impl).fill_framebuffer(colors); break; + + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::set_title(std::string title) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).set_title(std::move(title)); break; + case WM::WAYLAND: as(m_impl).set_title(std::move(title)); break; + + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + inline auto Window::title() const noexcept -> const std::string& { + switch (m_wm) { + case WM::X11: return as(m_impl).title(); + case WM::WAYLAND: return as(m_impl).title(); + + default: break; + } + + std::unreachable(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::set_extent(const math::uextent2& extent) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).set_extent(extent); break; + case WM::WAYLAND: as(m_impl).set_extent(extent); break; + + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + inline auto Window::extent() const noexcept -> const math::uextent2& { + switch (m_wm) { + case WM::X11: return as(m_impl).extent(); + case WM::WAYLAND: return as(m_impl).extent(); + + default: break; + } + + std::unreachable(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::set_fullscreen(bool enabled) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).set_fullscreen(enabled); break; + case WM::WAYLAND: as(m_impl).set_fullscreen(enabled); break; + + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + inline auto Window::fullscreen() const noexcept -> bool { + switch (m_wm) { + case WM::X11: return as(m_impl).fullscreen(); + case WM::WAYLAND: return as(m_impl).fullscreen(); + + default: break; + } + + std::unreachable(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::confine_mouse(bool confined, u8 mouse_id) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).confine_mouse(confined, mouse_id); break; + case WM::WAYLAND: as(m_impl).confine_mouse(confined, mouse_id); break; + + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + inline auto Window::is_mouse_confined(u8 mouse_id) const noexcept -> bool { + switch (m_wm) { + case WM::X11: return as(m_impl).is_mouse_confined(mouse_id); + case WM::WAYLAND: return as(m_impl).is_mouse_confined(mouse_id); + + default: break; + } + + std::unreachable(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::lock_mouse(bool locked, u8 mouse_id) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).lock_mouse(locked, mouse_id); break; + case WM::WAYLAND: as(m_impl).lock_mouse(locked, mouse_id); break; + + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + inline auto Window::is_mouse_locked(u8 mouse_id) const noexcept -> bool { + switch (m_wm) { + case WM::X11: return as(m_impl).is_mouse_locked(mouse_id); + case WM::WAYLAND: return as(m_impl).is_mouse_locked(mouse_id); + + default: break; + } + + std::unreachable(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::hide_mouse(bool hidden, u8 mouse_id) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).hide_mouse(hidden, mouse_id); break; + case WM::WAYLAND: as(m_impl).hide_mouse(hidden, mouse_id); break; + + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + inline auto Window::is_mouse_hidden(u8 mouse_id) const noexcept -> bool { + switch (m_wm) { + case WM::X11: return as(m_impl).is_mouse_hidden(mouse_id); + case WM::WAYLAND: return as(m_impl).is_mouse_hidden(mouse_id); + + default: break; + } + + std::unreachable(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::set_relative_mouse(bool enabled, u8 mouse_id) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).set_relative_mouse(enabled, mouse_id); break; + case WM::WAYLAND: as(m_impl).set_relative_mouse(enabled, mouse_id); break; + + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + inline auto Window::is_mouse_relative(u8 mouse_id) const noexcept -> bool { + switch (m_wm) { + case WM::X11: return as(m_impl).is_mouse_relative(mouse_id); + case WM::WAYLAND: return as(m_impl).is_mouse_relative(mouse_id); + + default: break; + } + + std::unreachable(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::set_key_repeat(bool enabled, u8 keyboard_id) noexcept -> void { + switch (m_wm) { + case WM::X11: return as(m_impl).set_key_repeat(enabled, keyboard_id); + case WM::WAYLAND: return as(m_impl).set_key_repeat(enabled, keyboard_id); + + default: break; + } + + std::unreachable(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + inline auto Window::is_key_repeat_enabled(u8 keyboard_id) const noexcept -> bool { + switch (m_wm) { + case WM::X11: return as(m_impl).is_key_repeat_enabled(keyboard_id); + case WM::WAYLAND: return as(m_impl).is_key_repeat_enabled(keyboard_id); + + default: break; + } + + std::unreachable(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::show_virtual_keyboard(bool visible) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).show_virtual_keyboard(visible); break; + case WM::WAYLAND: as(m_impl).show_virtual_keyboard(visible); break; + + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + inline auto Window::is_virtual_keyboard_visible() const noexcept -> bool { + switch (m_wm) { + case WM::X11: return as(m_impl).is_virtual_keyboard_visible(); + case WM::WAYLAND: return as(m_impl).is_virtual_keyboard_visible(); + + default: break; + } + + std::unreachable(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::set_mouse_position(const math::ivec2& position, u8 mouse_id) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).set_mouse_position(position, mouse_id); break; + case WM::WAYLAND: as(m_impl).set_mouse_position(position, mouse_id); break; + + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + inline auto Window::native_handle() const noexcept -> NativeHandle { + switch (m_wm) { + case WM::X11: return as(m_impl).native_handle(); + case WM::WAYLAND: return as(m_impl).native_handle(); + default: break; + } + + std::unreachable(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::set_closed_event(ClosedEventFunc&& func) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).closed_event = std::move(func); break; + case WM::WAYLAND: as(m_impl).closed_event = std::move(func); break; + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::set_monitor_changed_event(MonitorChangedEventFunc&& func) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).monitor_changed_event = std::move(func); break; + case WM::WAYLAND: as(m_impl).monitor_changed_event = std::move(func); break; + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::set_resized_event(ResizedEventFunc&& func) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).resized_event = std::move(func); break; + case WM::WAYLAND: as(m_impl).resized_event = std::move(func); break; + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::set_restored_event(RestoredEventFunc&& func) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).restored_event = std::move(func); break; + case WM::WAYLAND: as(m_impl).restored_event = std::move(func); break; + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::set_minimized_event(MinimizedEventFunc&& func) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).minimized_event = std::move(func); break; + case WM::WAYLAND: as(m_impl).minimized_event = std::move(func); break; + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::set_key_down_event(KeyDownEventFunc&& func) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).key_down_event = std::move(func); break; + case WM::WAYLAND: as(m_impl).key_down_event = std::move(func); break; + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::set_key_up_event(KeyUpEventFunc&& func) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).key_up_event = std::move(func); break; + case WM::WAYLAND: as(m_impl).key_up_event = std::move(func); break; + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::set_mouse_button_down_event(MouseButtonDownEventFunc&& func) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).mouse_button_down_event = std::move(func); break; + case WM::WAYLAND: as(m_impl).mouse_button_down_event = std::move(func); break; + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::set_mouse_button_up_event(MouseButtonUpEventFunc&& func) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).mouse_button_up_event = std::move(func); break; + case WM::WAYLAND: as(m_impl).mouse_button_up_event = std::move(func); break; + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::set_mouse_moved_event(MouseMovedEventFunc&& func) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).mouse_moved_event = std::move(func); break; + case WM::WAYLAND: as(m_impl).mouse_moved_event = std::move(func); break; + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::set_deactivate_event(DeactivateEventFunc&& func) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).deactivate_event = std::move(func); break; + case WM::WAYLAND: as(m_impl).deactivate_event = std::move(func); break; + default: std::unreachable(); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::set_activate_event(ActivateEventFunc&& func) noexcept -> void { + switch (m_wm) { + case WM::X11: as(m_impl).activate_event = std::move(func); break; + case WM::WAYLAND: as(m_impl).activate_event = std::move(func); break; + default: std::unreachable(); + } + } +} // namespace stormkit::wsi::linux diff --git a/src/wsi/linux/x11/context.mpp b/src/wsi/linux/x11/context.cppm similarity index 100% rename from src/wsi/linux/x11/context.mpp rename to src/wsi/linux/x11/context.cppm diff --git a/src/wsi/linux/x11/log.mpp b/src/wsi/linux/x11/log.cppm similarity index 96% rename from src/wsi/linux/x11/log.mpp rename to src/wsi/linux/x11/log.cppm index 8aff77271..b6e7b5f33 100644 --- a/src/wsi/linux/x11/log.mpp +++ b/src/wsi/linux/x11/log.cppm @@ -1,18 +1,18 @@ -// Copyright (C) 2021 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -export module stormkit.wsi:linux.x11.log; - -import std; - -import stormkit.core; -import stormkit.log; - -export namespace stormkit::wsi::linux::x11 { - IN_MODULE_LOGGER("StormKit.Wsi.Linux.X11") -} // namespace stormkit::wsi::linux::x11 +// Copyright (C) 2021 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.wsi:linux.x11.log; + +import std; + +import stormkit.core; +import stormkit.log; + +export namespace stormkit::wsi::linux::x11 { + IN_MODULE_LOGGER("StormKit.Wsi.Linux.X11") +} // namespace stormkit::wsi::linux::x11 diff --git a/src/wsi/linux/x11/monitor.mpp b/src/wsi/linux/x11/monitor.cppm similarity index 100% rename from src/wsi/linux/x11/monitor.mpp rename to src/wsi/linux/x11/monitor.cppm diff --git a/src/wsi/linux/x11/utils.mpp b/src/wsi/linux/x11/utils.cppm similarity index 97% rename from src/wsi/linux/x11/utils.mpp rename to src/wsi/linux/x11/utils.cppm index 73613b2e9..6e18687c3 100644 --- a/src/wsi/linux/x11/utils.mpp +++ b/src/wsi/linux/x11/utils.cppm @@ -1,172 +1,172 @@ -// Copyright (C) 2021 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -#include - -#include -#include -#include - -#include - -export module stormkit.wsi:linux.x11.utils; - -import stormkit.core; -import stormkit.wsi; - -import :linux.x11.log; - -export namespace stormkit::wsi::linux::x11 { - auto x11_key_to_char(xcb_keysym_t key) noexcept -> char; - auto x11_button_to_stormkit(xcb_button_t button) noexcept -> MouseButton; - auto default_root_window(xcb_connection_t* connection, i32 screen_id) noexcept -> xcb_window_t; -} // namespace stormkit::wsi::linux::x11 - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit::wsi::linux::x11 { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_CONST - inline auto x11_button_to_stormkit(xcb_button_t button) noexcept -> MouseButton { - switch (button) { - case XCB_BUTTON_INDEX_1: return MouseButton::LEFT; - case XCB_BUTTON_INDEX_2: return MouseButton::MIDDLE; - case XCB_BUTTON_INDEX_3: return MouseButton::RIGHT; - case XCB_BUTTON_INDEX_4: return MouseButton::BUTTON_1; - case XCB_BUTTON_INDEX_5: return MouseButton::BUTTON_2; - default: break; - } - - std::unreachable(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto screen_of_display(xcb_connection_t* c, int screen) noexcept -> xcb_screen_t* { - auto iter = xcb_screen_iterator_t {}; - - for (iter = xcb_setup_roots_iterator(xcb_get_setup(c)); iter.rem; --screen, xcb_screen_next(&iter)) - if (screen == 0) return iter.data; - - return iter.data; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto default_root_window(xcb_connection_t* connection, int32_t screen_id) noexcept -> xcb_window_t { - auto screen = screen_of_display(connection, screen_id); - - return screen->root; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_CONST - inline auto x11_key_to_char(xcb_keysym_t key) noexcept -> char { - switch (key) { - case XK_a: return u8'a'; - case XK_b: return u8'b'; - case XK_c: return u8'c'; - case XK_d: return u8'd'; - case XK_e: return u8'e'; - case XK_f: return u8'f'; - case XK_g: return u8'g'; - case XK_h: return u8'h'; - case XK_i: return u8'i'; - case XK_j: return u8'j'; - case XK_k: return u8'k'; - case XK_l: return u8'l'; - case XK_m: return u8'm'; - case XK_n: return u8'n'; - case XK_o: return u8'o'; - case XK_p: return u8'p'; - case XK_q: return u8'q'; - case XK_r: return u8'r'; - case XK_s: return u8's'; - case XK_t: return u8't'; - case XK_u: return u8'u'; - case XK_v: return u8'v'; - case XK_w: return u8'w'; - case XK_x: return u8'x'; - case XK_y: return u8'y'; - case XK_z: return u8'z'; - case XK_A: return u8'A'; - case XK_B: return u8'B'; - case XK_C: return u8'C'; - case XK_D: return u8'D'; - case XK_E: return u8'E'; - case XK_F: return u8'F'; - case XK_G: return u8'G'; - case XK_H: return u8'H'; - case XK_I: return u8'I'; - case XK_J: return u8'J'; - case XK_K: return u8'K'; - case XK_L: return u8'L'; - case XK_M: return u8'M'; - case XK_N: return u8'N'; - case XK_O: return u8'O'; - case XK_P: return u8'P'; - case XK_Q: return u8'Q'; - case XK_R: return u8'R'; - case XK_S: return u8'S'; - case XK_T: return u8'T'; - case XK_U: return u8'U'; - case XK_V: return u8'V'; - case XK_W: return u8'W'; - case XK_X: return u8'X'; - case XK_Y: return u8'Y'; - case XK_Z: return u8'Z'; - case XK_KP_0: [[fallthrough]]; - case XK_0: return u8'0'; - case XK_KP_1: [[fallthrough]]; - case XK_1: return u8'1'; - case XK_KP_2: [[fallthrough]]; - case XK_2: return u8'2'; - case XK_KP_3: [[fallthrough]]; - case XK_3: return u8'3'; - case XK_KP_4: [[fallthrough]]; - case XK_4: return u8'4'; - case XK_KP_5: [[fallthrough]]; - case XK_5: return u8'5'; - case XK_KP_6: [[fallthrough]]; - case XK_6: return u8'6'; - case XK_KP_7: [[fallthrough]]; - case XK_7: return u8'7'; - case XK_KP_8: [[fallthrough]]; - case XK_8: return u8'8'; - case XK_KP_9: [[fallthrough]]; - case XK_9: return u8'9'; - case XK_bracketleft: return u8'{'; - case XK_bracketright: return u8'}'; - case XK_semicolon: return u8';'; - case XK_comma: return u8','; - case XK_period: return u8'.'; - case XK_quoteright: [[fallthrough]]; - case XK_quoteleft: return u8'"'; - case XK_slash: return u8'/'; - case XK_backslash: return u8'\\'; - case XK_dead_grave: return u8'~'; - case XK_equal: return u8'='; - case XK_hyphen: return u8'-'; - case XK_space: return u8' '; - case XK_Return: return u8'\n'; - case XK_Tab: return u8'\t'; - case XK_KP_Add: return u8'+'; - case XK_KP_Subtract: return u8'-'; - case XK_KP_Multiply: return u8'*'; - case XK_KP_Divide: return u8'/'; - default: return u8'\0'; - } - - std::unreachable(); - } -} // namespace stormkit::wsi::linux::x11 +// Copyright (C) 2021 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +#include +#include +#include + +#include + +export module stormkit.wsi:linux.x11.utils; + +import stormkit.core; +import stormkit.wsi; + +import :linux.x11.log; + +export namespace stormkit::wsi::linux::x11 { + auto x11_key_to_char(xcb_keysym_t key) noexcept -> char; + auto x11_button_to_stormkit(xcb_button_t button) noexcept -> MouseButton; + auto default_root_window(xcb_connection_t* connection, i32 screen_id) noexcept -> xcb_window_t; +} // namespace stormkit::wsi::linux::x11 + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit::wsi::linux::x11 { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_CONST + inline auto x11_button_to_stormkit(xcb_button_t button) noexcept -> MouseButton { + switch (button) { + case XCB_BUTTON_INDEX_1: return MouseButton::LEFT; + case XCB_BUTTON_INDEX_2: return MouseButton::MIDDLE; + case XCB_BUTTON_INDEX_3: return MouseButton::RIGHT; + case XCB_BUTTON_INDEX_4: return MouseButton::BUTTON_1; + case XCB_BUTTON_INDEX_5: return MouseButton::BUTTON_2; + default: break; + } + + std::unreachable(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto screen_of_display(xcb_connection_t* c, int screen) noexcept -> xcb_screen_t* { + auto iter = xcb_screen_iterator_t {}; + + for (iter = xcb_setup_roots_iterator(xcb_get_setup(c)); iter.rem; --screen, xcb_screen_next(&iter)) + if (screen == 0) return iter.data; + + return iter.data; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto default_root_window(xcb_connection_t* connection, int32_t screen_id) noexcept -> xcb_window_t { + auto screen = screen_of_display(connection, screen_id); + + return screen->root; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_CONST + inline auto x11_key_to_char(xcb_keysym_t key) noexcept -> char { + switch (key) { + case XK_a: return u8'a'; + case XK_b: return u8'b'; + case XK_c: return u8'c'; + case XK_d: return u8'd'; + case XK_e: return u8'e'; + case XK_f: return u8'f'; + case XK_g: return u8'g'; + case XK_h: return u8'h'; + case XK_i: return u8'i'; + case XK_j: return u8'j'; + case XK_k: return u8'k'; + case XK_l: return u8'l'; + case XK_m: return u8'm'; + case XK_n: return u8'n'; + case XK_o: return u8'o'; + case XK_p: return u8'p'; + case XK_q: return u8'q'; + case XK_r: return u8'r'; + case XK_s: return u8's'; + case XK_t: return u8't'; + case XK_u: return u8'u'; + case XK_v: return u8'v'; + case XK_w: return u8'w'; + case XK_x: return u8'x'; + case XK_y: return u8'y'; + case XK_z: return u8'z'; + case XK_A: return u8'A'; + case XK_B: return u8'B'; + case XK_C: return u8'C'; + case XK_D: return u8'D'; + case XK_E: return u8'E'; + case XK_F: return u8'F'; + case XK_G: return u8'G'; + case XK_H: return u8'H'; + case XK_I: return u8'I'; + case XK_J: return u8'J'; + case XK_K: return u8'K'; + case XK_L: return u8'L'; + case XK_M: return u8'M'; + case XK_N: return u8'N'; + case XK_O: return u8'O'; + case XK_P: return u8'P'; + case XK_Q: return u8'Q'; + case XK_R: return u8'R'; + case XK_S: return u8'S'; + case XK_T: return u8'T'; + case XK_U: return u8'U'; + case XK_V: return u8'V'; + case XK_W: return u8'W'; + case XK_X: return u8'X'; + case XK_Y: return u8'Y'; + case XK_Z: return u8'Z'; + case XK_KP_0: [[fallthrough]]; + case XK_0: return u8'0'; + case XK_KP_1: [[fallthrough]]; + case XK_1: return u8'1'; + case XK_KP_2: [[fallthrough]]; + case XK_2: return u8'2'; + case XK_KP_3: [[fallthrough]]; + case XK_3: return u8'3'; + case XK_KP_4: [[fallthrough]]; + case XK_4: return u8'4'; + case XK_KP_5: [[fallthrough]]; + case XK_5: return u8'5'; + case XK_KP_6: [[fallthrough]]; + case XK_6: return u8'6'; + case XK_KP_7: [[fallthrough]]; + case XK_7: return u8'7'; + case XK_KP_8: [[fallthrough]]; + case XK_8: return u8'8'; + case XK_KP_9: [[fallthrough]]; + case XK_9: return u8'9'; + case XK_bracketleft: return u8'{'; + case XK_bracketright: return u8'}'; + case XK_semicolon: return u8';'; + case XK_comma: return u8','; + case XK_period: return u8'.'; + case XK_quoteright: [[fallthrough]]; + case XK_quoteleft: return u8'"'; + case XK_slash: return u8'/'; + case XK_backslash: return u8'\\'; + case XK_dead_grave: return u8'~'; + case XK_equal: return u8'='; + case XK_hyphen: return u8'-'; + case XK_space: return u8' '; + case XK_Return: return u8'\n'; + case XK_Tab: return u8'\t'; + case XK_KP_Add: return u8'+'; + case XK_KP_Subtract: return u8'-'; + case XK_KP_Multiply: return u8'*'; + case XK_KP_Divide: return u8'/'; + default: return u8'\0'; + } + + std::unreachable(); + } +} // namespace stormkit::wsi::linux::x11 diff --git a/src/wsi/linux/x11/window.mpp b/src/wsi/linux/x11/window.cppm similarity index 97% rename from src/wsi/linux/x11/window.mpp rename to src/wsi/linux/x11/window.cppm index 83bf59545..8642d9072 100644 --- a/src/wsi/linux/x11/window.mpp +++ b/src/wsi/linux/x11/window.cppm @@ -1,213 +1,213 @@ -// Copyright (C) 2021 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -#include - -#include -#include -#include -STORMKIT_PUSH_WARNINGS -#pragma GCC diagnostic ignored "-Wkeyword-macro" -#define explicit _explicit -#include -#undef explicit -STORMKIT_POP_WARNINGS - -export module stormkit.wsi:linux.x11.window; - -import std; - -import stormkit.core; -import stormkit.wsi; - -import :common.window_base; - -import :linux.common.xkb; - -import :linux.x11.context; -import :linux.x11.xcb; -import :linux.x11.log; -import :linux.x11.utils; - -namespace stdr = std::ranges; - -export namespace stormkit::wsi::linux::x11 { - namespace xcb { - template - inline constexpr auto XCB_DELETER = [](auto val) { - auto& globals = get_globals(); - - Destructor(globals.connection, val); - }; - using Window - = RAIICapsule, struct WindowTag, XCB_WINDOW_NONE>; - using ColorMap - = RAIICapsule, struct ColorMapTag, XCB_NONE>; - using GraphicsContext - = RAIICapsule, struct GraphicsContextTag, XCB_NONE>; - using Image = RAIICapsule; - using Pixmap = RAIICapsule, struct PixmapTag, XCB_NONE>; - } // namespace xcb - - class Window: public stormkit::wsi::common::WindowBase { - public: - struct Handles { - xcb_connection_t* connection; - xcb_window_t window; - xcb_key_symbols_t* key_symbols; - xkb_state* state; - }; - - Window() noexcept; - ~Window() noexcept; - - Window(const Window&) noexcept = delete; - auto operator=(const Window&) noexcept -> Window& = delete; - - Window(Window&&) noexcept; - auto operator=(Window&&) noexcept -> Window&; - - auto open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> void; - auto close() noexcept -> void; - - auto handle_events() noexcept -> void; - - auto clear(const rgbcolor& color) noexcept -> void; - auto fill_framebuffer(std::span> colors) noexcept -> void; - - auto set_title(std::string title) noexcept -> void; - auto set_extent(const math::uextent2& extent) noexcept -> void; - auto set_fullscreen(bool fullscreen) noexcept -> void; - - auto confine_mouse(bool confined, u8 mouse_id) noexcept -> void; - [[nodiscard]] - auto is_mouse_confined(u8 mouse_id) const noexcept -> bool; - - auto lock_mouse(bool locked, u8 mouse_id) noexcept -> void; - [[nodiscard]] - auto is_mouse_locked(u8 mouse_id) const noexcept -> bool; - - auto hide_mouse(bool hidden, u8 mouse_id) noexcept -> void; - [[nodiscard]] - auto is_mouse_hidden(u8 mouse_id) const noexcept -> bool; - - auto set_relative_mouse(bool enabled, u8 mouse_id) noexcept -> void; - [[nodiscard]] - auto is_mouse_relative(u8 mouse_id) const noexcept -> bool; - - auto set_key_repeat(bool enabled, u8 keyboard_id) noexcept -> void; - [[nodiscard]] - auto is_key_repeat_enabled(u8 keyboard_id) const noexcept -> bool; - - auto show_virtual_keyboard(bool visible) noexcept -> void; - [[nodiscard]] - auto is_virtual_keyboard_visible() const noexcept -> bool; - - auto set_mouse_position(const math::ivec2& position, u8 mouse_id) noexcept -> void; - - [[nodiscard]] - auto native_handle() const noexcept -> NativeHandle; - - private: - auto process_events(xcb_generic_event_t* xevent) -> void; - auto update_keymap() -> void; - - auto handle_key_event(xcb_keycode_t keycode, bool up) noexcept -> void; - - auto update_framebuffer() noexcept -> void; - - int m_xi_opcode = 0; - - Handles m_handles; - - xcb::Window m_window = xcb::Window::empty(); - xcb::ColorMap m_color_map = xcb::ColorMap::empty(); - xcb::GraphicsContext m_graphics_context = xcb::GraphicsContext::empty(); - xcb::Image m_image = xcb::Image::empty(); - std::span m_framebuffer; - xcb::Pixmap m_pixmap = xcb::Pixmap::empty(); - xcb::KeySymbols m_key_symbols = xcb::KeySymbols::empty(); - common::xkb::Keymap m_keymap = common::xkb::Keymap::empty(); - common::xkb::State m_xkb_state = common::xkb::State::empty(); - common::xkb::Mods m_mods; - f32 m_dpi = 1.f; - }; -} // namespace stormkit::wsi::linux::x11 - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit::wsi::linux::x11 { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Window::Window() noexcept { - xcb::init(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Window::Window(Window&&) noexcept - = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::operator=(Window&&) noexcept -> Window& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::is_mouse_confined(u8) const noexcept -> bool { - return m_mouse_states[GLOBAL_MOUSE_ID].confined; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Window::is_mouse_locked(u8) const noexcept -> bool { - return m_mouse_states[GLOBAL_MOUSE_ID].locked; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto Window::is_mouse_hidden(u8) const noexcept -> bool { - return m_mouse_states[GLOBAL_MOUSE_ID].hidden; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto Window::is_mouse_relative(u8) const noexcept -> bool { - return m_mouse_states[GLOBAL_MOUSE_ID].relative; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto Window::is_key_repeat_enabled(u8) const noexcept -> bool { - return m_keyboard_states[GLOBAL_KEYBOARD_ID].key_repeat; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto Window::is_virtual_keyboard_visible() const noexcept -> bool { - return false; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto Window::native_handle() const noexcept -> NativeHandle { - return std::bit_cast(&m_handles); - } -} // namespace stormkit::wsi::linux::x11 +// Copyright (C) 2021 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +#include +#include +#include +STORMKIT_PUSH_WARNINGS +#pragma GCC diagnostic ignored "-Wkeyword-macro" +#define explicit _explicit +#include +#undef explicit +STORMKIT_POP_WARNINGS + +export module stormkit.wsi:linux.x11.window; + +import std; + +import stormkit.core; +import stormkit.wsi; + +import :common.window_base; + +import :linux.common.xkb; + +import :linux.x11.context; +import :linux.x11.xcb; +import :linux.x11.log; +import :linux.x11.utils; + +namespace stdr = std::ranges; + +export namespace stormkit::wsi::linux::x11 { + namespace xcb { + template + inline constexpr auto XCB_DELETER = [](auto val) { + auto& globals = get_globals(); + + Destructor(globals.connection, val); + }; + using Window + = RAIICapsule, struct WindowTag, XCB_WINDOW_NONE>; + using ColorMap + = RAIICapsule, struct ColorMapTag, XCB_NONE>; + using GraphicsContext + = RAIICapsule, struct GraphicsContextTag, XCB_NONE>; + using Image = RAIICapsule; + using Pixmap = RAIICapsule, struct PixmapTag, XCB_NONE>; + } // namespace xcb + + class Window: public stormkit::wsi::common::WindowBase { + public: + struct Handles { + xcb_connection_t* connection; + xcb_window_t window; + xcb_key_symbols_t* key_symbols; + xkb_state* state; + }; + + Window() noexcept; + ~Window() noexcept; + + Window(const Window&) noexcept = delete; + auto operator=(const Window&) noexcept -> Window& = delete; + + Window(Window&&) noexcept; + auto operator=(Window&&) noexcept -> Window&; + + auto open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> void; + auto close() noexcept -> void; + + auto handle_events() noexcept -> void; + + auto clear(const rgbcolor& color) noexcept -> void; + auto fill_framebuffer(std::span> colors) noexcept -> void; + + auto set_title(std::string title) noexcept -> void; + auto set_extent(const math::uextent2& extent) noexcept -> void; + auto set_fullscreen(bool fullscreen) noexcept -> void; + + auto confine_mouse(bool confined, u8 mouse_id) noexcept -> void; + [[nodiscard]] + auto is_mouse_confined(u8 mouse_id) const noexcept -> bool; + + auto lock_mouse(bool locked, u8 mouse_id) noexcept -> void; + [[nodiscard]] + auto is_mouse_locked(u8 mouse_id) const noexcept -> bool; + + auto hide_mouse(bool hidden, u8 mouse_id) noexcept -> void; + [[nodiscard]] + auto is_mouse_hidden(u8 mouse_id) const noexcept -> bool; + + auto set_relative_mouse(bool enabled, u8 mouse_id) noexcept -> void; + [[nodiscard]] + auto is_mouse_relative(u8 mouse_id) const noexcept -> bool; + + auto set_key_repeat(bool enabled, u8 keyboard_id) noexcept -> void; + [[nodiscard]] + auto is_key_repeat_enabled(u8 keyboard_id) const noexcept -> bool; + + auto show_virtual_keyboard(bool visible) noexcept -> void; + [[nodiscard]] + auto is_virtual_keyboard_visible() const noexcept -> bool; + + auto set_mouse_position(const math::ivec2& position, u8 mouse_id) noexcept -> void; + + [[nodiscard]] + auto native_handle() const noexcept -> NativeHandle; + + private: + auto process_events(xcb_generic_event_t* xevent) -> void; + auto update_keymap() -> void; + + auto handle_key_event(xcb_keycode_t keycode, bool up) noexcept -> void; + + auto update_framebuffer() noexcept -> void; + + int m_xi_opcode = 0; + + Handles m_handles; + + xcb::Window m_window = xcb::Window::empty(); + xcb::ColorMap m_color_map = xcb::ColorMap::empty(); + xcb::GraphicsContext m_graphics_context = xcb::GraphicsContext::empty(); + xcb::Image m_image = xcb::Image::empty(); + std::span m_framebuffer; + xcb::Pixmap m_pixmap = xcb::Pixmap::empty(); + xcb::KeySymbols m_key_symbols = xcb::KeySymbols::empty(); + common::xkb::Keymap m_keymap = common::xkb::Keymap::empty(); + common::xkb::State m_xkb_state = common::xkb::State::empty(); + common::xkb::Mods m_mods; + f32 m_dpi = 1.f; + }; +} // namespace stormkit::wsi::linux::x11 + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit::wsi::linux::x11 { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Window::Window() noexcept { + xcb::init(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Window::Window(Window&&) noexcept + = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::operator=(Window&&) noexcept -> Window& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::is_mouse_confined(u8) const noexcept -> bool { + return m_mouse_states[GLOBAL_MOUSE_ID].confined; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Window::is_mouse_locked(u8) const noexcept -> bool { + return m_mouse_states[GLOBAL_MOUSE_ID].locked; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + inline auto Window::is_mouse_hidden(u8) const noexcept -> bool { + return m_mouse_states[GLOBAL_MOUSE_ID].hidden; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + inline auto Window::is_mouse_relative(u8) const noexcept -> bool { + return m_mouse_states[GLOBAL_MOUSE_ID].relative; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + inline auto Window::is_key_repeat_enabled(u8) const noexcept -> bool { + return m_keyboard_states[GLOBAL_KEYBOARD_ID].key_repeat; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + inline auto Window::is_virtual_keyboard_visible() const noexcept -> bool { + return false; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_PURE + inline auto Window::native_handle() const noexcept -> NativeHandle { + return std::bit_cast(&m_handles); + } +} // namespace stormkit::wsi::linux::x11 diff --git a/src/wsi/linux/x11/xcb.mpp b/src/wsi/linux/x11/xcb.cppm similarity index 97% rename from src/wsi/linux/x11/xcb.mpp rename to src/wsi/linux/x11/xcb.cppm index 3bb31b2ae..22a977843 100644 --- a/src/wsi/linux/x11/xcb.mpp +++ b/src/wsi/linux/x11/xcb.cppm @@ -1,67 +1,67 @@ -// Copyright (C) 2021 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include -#include -#include -#include -#include - -#include - -export module stormkit.wsi:linux.x11.xcb; - -import std; - -import stormkit.core; - -import :linux.x11.log; - -export namespace stormkit::wsi::linux::x11 { - struct Error { - std::string message; - }; - - namespace xcb { - using Connection = RAIICapsule; - using ErrorContext = RAIICapsule< - xcb_errors_context_t*, - monadic::init_by(), - xcb_errors_context_free, - struct ErrorContextTag, - nullptr>; - using GenericError = RAIICapsule; - using InternAtomReply - = RAIICapsule; - using AtomNameReply - = RAIICapsule; - using InputXIQueryDeviceReply = RAIICapsule; - using KeySymbols - = RAIICapsule; - - constexpr auto atom_error(std::string_view msg, std::string_view atom_name) -> decltype(auto); - } // namespace xcb -} // namespace stormkit::wsi::linux::x11 - -export namespace stormkit::wsi::linux::x11::xcb { - STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto atom_error(std::string_view atom_name) -> decltype(auto) { - return [atom_name](Error&& error) noexcept -> Error { - elog("Failed to get atom " - "{}\n > reason: {}", - atom_name, - error.message); - return std::forward(error); - }; - } -} // namespace stormkit::wsi::linux::x11::xcb +// Copyright (C) 2021 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include +#include +#include +#include +#include + +#include + +export module stormkit.wsi:linux.x11.xcb; + +import std; + +import stormkit.core; + +import :linux.x11.log; + +export namespace stormkit::wsi::linux::x11 { + struct Error { + std::string message; + }; + + namespace xcb { + using Connection = RAIICapsule; + using ErrorContext = RAIICapsule< + xcb_errors_context_t*, + monadic::init_by(), + xcb_errors_context_free, + struct ErrorContextTag, + nullptr>; + using GenericError = RAIICapsule; + using InternAtomReply + = RAIICapsule; + using AtomNameReply + = RAIICapsule; + using InputXIQueryDeviceReply = RAIICapsule; + using KeySymbols + = RAIICapsule; + + constexpr auto atom_error(std::string_view msg, std::string_view atom_name) -> decltype(auto); + } // namespace xcb +} // namespace stormkit::wsi::linux::x11 + +export namespace stormkit::wsi::linux::x11::xcb { + STORMKIT_FORCE_INLINE STORMKIT_PURE + constexpr auto atom_error(std::string_view atom_name) -> decltype(auto) { + return [atom_name](Error&& error) noexcept -> Error { + elog("Failed to get atom " + "{}\n > reason: {}", + atom_name, + error.message); + return std::forward(error); + }; + } +} // namespace stormkit::wsi::linux::x11::xcb diff --git a/src/wsi/macos/monitor.mpp b/src/wsi/macos/monitor.cppm similarity index 100% rename from src/wsi/macos/monitor.mpp rename to src/wsi/macos/monitor.cppm diff --git a/src/wsi/macos/window.mpp b/src/wsi/macos/window.cppm similarity index 100% rename from src/wsi/macos/window.mpp rename to src/wsi/macos/window.cppm diff --git a/src/wsi/win32/keyboard.mpp b/src/wsi/win32/keyboard.cppm similarity index 100% rename from src/wsi/win32/keyboard.mpp rename to src/wsi/win32/keyboard.cppm diff --git a/src/wsi/win32/log.mpp b/src/wsi/win32/log.cppm similarity index 100% rename from src/wsi/win32/log.mpp rename to src/wsi/win32/log.cppm diff --git a/src/wsi/win32/monitor.mpp b/src/wsi/win32/monitor.cppm similarity index 100% rename from src/wsi/win32/monitor.mpp rename to src/wsi/win32/monitor.cppm diff --git a/src/wsi/win32/mouse.mpp b/src/wsi/win32/mouse.cppm similarity index 100% rename from src/wsi/win32/mouse.mpp rename to src/wsi/win32/mouse.cppm diff --git a/src/wsi/win32/utils.mpp b/src/wsi/win32/utils.cppm similarity index 100% rename from src/wsi/win32/utils.mpp rename to src/wsi/win32/utils.cppm diff --git a/src/wsi/win32/window.mpp b/src/wsi/win32/window.cppm similarity index 100% rename from src/wsi/win32/window.mpp rename to src/wsi/win32/window.cppm diff --git a/xmake.lua b/xmake.lua index 726e46c4c..5713a3c4f 100644 --- a/xmake.lua +++ b/xmake.lua @@ -111,7 +111,7 @@ namespace("stormkit", function() local module_path = path.join("modules", "stormkit", modulename) local include_path = path.join("include", "(stormkit", modulename) - for _, file in ipairs(os.files(path.join(src_path, "**.mpp"))) do + for _, file in ipairs(os.files(path.join(src_path, "**.cppm"))) do add_files(file) end for _, file in ipairs(os.files(path.join(src_path, "**.cpp"))) do @@ -127,10 +127,10 @@ namespace("stormkit", function() add_files(file) end - if os.exists(module_path .. ".mpp") then add_files(module_path .. ".mpp", { public = true }) end + if os.exists(module_path .. ".cppm") then add_files(module_path .. ".cppm", { public = true }) end if os.files(module_path) then - for _, file in ipairs(os.files(path.join(module_path, "**.mpp"))) do + for _, file in ipairs(os.files(path.join(module_path, "**.cppm"))) do add_files(file, { public = true }) end for _, file in ipairs(os.files(path.join(module_path, "**.inl"))) do @@ -171,7 +171,7 @@ namespace("stormkit", function() end end - if not get_config("luau") then remove_files(path.join(module_path, "lua.mpp")) end + if not get_config("luau") then remove_files(path.join(module_path, "lua.cppm")) end add_includedirs("$(projectdir)/include", { public = true }) @@ -220,7 +220,7 @@ namespace("stormkit", function() set_languages("cxxlatest", "clatest") add_rules("stormkit.flags") - add_files("modules/stormkit.mpp") + add_files("modules/stormkit.cppm") add_deps("core", "main") for _, name in ipairs({ "log", "entities", "image", "wsi", "gpu", "luau" }) do From e18922f744ca465b4e3728d6d673daaca2b6c86c Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 5 Feb 2026 18:51:00 +0100 Subject: [PATCH 068/194] (all) restructure and simplify xmake code --- .../Windows}/manifest.manifest | 0 .../iOS => common/macOS}/info.plist | 88 +-- .../{gpu/triangleclear => entities/xmake.lua} | 0 examples/gpu/imgui/iOS/Info.plist | 46 -- .../gpu/imgui/iOS/LaunchScreen.storyboard | 36 -- examples/gpu/imgui/macOS/Info.plist | 36 -- examples/gpu/imgui/win32/manifest.manifest | 9 - examples/gpu/imgui/xmake.lua | 27 +- examples/gpu/textured_cube/iOS/Info.plist | 46 -- .../textured_cube/iOS/LaunchScreen.storyboard | 36 -- examples/gpu/textured_cube/macOS/Info.plist | 36 -- examples/gpu/textured_cube/src/main.cpp | 6 +- .../gpu/textured_cube/win32/manifest.manifest | 9 - examples/gpu/textured_cube/xmake.lua | 45 +- examples/gpu/triangle/iOS/Info.plist | 46 -- .../gpu/triangle/iOS/LaunchScreen.storyboard | 36 -- examples/gpu/triangle/macOS/Info.plist | 36 -- examples/gpu/triangle/win32/manifest.manifest | 9 - examples/gpu/triangle/xmake.lua | 58 +- examples/log/console-logger/iOS/info.plist | 44 -- examples/log/console-logger/macOS/info.plist | 36 -- examples/log/console-logger/src/main.cpp | 3 +- examples/log/console-logger/xmake.lua | 23 +- examples/log/file-logger/macOS/info.plist | 36 -- examples/log/file-logger/src/main.cpp | 3 +- examples/log/file-logger/xmake.lua | 23 +- .../luau => lua/wsi/events/lua}/events.luau | 1 - .../{wsi/luau => lua/wsi/events}/src/main.cpp | 21 +- examples/lua/wsi/events/xmake.lua | 18 + examples/wsi/events/iOS/Info.plist | 46 -- .../wsi/events/iOS/LaunchScreen.storyboard | 36 -- examples/wsi/events/macOS/Info.plist | 36 -- examples/wsi/events/src/main.cpp | 5 +- examples/wsi/events/xmake.lua | 19 +- examples/wsi/framebuffer/iOS/Info.plist | 46 -- .../framebuffer/iOS/LaunchScreen.storyboard | 36 -- examples/wsi/framebuffer/macOS/Info.plist | 36 -- examples/wsi/framebuffer/src/main.cpp | 4 +- .../wsi/framebuffer/win32/manifest.manifest | 9 - examples/wsi/framebuffer/xmake.lua | 19 +- examples/wsi/luau/xmake.lua | 37 -- include/stormkit/core/api.hpp | 16 + include/stormkit/core/config.hpp.in | 2 +- include/stormkit/entities/api.hpp | 16 + include/stormkit/gpu/api.hpp | 16 + include/stormkit/image/api.hpp | 16 + include/stormkit/log/api.hpp | 16 + include/stormkit/lua/api.hpp | 16 + include/stormkit/{luau => lua}/lua.hpp | 4 + include/stormkit/wsi/api.hpp | 16 + lua/src/core/xmake.lua | 0 lua/src/gpu/xmake.lua | 0 lua/src/image/xmake.lua | 0 lua/src/log/xmake.lua | 0 lua/src/wsi/xmake.lua | 0 lua/xmake.lua | 0 modules/stormkit.cppm | 15 +- .../stormkit/core/containers/shmbuffer.cppm | 7 +- modules/stormkit/core/containers/tree.cppm | 7 +- modules/stormkit/core/math/arithmetic.cppm | 21 +- modules/stormkit/core/parallelism/locked.cppm | 7 +- .../stormkit/core/parallelism/threadpool.cppm | 3 +- .../core/parallelism/threadutils.cppm | 13 +- .../stormkit/core/typesafe/checked_value.cppm | 11 +- modules/stormkit/core/typesafe/safecasts.cppm | 29 +- modules/stormkit/core/utils/app.cppm | 6 +- modules/stormkit/core/utils/contract.cppm | 11 +- .../stormkit/core/utils/dynamic_loader.cppm | 12 +- .../stormkit/core/utils/signal_handler.cppm | 3 +- modules/stormkit/core/utils/stacktrace.cppm | 3 +- modules/stormkit/entities.cppm | 16 +- modules/stormkit/entities/lua.cppm | 26 - modules/stormkit/gpu.cppm | 4 - modules/stormkit/gpu/core/device.cppm | 5 +- modules/stormkit/gpu/core/instance.cppm | 10 +- modules/stormkit/gpu/core/loader.cppm | 6 +- modules/stormkit/gpu/core/sync.cppm | 5 +- modules/stormkit/gpu/core/vulkan/enums.cppm | 555 +++++++++--------- .../stormkit/gpu/core/vulkan/enums.mpp.tpl | 1 + modules/stormkit/gpu/core/vulkan/vma.cppm | 5 +- .../gpu/execution/command_buffer.cppm | 15 +- .../stormkit/gpu/execution/descriptors.cppm | 7 +- modules/stormkit/gpu/execution/pipeline.cppm | 7 +- .../gpu/execution/raster_pipeline.cppm | 13 +- .../stormkit/gpu/execution/render_pass.cppm | 25 +- modules/stormkit/gpu/execution/swapchain.cppm | 45 +- modules/stormkit/gpu/resource/buffer.cppm | 3 +- modules/stormkit/gpu/resource/image.cppm | 51 +- modules/stormkit/gpu/resource/shader.cppm | 3 +- modules/stormkit/image.cppm | 21 +- modules/stormkit/log.cppm | 12 +- modules/stormkit/lua.cppm | 77 +++ modules/stormkit/luau.cppm | 152 ----- modules/stormkit/wsi.cppm | 4 - modules/stormkit/wsi/core.cppm | 9 +- modules/stormkit/wsi/monitor.cppm | 10 +- modules/stormkit/wsi/window.cppm | 4 +- src/gpu/core/vulkan.cpp | 4 +- src/log/console_logger.cpp | 5 +- src/log/file_logger.cpp | 7 +- {modules/stormkit/luau => src/lua}/core.cppm | 23 +- .../log/lua.cppm => src/lua/entities.cppm | 16 +- .../stormkit/gpu/lua.cppm => src/lua/gpu.cppm | 16 +- .../image/lua.cppm => src/lua/image.cppm | 16 +- src/lua/log.cppm | 22 + src/lua/lua.cpp | 206 +++++++ src/{wsi/lua.cpp => lua/wsi.cpp} | 62 +- .../stormkit/wsi/lua.cppm => src/lua/wsi.cppm | 26 +- src/main/macos/Main-macOS.swift | 3 - tools/terra/xmake.lua | 16 +- xmake.lua | 292 ++++----- xmake/ktx.xmake.lua | 46 -- xmake/options.xmake.lua | 27 +- xmake/rules/stormkit_application.xmake.lua | 12 + xmake/rules/stormkit_example.xmake.lua | 21 + xmake/rules/stormkit_flags.xmake.lua | 455 +++++++------- xmake/rules/stormkit_library.xmake.lua | 12 + xmake/targets.xmake.lua | 127 ---- .../xmake.lua => xmake/targets/core.xmake.lua | 38 +- xmake/targets/entities.xmake.lua | 22 + xmake/targets/examples.xmake.lua | 7 + xmake/targets/gpu.xmake.lua | 29 + xmake/targets/image.xmake.lua | 24 + xmake/targets/log.xmake.lua | 22 + xmake/targets/lua.xmake.lua | 53 ++ xmake/targets/main.xmake.lua | 31 + xmake/targets/test.xmake.lua | 20 + xmake/targets/tests.xmake.lua | 47 ++ xmake/targets/tools.xmake.lua | 1 + xmake/targets/wsi.xmake.lua | 91 +++ xmake/tests.xmake.lua | 56 -- 131 files changed, 1884 insertions(+), 2470 deletions(-) rename examples/{wsi/events/win32 => common/Windows}/manifest.manifest (100%) rename examples/{log/file-logger/iOS => common/macOS}/info.plist (97%) rename examples/{gpu/triangleclear => entities/xmake.lua} (100%) delete mode 100644 examples/gpu/imgui/iOS/Info.plist delete mode 100644 examples/gpu/imgui/iOS/LaunchScreen.storyboard delete mode 100644 examples/gpu/imgui/macOS/Info.plist delete mode 100644 examples/gpu/imgui/win32/manifest.manifest delete mode 100644 examples/gpu/textured_cube/iOS/Info.plist delete mode 100644 examples/gpu/textured_cube/iOS/LaunchScreen.storyboard delete mode 100644 examples/gpu/textured_cube/macOS/Info.plist delete mode 100644 examples/gpu/textured_cube/win32/manifest.manifest delete mode 100644 examples/gpu/triangle/iOS/Info.plist delete mode 100644 examples/gpu/triangle/iOS/LaunchScreen.storyboard delete mode 100644 examples/gpu/triangle/macOS/Info.plist delete mode 100644 examples/gpu/triangle/win32/manifest.manifest delete mode 100644 examples/log/console-logger/iOS/info.plist delete mode 100644 examples/log/console-logger/macOS/info.plist delete mode 100644 examples/log/file-logger/macOS/info.plist rename examples/{wsi/luau/luau => lua/wsi/events/lua}/events.luau (99%) rename examples/{wsi/luau => lua/wsi/events}/src/main.cpp (55%) create mode 100644 examples/lua/wsi/events/xmake.lua delete mode 100644 examples/wsi/events/iOS/Info.plist delete mode 100644 examples/wsi/events/iOS/LaunchScreen.storyboard delete mode 100644 examples/wsi/events/macOS/Info.plist delete mode 100644 examples/wsi/framebuffer/iOS/Info.plist delete mode 100644 examples/wsi/framebuffer/iOS/LaunchScreen.storyboard delete mode 100644 examples/wsi/framebuffer/macOS/Info.plist delete mode 100644 examples/wsi/framebuffer/win32/manifest.manifest delete mode 100644 examples/wsi/luau/xmake.lua create mode 100644 include/stormkit/core/api.hpp create mode 100644 include/stormkit/entities/api.hpp create mode 100644 include/stormkit/gpu/api.hpp create mode 100644 include/stormkit/image/api.hpp create mode 100644 include/stormkit/log/api.hpp create mode 100644 include/stormkit/lua/api.hpp rename include/stormkit/{luau => lua}/lua.hpp (76%) create mode 100644 include/stormkit/wsi/api.hpp create mode 100644 lua/src/core/xmake.lua create mode 100644 lua/src/gpu/xmake.lua create mode 100644 lua/src/image/xmake.lua create mode 100644 lua/src/log/xmake.lua create mode 100644 lua/src/wsi/xmake.lua create mode 100644 lua/xmake.lua delete mode 100644 modules/stormkit/entities/lua.cppm create mode 100644 modules/stormkit/lua.cppm delete mode 100644 modules/stormkit/luau.cppm rename {modules/stormkit/luau => src/lua}/core.cppm (62%) rename modules/stormkit/log/lua.cppm => src/lua/entities.cppm (53%) rename modules/stormkit/gpu/lua.cppm => src/lua/gpu.cppm (53%) rename modules/stormkit/image/lua.cppm => src/lua/image.cppm (52%) create mode 100644 src/lua/log.cppm create mode 100644 src/lua/lua.cpp rename src/{wsi/lua.cpp => lua/wsi.cpp} (86%) rename modules/stormkit/wsi/lua.cppm => src/lua/wsi.cppm (72%) delete mode 100644 src/main/macos/Main-macOS.swift delete mode 100644 xmake/ktx.xmake.lua create mode 100644 xmake/rules/stormkit_application.xmake.lua create mode 100644 xmake/rules/stormkit_example.xmake.lua create mode 100644 xmake/rules/stormkit_library.xmake.lua delete mode 100644 xmake/targets.xmake.lua rename src/core/xmake.lua => xmake/targets/core.xmake.lua (51%) create mode 100644 xmake/targets/entities.xmake.lua create mode 100644 xmake/targets/examples.xmake.lua create mode 100644 xmake/targets/gpu.xmake.lua create mode 100644 xmake/targets/image.xmake.lua create mode 100644 xmake/targets/log.xmake.lua create mode 100644 xmake/targets/lua.xmake.lua create mode 100644 xmake/targets/main.xmake.lua create mode 100644 xmake/targets/test.xmake.lua create mode 100644 xmake/targets/tests.xmake.lua create mode 100644 xmake/targets/tools.xmake.lua create mode 100644 xmake/targets/wsi.xmake.lua delete mode 100644 xmake/tests.xmake.lua diff --git a/examples/wsi/events/win32/manifest.manifest b/examples/common/Windows/manifest.manifest similarity index 100% rename from examples/wsi/events/win32/manifest.manifest rename to examples/common/Windows/manifest.manifest diff --git a/examples/log/file-logger/iOS/info.plist b/examples/common/macOS/info.plist similarity index 97% rename from examples/log/file-logger/iOS/info.plist rename to examples/common/macOS/info.plist index 83e13e582..6e96e13c8 100644 --- a/examples/log/file-logger/iOS/info.plist +++ b/examples/common/macOS/info.plist @@ -1,44 +1,44 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} - CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} - CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} - CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} - CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} - CFBundleSignature - ???? - CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} - LSRequiresIPhoneOS - - UISupportedInterfaceOrientations - - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} - - + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${MACOSX_BUNDLE_EXECUTABLE_NAME} + CFBundleGetInfoString + ${MACOSX_BUNDLE_INFO_STRING} + CFBundleIconFile + ${MACOSX_BUNDLE_ICON_FILE} + CFBundleIdentifier + ${MACOSX_BUNDLE_GUI_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleLongVersionString + ${MACOSX_BUNDLE_LONG_VERSION_STRING} + CFBundleName + ${MACOSX_BUNDLE_BUNDLE_NAME} + CFBundlePackageType + APPL + CFBundleShortVersionString + ${MACOSX_BUNDLE_SHORT_VERSION_STRING} + CFBundleSignature + ???? + CFBundleVersion + ${MACOSX_BUNDLE_BUNDLE_VERSION} + LSRequiresIPhoneOS + + UISupportedInterfaceOrientations + + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + NSHumanReadableCopyright + ${MACOSX_BUNDLE_COPYRIGHT} + + diff --git a/examples/gpu/triangleclear b/examples/entities/xmake.lua similarity index 100% rename from examples/gpu/triangleclear rename to examples/entities/xmake.lua diff --git a/examples/gpu/imgui/iOS/Info.plist b/examples/gpu/imgui/iOS/Info.plist deleted file mode 100644 index a62a3592d..000000000 --- a/examples/gpu/imgui/iOS/Info.plist +++ /dev/null @@ -1,46 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} - CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} - CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} - CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} - CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} - CFBundleSignature - ???? - CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UISupportedInterfaceOrientations - - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} - - diff --git a/examples/gpu/imgui/iOS/LaunchScreen.storyboard b/examples/gpu/imgui/iOS/LaunchScreen.storyboard deleted file mode 100644 index 436820912..000000000 --- a/examples/gpu/imgui/iOS/LaunchScreen.storyboard +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/gpu/imgui/macOS/Info.plist b/examples/gpu/imgui/macOS/Info.plist deleted file mode 100644 index f68f66070..000000000 --- a/examples/gpu/imgui/macOS/Info.plist +++ /dev/null @@ -1,36 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} - CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} - CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} - CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} - CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} - CFBundleSignature - ???? - CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} - CSResourcesFileMapped - - NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} - NSHighResolutionCapable - - - diff --git a/examples/gpu/imgui/win32/manifest.manifest b/examples/gpu/imgui/win32/manifest.manifest deleted file mode 100644 index 4a9b5f6a6..000000000 --- a/examples/gpu/imgui/win32/manifest.manifest +++ /dev/null @@ -1,9 +0,0 @@ - - - - - true - PerMonitorV2 - - - diff --git a/examples/gpu/imgui/xmake.lua b/examples/gpu/imgui/xmake.lua index 6c6a9e0a7..7eca49909 100644 --- a/examples/gpu/imgui/xmake.lua +++ b/examples/gpu/imgui/xmake.lua @@ -3,30 +3,21 @@ add_requires("imgui", { system = false, debug = true, }) -target("imgui", function() - set_kind("binary") - set_languages("cxxlatest", "clatest") - - add_rules("stormkit.flags") - -- add_rules("platform.windows.subsystem.windows") - add_rules("platform.windows.subsystem.console") - add_deps("core", "main", "log", "wsi", "gpu", "stormkit") +target("imgui", function() + add_rules("stormkit::example") - add_packages("imgui") + add_files("src/*.cpp", "src/*.cppm", "../common/app.cppm") - if is_mode("debug") then - add_defines("STORMKIT_BUILD_DEBUG") - add_defines("STORMKIT_ASSERT=1") - set_suffixname("-d") - else - add_defines("STORMKIT_ASSERT=0") + if get_config("devmode") then + add_defines(format('RESOURCE_DIR="%s"', path.unix(path.join(os.projectdir(), "gpu/imgui")))) + add_defines(format('SHADER_DIR="%s"', path.unix("$(builddir)/shader"))) end - - add_files("src/*.cpp", "src/*.cppm", "../common/app.cppm") - if is_plat("windows") then add_files("win32/*.manifest") end + add_embeddirs("$(builddir)/shaders") if get_config("devmode") then set_rundir("$(projectdir)") end + add_packages("imgui", "volk", "vulkan-headers") + set_group("examples/stormkit-gpu") end) diff --git a/examples/gpu/textured_cube/iOS/Info.plist b/examples/gpu/textured_cube/iOS/Info.plist deleted file mode 100644 index a62a3592d..000000000 --- a/examples/gpu/textured_cube/iOS/Info.plist +++ /dev/null @@ -1,46 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} - CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} - CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} - CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} - CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} - CFBundleSignature - ???? - CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UISupportedInterfaceOrientations - - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} - - diff --git a/examples/gpu/textured_cube/iOS/LaunchScreen.storyboard b/examples/gpu/textured_cube/iOS/LaunchScreen.storyboard deleted file mode 100644 index 436820912..000000000 --- a/examples/gpu/textured_cube/iOS/LaunchScreen.storyboard +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/gpu/textured_cube/macOS/Info.plist b/examples/gpu/textured_cube/macOS/Info.plist deleted file mode 100644 index f68f66070..000000000 --- a/examples/gpu/textured_cube/macOS/Info.plist +++ /dev/null @@ -1,36 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} - CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} - CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} - CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} - CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} - CFBundleSignature - ???? - CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} - CSResourcesFileMapped - - NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} - NSHighResolutionCapable - - - diff --git a/examples/gpu/textured_cube/src/main.cpp b/examples/gpu/textured_cube/src/main.cpp index 681992319..77db8fcf6 100644 --- a/examples/gpu/textured_cube/src/main.cpp +++ b/examples/gpu/textured_cube/src/main.cpp @@ -18,8 +18,8 @@ import gpu_app; #define SHADER_DIR "../share/stormkit/shaders/" #endif -#ifndef TEXTURE_DIR - #define TEXTURE_DIR "../share/stormkit/textures/" +#ifndef RESOURCE_DIR + #define RESOURCE_DIR "../share/stormkit/" #endif namespace stdc = std::chrono; @@ -79,7 +79,7 @@ struct ViewerData { namespace { const auto SHADER = stdfs::path { SHADER_DIR } / "textured_cube.spv"; - const auto TEXTURE = stdfs::path { TEXTURE_DIR } / "cube.png"; + const auto TEXTURE = stdfs::path { RESOURCE_DIR } / "textures/cube.png"; constexpr auto VERTICES = std::array { Vertex { { -1.f, -1.f, -1.f }, { 2.f / 3.f, 3.f / 4.f } }, // -X side { { -1.f, -1.f, 1.f }, { 1.f / 3.f, 3.f / 4.f } }, diff --git a/examples/gpu/textured_cube/win32/manifest.manifest b/examples/gpu/textured_cube/win32/manifest.manifest deleted file mode 100644 index 4a9b5f6a6..000000000 --- a/examples/gpu/textured_cube/win32/manifest.manifest +++ /dev/null @@ -1,9 +0,0 @@ - - - - - true - PerMonitorV2 - - - diff --git a/examples/gpu/textured_cube/xmake.lua b/examples/gpu/textured_cube/xmake.lua index 71c387533..f58a3f1dc 100644 --- a/examples/gpu/textured_cube/xmake.lua +++ b/examples/gpu/textured_cube/xmake.lua @@ -1,41 +1,24 @@ --- add_requires("nzsl", { configs = { fs_watcher = false, kind = "binary" } }) +add_requires("nzsl", { + configs = { + fs_watcher = false, + kind = "binary", + }, +}) target("textured_cube", function() - set_kind("binary") - set_languages("cxxlatest", "clatest") + add_rules("stormkit::example", "compile.shaders") - add_rules("stormkit.flags") - add_rules("platform.windows.subsystem.console") - -- add_rules("platform.windows.subsystem.windows") + add_files("src/*.cpp", "src/*.cppm", "../common/app.cppm", "shaders/*.nzsl") - add_rules("compile.shaders") - add_deps("core", "main", "log", "wsi", "gpu", "stormkit") - - if is_mode("debug") then - add_defines("STORMKIT_BUILD_DEBUG") - add_defines("STORMKIT_ASSERT=1") - set_suffixname("-d") - else - add_defines("STORMKIT_ASSERT=0") + if get_config("devmode") then + add_defines(format('RESOURCE_DIR="%s"', path.unix(path.join(os.projectdir(), "gpu/textured_cube")))) + add_defines(format('SHADER_DIR="%s"', path.unix("$(builddir)/shader"))) end - - add_files("src/*.cpp", "src/*.cppm", "../common/app.cppm") - add_files("shaders/*.nzsl") - if is_plat("windows") then add_files("win32/*.manifest") end - - add_includedirs("$(builddir)/shaders") - - on_load(function(target) - if get_config("devmode") then - import("core.project.config") - local shader_dir = path.unix(path.join(config.builddir(), "shaders")) - target:add("defines", format('SHADER_DIR="%s"', shader_dir)) - local texture_dir = path.unix(path.join(os.projectdir(), "examples", "gpu", "textured_cube", "textures")) - target:add("defines", format('TEXTURE_DIR="%s"', texture_dir)) - end - end) + add_embeddirs("$(builddir)/shaders") if get_config("devmode") then set_rundir("$(projectdir)") end + add_packages("nzsl") + set_group("examples/stormkit-gpu") end) diff --git a/examples/gpu/triangle/iOS/Info.plist b/examples/gpu/triangle/iOS/Info.plist deleted file mode 100644 index a62a3592d..000000000 --- a/examples/gpu/triangle/iOS/Info.plist +++ /dev/null @@ -1,46 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} - CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} - CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} - CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} - CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} - CFBundleSignature - ???? - CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UISupportedInterfaceOrientations - - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} - - diff --git a/examples/gpu/triangle/iOS/LaunchScreen.storyboard b/examples/gpu/triangle/iOS/LaunchScreen.storyboard deleted file mode 100644 index 436820912..000000000 --- a/examples/gpu/triangle/iOS/LaunchScreen.storyboard +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/gpu/triangle/macOS/Info.plist b/examples/gpu/triangle/macOS/Info.plist deleted file mode 100644 index f68f66070..000000000 --- a/examples/gpu/triangle/macOS/Info.plist +++ /dev/null @@ -1,36 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} - CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} - CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} - CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} - CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} - CFBundleSignature - ???? - CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} - CSResourcesFileMapped - - NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} - NSHighResolutionCapable - - - diff --git a/examples/gpu/triangle/win32/manifest.manifest b/examples/gpu/triangle/win32/manifest.manifest deleted file mode 100644 index 4a9b5f6a6..000000000 --- a/examples/gpu/triangle/win32/manifest.manifest +++ /dev/null @@ -1,9 +0,0 @@ - - - - - true - PerMonitorV2 - - - diff --git a/examples/gpu/triangle/xmake.lua b/examples/gpu/triangle/xmake.lua index d79cfc520..5d823d55e 100644 --- a/examples/gpu/triangle/xmake.lua +++ b/examples/gpu/triangle/xmake.lua @@ -1,54 +1,24 @@ --- if is_plat("windows") then --- add_requires("nzsl", { configs = { toolchains = "msvc", runtimes = "MD", fs_watcher = false, links = {} } }) --- else --- add_requires("nzsl", { configs = { fs_watcher = false } }) --- end -local runtimes -local toolchain -if is_plat("windows") then - runtimes = "MD" - toolchain = "msvc" -elseif is_plat("linux") then - runtimes = "stdc++_shared" - toolchain = "gcc" -end -add_requires("nzsl", { configs = { fs_watcher = false, kind = "binary", toolchains = toolchain, runtimes = runtimes } }) -target("triangle", function() - set_kind("binary") - set_languages("cxxlatest", "clatest") +add_requires("nzsl", { + configs = { + fs_watcher = false, + kind = "binary", + }, +}) - add_rules("stormkit.flags") - -- add_rules("platform.windows.subsystem.windows") - add_rules("platform.windows.subsystem.console") +target("triangle", function() + add_rules("stormkit::example", "compile.shaders") - add_rules("compile.shaders") - add_deps("core", "main", "log", "wsi", "gpu", "stormkit") + add_files("src/*.cpp", "src/*.cppm", "../common/app.cppm", "shaders/*.nzsl") - if is_mode("debug") then - add_defines("STORMKIT_BUILD_DEBUG") - add_defines("STORMKIT_ASSERT=1") - set_suffixname("-d") - else - add_defines("STORMKIT_ASSERT=0") + if get_config("devmode") then + add_defines(format('RESOURCE_DIR="%s"', path.unix(path.join(os.projectdir(), "gpu/triangle")))) + add_defines(format('SHADER_DIR="%s"', path.unix("$(builddir)/shader"))) end - - add_files("src/*.cpp", "src/*.cppm", "../common/app.cppm") - add_files("shaders/*.nzsl") - if is_plat("windows") then add_files("win32/*.manifest") end - - add_includedirs("$(builddir)/shaders") - - on_load(function(target) - if get_config("devmode") then - import("core.project.config") - local shader_dir = path.unix(path.join(config.builddir(), "shaders")) - target:add("defines", format('SHADER_DIR="%s"', shader_dir)) - end - end) + add_embeddirs("$(builddir)/shaders") if get_config("devmode") then set_rundir("$(projectdir)") end - add_embeddirs("$(builddir)/shaders") + add_packages("nzsl") set_group("examples/stormkit-gpu") end) diff --git a/examples/log/console-logger/iOS/info.plist b/examples/log/console-logger/iOS/info.plist deleted file mode 100644 index 83e13e582..000000000 --- a/examples/log/console-logger/iOS/info.plist +++ /dev/null @@ -1,44 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} - CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} - CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} - CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} - CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} - CFBundleSignature - ???? - CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} - LSRequiresIPhoneOS - - UISupportedInterfaceOrientations - - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} - - diff --git a/examples/log/console-logger/macOS/info.plist b/examples/log/console-logger/macOS/info.plist deleted file mode 100644 index f68f66070..000000000 --- a/examples/log/console-logger/macOS/info.plist +++ /dev/null @@ -1,36 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} - CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} - CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} - CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} - CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} - CFBundleSignature - ???? - CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} - CSResourcesFileMapped - - NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} - NSHighResolutionCapable - - - diff --git a/examples/log/console-logger/src/main.cpp b/examples/log/console-logger/src/main.cpp index 31bdb07e3..73a9d3568 100644 --- a/examples/log/console-logger/src/main.cpp +++ b/examples/log/console-logger/src/main.cpp @@ -4,8 +4,7 @@ import std; -import stormkit.core; -import stormkit.log; +import stormkit; #include diff --git a/examples/log/console-logger/xmake.lua b/examples/log/console-logger/xmake.lua index c7a024340..91bc43c2e 100644 --- a/examples/log/console-logger/xmake.lua +++ b/examples/log/console-logger/xmake.lua @@ -1,22 +1,7 @@ -target("console-logger") -do - set_kind("binary") - set_languages("cxxlatest", "clatest") +target("console-logger", function() + add_rules("stormkit::example") - add_rules("stormkit.flags") - add_rules("platform.windows.subsystem.console") - - add_deps("core", "main", "log") - - if is_mode("debug") then - add_defines("STORMKIT_BUILD_DEBUG") - add_defines("STORMKIT_ASSERT=1") - set_suffixname("-d") - else - add_defines("STORMKIT_ASSERT=0") - end - - add_files("src/main.cpp") + add_files("src/*.cpp") set_group("examples/stormkit-log") -end +end) diff --git a/examples/log/file-logger/macOS/info.plist b/examples/log/file-logger/macOS/info.plist deleted file mode 100644 index f68f66070..000000000 --- a/examples/log/file-logger/macOS/info.plist +++ /dev/null @@ -1,36 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} - CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} - CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} - CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} - CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} - CFBundleSignature - ???? - CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} - CSResourcesFileMapped - - NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} - NSHighResolutionCapable - - - diff --git a/examples/log/file-logger/src/main.cpp b/examples/log/file-logger/src/main.cpp index 475eb6e2b..10f90698d 100644 --- a/examples/log/file-logger/src/main.cpp +++ b/examples/log/file-logger/src/main.cpp @@ -4,8 +4,7 @@ import std; -import stormkit.core; -import stormkit.log; +import stormkit; #include diff --git a/examples/log/file-logger/xmake.lua b/examples/log/file-logger/xmake.lua index 44fd4c8f4..e5ef36883 100644 --- a/examples/log/file-logger/xmake.lua +++ b/examples/log/file-logger/xmake.lua @@ -1,22 +1,7 @@ -target("file-logger") -do - set_kind("binary") - set_languages("cxxlatest", "clatest") +target("file-logger", function() + add_rules("stormkit::example") - add_rules("stormkit.flags") - add_rules("platform.windows.subsystem.console") - - add_deps("core", "main", "log") - - if is_mode("debug") then - add_defines("STORMKIT_BUILD_DEBUG") - add_defines("STORMKIT_ASSERT=1") - set_suffixname("-d") - else - add_defines("STORMKIT_ASSERT=0") - end - - add_files("src/main.cpp") + add_files("src/*.cpp") set_group("examples/stormkit-log") -end +end) diff --git a/examples/wsi/luau/luau/events.luau b/examples/lua/wsi/events/lua/events.luau similarity index 99% rename from examples/wsi/luau/luau/events.luau rename to examples/lua/wsi/events/lua/events.luau index 48768b587..40a241007 100644 --- a/examples/wsi/luau/luau/events.luau +++ b/examples/lua/wsi/events/lua/events.luau @@ -1,7 +1,6 @@ local function main() local window = wsi.open_window("test", 800, 600, wsi.window_flag.RESIZEABLE) - window:on_closed(function() print("Close event!") return true diff --git a/examples/wsi/luau/src/main.cpp b/examples/lua/wsi/events/src/main.cpp similarity index 55% rename from examples/wsi/luau/src/main.cpp rename to examples/lua/wsi/events/src/main.cpp index 196351df0..b417cecd1 100644 --- a/examples/wsi/luau/src/main.cpp +++ b/examples/lua/wsi/events/src/main.cpp @@ -2,29 +2,25 @@ // This file is subject to the license terms in the LICENSE file // found in the top-level of this distribution -#include +#include import std; -import stormkit.core; -import stormkit.main; -import stormkit.log; -import stormkit.wsi; -import stormkit.luau; +import stormkit; #include #include -LOGGER("Luau-Events"); +LOGGER("lua-Events"); -#ifndef LUAU_DIR - #define LUAU_DIR "../share/luau" +#ifndef RESOURCE_DIR + #define RESOURCE_DIR "../share/stormkit" #endif namespace stdfs = std::filesystem; -static const auto LUAU_FILE = stdfs::path { LUAU_DIR } / "events.luau"; +static const auto LUA_FILE = stdfs::path { RESOURCE_DIR } / "lua/events.luau"; using namespace stormkit; @@ -36,9 +32,8 @@ auto main(std::span args) -> int { auto logger = log::Logger::create_logger_instance(); - auto engine = luau::Engine::create(LUAU_FILE); - wsi::lua::init_lua(engine.global_namespace()); - auto _ = engine.lua_main().transform_error(monadic::assert("lua runtime error!\n-------------------------------\n")); + auto engine = lua::Engine::create(LUA_FILE, { .wsi = true }); + auto _ = engine.lua_main().transform_error(monadic::assert("lua runtime error!\n-------------------------------\n")); return 0; } diff --git a/examples/lua/wsi/events/xmake.lua b/examples/lua/wsi/events/xmake.lua new file mode 100644 index 000000000..ad101a6d2 --- /dev/null +++ b/examples/lua/wsi/events/xmake.lua @@ -0,0 +1,18 @@ +namespace("lua", function() + target("events", function() + add_rules("stormkit::example", "compile.shaders") + + add_files("src/*.cpp") + + if get_config("devmode") then + add_defines(format('RESOURCE_DIR="%s"', path.unix(path.join(os.projectdir(), "examples/lua/wsi/events")))) + end + add_embeddirs("$(builddir)/shaders") + + if get_config("devmode") then set_rundir("$(projectdir)") end + + add_packages("luau", "luabridge3") + + set_group("examples/stormkit-lua") + end) +end) diff --git a/examples/wsi/events/iOS/Info.plist b/examples/wsi/events/iOS/Info.plist deleted file mode 100644 index 823db4f45..000000000 --- a/examples/wsi/events/iOS/Info.plist +++ /dev/null @@ -1,46 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} - CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} - CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} - CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} - CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} - CFBundleSignature - ???? - CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UISupportedInterfaceOrientations - - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} - - diff --git a/examples/wsi/events/iOS/LaunchScreen.storyboard b/examples/wsi/events/iOS/LaunchScreen.storyboard deleted file mode 100644 index 94d24c83b..000000000 --- a/examples/wsi/events/iOS/LaunchScreen.storyboard +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/wsi/events/macOS/Info.plist b/examples/wsi/events/macOS/Info.plist deleted file mode 100644 index e8cc71539..000000000 --- a/examples/wsi/events/macOS/Info.plist +++ /dev/null @@ -1,36 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} - CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} - CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} - CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} - CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} - CFBundleSignature - ???? - CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} - CSResourcesFileMapped - - NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} - NSHighResolutionCapable - - - diff --git a/examples/wsi/events/src/main.cpp b/examples/wsi/events/src/main.cpp index 8e5e97bc3..71bfa75d7 100644 --- a/examples/wsi/events/src/main.cpp +++ b/examples/wsi/events/src/main.cpp @@ -4,10 +4,7 @@ import std; -import stormkit.core; -import stormkit.main; -import stormkit.log; -import stormkit.wsi; +import stormkit; #include #include diff --git a/examples/wsi/events/xmake.lua b/examples/wsi/events/xmake.lua index 6713719ad..0340337ff 100644 --- a/examples/wsi/events/xmake.lua +++ b/examples/wsi/events/xmake.lua @@ -1,22 +1,7 @@ target("events", function() - set_kind("binary") - set_languages("cxxlatest", "clatest") + add_rules("stormkit::example") - add_rules("stormkit.flags") - add_rules("platform.windows.subsystem.console") - - add_deps("core", "main", "log", "wsi") - - if is_mode("debug") then - add_defines("STORMKIT_BUILD_DEBUG") - add_defines("STORMKIT_ASSERT=1") - set_suffixname("-d") - else - add_defines("STORMKIT_ASSERT=0") - end - - add_files("src/main.cpp") - if is_plat("windows") then add_files("win32/*.manifest") end + add_files("src/*.cpp") set_group("examples/stormkit-wsi") end) diff --git a/examples/wsi/framebuffer/iOS/Info.plist b/examples/wsi/framebuffer/iOS/Info.plist deleted file mode 100644 index 823db4f45..000000000 --- a/examples/wsi/framebuffer/iOS/Info.plist +++ /dev/null @@ -1,46 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} - CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} - CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} - CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} - CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} - CFBundleSignature - ???? - CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UISupportedInterfaceOrientations - - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} - - diff --git a/examples/wsi/framebuffer/iOS/LaunchScreen.storyboard b/examples/wsi/framebuffer/iOS/LaunchScreen.storyboard deleted file mode 100644 index 94d24c83b..000000000 --- a/examples/wsi/framebuffer/iOS/LaunchScreen.storyboard +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/wsi/framebuffer/macOS/Info.plist b/examples/wsi/framebuffer/macOS/Info.plist deleted file mode 100644 index e8cc71539..000000000 --- a/examples/wsi/framebuffer/macOS/Info.plist +++ /dev/null @@ -1,36 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - ${MACOSX_BUNDLE_EXECUTABLE_NAME} - CFBundleGetInfoString - ${MACOSX_BUNDLE_INFO_STRING} - CFBundleIconFile - ${MACOSX_BUNDLE_ICON_FILE} - CFBundleIdentifier - ${MACOSX_BUNDLE_GUI_IDENTIFIER} - CFBundleInfoDictionaryVersion - 6.0 - CFBundleLongVersionString - ${MACOSX_BUNDLE_LONG_VERSION_STRING} - CFBundleName - ${MACOSX_BUNDLE_BUNDLE_NAME} - CFBundlePackageType - APPL - CFBundleShortVersionString - ${MACOSX_BUNDLE_SHORT_VERSION_STRING} - CFBundleSignature - ???? - CFBundleVersion - ${MACOSX_BUNDLE_BUNDLE_VERSION} - CSResourcesFileMapped - - NSHumanReadableCopyright - ${MACOSX_BUNDLE_COPYRIGHT} - NSHighResolutionCapable - - - diff --git a/examples/wsi/framebuffer/src/main.cpp b/examples/wsi/framebuffer/src/main.cpp index 8af3a7cfe..b302fc140 100644 --- a/examples/wsi/framebuffer/src/main.cpp +++ b/examples/wsi/framebuffer/src/main.cpp @@ -4,9 +4,7 @@ import std; -import stormkit.core; -import stormkit.log; -import stormkit.wsi; +import stormkit; #include #include diff --git a/examples/wsi/framebuffer/win32/manifest.manifest b/examples/wsi/framebuffer/win32/manifest.manifest deleted file mode 100644 index f2708ecb1..000000000 --- a/examples/wsi/framebuffer/win32/manifest.manifest +++ /dev/null @@ -1,9 +0,0 @@ - - - - - true - PerMonitorV2 - - - diff --git a/examples/wsi/framebuffer/xmake.lua b/examples/wsi/framebuffer/xmake.lua index 0d9bb9906..ecb3674f3 100644 --- a/examples/wsi/framebuffer/xmake.lua +++ b/examples/wsi/framebuffer/xmake.lua @@ -1,22 +1,7 @@ target("framebuffer", function() - set_kind("binary") - set_languages("cxxlatest", "clatest") + add_rules("stormkit::example") - add_rules("stormkit.flags") - add_rules("platform.windows.subsystem.console") - - add_deps("core", "main", "log", "wsi") - - if is_mode("debug") then - add_defines("STORMKIT_BUILD_DEBUG") - add_defines("STORMKIT_ASSERT=1") - set_suffixname("-d") - else - add_defines("STORMKIT_ASSERT=0") - end - - add_files("src/main.cpp") - if is_plat("windows") then add_files("win32/*.manifest") end + add_files("src/*.cpp") set_group("examples/stormkit-wsi") end) diff --git a/examples/wsi/luau/xmake.lua b/examples/wsi/luau/xmake.lua deleted file mode 100644 index 3b210b059..000000000 --- a/examples/wsi/luau/xmake.lua +++ /dev/null @@ -1,37 +0,0 @@ -if get_config("luau") then - namespace("luau", function() - target("events", function() - set_kind("binary") - set_languages("cxxlatest", "clatest") - - add_rules("stormkit.flags") - add_rules("platform.windows.subsystem.console") - - add_deps("stormkit::core", "stormkit::main", "stormkit::log", "stormkit::wsi", "stormkit::luau") - - add_packages("luau") - - if is_mode("debug") then - add_defines("STORMKIT_BUILD_DEBUG") - add_defines("STORMKIT_ASSERT=1") - set_suffixname("-d") - else - add_defines("STORMKIT_ASSERT=0") - end - - add_files("src/main.cpp") - -- if is_plat("windows") then add_files("win32/*.manifest") end - - on_load(function(target) - if get_config("devmode") then - local lua_dir = path.unix(path.join(os.projectdir(), "examples", "wsi", "luau", "luau")) - target:add("defines", format('LUAU_DIR="%s"', lua_dir)) - end - end) - - if get_config("devmode") then set_rundir("$(projectdir)") end - - set_group("examples/stormkit-wsi/luau") - end) - end) -end diff --git a/include/stormkit/core/api.hpp b/include/stormkit/core/api.hpp new file mode 100644 index 000000000..ef5e0d316 --- /dev/null +++ b/include/stormkit/core/api.hpp @@ -0,0 +1,16 @@ +// Copryright (C) 2022 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +#ifndef STORMKIT_CORE_API_HPP +#define STORMKIT_CORE_API_HPP + +#include + +#ifdef STORMKIT_CORE_BUILD + #define STORMKIT_CORE_API STORMKIT_EXPORT +#else + #define STORMKIT_CORE_API STORMKIT_IMPORT +#endif + +#endif diff --git a/include/stormkit/core/config.hpp.in b/include/stormkit/core/config.hpp.in index b5fa6e918..0172e41b0 100644 --- a/include/stormkit/core/config.hpp.in +++ b/include/stormkit/core/config.hpp.in @@ -14,7 +14,7 @@ ${define STORMKIT_LIB_ENTITIES_ENABLED} ${define STORMKIT_LIB_IMAGE_ENABLED} ${define STORMKIT_LIB_WSI_ENABLED} ${define STORMKIT_LIB_GPU_ENABLED} -${define STORMKIT_LIB_LUAU_ENABLED} +${define STORMKIT_LIB_LUA_ENABLED} #ifndef NO_CONSTANTS _STORMKIT_EXPORT namespace stormkit { inline namespace core { diff --git a/include/stormkit/entities/api.hpp b/include/stormkit/entities/api.hpp new file mode 100644 index 000000000..be8909415 --- /dev/null +++ b/include/stormkit/entities/api.hpp @@ -0,0 +1,16 @@ +// Copryright (C) 2022 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +#ifndef STORMKIT_ENTITIES_API_HPP +#define STORMKIT_ENTITIES_API_HPP + +#include + +#ifdef STORMKIT_ENTITIES_BUILD + #define STORMKIT_ENTITIES_API STORMKIT_EXPORT +#else + #define STORMKIT_ENTITIES_API STORMKIT_IMPORT +#endif + +#endif diff --git a/include/stormkit/gpu/api.hpp b/include/stormkit/gpu/api.hpp new file mode 100644 index 000000000..2c8e37bbe --- /dev/null +++ b/include/stormkit/gpu/api.hpp @@ -0,0 +1,16 @@ +// Copryright (C) 2022 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +#ifndef STORMKIT_GPU_API_HPP +#define STORMKIT_GPU_API_HPP + +#include + +#ifdef STORMKIT_GPU_BUILD + #define STORMKIT_GPU_API STORMKIT_EXPORT +#else + #define STORMKIT_GPU_API STORMKIT_IMPORT +#endif + +#endif diff --git a/include/stormkit/image/api.hpp b/include/stormkit/image/api.hpp new file mode 100644 index 000000000..fb762c298 --- /dev/null +++ b/include/stormkit/image/api.hpp @@ -0,0 +1,16 @@ +// Copryright (C) 2022 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +#ifndef STORMKIT_IMAGE_API_HPP +#define STORMKIT_IMAGE_API_HPP + +#include + +#ifdef STORMKIT_IMAGE_BUILD + #define STORMKIT_IMAGE_API STORMKIT_EXPORT +#else + #define STORMKIT_IMAGE_API STORMKIT_IMPORT +#endif + +#endif diff --git a/include/stormkit/log/api.hpp b/include/stormkit/log/api.hpp new file mode 100644 index 000000000..2977bbc8a --- /dev/null +++ b/include/stormkit/log/api.hpp @@ -0,0 +1,16 @@ +// Copryright (C) 2022 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +#ifndef STORMKIT_LOG_API_HPP +#define STORMKIT_LOG_API_HPP + +#include + +#ifdef STORMKIT_LOG_BUILD + #define STORMKIT_LOG_API STORMKIT_EXPORT +#else + #define STORMKIT_LOG_API STORMKIT_IMPORT +#endif + +#endif diff --git a/include/stormkit/lua/api.hpp b/include/stormkit/lua/api.hpp new file mode 100644 index 000000000..aeb00feed --- /dev/null +++ b/include/stormkit/lua/api.hpp @@ -0,0 +1,16 @@ +// Copryright (C) 2022 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +#ifndef STORMKIT_LUA_API_HPP +#define STORMKIT_LUA_API_HPP + +#include + +#ifdef STORMKIT_LUA_BUILD + #define STORMKIT_LUA_API STORMKIT_EXPORT +#else + #define STORMKIT_LUA_API STORMKIT_IMPORT +#endif + +#endif diff --git a/include/stormkit/luau/lua.hpp b/include/stormkit/lua/lua.hpp similarity index 76% rename from include/stormkit/luau/lua.hpp rename to include/stormkit/lua/lua.hpp index c7293d24c..a97f139de 100644 --- a/include/stormkit/luau/lua.hpp +++ b/include/stormkit/lua/lua.hpp @@ -5,6 +5,8 @@ STORMKIT_PUSH_WARNINGS +#define LUA_API extern __attribute__((visibility("default"))) + extern "C" { #include @@ -13,6 +15,8 @@ extern "C" { } #pragma clang diagnostic ignored "-Wdeprecated-declarations" +#undef lua_rawgetp +#undef lua_rawsetp #include #undef assert diff --git a/include/stormkit/wsi/api.hpp b/include/stormkit/wsi/api.hpp new file mode 100644 index 000000000..e9b56cf3d --- /dev/null +++ b/include/stormkit/wsi/api.hpp @@ -0,0 +1,16 @@ +// Copryright (C) 2022 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +#ifndef STORMKIT_WSI_API_HPP +#define STORMKIT_WSI_API_HPP + +#include + +#ifdef STORMKIT_WSI_BUILD + #define STORMKIT_WSI_API STORMKIT_EXPORT +#else + #define STORMKIT_WSI_API STORMKIT_IMPORT +#endif + +#endif diff --git a/lua/src/core/xmake.lua b/lua/src/core/xmake.lua new file mode 100644 index 000000000..e69de29bb diff --git a/lua/src/gpu/xmake.lua b/lua/src/gpu/xmake.lua new file mode 100644 index 000000000..e69de29bb diff --git a/lua/src/image/xmake.lua b/lua/src/image/xmake.lua new file mode 100644 index 000000000..e69de29bb diff --git a/lua/src/log/xmake.lua b/lua/src/log/xmake.lua new file mode 100644 index 000000000..e69de29bb diff --git a/lua/src/wsi/xmake.lua b/lua/src/wsi/xmake.lua new file mode 100644 index 000000000..e69de29bb diff --git a/lua/xmake.lua b/lua/xmake.lua new file mode 100644 index 000000000..e69de29bb diff --git a/modules/stormkit.cppm b/modules/stormkit.cppm index b19c4ce20..469b22768 100644 --- a/modules/stormkit.cppm +++ b/modules/stormkit.cppm @@ -12,23 +12,22 @@ import std; export module stormkit; export import stormkit.core; -export import stormkit.main; -#ifdef STORMKIT_LIB_LOG_ENABLED +#if STORMKIT_LIB_LOG_ENABLED export import stormkit.log; #endif -#ifdef STORMKIT_LIB_ENTITIES_ENABLED +#if STORMKIT_LIB_ENTITIES_ENABLED export import stormkit.entities; #endif -#ifdef STORMKIT_LIB_IMAGE_ENABLED +#if STORMKIT_LIB_IMAGE_ENABLED export import stormkit.image; #endif -#ifdef STORMKIT_LIB_WSI_ENABLED +#if STORMKIT_LIB_WSI_ENABLED export import stormkit.wsi; #endif -#ifdef STORMKIT_LIB_GPU_ENABLED +#if STORMKIT_LIB_GPU_ENABLED export import stormkit.gpu; #endif -#ifdef STORMKIT_LIB_LUAU_ENABLED -export import stormkit.luau; +#if STORMKIT_LIB_LUA_ENABLED +export import stormkit.lua; #endif diff --git a/modules/stormkit/core/containers/shmbuffer.cppm b/modules/stormkit/core/containers/shmbuffer.cppm index 1a8418131..dd79ad43e 100644 --- a/modules/stormkit/core/containers/shmbuffer.cppm +++ b/modules/stormkit/core/containers/shmbuffer.cppm @@ -4,11 +4,10 @@ module; -#include - +#include #include - #include +#include export module stormkit.core:containers.shmbuffer; @@ -21,7 +20,7 @@ import :functional.monadic; import :utils.contract; export namespace stormkit { inline namespace core { - class STORMKIT_API SHMBuffer { + class STORMKIT_CORE_API SHMBuffer { struct PrivateFuncTag {}; public: diff --git a/modules/stormkit/core/containers/tree.cppm b/modules/stormkit/core/containers/tree.cppm index 02dfe1eca..96ab888e8 100644 --- a/modules/stormkit/core/containers/tree.cppm +++ b/modules/stormkit/core/containers/tree.cppm @@ -4,12 +4,11 @@ module; +#include +#include #include - #include -#include - export module stormkit.core:containers.tree; import std; @@ -26,7 +25,7 @@ namespace stdr = std::ranges; namespace stdfs = std::filesystem; export namespace stormkit { inline namespace core { - class STORMKIT_API TreeNode { + class STORMKIT_CORE_API TreeNode { public: using IndexType = Handle32; using DirtyBitType = u32; diff --git a/modules/stormkit/core/math/arithmetic.cppm b/modules/stormkit/core/math/arithmetic.cppm index dbf9bb6f5..b0abde910 100644 --- a/modules/stormkit/core/math/arithmetic.cppm +++ b/modules/stormkit/core/math/arithmetic.cppm @@ -4,6 +4,7 @@ module; +#include #include export module stormkit.core:math.arithmetic; @@ -175,18 +176,18 @@ namespace stormkit { inline namespace core { namespace math { } #ifndef STORMKIT_OS_WINDOWS - #undef STORMKIT_API - #define STORMKIT_API + #undef STORMKIT_CORE_API + #define STORMKIT_CORE_API #endif -#define INSTANCIATE(t) \ - template STORMKIT_API auto is_positive(t) noexcept -> bool; \ - template STORMKIT_API auto is_negative(t) noexcept -> bool; \ - template STORMKIT_API auto abs(t) noexcept -> t; \ - template STORMKIT_API auto min(t, t) noexcept -> t; \ - template STORMKIT_API auto max(t, t) noexcept -> t; \ - template STORMKIT_API auto log2(t) noexcept -> t; \ - template STORMKIT_API auto floor(t) noexcept -> t; +#define INSTANCIATE(t) \ + template STORMKIT_CORE_API auto is_positive(t) noexcept -> bool; \ + template STORMKIT_CORE_API auto is_negative(t) noexcept -> bool; \ + template STORMKIT_CORE_API auto abs(t) noexcept -> t; \ + template STORMKIT_CORE_API auto min(t, t) noexcept -> t; \ + template STORMKIT_CORE_API auto max(t, t) noexcept -> t; \ + template STORMKIT_CORE_API auto log2(t) noexcept -> t; \ + template STORMKIT_CORE_API auto floor(t) noexcept -> t; INSTANCIATE(u8); INSTANCIATE(i8); diff --git a/modules/stormkit/core/parallelism/locked.cppm b/modules/stormkit/core/parallelism/locked.cppm index 6169e3861..c3dd0ee3d 100644 --- a/modules/stormkit/core/parallelism/locked.cppm +++ b/modules/stormkit/core/parallelism/locked.cppm @@ -4,6 +4,7 @@ module; +#include #include export module stormkit.core:parallelism.locked; @@ -29,8 +30,7 @@ export namespace stormkit { inline namespace core { }; template - class STORMKIT_API - Locked { + class STORMKIT_CORE_API Locked { public: using ValueType = T; using ReferenceType = ValueType&; @@ -138,8 +138,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - Locked::Locked() noexcept(noexcept(std::is_nothrow_default_constructible_v)) - = default; + Locked::Locked() noexcept(noexcept(std::is_nothrow_default_constructible_v)) = default; //////////////////////////////////////// //////////////////////////////////////// diff --git a/modules/stormkit/core/parallelism/threadpool.cppm b/modules/stormkit/core/parallelism/threadpool.cppm index e1cc1c6e4..5230ef604 100644 --- a/modules/stormkit/core/parallelism/threadpool.cppm +++ b/modules/stormkit/core/parallelism/threadpool.cppm @@ -4,6 +4,7 @@ module; +#include #include export module stormkit.core:parallelism.threadpool; @@ -18,7 +19,7 @@ import :utils.numeric_range; import :typesafe.integer; export namespace stormkit { inline namespace core { - class STORMKIT_API ThreadPool { + class STORMKIT_CORE_API ThreadPool { public: static constexpr struct NoFutureType { } NO_FUTURE = {}; diff --git a/modules/stormkit/core/parallelism/threadutils.cppm b/modules/stormkit/core/parallelism/threadutils.cppm index 55ba248a2..d0a85a4a5 100644 --- a/modules/stormkit/core/parallelism/threadutils.cppm +++ b/modules/stormkit/core/parallelism/threadutils.cppm @@ -4,6 +4,7 @@ module; +#include #include export module stormkit.core:parallelism.threadutils; @@ -13,17 +14,17 @@ import std; import :meta; export namespace stormkit { inline namespace core { - STORMKIT_API + STORMKIT_CORE_API auto set_current_thread_name(std::string_view name) noexcept -> void; - STORMKIT_API + STORMKIT_CORE_API auto set_thread_name(std::thread& thread, std::string_view name) noexcept -> void; - STORMKIT_API + STORMKIT_CORE_API auto set_thread_name(std::jthread& thread, std::string_view name) noexcept -> void; - STORMKIT_API + STORMKIT_CORE_API auto get_current_thread_name() noexcept -> std::string; - STORMKIT_API + STORMKIT_CORE_API auto get_thread_name(const std::thread& thread) noexcept -> std::string; - STORMKIT_API + STORMKIT_CORE_API auto get_thread_name(const std::jthread& thread) noexcept -> std::string; template diff --git a/modules/stormkit/core/typesafe/checked_value.cppm b/modules/stormkit/core/typesafe/checked_value.cppm index f2bd27164..6f6969824 100644 --- a/modules/stormkit/core/typesafe/checked_value.cppm +++ b/modules/stormkit/core/typesafe/checked_value.cppm @@ -4,6 +4,7 @@ module; +#include #include #include @@ -377,13 +378,13 @@ namespace stormkit { inline namespace core { } #ifndef STORMKIT_OS_WINDOWS - #undef STORMKIT_API - #define STORMKIT_API + #undef STORMKIT_CORE_API + #define STORMKIT_CORE_API #endif -#define INSTANCIATE(t) \ - template struct STORMKIT_API CheckedValue>; \ - template struct STORMKIT_API CheckedValue> +#define INSTANCIATE(t) \ + template struct STORMKIT_CORE_API CheckedValue>; \ + template struct STORMKIT_CORE_API CheckedValue> INSTANCIATE(u8); INSTANCIATE(i8); diff --git a/modules/stormkit/core/typesafe/safecasts.cppm b/modules/stormkit/core/typesafe/safecasts.cppm index 3d3fe2bb5..66c2d7ed3 100644 --- a/modules/stormkit/core/typesafe/safecasts.cppm +++ b/modules/stormkit/core/typesafe/safecasts.cppm @@ -4,6 +4,7 @@ module; +#include #include export module stormkit.core:typesafe.safecasts; @@ -22,8 +23,7 @@ export { namespace stormkit { inline namespace core { template [[nodiscard]] - constexpr auto is_equal_impl(Args...) noexcept -> bool - = delete + constexpr auto is_equal_impl(Args...) noexcept -> bool = delete #if defined(STORMKIT_COMPILER_MSVC) ; #else @@ -32,8 +32,7 @@ export { template [[nodiscard]] - constexpr auto is_impl(Args...) noexcept -> bool - = delete + constexpr auto is_impl(Args...) noexcept -> bool = delete #if defined(STORMKIT_COMPILER_MSVC) ; #else @@ -42,8 +41,7 @@ export { template [[nodiscard]] - constexpr auto as_impl(Args..., const std::source_location&) noexcept -> T - = delete + constexpr auto as_impl(Args..., const std::source_location&) noexcept -> T = delete #if defined(STORMKIT_COMPILER_MSVC) ; #else @@ -52,8 +50,7 @@ export { template [[nodiscard]] - constexpr auto narrow_impl(Args...) noexcept -> T - = delete + constexpr auto narrow_impl(Args...) noexcept -> T = delete #if defined(STORMKIT_COMPILER_MSVC) ; #else @@ -529,13 +526,13 @@ namespace stormkit { inline namespace core { } #ifndef STORMKIT_OS_WINDOWS - #undef STORMKIT_API - #define STORMKIT_API + #undef STORMKIT_CORE_API + #define STORMKIT_CORE_API #endif -#define IS_EQUAL_INSTANCIATE(t1, t2) template STORMKIT_API auto is_equal_impl(t1, t2) noexcept -> bool; -#define IS_EQUAL_INSTANCIATE_F1(t1, t2) template STORMKIT_API auto is_equal_impl(t1, t2, t1) noexcept -> bool; -#define IS_EQUAL_INSTANCIATE_F2(t1, t2) template STORMKIT_API auto is_equal_impl(t1, t2, t2) noexcept -> bool +#define IS_EQUAL_INSTANCIATE(t1, t2) template STORMKIT_CORE_API auto is_equal_impl(t1, t2) noexcept -> bool; +#define IS_EQUAL_INSTANCIATE_F1(t1, t2) template STORMKIT_CORE_API auto is_equal_impl(t1, t2, t1) noexcept -> bool; +#define IS_EQUAL_INSTANCIATE_F2(t1, t2) template STORMKIT_CORE_API auto is_equal_impl(t1, t2, t2) noexcept -> bool IS_EQUAL_INSTANCIATE(u8, u8); IS_EQUAL_INSTANCIATE(u8, i8); @@ -709,9 +706,9 @@ namespace stormkit { inline namespace core { #undef IS_EQUAL_INSTANCIATE_F1 #undef IS_EQUAL_INSTANCIATE_F2 -#define AS_NARROW_INSTANCIATE(t1, t2) \ - template STORMKIT_API auto as_impl(t2, const std::source_location&) noexcept -> t1; \ - template STORMKIT_API auto narrow_impl(t2) noexcept -> t1 +#define AS_NARROW_INSTANCIATE(t1, t2) \ + template STORMKIT_CORE_API auto as_impl(t2, const std::source_location&) noexcept -> t1; \ + template STORMKIT_CORE_API auto narrow_impl(t2) noexcept -> t1 AS_NARROW_INSTANCIATE(u8, u8); AS_NARROW_INSTANCIATE(u8, i8); diff --git a/modules/stormkit/core/utils/app.cppm b/modules/stormkit/core/utils/app.cppm index c908ca5e3..f0f137022 100644 --- a/modules/stormkit/core/utils/app.cppm +++ b/modules/stormkit/core/utils/app.cppm @@ -4,9 +4,9 @@ module; -#include - +#include #include +#include export module stormkit.core:utils.app; @@ -15,7 +15,7 @@ import std; import :typesafe.integer; export namespace stormkit { inline namespace core { - class STORMKIT_API App { + class STORMKIT_CORE_API App { public: App() noexcept = default; virtual ~App() noexcept = default; diff --git a/modules/stormkit/core/utils/contract.cppm b/modules/stormkit/core/utils/contract.cppm index 212a7a3d2..c60a7ca48 100644 --- a/modules/stormkit/core/utils/contract.cppm +++ b/modules/stormkit/core/utils/contract.cppm @@ -4,6 +4,7 @@ module; +#include #include #ifndef STORMKIT_ASSERT @@ -31,11 +32,11 @@ export namespace stormkit { inline namespace core { constexpr auto as_string(AssertType type) noexcept -> std::string_view; constexpr auto to_string(AssertType type) noexcept -> std::string; - STORMKIT_API - auto assert_base(bool cond, - AssertType type, - std::string_view message, - const std::source_location& location = std::source_location::current()) noexcept -> void; + STORMKIT_CORE_API + auto assert_base(bool cond, + AssertType type, + std::string_view message, + const std::source_location& location = std::source_location::current()) noexcept -> void; consteval auto consteval_assert_base(bool cond, AssertType type, std::string_view message) noexcept -> void; diff --git a/modules/stormkit/core/utils/dynamic_loader.cppm b/modules/stormkit/core/utils/dynamic_loader.cppm index 2b909962f..540c87c57 100644 --- a/modules/stormkit/core/utils/dynamic_loader.cppm +++ b/modules/stormkit/core/utils/dynamic_loader.cppm @@ -4,11 +4,10 @@ module; -#include - -#include - +#include #include +#include +#include export module stormkit.core:utils.dynamic_loader; @@ -18,7 +17,7 @@ import :utils.contract; import :utils.pimpl; export namespace stormkit { inline namespace core { - class STORMKIT_API DynamicLoader { + class STORMKIT_CORE_API DynamicLoader { public: template using Expected = std::expected; @@ -67,8 +66,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DynamicLoader::DynamicLoader() noexcept - = default; + inline DynamicLoader::DynamicLoader() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// diff --git a/modules/stormkit/core/utils/signal_handler.cppm b/modules/stormkit/core/utils/signal_handler.cppm index b7bd585fe..1b310b09f 100644 --- a/modules/stormkit/core/utils/signal_handler.cppm +++ b/modules/stormkit/core/utils/signal_handler.cppm @@ -1,5 +1,6 @@ module; +#include #include #include @@ -10,7 +11,7 @@ import std; import :utils.stracktrace; export namespace stormkit { inline namespace core { - STORMKIT_API + STORMKIT_CORE_API auto setup_signal_handler() noexcept -> void; }} // namespace stormkit::core diff --git a/modules/stormkit/core/utils/stacktrace.cppm b/modules/stormkit/core/utils/stacktrace.cppm index ce6d3005f..014631f59 100644 --- a/modules/stormkit/core/utils/stacktrace.cppm +++ b/modules/stormkit/core/utils/stacktrace.cppm @@ -1,5 +1,6 @@ module; +#include #include export module stormkit.core:utils.stracktrace; @@ -9,6 +10,6 @@ import std; import :parallelism.threadutils; export namespace stormkit { inline namespace core { - STORMKIT_API + STORMKIT_CORE_API auto print_stacktrace(int ignore_count = 0) noexcept -> void; }} // namespace stormkit::core diff --git a/modules/stormkit/entities.cppm b/modules/stormkit/entities.cppm index fedc6f015..bb9d7a3dc 100644 --- a/modules/stormkit/entities.cppm +++ b/modules/stormkit/entities.cppm @@ -4,11 +4,11 @@ module; +#include +#include #include -#include - -#include +#include export module stormkit.entities; @@ -16,10 +16,6 @@ import std; import stormkit.core; -#ifdef STORMKIT_LUA_BINDING -export import :lua; -#endif - namespace stdr = std::ranges; namespace stdv = std::views; @@ -69,7 +65,7 @@ export namespace stormkit::entities { std::vector entities; }; - class STORMKIT_API MessageBus { + class STORMKIT_ENTITIES_API MessageBus { public: MessageBus(); ~MessageBus(); @@ -94,7 +90,7 @@ export namespace stormkit::entities { class EntityManager; - class STORMKIT_API System { + class STORMKIT_ENTITIES_API System { public: using ComponentTypes = HashSet; @@ -146,7 +142,7 @@ export namespace stormkit::entities { ComponentTypes m_types; }; - class STORMKIT_API EntityManager { + class STORMKIT_ENTITIES_API EntityManager { public: static constexpr auto ADDED_ENTITY_MESSAGE_ID = 1; static constexpr auto REMOVED_ENTITY_MESSAGE_ID = 2; diff --git a/modules/stormkit/entities/lua.cppm b/modules/stormkit/entities/lua.cppm deleted file mode 100644 index b38aa03a0..000000000 --- a/modules/stormkit/entities/lua.cppm +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include - -export module stormkit.entities:lua; - -import std; - -import stormkit.core; - -namespace lb = luabridge; - -export namespace stormkit::entities::lua { - inline auto init_lua(lb::Namespace global_namespace) noexcept -> void; -} - -namespace stormkit::entities::lua { - //////////////////////////////////////// - //////////////////////////////////////// - inline auto init_lua(lb::Namespace) noexcept -> void { - } -} // namespace stormkit::entities::lua diff --git a/modules/stormkit/gpu.cppm b/modules/stormkit/gpu.cppm index b62d527bf..56f5892b7 100644 --- a/modules/stormkit/gpu.cppm +++ b/modules/stormkit/gpu.cppm @@ -8,7 +8,3 @@ export module stormkit.gpu; export import stormkit.gpu.core; export import stormkit.gpu.execution; export import stormkit.gpu.resource; - -#ifdef STORMKIT_LUA_BINDING -export import :lua; -#endif diff --git a/modules/stormkit/gpu/core/device.cppm b/modules/stormkit/gpu/core/device.cppm index 18e00b7a7..b8b3b567c 100644 --- a/modules/stormkit/gpu/core/device.cppm +++ b/modules/stormkit/gpu/core/device.cppm @@ -7,6 +7,7 @@ module; #include #include +#include #include export module stormkit.gpu.core:device; @@ -27,7 +28,7 @@ export { class Fence; class Semaphore; - class STORMKIT_API Device { + class STORMKIT_GPU_API Device { struct PrivateFuncTag {}; public: @@ -117,7 +118,7 @@ export { VkRAIIHandle m_vma_allocator = { [](auto handle) static noexcept { vmaDestroyAllocator(handle); } }; }; - STORMKIT_API + STORMKIT_GPU_API auto imgui_vk_loader(const char* func_name, void*) noexcept -> PFN_vkVoidFunction; } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/core/instance.cppm b/modules/stormkit/gpu/core/instance.cppm index 4de01a234..1e9aab715 100644 --- a/modules/stormkit/gpu/core/instance.cppm +++ b/modules/stormkit/gpu/core/instance.cppm @@ -7,6 +7,7 @@ module; #include #include +#include #include export module stormkit.gpu.core:instance; @@ -24,7 +25,7 @@ export { namespace stormkit::gpu { class PhysicalDevice; - class STORMKIT_API Instance { + class STORMKIT_GPU_API Instance { struct PrivateFuncTag {}; public: @@ -69,10 +70,9 @@ export { }; [[nodiscard]] - STORMKIT_API - auto score_physical_device(const PhysicalDevice& physical_device) noexcept -> u64; + STORMKIT_GPU_API auto score_physical_device(const PhysicalDevice& physical_device) noexcept -> u64; - class STORMKIT_API PhysicalDevice { + class STORMKIT_GPU_API PhysicalDevice { public: static constexpr auto DEBUG_TYPE = DebugObjectType::PHYSICAL_DEVICE; @@ -125,7 +125,7 @@ export { friend class Instance; }; - class STORMKIT_API Surface { + class STORMKIT_GPU_API Surface { struct PrivateFuncTag {}; public: diff --git a/modules/stormkit/gpu/core/loader.cppm b/modules/stormkit/gpu/core/loader.cppm index 3ade381d4..352f76930 100644 --- a/modules/stormkit/gpu/core/loader.cppm +++ b/modules/stormkit/gpu/core/loader.cppm @@ -1,12 +1,12 @@ module; -#include +#include export module stormkit.gpu.core:loader; import :structs; export namespace stormkit::gpu { - STORMKIT_API + STORMKIT_GPU_API auto initialize_backend() -> Expected; -} +} // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/core/sync.cppm b/modules/stormkit/gpu/core/sync.cppm index ba8e488e1..fb4c62104 100644 --- a/modules/stormkit/gpu/core/sync.cppm +++ b/modules/stormkit/gpu/core/sync.cppm @@ -7,6 +7,7 @@ module; #include #include +#include #include export module stormkit.gpu.core:sync; @@ -22,7 +23,7 @@ import :device; export namespace stormkit::gpu { class Device; - class STORMKIT_API Fence { + class STORMKIT_GPU_API Fence { struct PrivateFuncTag {}; public: @@ -69,7 +70,7 @@ export namespace stormkit::gpu { VkRAIIHandle m_vk_handle; }; - class STORMKIT_API Semaphore { + class STORMKIT_GPU_API Semaphore { struct PrivateFuncTag {}; public: diff --git a/modules/stormkit/gpu/core/vulkan/enums.cppm b/modules/stormkit/gpu/core/vulkan/enums.cppm index 99b74f0ff..31545990d 100644 --- a/modules/stormkit/gpu/core/vulkan/enums.cppm +++ b/modules/stormkit/gpu/core/vulkan/enums.cppm @@ -7,6 +7,7 @@ module; #include #include +#include #include export module stormkit.gpu.core:vulkan.enums; @@ -3589,272 +3590,288 @@ namespace stormkit::gpu { } } // namespace stormkit::gpu -template stormkit::gpu::AccessFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::AccessFlag - STORMKIT_API stormkit::gpu::from_vk(VkAccessFlagBits); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); -template VkAccessFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); - -template stormkit::gpu::AttachmentLoadOperation - STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::AttachmentLoadOperation - STORMKIT_API stormkit::gpu::from_vk(VkAttachmentLoadOp); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); -template VkAttachmentLoadOp STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); - -template stormkit::gpu::AttachmentStoreOperation - STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::AttachmentStoreOperation - STORMKIT_API stormkit::gpu::from_vk(VkAttachmentStoreOp); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); -template VkAttachmentStoreOp STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); - -template stormkit::gpu::BlendFactor STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::BlendFactor STORMKIT_API stormkit::gpu::from_vk(VkBlendFactor); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); -template VkBlendFactor STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); - -template stormkit::gpu::BlendOperation STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::BlendOperation STORMKIT_API stormkit::gpu::from_vk(VkBlendOp); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); -template VkBlendOp STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); - -template stormkit::gpu::BorderColor STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::BorderColor STORMKIT_API stormkit::gpu::from_vk(VkBorderColor); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::BorderColor); -template VkBorderColor STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::BorderColor); - -template stormkit::gpu::BufferUsageFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::BufferUsageFlag - STORMKIT_API stormkit::gpu::from_vk(VkBufferUsageFlagBits); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); -template VkBufferUsageFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); - -template stormkit::gpu::ColorComponentFlag - STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ColorComponentFlag - STORMKIT_API stormkit::gpu::from_vk(VkColorComponentFlagBits); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); -template VkColorComponentFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); - -template stormkit::gpu::ColorSpace STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ColorSpace - STORMKIT_API stormkit::gpu::from_vk(VkColorSpaceKHR); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); -template VkColorSpaceKHR STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); - -template stormkit::gpu::CommandBufferLevel - STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::CommandBufferLevel - STORMKIT_API stormkit::gpu::from_vk(VkCommandBufferLevel); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); -template VkCommandBufferLevel STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); - -template stormkit::gpu::CompareOperation STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::CompareOperation - STORMKIT_API stormkit::gpu::from_vk(VkCompareOp); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); -template VkCompareOp STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); - -template stormkit::gpu::CullModeFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::CullModeFlag - STORMKIT_API stormkit::gpu::from_vk(VkCullModeFlagBits); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); -template VkCullModeFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); - -template stormkit::gpu::DebugObjectType STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::DebugObjectType - STORMKIT_API stormkit::gpu::from_vk(VkObjectType); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); -template VkObjectType STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); - -template stormkit::gpu::DependencyFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::DependencyFlag - STORMKIT_API stormkit::gpu::from_vk(VkDependencyFlagBits); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); -template VkDependencyFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); - -template stormkit::gpu::DescriptorType STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::DescriptorType - STORMKIT_API stormkit::gpu::from_vk(VkDescriptorType); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); -template VkDescriptorType STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); - -template stormkit::gpu::DynamicState STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::DynamicState - STORMKIT_API stormkit::gpu::from_vk(VkDynamicState); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::DynamicState); -template VkDynamicState STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::DynamicState); - -template stormkit::gpu::Filter STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::Filter STORMKIT_API stormkit::gpu::from_vk(VkFilter); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::Filter); -template VkFilter STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::Filter); - -template stormkit::gpu::FormatFeatureFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::FormatFeatureFlag - STORMKIT_API stormkit::gpu::from_vk(VkFormatFeatureFlagBits); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); -template VkFormatFeatureFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); - -template stormkit::gpu::FrontFace STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::FrontFace STORMKIT_API stormkit::gpu::from_vk(VkFrontFace); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::FrontFace); -template VkFrontFace STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::FrontFace); - -template stormkit::gpu::GeometryFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::GeometryFlag - STORMKIT_API stormkit::gpu::from_vk(VkGeometryFlagBitsKHR); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); -template VkGeometryFlagBitsKHR STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); - -template stormkit::gpu::GeometryType STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::GeometryType - STORMKIT_API stormkit::gpu::from_vk(VkGeometryTypeKHR); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::GeometryType); -template VkGeometryTypeKHR STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::GeometryType); - -template stormkit::gpu::ImageAspectFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageAspectFlag - STORMKIT_API stormkit::gpu::from_vk(VkImageAspectFlagBits); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); -template VkImageAspectFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); - -template stormkit::gpu::ImageCreateFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageCreateFlag - STORMKIT_API stormkit::gpu::from_vk(VkImageCreateFlagBits); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); -template VkImageCreateFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); - -template stormkit::gpu::ImageLayout STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageLayout STORMKIT_API stormkit::gpu::from_vk(VkImageLayout); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); -template VkImageLayout STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); - -template stormkit::gpu::ImageTiling STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageTiling STORMKIT_API stormkit::gpu::from_vk(VkImageTiling); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); -template VkImageTiling STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); - -template stormkit::gpu::ImageType STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageType STORMKIT_API stormkit::gpu::from_vk(VkImageType); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageType); -template VkImageType STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageType); - -template stormkit::gpu::ImageUsageFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageUsageFlag - STORMKIT_API stormkit::gpu::from_vk(VkImageUsageFlagBits); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); -template VkImageUsageFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); - -template stormkit::gpu::ImageViewType STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageViewType - STORMKIT_API stormkit::gpu::from_vk(VkImageViewType); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); -template VkImageViewType STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); - -template stormkit::gpu::LogicOperation STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::LogicOperation STORMKIT_API stormkit::gpu::from_vk(VkLogicOp); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); -template VkLogicOp STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); - -template stormkit::gpu::MemoryPropertyFlag - STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::MemoryPropertyFlag - STORMKIT_API stormkit::gpu::from_vk(VkMemoryPropertyFlagBits); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); -template VkMemoryPropertyFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); - -template stormkit::gpu::PhysicalDeviceType - STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PhysicalDeviceType - STORMKIT_API stormkit::gpu::from_vk(VkPhysicalDeviceType); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); -template VkPhysicalDeviceType STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); - -template stormkit::gpu::PipelineBindPoint STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PipelineBindPoint - STORMKIT_API stormkit::gpu::from_vk(VkPipelineBindPoint); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); -template VkPipelineBindPoint STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); - -template stormkit::gpu::PipelineStageFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PipelineStageFlag - STORMKIT_API stormkit::gpu::from_vk(VkPipelineStageFlagBits); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); -template VkPipelineStageFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); - -template stormkit::gpu::PixelFormat STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PixelFormat STORMKIT_API stormkit::gpu::from_vk(VkFormat); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); -template VkFormat STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); - -template stormkit::gpu::PolygonMode STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PolygonMode STORMKIT_API stormkit::gpu::from_vk(VkPolygonMode); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); -template VkPolygonMode STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); - -template stormkit::gpu::PresentMode STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PresentMode - STORMKIT_API stormkit::gpu::from_vk(VkPresentModeKHR); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PresentMode); -template VkPresentModeKHR STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PresentMode); - -template stormkit::gpu::PrimitiveTopology STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PrimitiveTopology - STORMKIT_API stormkit::gpu::from_vk(VkPrimitiveTopology); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); -template VkPrimitiveTopology STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); - -template stormkit::gpu::QueueFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::QueueFlag STORMKIT_API stormkit::gpu::from_vk(VkQueueFlagBits); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); -template VkQueueFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); - -template stormkit::gpu::ResolveModeFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ResolveModeFlag - STORMKIT_API stormkit::gpu::from_vk(VkResolveModeFlagBits); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ResolveModeFlag); -template VkResolveModeFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ResolveModeFlag); - -template stormkit::gpu::Result STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::Result STORMKIT_API stormkit::gpu::from_vk(VkResult); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::Result); -template VkResult STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::Result); - -template stormkit::gpu::SampleCountFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::SampleCountFlag - STORMKIT_API stormkit::gpu::from_vk(VkSampleCountFlagBits); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); -template VkSampleCountFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); - -template stormkit::gpu::SamplerAddressMode - STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::SamplerAddressMode - STORMKIT_API stormkit::gpu::from_vk(VkSamplerAddressMode); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); -template VkSamplerAddressMode STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); - -template stormkit::gpu::SamplerMipmapMode STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::SamplerMipmapMode - STORMKIT_API stormkit::gpu::from_vk(VkSamplerMipmapMode); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); -template VkSamplerMipmapMode STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); - -template stormkit::gpu::ShaderStageFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ShaderStageFlag - STORMKIT_API stormkit::gpu::from_vk(VkShaderStageFlagBits); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); -template VkShaderStageFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); - -template stormkit::gpu::StencilFaceFlag STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::StencilFaceFlag - STORMKIT_API stormkit::gpu::from_vk(VkStencilFaceFlagBits); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); -template VkStencilFaceFlagBits STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); - -template stormkit::gpu::VertexInputRate STORMKIT_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::VertexInputRate - STORMKIT_API stormkit::gpu::from_vk(VkVertexInputRate); -template VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); -template VkVertexInputRate STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); +template stormkit::gpu::AccessFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::AccessFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkAccessFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); +template VkAccessFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); + +template stormkit::gpu::AttachmentLoadOperation STORMKIT_GPU_API + stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::AttachmentLoadOperation STORMKIT_GPU_API + stormkit::gpu::from_vk(VkAttachmentLoadOp); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); +template VkAttachmentLoadOp STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); + +template stormkit::gpu::AttachmentStoreOperation STORMKIT_GPU_API + stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::AttachmentStoreOperation STORMKIT_GPU_API + stormkit::gpu::from_vk(VkAttachmentStoreOp); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); +template VkAttachmentStoreOp STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); + +template stormkit::gpu::BlendFactor STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::BlendFactor STORMKIT_GPU_API + stormkit::gpu::from_vk(VkBlendFactor); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); +template VkBlendFactor STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); + +template stormkit::gpu::BlendOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::BlendOperation STORMKIT_GPU_API + stormkit::gpu::from_vk(VkBlendOp); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); +template VkBlendOp STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); + +template stormkit::gpu::BorderColor STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::BorderColor STORMKIT_GPU_API + stormkit::gpu::from_vk(VkBorderColor); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BorderColor); +template VkBorderColor STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BorderColor); + +template stormkit::gpu::BufferUsageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::BufferUsageFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkBufferUsageFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); +template VkBufferUsageFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); + +template stormkit::gpu::ColorComponentFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ColorComponentFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkColorComponentFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); +template VkColorComponentFlagBits STORMKIT_GPU_API + stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); + +template stormkit::gpu::ColorSpace STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ColorSpace STORMKIT_GPU_API + stormkit::gpu::from_vk(VkColorSpaceKHR); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); +template VkColorSpaceKHR STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); + +template stormkit::gpu::CommandBufferLevel STORMKIT_GPU_API + stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::CommandBufferLevel STORMKIT_GPU_API + stormkit::gpu::from_vk(VkCommandBufferLevel); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); +template VkCommandBufferLevel STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); + +template stormkit::gpu::CompareOperation STORMKIT_GPU_API + stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::CompareOperation STORMKIT_GPU_API + stormkit::gpu::from_vk(VkCompareOp); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); +template VkCompareOp STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); + +template stormkit::gpu::CullModeFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::CullModeFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkCullModeFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); +template VkCullModeFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); + +template stormkit::gpu::DebugObjectType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::DebugObjectType STORMKIT_GPU_API + stormkit::gpu::from_vk(VkObjectType); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); +template VkObjectType STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); + +template stormkit::gpu::DependencyFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::DependencyFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkDependencyFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); +template VkDependencyFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); + +template stormkit::gpu::DescriptorType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::DescriptorType STORMKIT_GPU_API + stormkit::gpu::from_vk(VkDescriptorType); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); +template VkDescriptorType STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); + +template stormkit::gpu::DynamicState STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::DynamicState STORMKIT_GPU_API + stormkit::gpu::from_vk(VkDynamicState); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DynamicState); +template VkDynamicState STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DynamicState); + +template stormkit::gpu::Filter STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::Filter STORMKIT_GPU_API stormkit::gpu::from_vk(VkFilter); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::Filter); +template VkFilter STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::Filter); + +template stormkit::gpu::FormatFeatureFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::FormatFeatureFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkFormatFeatureFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); +template VkFormatFeatureFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); + +template stormkit::gpu::FrontFace STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::FrontFace STORMKIT_GPU_API stormkit::gpu::from_vk(VkFrontFace); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::FrontFace); +template VkFrontFace STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::FrontFace); + +template stormkit::gpu::GeometryFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::GeometryFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkGeometryFlagBitsKHR); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); +template VkGeometryFlagBitsKHR STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); + +template stormkit::gpu::GeometryType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::GeometryType STORMKIT_GPU_API + stormkit::gpu::from_vk(VkGeometryTypeKHR); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::GeometryType); +template VkGeometryTypeKHR STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::GeometryType); + +template stormkit::gpu::ImageAspectFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageAspectFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkImageAspectFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); +template VkImageAspectFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); + +template stormkit::gpu::ImageCreateFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageCreateFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkImageCreateFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); +template VkImageCreateFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); + +template stormkit::gpu::ImageLayout STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageLayout STORMKIT_GPU_API + stormkit::gpu::from_vk(VkImageLayout); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); +template VkImageLayout STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); + +template stormkit::gpu::ImageTiling STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageTiling STORMKIT_GPU_API + stormkit::gpu::from_vk(VkImageTiling); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); +template VkImageTiling STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); + +template stormkit::gpu::ImageType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageType STORMKIT_GPU_API stormkit::gpu::from_vk(VkImageType); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageType); +template VkImageType STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageType); + +template stormkit::gpu::ImageUsageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageUsageFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkImageUsageFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); +template VkImageUsageFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); + +template stormkit::gpu::ImageViewType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ImageViewType STORMKIT_GPU_API + stormkit::gpu::from_vk(VkImageViewType); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); +template VkImageViewType STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); + +template stormkit::gpu::LogicOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::LogicOperation STORMKIT_GPU_API + stormkit::gpu::from_vk(VkLogicOp); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); +template VkLogicOp STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); + +template stormkit::gpu::MemoryPropertyFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::MemoryPropertyFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkMemoryPropertyFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); +template VkMemoryPropertyFlagBits STORMKIT_GPU_API + stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); + +template stormkit::gpu::PhysicalDeviceType STORMKIT_GPU_API + stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PhysicalDeviceType STORMKIT_GPU_API + stormkit::gpu::from_vk(VkPhysicalDeviceType); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); +template VkPhysicalDeviceType STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); + +template stormkit::gpu::PipelineBindPoint STORMKIT_GPU_API + stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PipelineBindPoint STORMKIT_GPU_API + stormkit::gpu::from_vk(VkPipelineBindPoint); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); +template VkPipelineBindPoint STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); + +template stormkit::gpu::PipelineStageFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PipelineStageFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkPipelineStageFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); +template VkPipelineStageFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); + +template stormkit::gpu::PixelFormat STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PixelFormat STORMKIT_GPU_API stormkit::gpu::from_vk(VkFormat); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); +template VkFormat STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); + +template stormkit::gpu::PolygonMode STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PolygonMode STORMKIT_GPU_API + stormkit::gpu::from_vk(VkPolygonMode); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); +template VkPolygonMode STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); + +template stormkit::gpu::PresentMode STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PresentMode STORMKIT_GPU_API + stormkit::gpu::from_vk(VkPresentModeKHR); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PresentMode); +template VkPresentModeKHR STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PresentMode); + +template stormkit::gpu::PrimitiveTopology STORMKIT_GPU_API + stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::PrimitiveTopology STORMKIT_GPU_API + stormkit::gpu::from_vk(VkPrimitiveTopology); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); +template VkPrimitiveTopology STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); + +template stormkit::gpu::QueueFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::QueueFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkQueueFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); +template VkQueueFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); + +template stormkit::gpu::ResolveModeFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ResolveModeFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkResolveModeFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ResolveModeFlag); +template VkResolveModeFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ResolveModeFlag); + +template stormkit::gpu::Result STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::Result STORMKIT_GPU_API stormkit::gpu::from_vk(VkResult); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::Result); +template VkResult STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::Result); + +template stormkit::gpu::SampleCountFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::SampleCountFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkSampleCountFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); +template VkSampleCountFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); + +template stormkit::gpu::SamplerAddressMode STORMKIT_GPU_API + stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::SamplerAddressMode STORMKIT_GPU_API + stormkit::gpu::from_vk(VkSamplerAddressMode); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); +template VkSamplerAddressMode STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); + +template stormkit::gpu::SamplerMipmapMode STORMKIT_GPU_API + stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::SamplerMipmapMode STORMKIT_GPU_API + stormkit::gpu::from_vk(VkSamplerMipmapMode); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); +template VkSamplerMipmapMode STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); + +template stormkit::gpu::ShaderStageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::ShaderStageFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkShaderStageFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); +template VkShaderStageFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); + +template stormkit::gpu::StencilFaceFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::StencilFaceFlag STORMKIT_GPU_API + stormkit::gpu::from_vk(VkStencilFaceFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); +template VkStencilFaceFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); + +template stormkit::gpu::VertexInputRate STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); +template stormkit::gpu::VertexInputRate STORMKIT_GPU_API + stormkit::gpu::from_vk(VkVertexInputRate); +template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); +template VkVertexInputRate STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); diff --git a/modules/stormkit/gpu/core/vulkan/enums.mpp.tpl b/modules/stormkit/gpu/core/vulkan/enums.mpp.tpl index 5e5ec2f38..3105dce81 100644 --- a/modules/stormkit/gpu/core/vulkan/enums.mpp.tpl +++ b/modules/stormkit/gpu/core/vulkan/enums.mpp.tpl @@ -7,6 +7,7 @@ module; #include #include +#include #include export module stormkit.gpu.core:vulkan.enums; diff --git a/modules/stormkit/gpu/core/vulkan/vma.cppm b/modules/stormkit/gpu/core/vulkan/vma.cppm index 6daf39e8c..46a2e875c 100644 --- a/modules/stormkit/gpu/core/vulkan/vma.cppm +++ b/modules/stormkit/gpu/core/vulkan/vma.cppm @@ -3,11 +3,14 @@ module; #include #include +#include #include #define VMA_DYNAMIC_VULKAN_FUNCTIONS 0 #define VMA_STATIC_VULKAN_FUNCTIONS 0 -#define VMA_CALL_PRE STORMKIT_API +// #ifdef STORMKIT_GPU_BUILD +#define VMA_CALL_PRE STORMKIT_GPU_API +// #endif #include export module stormkit.gpu.core:vulkan.vma; diff --git a/modules/stormkit/gpu/execution/command_buffer.cppm b/modules/stormkit/gpu/execution/command_buffer.cppm index 61a341c61..c69861413 100644 --- a/modules/stormkit/gpu/execution/command_buffer.cppm +++ b/modules/stormkit/gpu/execution/command_buffer.cppm @@ -7,6 +7,7 @@ module; #include #include +#include #include export module stormkit.gpu.execution:command_buffer; @@ -34,7 +35,7 @@ export namespace stormkit::gpu { class SwapChain; - class STORMKIT_API Queue { + class STORMKIT_GPU_API Queue { struct PrivateFuncTag {}; public: @@ -115,7 +116,7 @@ export namespace stormkit::gpu { std::optional stencil_attachment = std::nullopt; }; - class STORMKIT_API CommandBuffer { + class STORMKIT_GPU_API CommandBuffer { struct PrivateFuncTag {}; public: @@ -152,10 +153,8 @@ export namespace stormkit::gpu { -> Expected>; auto end() noexcept -> Expected>; - auto begin_debug_region(std::string_view name, const rgbcolor_f& color = colors::WHITE) noexcept - -> CommandBuffer&; - auto insert_debug_label(std::string_view name, const rgbcolor_f& color = colors::WHITE) noexcept - -> CommandBuffer&; + auto begin_debug_region(std::string_view name, const rgbcolor_f& color = colors::WHITE) noexcept -> CommandBuffer&; + auto insert_debug_label(std::string_view name, const rgbcolor_f& color = colors::WHITE) noexcept -> CommandBuffer&; auto end_debug_region() noexcept -> CommandBuffer&; auto begin_rendering(const RenderingInfo& info) noexcept -> CommandBuffer&; @@ -213,7 +212,7 @@ export namespace stormkit::gpu { ImageLayout dst_layout, const ImageSubresourceLayers& src_subresource_layers, const ImageSubresourceLayers& dst_subresource_layers, - const math::uextent3& extent) noexcept -> CommandBuffer&; + const math::uextent3& extent) noexcept -> CommandBuffer&; auto resolve_image(const Image& src, const Image& dst, @@ -286,7 +285,7 @@ export namespace stormkit::gpu { VkRAIIHandle m_vk_handle; }; - class STORMKIT_API CommandPool { + class STORMKIT_GPU_API CommandPool { struct PrivateFuncTag {}; public: diff --git a/modules/stormkit/gpu/execution/descriptors.cppm b/modules/stormkit/gpu/execution/descriptors.cppm index 35c0da849..c71a4c3f5 100644 --- a/modules/stormkit/gpu/execution/descriptors.cppm +++ b/modules/stormkit/gpu/execution/descriptors.cppm @@ -7,6 +7,7 @@ module; #include #include +#include #include export module stormkit.gpu.execution:descriptors; @@ -40,7 +41,7 @@ export namespace stormkit::gpu { using Descriptor = std::variant; class DescriptorPool; - class STORMKIT_API DescriptorSet { + class STORMKIT_GPU_API DescriptorSet { struct PrivateFuncTag {}; using Deleter = std::function; @@ -83,7 +84,7 @@ export namespace stormkit::gpu { usize descriptor_count; }; - class STORMKIT_API DescriptorSetLayout { + class STORMKIT_GPU_API DescriptorSetLayout { struct PrivateFuncTag {}; public: @@ -125,7 +126,7 @@ export namespace stormkit::gpu { VkRAIIHandle m_vk_handle; }; - class STORMKIT_API DescriptorPool { + class STORMKIT_GPU_API DescriptorPool { struct PrivateFuncTag {}; public: diff --git a/modules/stormkit/gpu/execution/pipeline.cppm b/modules/stormkit/gpu/execution/pipeline.cppm index f2f82b94c..e3de6c929 100644 --- a/modules/stormkit/gpu/execution/pipeline.cppm +++ b/modules/stormkit/gpu/execution/pipeline.cppm @@ -9,6 +9,7 @@ module; #include +#include #include export module stormkit.gpu.execution:pipeline; @@ -24,7 +25,7 @@ import :render_pass; export namespace stormkit::gpu { class CommandBuffer; - class STORMKIT_API PipelineCache { + class STORMKIT_GPU_API PipelineCache { struct PrivateFuncTag {}; public: @@ -82,7 +83,7 @@ export namespace stormkit::gpu { VkRAIIHandle m_vk_handle; }; - class STORMKIT_API PipelineLayout { + class STORMKIT_GPU_API PipelineLayout { struct PrivateFuncTag {}; public: @@ -114,7 +115,7 @@ export namespace stormkit::gpu { VkRAIIHandle m_vk_handle; }; - class STORMKIT_API Pipeline { + class STORMKIT_GPU_API Pipeline { struct PrivateFuncTag {}; public: diff --git a/modules/stormkit/gpu/execution/raster_pipeline.cppm b/modules/stormkit/gpu/execution/raster_pipeline.cppm index e738ac664..944ee1a36 100644 --- a/modules/stormkit/gpu/execution/raster_pipeline.cppm +++ b/modules/stormkit/gpu/execution/raster_pipeline.cppm @@ -4,9 +4,8 @@ module; -#include - #include +#include #include @@ -58,15 +57,15 @@ export namespace stormkit::gpu { CullModeFlag cull_mode = CullModeFlag::BACK; FrontFace front_face = FrontFace::CLOCKWISE; bool depth_bias_enable = false; - f32 depth_bias_constant_factor = 0.f; - f32 depth_bias_clamp = 0.f; - f32 depth_bias_slope_factor = 0.f; + f32 depth_bias_constant_factor = 0.f; + f32 depth_bias_clamp = 0.f; + f32 depth_bias_slope_factor = 0.f; }; struct RasterPipelineMultiSampleState { bool sample_shading_enable = false; SampleCountFlag rasterization_samples = SampleCountFlag::C1; - f32 min_sample_shading = 0.f; + f32 min_sample_shading = 0.f; }; struct RasterPipelineColorBlendAttachmentState { @@ -86,7 +85,7 @@ export namespace stormkit::gpu { bool logic_operation_enable = false; LogicOperation logic_operation = LogicOperation::COPY; std::vector attachments; - std::array blend_constants = { 0.f, 0.f, 0.f, 0.f }; + std::array blend_constants = { 0.f, 0.f, 0.f, 0.f }; }; using RasterPipelineDynamicState = std::vector; diff --git a/modules/stormkit/gpu/execution/render_pass.cppm b/modules/stormkit/gpu/execution/render_pass.cppm index 87ccd7538..8cf9a5113 100644 --- a/modules/stormkit/gpu/execution/render_pass.cppm +++ b/modules/stormkit/gpu/execution/render_pass.cppm @@ -7,6 +7,7 @@ module; #include #include +#include #include export module stormkit.gpu.execution:render_pass; @@ -20,7 +21,7 @@ import stormkit.gpu.resource; export namespace stormkit::gpu { class RenderPass; - class STORMKIT_API FrameBuffer { + class STORMKIT_GPU_API FrameBuffer { struct PrivateFuncTag {}; public: @@ -28,11 +29,11 @@ export namespace stormkit::gpu { static auto create(const Device& device, const RenderPass& render_pass, - const math::uextent2& extent, + const math::uextent2& extent, std::vector> attachments) noexcept -> Expected; static auto allocate(const Device& device, const RenderPass& render_pass, - const math::uextent2& extent, + const math::uextent2& extent, std::vector> attachments) noexcept -> Expected>; ~FrameBuffer() noexcept; @@ -55,7 +56,7 @@ export namespace stormkit::gpu { private: auto do_init(const RenderPass&) noexcept -> Expected; - math::uextent2 m_extent = { 0, 0 }; + math::uextent2 m_extent = { 0, 0 }; std::vector> m_attachments; VkDevice m_vk_device = nullptr; @@ -103,7 +104,7 @@ export namespace stormkit::gpu { auto is_compatible(const RenderPassDescription& description) const noexcept -> bool; }; - class STORMKIT_API RenderPass { + class STORMKIT_GPU_API RenderPass { struct PrivateFuncTag {}; public: @@ -121,10 +122,10 @@ export namespace stormkit::gpu { auto operator=(RenderPass&&) noexcept -> RenderPass&; auto create_frame_buffer(const Device& device, - const math::uextent2& extent, + const math::uextent2& extent, std::vector> attachments) const noexcept -> Expected; auto allocate_frame_buffer(const Device& device, - const math::uextent2& extent, + const math::uextent2& extent, std::vector> attachments) const noexcept -> Expected>; [[nodiscard]] @@ -169,7 +170,7 @@ namespace stormkit::gpu { ///////////////////////////////////// STORMKIT_FORCE_INLINE inline FrameBuffer::FrameBuffer(const Device& device, - const math::uextent2& extent, + const math::uextent2& extent, std::vector> attachments, PrivateFuncTag) noexcept : m_extent { extent }, @@ -186,7 +187,7 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto FrameBuffer::create(const Device& device, const RenderPass& render_pass, - const math::uextent2& extent, + const math::uextent2& extent, std::vector> attachments) noexcept -> Expected { auto frame_buffer = FrameBuffer { device, extent, std::move(attachments), PrivateFuncTag {} }; return frame_buffer.do_init(render_pass).transform(core::monadic::consume(frame_buffer)); @@ -197,7 +198,7 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto FrameBuffer::allocate(const Device& device, const RenderPass& render_pass, - const math::uextent2& extent, + const math::uextent2& extent, std::vector> attachments) noexcept -> Expected> { auto frame_buffer = allocate_unsafe(device, extent, std::move(attachments), PrivateFuncTag {}); return frame_buffer->do_init(render_pass).transform(core::monadic::consume(frame_buffer)); @@ -312,7 +313,7 @@ namespace stormkit::gpu { ///////////////////////////////////// STORMKIT_FORCE_INLINE inline auto RenderPass::create_frame_buffer(const Device& device, - const math::uextent2& extent, + const math::uextent2& extent, std::vector> attachments) const noexcept -> Expected { return FrameBuffer::create(device, *this, extent, std::move(attachments)); @@ -322,7 +323,7 @@ namespace stormkit::gpu { ///////////////////////////////////// STORMKIT_FORCE_INLINE inline auto RenderPass::allocate_frame_buffer(const Device& device, - const math::uextent2& extent, + const math::uextent2& extent, std::vector> attachments) const noexcept -> Expected> { return FrameBuffer::allocate(device, *this, extent, std::move(attachments)); diff --git a/modules/stormkit/gpu/execution/swapchain.cppm b/modules/stormkit/gpu/execution/swapchain.cppm index 68356962c..17c4d50bb 100644 --- a/modules/stormkit/gpu/execution/swapchain.cppm +++ b/modules/stormkit/gpu/execution/swapchain.cppm @@ -6,6 +6,7 @@ module; #include +#include #include export module stormkit.gpu.execution:swapchain; @@ -17,7 +18,7 @@ import stormkit.gpu.core; import stormkit.gpu.resource; export namespace stormkit::gpu { - class STORMKIT_API SwapChain { + class STORMKIT_GPU_API SwapChain { struct PrivateFuncTag {}; public: @@ -30,14 +31,14 @@ export namespace stormkit::gpu { ImageID id; }; - static auto create(const Device& device, - const Surface& surface, - const math::uextent2& extent, - OptionalRef old_swapchain = std::nullopt) noexcept -> Expected; - static auto allocate(const Device& device, - const Surface& surface, - const math::uextent2& extent, - OptionalRef old_swapchain = std::nullopt) noexcept -> Expected>; + static auto create(const Device& device, + const Surface& surface, + const math::uextent2& extent, + OptionalRef old_swapchain = std::nullopt) noexcept -> Expected; + static auto allocate(const Device& device, + const Surface& surface, + const math::uextent2& extent, + OptionalRef old_swapchain = std::nullopt) noexcept -> Expected>; ~SwapChain(); SwapChain(const SwapChain&) = delete; @@ -62,8 +63,8 @@ export namespace stormkit::gpu { auto do_init(const Device&, const Surface&, const math::uextent2&, VkSwapchainKHR) noexcept -> Expected; math::uextent2 m_extent; - PixelFormat m_pixel_format; - u32 m_image_count; + PixelFormat m_pixel_format; + u32 m_image_count; VkDevice m_vk_device; Ref m_vk_device_table; @@ -89,14 +90,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline SwapChain::~SwapChain() - = default; + inline SwapChain::~SwapChain() = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline SwapChain::SwapChain(SwapChain&&) noexcept - = default; + inline SwapChain::SwapChain(SwapChain&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// @@ -106,10 +105,10 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto SwapChain::create(const Device& device, - const Surface& surface, - const math::uextent2& extent, - OptionalRef old_swapchain) noexcept -> Expected { + inline auto SwapChain::create(const Device& device, + const Surface& surface, + const math::uextent2& extent, + OptionalRef old_swapchain) noexcept -> Expected { auto swapchain = SwapChain { device, PrivateFuncTag {} }; return swapchain.do_init(device, surface, extent, old_swapchain ? old_swapchain->native_handle() : nullptr) .transform(core::monadic::consume(swapchain)); @@ -118,10 +117,10 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto SwapChain::allocate(const Device& device, - const Surface& surface, - const math::uextent2& extent, - OptionalRef old_swapchain) noexcept -> Expected> { + inline auto SwapChain::allocate(const Device& device, + const Surface& surface, + const math::uextent2& extent, + OptionalRef old_swapchain) noexcept -> Expected> { auto swapchain = std::make_unique(device, PrivateFuncTag {}); return swapchain->do_init(device, surface, extent, old_swapchain ? old_swapchain->native_handle() : nullptr) .transform(core::monadic::consume(swapchain)); diff --git a/modules/stormkit/gpu/resource/buffer.cppm b/modules/stormkit/gpu/resource/buffer.cppm index 1e70bd574..67c0d95ad 100644 --- a/modules/stormkit/gpu/resource/buffer.cppm +++ b/modules/stormkit/gpu/resource/buffer.cppm @@ -7,6 +7,7 @@ module; #include #include +#include #include export module stormkit.gpu.resource:buffer; @@ -19,7 +20,7 @@ import stormkit.gpu.core; namespace stdr = std::ranges; export namespace stormkit::gpu { - class STORMKIT_API Buffer { + class STORMKIT_GPU_API Buffer { struct PrivateFuncTag {}; public: diff --git a/modules/stormkit/gpu/resource/image.cppm b/modules/stormkit/gpu/resource/image.cppm index a78502386..5e71b597a 100644 --- a/modules/stormkit/gpu/resource/image.cppm +++ b/modules/stormkit/gpu/resource/image.cppm @@ -7,6 +7,7 @@ module; #include #include +#include #include export module stormkit.gpu.resource:image; @@ -18,7 +19,7 @@ import stormkit.image; import stormkit.gpu.core; export namespace stormkit::gpu { - class STORMKIT_API Sampler { + class STORMKIT_GPU_API Sampler { struct PrivateFuncTag {}; public: @@ -30,8 +31,8 @@ export namespace stormkit::gpu { SamplerAddressMode address_mode_v = SamplerAddressMode::REPEAT; SamplerAddressMode address_mode_w = SamplerAddressMode::REPEAT; - bool enable_anisotropy = false; - f32 max_anisotropy = 0.f; + bool enable_anisotropy = false; + f32 max_anisotropy = 0.f; BorderColor border_color = BorderColor::INT_OPAQUE_BLACK; @@ -41,7 +42,7 @@ export namespace stormkit::gpu { CompareOperation compare_operation = CompareOperation::ALWAYS; SamplerMipmapMode mipmap_mode = SamplerMipmapMode::LINEAR; - f32 mip_lod_bias = 0.f; + f32 mip_lod_bias = 0.f; f32 min_lod = 0.f; f32 max_lod = 0.f; @@ -79,7 +80,7 @@ export namespace stormkit::gpu { class Image; - class STORMKIT_API ImageView { + class STORMKIT_GPU_API ImageView { struct PrivateFuncTag {}; public: @@ -122,12 +123,12 @@ export namespace stormkit::gpu { VkRAIIHandle m_vk_handle; }; - class STORMKIT_API Image { + class STORMKIT_GPU_API Image { struct PrivateFuncTag {}; public: struct CreateInfo { - math::uextent3 extent; + math::uextent3 extent; PixelFormat format = PixelFormat::RGBA8_UNORM; u32 layers = 1u; u32 mip_levels = 1u; @@ -180,15 +181,15 @@ export namespace stormkit::gpu { auto do_init(const CreateInfo&) noexcept -> Expected; auto do_init(const VkImageCreateInfo&, MemoryPropertyFlag) noexcept -> Expected; - math::uextent3 m_extent = { 0, 0, 0 }; - PixelFormat m_format = {}; - u32 m_layers = 0; - u32 m_faces = 0; - u32 m_mip_levels = 0; - ImageType m_type = {}; - ImageCreateFlag m_flags = {}; - SampleCountFlag m_samples = {}; - ImageUsageFlag m_usages = {}; + math::uextent3 m_extent = { 0, 0, 0 }; + PixelFormat m_format = {}; + u32 m_layers = 0; + u32 m_faces = 0; + u32 m_mip_levels = 0; + ImageType m_type = {}; + ImageCreateFlag m_flags = {}; + SampleCountFlag m_samples = {}; + ImageUsageFlag m_usages = {}; VkDevice m_vk_device = nullptr; Ref m_vk_device_table; @@ -261,14 +262,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Sampler::~Sampler() - = default; + inline Sampler::~Sampler() = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Sampler::Sampler(Sampler&&) noexcept - = default; + inline Sampler::Sampler(Sampler&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// @@ -356,14 +355,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline ImageView::~ImageView() - = default; + inline ImageView::~ImageView() = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline ImageView::ImageView(ImageView&&) noexcept - = default; + inline ImageView::ImageView(ImageView&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// @@ -438,14 +435,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Image::~Image() - = default; + inline Image::~Image() = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Image::Image(Image&&) noexcept - = default; + inline Image::Image(Image&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// diff --git a/modules/stormkit/gpu/resource/shader.cppm b/modules/stormkit/gpu/resource/shader.cppm index 60aa1e563..6e8f58016 100644 --- a/modules/stormkit/gpu/resource/shader.cppm +++ b/modules/stormkit/gpu/resource/shader.cppm @@ -7,6 +7,7 @@ module; #include #include +#include #include export module stormkit.gpu.resource:shader; @@ -19,7 +20,7 @@ import stormkit.gpu.core; namespace stdr = std::ranges; export namespace stormkit::gpu { - class STORMKIT_API Shader { + class STORMKIT_GPU_API Shader { struct PrivateFuncTag {}; public: diff --git a/modules/stormkit/image.cppm b/modules/stormkit/image.cppm index 00ad1a73d..6ca408cac 100644 --- a/modules/stormkit/image.cppm +++ b/modules/stormkit/image.cppm @@ -4,9 +4,10 @@ module; +#include #include -#include +#include export module stormkit.image; @@ -14,12 +15,8 @@ import std; import stormkit.core; -#ifdef STORMKIT_LUA_BINDING -export import :lua; -#endif - export namespace stormkit::image { - class STORMKIT_API Image { + class STORMKIT_IMAGE_API Image { public: enum class Format : u8 { R8_SNORM = 0, @@ -112,12 +109,12 @@ export namespace stormkit::image { struct ImageData { math::uextent3 extent = { .width = 0u, .height = 0u }; - u32 channel_count = 0u; - u32 bytes_per_channel = 0u; - u32 layers = 1u; - u32 faces = 1u; - u32 mip_levels = 1u; - Format format = Format::UNDEFINED; + u32 channel_count = 0u; + u32 bytes_per_channel = 0u; + u32 layers = 1u; + u32 faces = 1u; + u32 mip_levels = 1u; + Format format = Format::UNDEFINED; std::vector data = {}; }; diff --git a/modules/stormkit/log.cppm b/modules/stormkit/log.cppm index cc5baff81..860efa92c 100644 --- a/modules/stormkit/log.cppm +++ b/modules/stormkit/log.cppm @@ -8,6 +8,8 @@ module; #include #include +#include + export module stormkit.log; import std; @@ -35,10 +37,10 @@ export { [[nodiscard]] constexpr auto to_string(Severity severity) noexcept -> std::string; - STORMKIT_API - auto parse_args(std::span args) noexcept -> void; + STORMKIT_LOG_API + auto parse_args(std::span args) noexcept -> void; - class STORMKIT_API Logger { + class STORMKIT_LOG_API Logger { public: using LogClock = std::chrono::high_resolution_clock; @@ -128,7 +130,7 @@ export { [[nodiscard]] constexpr auto operator""_module() noexcept -> stormkit::log::Module; - class STORMKIT_API FileLogger final: public Logger { + class STORMKIT_LOG_API FileLogger final: public Logger { public: FileLogger(LogClock::time_point start, std::filesystem::path path) noexcept; FileLogger(LogClock::time_point start, std::filesystem::path path, Severity log_level) noexcept; @@ -149,7 +151,7 @@ export { std::filesystem::path m_base_path; }; - class STORMKIT_API ConsoleLogger final: public Logger { + class STORMKIT_LOG_API ConsoleLogger final: public Logger { public: explicit ConsoleLogger(LogClock::time_point start) noexcept; ConsoleLogger(LogClock::time_point start, Severity log_level) noexcept; diff --git a/modules/stormkit/lua.cppm b/modules/stormkit/lua.cppm new file mode 100644 index 000000000..0f87f3c18 --- /dev/null +++ b/modules/stormkit/lua.cppm @@ -0,0 +1,77 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include +#include +#include + +#include +#include + +export module stormkit.lua; + +import std; + +import stormkit.core; + +namespace stdfs = std::filesystem; + +namespace lb = luabridge; + +export namespace stormkit::lua { + struct Modules { + bool log = false; + bool image = false; + bool entities = false; + bool wsi = false; + bool gpu = false; + }; + + class STORMKIT_LUA_API Engine { + public: + ~Engine() noexcept; + + Engine(const Engine&) = delete; + auto operator=(const Engine&) -> Engine& = delete; + + Engine(Engine&& other) noexcept; + auto operator=(Engine&& other) noexcept -> Engine&; + + auto lua_main() noexcept -> std::expected; + + auto global_namespace() noexcept -> lb::Namespace; + + static auto create(const stdfs::path& file, Modules modules = {}) noexcept -> Engine; + + private: + explicit Engine(Modules) noexcept; + + auto load(const stdfs::path&) noexcept -> void; + + lua_State* m_global_state = nullptr; + lua_State* m_main_thread = nullptr; + }; +} // namespace stormkit::lua + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit::lua { + //////////////////////////////////////// + //////////////////////////////////////// + inline auto Engine::global_namespace() noexcept -> lb::Namespace { + return lb::getGlobalNamespace(m_global_state); + } + + //////////////////////////////////////// + //////////////////////////////////////// + inline auto Engine::create(const stdfs::path& file, Modules modules) noexcept -> Engine { + auto engine = Engine { std::move(modules) }; + engine.load(file); + return engine; + } +} // namespace stormkit::lua diff --git a/modules/stormkit/luau.cppm b/modules/stormkit/luau.cppm deleted file mode 100644 index 4ec5b4bf9..000000000 --- a/modules/stormkit/luau.cppm +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright (C) 2024 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include -#include -#include - -#include - -export module stormkit.luau; - -import std; - -import stormkit.core; - -import :core; - -namespace stdfs = std::filesystem; -namespace stdr = std::ranges; - -namespace lb = luabridge; - -export namespace stormkit::luau { - class STORMKIT_API Engine { - public: - Engine(const Engine&) = delete; - auto operator=(const Engine&) -> Engine& = delete; - - Engine(Engine&& other) noexcept - : m_global_state { std::exchange(other.m_global_state, nullptr) }, - m_main_thread { std::exchange(other.m_main_thread, nullptr) } {} - - auto operator=(Engine&& other) noexcept -> Engine& { - if (&other == this) [[unlikely]] - return *this; - m_global_state = std::exchange(other.m_global_state, nullptr); - m_main_thread = std::exchange(other.m_main_thread, nullptr); - - return *this; - }; - - ~Engine() noexcept { - if (m_main_thread) m_main_thread = nullptr; - - if (m_global_state) { - lua_close(m_global_state); - m_global_state = nullptr; - } - } - - auto load(const stdfs::path& file) noexcept { - auto data = TryAssert(io::read_text(file), std::format("Failed to load {}", file.string())); - - auto bytecode_size = 0_usize; - auto bytecode = luau_compile(stdr::data(data), stdr::size(data), nullptr, &bytecode_size); - auto result = luau_load(m_global_state, "main", bytecode, bytecode_size, 0); - std::free(bytecode); - - if (result != 0) { - auto len = usize { 0 }; - auto msg = lua_tolstring(m_global_state, -1, &len); - - ensures(result == 0, - std::format("Lua compilation error!\n-------------------------------\n{}", - std::string_view { msg, len })); - } - - core::init_lua(global_namespace()); - - m_main_thread = lua_newthread(m_global_state); - ensures(m_main_thread); - - lua_pushvalue(m_global_state, -2); - lua_remove(m_global_state, -3); - lua_xmove(m_global_state, m_main_thread, 1); - } - - auto lua_main() noexcept -> std::expected { - EXPECTS(m_main_thread); - - auto out = std::expected {}; - - luaL_sandbox(m_global_state); - luaL_sandboxthread(m_global_state); - - auto status = lua_resume(m_main_thread, nullptr, 0); - if (status == 0) { - if (const auto n = lua_gettop(m_main_thread); n) { - luaL_checkstack(m_main_thread, LUA_MINSTACK, "too many results to print"); - lua_getglobal(m_main_thread, "print"); - lua_insert(m_main_thread, 1); - lua_pcall(m_main_thread, n, 0, 0); - } - - lua_pop(m_global_state, 1); - } else { - auto l = 0; - luaL_traceback(m_global_state, m_main_thread, nullptr, l); - - const auto str = lua_tostring(m_main_thread, -1); - out = std::unexpected { std::string { str } }; - lua_pop(m_global_state, 1); - } - - return out; - } - - // template - // struct Binder { - // lb::Namespace _namespace; - // lb::Namespace::Class class; - - // auto bind_function(std::string_view name, auto&& function) noexcept -> Binder { - // _namespace.addFunction(stdr::data(name), std::forward(function)); - // return Binder { _namespace }; - // } - - // auto begin_namespace(std::string_view name) noexcept -> Binder { - // return Binder { _namespace.beginNamespace(stdr::data(name)) }; - // } - - // auto end_namespace() noexcept -> Binder { return Binder { _namespace.endNamespace() }; } - - // template - // auto begin_class(std::string_view name) noexcept -> Binder { - // return Binder { _namespace, _namespace.beginClass(stdr::data(name)) }; - // } - - // auto end_class(std::string_view name) noexcept -> Binder { return Binder { class.endClass() }; } - // }; - - auto global_namespace() noexcept -> lb::Namespace { return lb::getGlobalNamespace(m_global_state); } - - static auto create(const stdfs::path& file) noexcept -> Engine { - auto engine = Engine {}; - engine.load(file); - return engine; - } - - private: - Engine() noexcept { - m_global_state = luaL_newstate(); - luaL_openlibs(m_global_state); - } - - lua_State* m_global_state = nullptr; - lua_State* m_main_thread = nullptr; - }; -} // namespace stormkit::luau diff --git a/modules/stormkit/wsi.cppm b/modules/stormkit/wsi.cppm index 6190aca02..44ecc9ae2 100644 --- a/modules/stormkit/wsi.cppm +++ b/modules/stormkit/wsi.cppm @@ -10,7 +10,3 @@ export import :window; // export import :event_handler; export import :keyboard; export import :mouse; - -#ifdef STORMKIT_LUA_BINDING -export import :lua; -#endif diff --git a/modules/stormkit/wsi/core.cppm b/modules/stormkit/wsi/core.cppm index 4f5eeaa2f..8a586a654 100644 --- a/modules/stormkit/wsi/core.cppm +++ b/modules/stormkit/wsi/core.cppm @@ -6,6 +6,8 @@ module; #include +#include + export module stormkit.wsi:core; import std; @@ -26,12 +28,11 @@ export namespace stormkit::wsi { constexpr auto as_string(WM wm) noexcept -> std::string_view; - STORMKIT_API - auto parse_args(std::span args) noexcept -> void; + STORMKIT_WSI_API + auto parse_args(std::span args) noexcept -> void; [[nodiscard]] - STORMKIT_API - auto wm() noexcept -> WM; + STORMKIT_WSI_API auto wm() noexcept -> WM; } // namespace stormkit::wsi //////////////////////////////////////////////////////////////////// diff --git a/modules/stormkit/wsi/monitor.cppm b/modules/stormkit/wsi/monitor.cppm index 8c463afc3..93640527d 100644 --- a/modules/stormkit/wsi/monitor.cppm +++ b/modules/stormkit/wsi/monitor.cppm @@ -7,6 +7,8 @@ module; #include #include +#include + export module stormkit.wsi:monitor; import std; @@ -25,7 +27,7 @@ export { std::string name; std::vector extents; - u32 scale_factor = 1; + u32 scale_factor = 1; [[nodiscard]] constexpr auto operator<=>(const Monitor& other) const noexcept -> std::strong_ordering; @@ -39,12 +41,10 @@ export { auto format_as(const Monitor& monitor, FormatContext& ctx) noexcept -> decltype(ctx.out()); [[nodiscard]] - STORMKIT_API - auto get_monitors(bool update = false) noexcept -> std::span; + STORMKIT_WSI_API auto get_monitors(bool update = false) noexcept -> std::span; [[nodiscard]] - STORMKIT_API - auto get_primary_monitor() noexcept -> const Monitor&; + STORMKIT_WSI_API auto get_primary_monitor() noexcept -> const Monitor&; } // namespace stormkit::wsi FLAG_ENUM(stormkit::wsi::Monitor::Flags); diff --git a/modules/stormkit/wsi/window.cppm b/modules/stormkit/wsi/window.cppm index c11b9b874..10fae104d 100644 --- a/modules/stormkit/wsi/window.cppm +++ b/modules/stormkit/wsi/window.cppm @@ -8,6 +8,8 @@ module; #include #include +#include + export module stormkit.wsi:window; import std; @@ -121,7 +123,7 @@ export { DeactivateEventFunc, ActivateEventFunc>; - class STORMKIT_API Window { + class STORMKIT_WSI_API Window { public: ~Window() noexcept; diff --git a/src/gpu/core/vulkan.cpp b/src/gpu/core/vulkan.cpp index be4ef9241..58a5eaac1 100644 --- a/src/gpu/core/vulkan.cpp +++ b/src/gpu/core/vulkan.cpp @@ -1,12 +1,14 @@ #include +#include + #define STORMKIT_DEFINE_VK_PLATFORM #define VOLK_IMPLEMENTATION #include #include "assert.hpp" -#define VMA_CALL_PRE STORMKIT_API +#define VMA_CALL_PRE STORMKIT_GPU_API #define VMA_IMPLEMENTATION #define VMA_ASSERT(expr) vma_assert(expr, #expr) #include diff --git a/src/log/console_logger.cpp b/src/log/console_logger.cpp index 17cace9bf..bf61d6435 100644 --- a/src/log/console_logger.cpp +++ b/src/log/console_logger.cpp @@ -48,9 +48,10 @@ namespace stormkit::log { const auto out = (is_error) ? get_stderr() : get_stdout(); const auto header = [&severity, &module, &time] noexcept { - if (std::empty(module.name)) return std::format("[{}, {:%S}]", as_string(severity), time); + const auto severity_str = replace(as_string(severity), "Severity::", ""); + if (std::empty(module.name)) return std::format("[{}, {:%S}]", severity_str, time); else - return std::format("[{}, {:%S}, {}]", as_string(severity), time, module.name); + return std::format("[{}, {:%S}, {}]", severity_str, time, module.name); }(); const auto prefixed_string = [&header, string] noexcept { diff --git a/src/log/file_logger.cpp b/src/log/file_logger.cpp index 3ea007966..a87d3ed64 100644 --- a/src/log/file_logger.cpp +++ b/src/log/file_logger.cpp @@ -63,10 +63,11 @@ namespace stormkit::log { static constexpr auto LOG_LINE = "[{}, {}] {}\n"sv; static constexpr auto LOG_LINE_MODULE = "[{}, {}, {}] {}\n"sv; - auto final_string = std::string {}; - if (std::empty(m.name)) final_string = std::format(LOG_LINE, to_string(severity), time, string); + auto final_string = std::string {}; + const auto severity_str = replace(as_string(severity), "Severity::", ""); + if (std::empty(m.name)) final_string = std::format(LOG_LINE, severity_str, time, string); else - final_string = std::format(LOG_LINE_MODULE, to_string(severity), time, m.name, string); + final_string = std::format(LOG_LINE_MODULE, severity_str, time, m.name, string); m_streams.at(filepath.string()) << final_string << std::flush; } diff --git a/modules/stormkit/luau/core.cppm b/src/lua/core.cppm similarity index 62% rename from modules/stormkit/luau/core.cppm rename to src/lua/core.cppm index 506cfc246..6447757fe 100644 --- a/modules/stormkit/luau/core.cppm +++ b/src/lua/core.cppm @@ -4,9 +4,9 @@ module; -#include +#include -export module stormkit.luau:core; +module stormkit.lua:core; import std; @@ -14,20 +14,16 @@ import stormkit.core; namespace lb = luabridge; -export namespace stormkit::luau::core { - inline auto init_lua(lb::Namespace global_namespace) noexcept -> void; -} // namespace stormkit::luau::core - -namespace stormkit::luau::core { +namespace stormkit::lua::core { //////////////////////////////////////// //////////////////////////////////////// - inline auto bind_color(lb::Namespace& global_namespace) noexcept -> lb::Namespace { + inline auto bind_color(lb::Namespace&& global_namespace) noexcept -> lb::Namespace { return global_namespace.beginClass>("fcolor").endClass().beginClass>("ucolor").endClass(); } //////////////////////////////////////// //////////////////////////////////////// - inline auto bind_extent(lb::Namespace& global_namespace) noexcept -> lb::Namespace { + inline auto bind_extent(lb::Namespace&& global_namespace) noexcept -> lb::Namespace { return global_namespace.beginNamespace("math") .beginClass("uextent2") .endClass() @@ -42,8 +38,9 @@ namespace stormkit::luau::core { //////////////////////////////////////// //////////////////////////////////////// - inline auto init_lua(lb::Namespace global_namespace) noexcept -> void { - global_namespace = bind_color(global_namespace); - global_namespace = bind_extent(global_namespace); + export inline auto init_lua(lb::Namespace&& global_namespace) noexcept -> lb::Namespace { + global_namespace = bind_color(std::move(global_namespace)); + global_namespace = bind_extent(std::move(global_namespace)); + return global_namespace; } -} // namespace stormkit::luau::core +} // namespace stormkit::lua::core diff --git a/modules/stormkit/log/lua.cppm b/src/lua/entities.cppm similarity index 53% rename from modules/stormkit/log/lua.cppm rename to src/lua/entities.cppm index ad09fda84..497c16bb9 100644 --- a/modules/stormkit/log/lua.cppm +++ b/src/lua/entities.cppm @@ -4,23 +4,21 @@ module; -#include +#include -export module stormkit.log:lua; +module stormkit.lua:entities; import std; import stormkit.core; +import stormkit.entities; namespace lb = luabridge; -export namespace stormkit::log::lua { - inline auto init_lua(lb::Namespace global_namespace) noexcept -> void; -} - -namespace stormkit::log::lua { +export namespace stormkit::lua::entities { //////////////////////////////////////// //////////////////////////////////////// - inline auto init_lua(lb::Namespace) noexcept -> void { + inline auto init_lua(lb::Namespace&& global_namespace) noexcept -> lb::Namespace { + return global_namespace; } -} // namespace stormkit::log::lua +} // namespace stormkit::lua::entities diff --git a/modules/stormkit/gpu/lua.cppm b/src/lua/gpu.cppm similarity index 53% rename from modules/stormkit/gpu/lua.cppm rename to src/lua/gpu.cppm index a4384c047..b0d2e9617 100644 --- a/modules/stormkit/gpu/lua.cppm +++ b/src/lua/gpu.cppm @@ -4,23 +4,21 @@ module; -#include +#include -export module stormkit.gpu:lua; +module stormkit.lua:gpu; import std; import stormkit.core; +import stormkit.gpu; namespace lb = luabridge; -export namespace stormkit::gpu::lua { - inline auto init_lua(lb::Namespace global_namespace) noexcept -> void; -} - -namespace stormkit::gpu::lua { +export namespace stormkit::lua::gpu { //////////////////////////////////////// //////////////////////////////////////// - inline auto init_lua(lb::Namespace) noexcept -> void { + inline auto init_lua(lb::Namespace&& global_namespace) noexcept -> lb::Namespace { + return global_namespace; } -} // namespace stormkit::gpu::lua +} // namespace stormkit::lua::gpu diff --git a/modules/stormkit/image/lua.cppm b/src/lua/image.cppm similarity index 52% rename from modules/stormkit/image/lua.cppm rename to src/lua/image.cppm index 6e7293e56..6d94fd997 100644 --- a/modules/stormkit/image/lua.cppm +++ b/src/lua/image.cppm @@ -4,23 +4,21 @@ module; -#include +#include -export module stormkit.image:lua; +module stormkit.lua:image; import std; import stormkit.core; +import stormkit.image; namespace lb = luabridge; -export namespace stormkit::image::lua { - inline auto init_lua(lb::Namespace global_namespace) noexcept -> void; -} - -namespace stormkit::image::lua { +export namespace stormkit::lua::image { //////////////////////////////////////// //////////////////////////////////////// - inline auto init_lua(lb::Namespace) noexcept -> void { + inline auto init_lua(lb::Namespace&& global_namespace) noexcept -> lb::Namespace { + return global_namespace; } -} // namespace stormkit::image::lua +} // namespace stormkit::lua::image diff --git a/src/lua/log.cppm b/src/lua/log.cppm new file mode 100644 index 000000000..e719ee32b --- /dev/null +++ b/src/lua/log.cppm @@ -0,0 +1,22 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +module stormkit.lua:log; + +import std; + +import stormkit.core; +import stormkit.log; + +namespace lb = luabridge; + +export namespace stormkit::lua::log { + inline auto init_lua(lb::Namespace&& global_namespace) noexcept -> lb::Namespace { + return global_namespace; + } +} // namespace stormkit::lua::log diff --git a/src/lua/lua.cpp b/src/lua/lua.cpp new file mode 100644 index 000000000..443ff34f8 --- /dev/null +++ b/src/lua/lua.cpp @@ -0,0 +1,206 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#define NO_CONSTANTS +#include + +#include +#include +#include + +#include + +#include + +module stormkit.lua; + +import stormkit.core; +import :core; + +import stormkit.log; +import :log; + +#if STORMKIT_LIB_ENTITIES_ENABLED +import stormkit.entities; +import :entities; +#endif +#if STORMKIT_LIB_IMAGE_ENABLED +import stormkit.image; +import :image; +#endif +#if STORMKIT_LIB_WSI_ENABLED +import stormkit.wsi; +import :wsi; +#endif +#if STORMKIT_LIB_GPU_ENABLED +import stormkit.gpu; +import :gpu; +#endif + +namespace stdfs = std::filesystem; +namespace stdr = std::ranges; + +namespace lb = luabridge; + +LOGGER("stormkit.lua") + +namespace stormkit::lua { + //////////////////////////////////////// + //////////////////////////////////////// + Engine::Engine(Modules modules) noexcept { + m_global_state = luaL_newstate(); + luaL_openlibs(m_global_state); + + auto global_namespace = lb::getGlobalNamespace(m_global_state); + + global_namespace = core::init_lua(std::move(global_namespace)); + if (modules.log) { +#if STORMKIT_LIB_LOG_ENABLED + dlog("Log module enabled"); + global_namespace = log::init_lua(std::move(global_namespace)); +#else + elog("Trying to bind log module while disabled in this stormkit distribution!"); +#endif + } + if (modules.entities) { +#if STORMKIT_LIB_ENTITIES_ENABLED + dlog("Entities module enabled"); + global_namespace = entities::init_lua(std::move(global_namespace)); +#else + elog("Trying to bind entities module while disabled in this stormkit distribution!"); +#endif + } + if (modules.image) { +#if STORMKIT_LIB_IMAGE_ENABLED + dlog("Image module enabled"); + global_namespace = image::init_lua(std::move(global_namespace)); +#else + elog("Trying to bind image module while disabled in this stormkit distribution!"); +#endif + } + if (modules.wsi) { +#if STORMKIT_LIB_WSI_ENABLED + dlog("Wsi module enabled"); + global_namespace = wsi::init_lua(std::move(global_namespace)); +#else + elog("Trying to bind wsi module while disabled in this stormkit distribution!"); +#endif + } + if (modules.gpu) { +#if STORMKIT_LIB_GPU_ENABLED + dlog("Gpu module enabled"); + global_namespace = gpu::init_lua(std::move(global_namespace)); +#else + elog("Trying to bind gpu module while disabled in this stormkit distribution!"); +#endif + } + } + + //////////////////////////////////////// + //////////////////////////////////////// + Engine::Engine(Engine&& other) noexcept + : m_global_state { std::exchange(other.m_global_state, nullptr) }, + m_main_thread { std::exchange(other.m_main_thread, nullptr) } { + } + + //////////////////////////////////////// + //////////////////////////////////////// + auto Engine::operator=(Engine&& other) noexcept -> Engine& { + if (&other == this) [[unlikely]] + return *this; + m_global_state = std::exchange(other.m_global_state, nullptr); + m_main_thread = std::exchange(other.m_main_thread, nullptr); + + return *this; + }; + + //////////////////////////////////////// + //////////////////////////////////////// + Engine::~Engine() noexcept { + if (m_main_thread) m_main_thread = nullptr; + + if (m_global_state) { + lua_close(m_global_state); + m_global_state = nullptr; + } + } + + //////////////////////////////////////// + //////////////////////////////////////// + auto Engine::load(const stdfs::path& file) noexcept -> void { + auto data = TryAssert(io::read_text(file), std::format("Failed to load {}", file.string())); + + auto bytecode_size = 0_usize; + auto bytecode = luau_compile(stdr::data(data), stdr::size(data), nullptr, &bytecode_size); + auto result = luau_load(m_global_state, "main", bytecode, bytecode_size, 0); + std::free(bytecode); + + if (result != 0) { + auto len = usize { 0 }; + auto msg = lua_tolstring(m_global_state, -1, &len); + + ensures(result == 0, + std::format("Lua compilation error!\n-------------------------------\n{}", std::string_view { msg, len })); + } + + // m_main_thread = lua_newthread(m_global_state); + // ensures(m_main_thread); + + // lua_pushvalue(m_global_state, -2); + // lua_remove(m_global_state, -3); + // lua_xmove(m_global_state, m_main_thread, 1); + } + + static int traceback(lua_State* L) { + if (!lua_isstring(L, 1)) /* 'message' not a string? */ + return 1; /* keep it intact */ + lua_getfield(L, LUA_GLOBALSINDEX, "debug"); + if (!lua_istable(L, -1)) { + lua_pop(L, 1); + return 1; + } + lua_getfield(L, -1, "traceback"); + if (!lua_isfunction(L, -1)) { + lua_pop(L, 2); + return 1; + } + lua_pushvalue(L, 1); /* pass error message */ + lua_pushinteger(L, 2); /* skip this function and traceback */ + lua_call(L, 2, 1); /* call debug.traceback */ + return 1; + } + + //////////////////////////////////////// + //////////////////////////////////////// + auto Engine::lua_main() noexcept -> std::expected { + // EXPECTS(m_main_thread); + + auto out = std::expected {}; + + traceback(m_global_state); + + luaL_sandbox(m_global_state); + luaL_sandboxthread(m_global_state); + + auto status = lua_resume(m_global_state, nullptr, 0); + if (status == 0) { + // if (const auto n = lua_gettop(m_global_state); n) { + // luaL_checkstack(m_global_state, LUA_MINSTACK, "too many results to print"); + // lua_getglobal(m_global_state, "print"); + // lua_insert(m_global_state, 1); + // lua_pcall(m_global_state, n, 0, 0); + // } + + // lua_pop(m_global_state, 1); + } else { + traceback(m_global_state); + auto error = std::string { lua_tostring(m_global_state, -1) }; + out = std::unexpected { std::move(error) }; + } + + return out; + } +} // namespace stormkit::lua diff --git a/src/wsi/lua.cpp b/src/lua/wsi.cpp similarity index 86% rename from src/wsi/lua.cpp rename to src/lua/wsi.cpp index adc4dca08..87000a9bb 100644 --- a/src/wsi/lua.cpp +++ b/src/lua/wsi.cpp @@ -6,34 +6,46 @@ module; #include -#include +#include -module stormkit.wsi; +module stormkit.lua; import std; import stormkit.core; - -import :core; - -import :core; -import :mouse; -import :keyboard; -import :monitor; -import :window; +import stormkit.wsi; namespace lb = luabridge; -namespace stormkit::wsi::lua { +namespace stormkit::lua::wsi { using stormkit::wsi::EventType; using stormkit::wsi::Window; using stormkit::wsi::WindowFlag; using stormkit::wsi::WM; + //////////////////////////////////////// + //////////////////////////////////////// + auto open_window(std::string name, u32 width, u32 height, wsi::WindowFlag flags) noexcept -> wsi::Window { + std::println("AAAAAAAAAAAAAAA"); + return wsi::Window::open(std::move(name), { width, height }, flags); + } + namespace { //////////////////////////////////////// //////////////////////////////////////// - auto bind_core(lb::Namespace& global_namespace) noexcept -> lb::Namespace { + template + constexpr auto make_lua_closure() noexcept { + return [](Window* window, lb::LuaRef func) static noexcept { + window->on([func = std::move(func)](Args&&... args) noexcept { + const auto result = func(std::forward(args)...); + ensures(result.wasOk(), result.errorMessage()); + }); + }; + } + + //////////////////////////////////////// + //////////////////////////////////////// + auto bind_core(lb::Namespace&& global_namespace) noexcept -> lb::Namespace { return global_namespace.beginNamespace("wsi") .beginNamespace("wm") .addProperty("WIN32", [] static noexcept { return WM::WIN32; }) @@ -50,20 +62,7 @@ namespace stormkit::wsi::lua { //////////////////////////////////////// //////////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto make_lua_closure() noexcept { - return [](Window* window, lb::LuaRef func) static noexcept { - window->on([func = std::move(func)](Args&&... args) noexcept { - const auto result = func(std::forward(args)...); - ensures(result.wasOk(), result.errorMessage()); - }); - }; - } - - //////////////////////////////////////// - //////////////////////////////////////// - auto bind_window(lb::Namespace& global_namespace) noexcept -> lb::Namespace { + auto bind_window(lb::Namespace&& global_namespace) noexcept -> lb::Namespace { return global_namespace.beginNamespace("wsi") .beginNamespace("window_flag") .addProperty("DEFAULT", [] static noexcept { return WindowFlag::DEFAULT; }) @@ -116,15 +115,16 @@ namespace stormkit::wsi::lua { .addFunction("on_activate", (make_lua_closure())) .addFunction("on_deactivate", (make_lua_closure())) .endClass() - .addFunction("open_window", &open_window) + .addFunction("open_window", open_window) .endNamespace(); } } // namespace //////////////////////////////////////// //////////////////////////////////////// - auto init_lua(lb::Namespace global_namespace) noexcept -> void { - global_namespace = bind_core(global_namespace); - global_namespace = bind_window(global_namespace); + auto init_lua(lb::Namespace&& global_namespace) noexcept -> lb::Namespace { + global_namespace = bind_core(std::move(global_namespace)); + global_namespace = bind_window(std::move(global_namespace)); + return global_namespace; } -} // namespace stormkit::wsi::lua +} // namespace stormkit::lua::wsi diff --git a/modules/stormkit/wsi/lua.cppm b/src/lua/wsi.cppm similarity index 72% rename from modules/stormkit/wsi/lua.cppm rename to src/lua/wsi.cppm index 35fb8f101..15fc0cb9b 100644 --- a/modules/stormkit/wsi/lua.cppm +++ b/src/lua/wsi.cppm @@ -6,25 +6,18 @@ module; #include -#include +#include -export module stormkit.wsi:lua; +module stormkit.lua:wsi; import std; import stormkit.core; - -import :core; -import :window; +import stormkit.wsi; namespace lb = luabridge; export { - namespace stormkit::wsi::lua { - STORMKIT_API - auto init_lua(lb::Namespace global_namespace) noexcept -> void; - } // namespace stormkit::wsi::lua - template<> struct lb::Stack: lb::Enum {}; @@ -56,13 +49,8 @@ export { stormkit::wsi::EventType::MOUSE_MOVED, stormkit::wsi::EventType::ACTIVATE, stormkit::wsi::EventType::DEACTIVATE> {}; -} -namespace stormkit::wsi::lua { - //////////////////////////////////////// - //////////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto open_window(std::string name, u32 width, u32 height, wsi::WindowFlag flags) noexcept -> wsi::Window { - return wsi::Window::open(std::move(name), { width, height }, flags); - } -} // namespace stormkit::wsi::lua + namespace stormkit::lua::wsi { + auto init_lua(lb::Namespace&& global_namespace) noexcept -> lb::Namespace; + } // namespace stormkit::lua::wsi +} diff --git a/src/main/macos/Main-macOS.swift b/src/main/macos/Main-macOS.swift deleted file mode 100644 index 3f3e328cd..000000000 --- a/src/main/macos/Main-macOS.swift +++ /dev/null @@ -1,3 +0,0 @@ -import Foundation - -print("hello world") diff --git a/tools/terra/xmake.lua b/tools/terra/xmake.lua index 9cbef4d3b..fb5a071e1 100644 --- a/tools/terra/xmake.lua +++ b/tools/terra/xmake.lua @@ -1,19 +1,5 @@ target("terra", function() - set_kind("binary") - set_languages("cxxlatest", "clatest") - - add_rules("stormkit.flags") - add_rules("platform.windows.subsystem.console") - - add_deps("core", "main", "log") - - if is_mode("debug") then - add_defines("STORMKIT_BUILD_DEBUG") - add_defines("STORMKIT_ASSERT=1") - set_suffixname("-d") - else - add_defines("STORMKIT_ASSERT=0") - end + add_rules("stormkit::example") add_files("src/main.cpp") diff --git a/xmake.lua b/xmake.lua index 5713a3c4f..de5ef2071 100644 --- a/xmake.lua +++ b/xmake.lua @@ -6,7 +6,6 @@ local allowed_modes = { "profile", } --- add_repositories("nazara-repo https://github.com/arthapz/xmake-repo-nazara") add_repositories("nazara-repo https://github.com/NazaraEngine/xmake-repo") add_repositories("tapzcrew-repo https://github.com/Tapzcrew/xmake-repo main") @@ -15,24 +14,17 @@ set_project("StormKit") set_version("0.1.0", { build = "%Y%m%d%H%M" }) -includes("xmake/rules/*.lua") - ---------------------------- options ---------------------------- includes("xmake/options.xmake.lua") -if get_config("devmode") then - -- set_policy("build.c++.modules.non_cascading_changes", true) - set_policy("build.c++.modules.hide_dependencies", true) -end +if get_config("devmode") then set_policy("build.c++.modules.hide_dependencies", true) end ---------------------------- global rules ---------------------------- +includes("xmake/rules/*.xmake.lua") + if get_config("vsxmake") then add_rules("plugin.vsxmake.autoupdate") end if get_config("compile_commands") then - if test then - if test2 then - end - end add_rules("plugin.compile_commands.autoupdate", { outputdir = "build", lsp = "clangd" }) end @@ -42,216 +34,128 @@ end if not is_host("windows") then add_rules("mode.valgrind") end +---------------------------- global configs ---------------------------- +set_allowedmodes(allowed_modes) +set_allowedplats("windows", "mingw", "linux", "macosx", "wasm") +set_allowedarchs("windows|x64", "windows|arm64", "linux|x86_64", "linux|aarch64", "macosx|x86_64", "macosx|arm64") + set_fpmodels("fast") add_vectorexts("fma") add_vectorexts("neon") add_vectorexts("avx", "avx2") add_vectorexts("sse", "sse2", "sse3", "ssse3", "sse4.2") ----------------------------- global configs ---------------------------- -set_allowedmodes(allowed_modes) -set_allowedplats("windows", "mingw", "linux", "macosx", "wasm") -set_allowedarchs("windows|x64", "windows|arm64", "linux|x86_64", "linux|aarch64", "macosx|x86_64", "macosx|arm64") +local suffix +if is_kind("static") then suffix = "-static" end -add_defines("ANKERL_UNORDERED_DENSE_STD_MODULE=1", "FROZEN_STD_MODULE=1") +if is_mode("debug") then + suffix = (suffix or "") .. "-debug" +elseif is_mode("reldbg") then + suffix = (suffix or "") .. "-reldebug" +end -includes("xmake/dependencies.xmake.lua") -includes("xmake/targets.xmake.lua") +if suffix then set_suffixname(suffix) end ---------------------------- dependencies ---------------------------- -for name, module in pairs(modules) do - if name == "core" or name == "main" or name == "test" or get_config(name) then - for _, package in ipairs(module.public_packages) do - add_requires_with_conf_transitive(package) - end - for _, package in ipairs(module.packages) do - add_requires_with_conf(package) - end +includes("xmake/packages/*.xmake.lua") + +-- core -- +add_requires("frozen", { system = false, configs = { modules = true, std_import = true, cpp = "latest" } }) +add_requires("unordered_dense", { system = false, configs = { modules = true, std_import = true } }) +add_requires("tl_function_ref", { system = false, configs = { modules = true, std_import = true } }) + +-- wsi -- +if get_config("wsi") then + if is_plat("linux") then + add_requires("libxcb") + add_requires("xcb-util-keysyms") + add_requires("xcb-util") + add_requires("xcb-util-image") + add_requires("xcb-util-wm") + add_requires("xcb-util-errors") + add_requires("wayland") + add_requires("wayland-protocols") + add_requires("libxkbcommon", { + system = false, + configs = { + wayland = true, + x11 = true, + }, + }) end end -set_suffixname("-d") +-- image -- +if get_config("image") then + add_requires("libktx") + add_requires("libpng") + add_requires("libjpeg-turbo", is_plat("windows") and { + system = false, + configs = { + runtimes = "MD", + shared = true, + }, + }) +end + +-- gpu -- +if get_config("gpu") then + local vulkan_version = "1.4.335" + add_requires("volk", { + version = vulkan_version, + system = false, + }) + add_requires("vulkan-headers", { + version = vulkan_version, + system = false, + configs = { + modules = false, + }, + }) + add_requires("vulkan-memory-allocator", { + version = "v3.3.0", + system = false, + }) +end + +---------------------------- configvar ---------------------------- +for _, name in ipairs({ "log", "entities", "image", "wsi", "gpu", "lua" }) do + if get_config(name) then set_configvar("STORMKIT_LIB_" .. string.upper(name) .. "_ENABLED", true) end +end ---------------------------- targets ---------------------------- namespace("stormkit", function() - for _, name in ipairs({ "log", "entities", "image", "wsi", "gpu", "luau" }) do - if get_config(name) then set_configvar("STORMKIT_LIB_" .. string.upper(name) .. "_ENABLED", "true") end - end + module_dir = "$(projectdir)/modules/stormkit" + src_dir = "$(projectdir)/src" + include_dir = "$(projectdir)/include" - includes("src/core/xmake.lua") - - for name, module in pairs(modules) do - if module then - local modulename = module.modulename - - if name == "core" or name == "main" or name == "test" or get_config(name) then - target(name, function() - set_group("libraries") - - if module.custom then module.custom() end - - if name == "main" or name == "test" then - set_kind("static") - else - set_kind("$(kind)") - end - - set_languages("cxxlatest", "clatest") - - add_rules("stormkit.flags") - add_defines("STORMKIT_BUILD") - if is_mode("debug") then - add_defines("STORMKIT_BUILD_DEBUG") - set_suffixname("-d") - end - - if is_kind("static") then add_defines("STORMKIT_STATIC", { public = true }) end - - local src_path = path.join("src", modulename) - local module_path = path.join("modules", "stormkit", modulename) - local include_path = path.join("include", "(stormkit", modulename) - - for _, file in ipairs(os.files(path.join(src_path, "**.cppm"))) do - add_files(file) - end - for _, file in ipairs(os.files(path.join(src_path, "**.cpp"))) do - add_files(file) - end - for _, file in ipairs(os.files(path.join(src_path, "**.mm"))) do - add_files(file, { mxxflags = "-std=c++23" }) - end - for _, file in ipairs(os.files(path.join(src_path, "**.m"))) do - add_files(file) - end - for _, file in ipairs(os.files(path.join(src_path, "**.inl"))) do - add_files(file) - end - - if os.exists(module_path .. ".cppm") then add_files(module_path .. ".cppm", { public = true }) end - - if os.files(module_path) then - for _, file in ipairs(os.files(path.join(module_path, "**.cppm"))) do - add_files(file, { public = true }) - end - for _, file in ipairs(os.files(path.join(module_path, "**.inl"))) do - add_headerfiles(file) - end - end - - local _include_path = include_path:gsub("%(", "") - if os.exists(_include_path) then - add_headerfiles(path.join(include_path, "**.inl)")) - add_headerfiles(path.join(include_path, "**.hpp)")) - end - - if is_plat("windows") or is_plat("mingw") then - for _, plat in ipairs({ "posix", "linux", "darwin", "macos", "ios", "bsd", "android" }) do - remove_files(path.join(src_path, plat, "**")) - remove_headerfiles(path.join(src_path, plat, "**")) - end - elseif is_plat("macosx") then - for _, plat in ipairs({ "linux", "win32", "ios", "bsd", "android" }) do - remove_files(path.join(src_path, plat, "**")) - remove_headerfiles(path.join(src_path, plat, "**")) - end - elseif is_plat("ios") then - for _, plat in ipairs({ "linux", "macos", "win32", "bsd", "android" }) do - remove_files(path.join(src_path, plat, "**")) - remove_headerfiles(path.join(src_path, plat, "**")) - end - elseif is_plat("android") then - for _, plat in ipairs({ "linux", "darwin", "macos", "ios", "bsd", "win32" }) do - remove_files(path.join(src_path, plat, "**")) - remove_headerfiles(path.join(src_path, plat, "**")) - end - elseif is_plat("linux") then - for _, plat in ipairs({ "win32", "darwin", "macos", "ios", "bsd", "android" }) do - remove_files(path.join(src_path, plat, "**")) - remove_headerfiles(path.join(src_path, plat, "**")) - end - end - - if not get_config("luau") then remove_files(path.join(module_path, "lua.cppm")) end - - add_includedirs("$(projectdir)/include", { public = true }) - - if module.defines then add_defines(module.defines) end - - if module.public_defines then add_defines(module.public_defines, { public = true }) end - - if module.cxxflags then - add_cxxflags(module.cxxflags) - add_mxxflags(module.cxxflags) - end - - if module.deps then add_deps(module.deps) end - - if module.public_deps then add_deps(module.public_deps, { public = true }) end - - if module.packages then - local packages = {} - for _, package in ipairs(module.packages) do - table.insert(packages, package:split(" ")[1]) - end - - add_packages(packages, { public = is_kind("static") }) - end - - if module.public_packages then - local packages = {} - for _, package in ipairs(module.public_packages) do - table.insert(packages, package:split(" ")[1]) - end - add_packages(packages, { public = true }) - end - - if module.frameworks then add_frameworks(module.frameworks, { public = is_kind("static") }) end - - add_options("sanitizers") - end) - end - end + includes("xmake/targets/core.xmake.lua") + includes("xmake/targets/main.xmake.lua") + includes("xmake/targets/test.xmake.lua") + + for _, name in ipairs({ "log", "entities", "gpu", "image", "wsi", "lua" }) do + if get_config(name) then includes("xmake/targets/" .. name .. ".xmake.lua") end end + includes("xmake/targets/examples.xmake.lua") + + if get_config("tests") then includes("xmake/targets/tests.xmake.lua") end + if get_config("tools") then includes("xmake/targets/tools.xmake.lua") end + target("stormkit", function() - set_group("libraries") set_kind("moduleonly") set_languages("cxxlatest", "clatest") - add_rules("stormkit.flags") + add_rules("stormkit::flags") + add_files("modules/stormkit.cppm") - add_deps("core", "main") - for _, name in ipairs({ "log", "entities", "image", "wsi", "gpu", "luau" }) do - if get_config(name) then - add_deps(name) - set_configvar("STORMKIT_LIB_" .. string.upper(name) .. "_ENABLED", "true") - end + add_deps("stormkit::core") + for _, name in ipairs({ "log", "entities", "gpu", "image", "wsi", "lua" }) do + if get_config(name) then add_deps("stormkit::" .. name) end end - add_headerfiles("$(builddir)/.gens/include/(stormkit/*.hpp)") + set_group("libraries") end) - add_includedirs("$(builddir)/.gens/include") - - -- if not is_host("windows") then add_requireconfs("**.pkg-config", { override = true, system = true }) end - -- add_requireconfs("**.bison", { override = true, system = true }) - -- add_requireconfs("**.m4", { override = true, system = true }) - -- add_requireconfs("**.python", { override = true, system = true }) - -- add_requireconfs("**.meson", { override = true, system = true }) - -- add_requireconfs("**.autoconf", { override = true, system = true }) - -- add_requireconfs("**.cmake", { override = true, system = true }) - -- add_requireconfs("**.nasm", { override = true, system = true }) - - for name, _ in pairs(modules) do - if get_config("examples_" .. name) then - local example_dir = path.join("examples", name) - if os.exists(example_dir) and has_config("" .. name) then - includes(path.join(example_dir, "**", "xmake.lua")) - end - end - end - - if get_config("tests") then includes("xmake/tests.xmake.lua") end - if get_config("tools") then includes("tools/**.lua") end end) diff --git a/xmake/ktx.xmake.lua b/xmake/ktx.xmake.lua deleted file mode 100644 index 59bd44d8a..000000000 --- a/xmake/ktx.xmake.lua +++ /dev/null @@ -1,46 +0,0 @@ -package("libktx", function() - set_kind("library") - set_homepage("https://github.com/KhronosGroup/KTX-Software") - set_description("KTX (Khronos Texture) Library and Tools") - set_license("Apache-2.0") - - set_urls( - "https://github.com/KhronosGroup/KTX-Software/archive/refs/tags/$(version).tar.gz", - "https://github.com/KhronosGroup/KTX-Software.git" - ) - add_versions("v4.3.2", "74a114f465442832152e955a2094274b446c7b2427c77b1964c85c173a52ea1f") - add_versions("v4.4.0", "3585d76edcdcbe3a671479686f8c81c1c10339f419e4b02a9a6f19cc6e4e0612") - - add_deps("cmake") - - add_configs("vulkan", { description = "Enable Vulkan texture upload.", default = true, type = "boolean" }) - add_configs("opengl", { description = "Enable OpenGL texture upload.", default = true, type = "boolean" }) - - on_install("macosx", "android", "linux", "windows", "mingw", "cross", function(package) - local configs = { - "-DCMAKE_BUILD_TYPE=" .. (package:is_debug() and "Debug" or "Release"), - "-DBUILD_SHARED_LIBS=" .. (package:config("shared") and "ON" or "OFF"), - "-DKTX_FEATURE_STATIC_LIBRARY=" .. (package:config("shared") and "OFF" or "ON"), - "-DKTX_FEATURE_VK_UPLOAD=" .. (package:config("vulkan") and "ON" or "OFF"), - "-DKTX_FEATURE_GL_UPLOAD=" .. (package:config("opengl") and "ON" or "OFF"), - "-DKTX_FEATURE_TESTS=OFF", - "-DKTX_FEATURE_TOOLS=OFF", - } - - import("package.tools.cmake").install(package, configs) - end) - - on_test( - function(package) - assert(package:check_csnippets({ - test = [[ - #include - - void test() { - ktxTexture* kTexture; - } - ]], - })) - end - ) -end) diff --git a/xmake/options.xmake.lua b/xmake/options.xmake.lua index ec610b00e..01cb52673 100644 --- a/xmake/options.xmake.lua +++ b/xmake/options.xmake.lua @@ -2,36 +2,43 @@ option("examples_gpu", { default = false, category = "root menu/build", - deps = { "examples" }, + deps = { "examples", "gpu" }, after_check = function(option) - if option:dep("examples"):enabled() then option:enable(true) end + if option:dep("examples"):enabled() then option:enable(option:dep("gpu"):enabled()) end end, }) option("examples_wsi", { default = false, category = "root menu/build", - deps = { "examples" }, + deps = { "examples", "wsi" }, after_check = function(option) - if option:dep("examples"):enabled() then option:enable(true) end + if option:dep("examples"):enabled() then option:enable(option:dep("wsi"):enabled()) end end, }) option("examples_log", { default = false, category = "root menu/build", - deps = { "examples" }, + deps = { "examples", "log" }, after_check = function(option) - if option:dep("examples"):enabled() then option:enable(true) end + if option:dep("examples"):enabled() then option:enable(option:dep("log"):enabled()) end end, }) option("examples_entities", { default = false, category = "root menu/build", - deps = { "examples" }, + deps = { "examples", "entities" }, after_check = function(option) - if option:dep("examples"):enabled() then - end + if option:dep("examples"):enabled() then option:enable(option:dep("entities"):enabled()) end end, }) --option:enable(true) end end }) +option("examples_lua", { + default = false, + category = "root menu/build", + deps = { "examples", "lua" }, + after_check = function(option) + if option:dep("examples"):enabled() then option:enable(option:dep("lua"):enabled()) end + end, +}) option("examples", { default = false, category = "root menu/build" }) option("tools", { default = false, @@ -51,7 +58,7 @@ option("entities", { default = true, category = "root menu/modules" }) option("image", { default = true, category = "root menu/modules", deps = { "log" } }) option("wsi", { default = true, category = "root menu/modules", deps = { "log" } }) option("gpu", { default = true, category = "root menu/modules", deps = { "log", "image", "wsi" } }) -option("luau", { default = true, category = "root menu/modules", deps = { "log", "entities", "image", "wsi", "gpu" } }) +option("lua", { default = true, category = "root menu/modules", deps = { "log" } }) option("compile_commands", { default = false, category = "root menu/support" }) option("vsxmake", { default = false, category = "root menu/support" }) diff --git a/xmake/rules/stormkit_application.xmake.lua b/xmake/rules/stormkit_application.xmake.lua new file mode 100644 index 000000000..259c1de01 --- /dev/null +++ b/xmake/rules/stormkit_application.xmake.lua @@ -0,0 +1,12 @@ +namespace("stormkit", function() + rule("application", function() + add_deps("flags") + + on_config(function(target) + local stormkit_components = target:values("stormkit.components") or {} + target:set("kind", "binary") + target:set("languages", "cxxlatest", "clatest") + target:add("packages", "stormkit", { components = table.join("core", "main", stormkit_components) }) + end) + end) +end) diff --git a/xmake/rules/stormkit_example.xmake.lua b/xmake/rules/stormkit_example.xmake.lua new file mode 100644 index 000000000..131dc2c14 --- /dev/null +++ b/xmake/rules/stormkit_example.xmake.lua @@ -0,0 +1,21 @@ +namespace("stormkit", function() + rule("example", function() + add_deps("stormkit::flags") + add_deps("platform.windows.subsystem.console") + + on_load(function(target) + target:set("kind", "binary") + target:set("languages", "cxxlatest", "clatest") + target:add("deps", "stormkit::stormkit", "stormkit::main") + if target:is_plat("windows") then target:add("files", "examples/common/Windows/manifest.manifest") end + if get_config("apple_bundle") then + target:add("rules", "xcode.application") + if target:is_plat("macosx") then + target:add("files", path.join("$(projectdir)", "examples/common/macOS/info.plist")) + elseif target:is_plat("iphoneos") then + target:add("files", path.join("$(projectdir)", "examples/common/iOS/info.plist")) + end + end + end) + end) +end) diff --git a/xmake/rules/stormkit_flags.xmake.lua b/xmake/rules/stormkit_flags.xmake.lua index 77901b54e..6a8168ebb 100644 --- a/xmake/rules/stormkit_flags.xmake.lua +++ b/xmake/rules/stormkit_flags.xmake.lua @@ -1,249 +1,254 @@ -rule("stormkit.flags", function() - on_load("linux", "mingw", "macosx", "ios", "android", function(target) - if get_config("lto") then - target:set("policy", "build.optimization.lto", true) - if get_config("toolchain") == "llvm" or get_config("toolchain") == "clang" then - target:add("ldflags", "-flto=thin", { force = true }) - target:add("shflags", "-flto=thin", { force = true }) +namespace("stormkit", function() + rule("flags", function() + on_load("linux", "mingw", "macosx", "ios", "android", function(target) + if get_config("lto") then + target:set("policy", "build.optimization.lto", true) + if get_config("toolchain") == "llvm" or get_config("toolchain") == "clang" then + target:add("ldflags", "-flto=thin", { force = true }) + target:add("shflags", "-flto=thin", { force = true }) + end + end + if get_config("mold") and not is_subhost("windows") then + local arg = "-fuse-ld=mold" + if type(get_config("mold")) == "string" then arg = "-fuse-ld=" .. get_config("mold") end + target:add("ldflags", arg, { force = true }) + target:add("shflags", arg, { force = true }) end - end - if get_config("mold") and not is_subhost("windows") then - local arg = "-fuse-ld=mold" - if type(get_config("mold")) == "string" then arg = "-fuse-ld=" .. get_config("mold") end - target:add("ldflags", arg, { force = true }) - target:add("shflags", arg, { force = true }) - end - target:set("utf-8", true) + target:set("utf-8", true) - if get_config("sanitizers") and is_mode("debug", "release", "releasedbg") and target:is_binary() then - target:set("policy", "build.sanitizer.address", true) - target:set("policy", "build.sanitizer.undefined", true) - end - if - get_config("toolchain") == "llvm" - or get_config("toolchain") == "clang" - or get_config("toolchain") == "gcc" - then - target:add("syslinks", "dl") - end - end) - on_load("windows", function(target) - import("core.tool.compiler") - local rad_enabled = false - if get_config("rad") and is_subhost("windows") then - rad_enabled = true - target:add("ldflags", "-fuse-ld=radlink", { force = true }) - target:add("shflags", "-fuse-ld=radlink", { force = true }) - end + if get_config("sanitizers") and is_mode("debug", "release", "releasedbg") and target:is_binary() then + target:set("policy", "build.sanitizer.address", true) + target:set("policy", "build.sanitizer.undefined", true) + end + if + get_config("toolchain") == "llvm" + or get_config("toolchain") == "clang" + or get_config("toolchain") == "gcc" + then + target:add("syslinks", "dl") + end + end) + on_load("windows", function(target) + import("core.tool.compiler") + local rad_enabled = false + if get_config("rad") and is_subhost("windows") then + rad_enabled = true + target:add("ldflags", "-fuse-ld=radlink", { force = true }) + target:add("shflags", "-fuse-ld=radlink", { force = true }) + end - if get_config("sanitizers") and is_mode("release", "releasedbg") and target:is_binary() then - if get_config("toolchain") == "llvm" or get_config("toolchain") == "clang" then - if get_config("runtimes") == "c++_shared" or get_config("runtimes") == "c++_static" then - target:set("policy", "build.sanitizer.address", true) - target:set("policy", "build.sanitizer.undefined", true) + if get_config("sanitizers") and is_mode("release", "releasedbg") and target:is_binary() then + if get_config("toolchain") == "llvm" or get_config("toolchain") == "clang" then + if get_config("runtimes") == "c++_shared" or get_config("runtimes") == "c++_static" then + target:set("policy", "build.sanitizer.address", true) + target:set("policy", "build.sanitizer.undefined", true) + end end end - end - end) - on_config(function(target) - if get_config("devmode") then - target:set("warnings", "allextra", "pedantic") - else - target:set("warnings", "allextra", "pedantic", "error") - end - local flags = { - cl = { - cxx = { - "/Zc:__cplusplus", - "/Zc:lambda", - "/Zc:referenceBinding", - }, - cx = { - "/bigobj", - "/permissive-", - "/Zc:wchar_t", - "/Zc:inline", - "/Zc:preprocessor", - "/Zc:strictStrings", - "/analyze", - "/wd4251", -- Disable warning: class needs to have dll-interface to be used by clients of class blah blah blah - "/wd4297", - "/wd4996", - "/wd5063", - "/wd5260", - "/wd5050", - "/wd4005", - "/wd4611", -- Disable setjmp warning - }, - }, - gcc = { - cx = table.join( - { - "-fstrict-aliasing", - "-Wno-error=unknown-attributes", - "-Wno-error=sign-conversion", - "-Wno-error=shadow", - "-Wstrict-aliasing", - "-fanalyzer", - "-Wconversion", - "-Wshadow", - "-fdiagnostics-color=always", - "-fstack-protector-strong", - "-fstack-clash-protection", - "-fcf-protection=full", - "-ftrivial-auto-var-init=zero", - "-Wsuggest-attribute=pure", - "-Wsuggest-attribute=const", + end) + on_config(function(target) + if get_config("devmode") then + target:set("warnings", "allextra", "pedantic") + else + target:set("warnings", "allextra", "pedantic", "error") + end + local flags = { + cl = { + cxx = { + "/Zc:__cplusplus", + "/Zc:lambda", + "/Zc:referenceBinding", }, - is_mode("debug", "releasedbg") and { "-ggdb3", "-fno-omit-frame-pointer", "-fno-sanitize-merge" } - or {} - ), - ld = target:has_runtime("c++_shared", "c++_static") and {} or {}, - sh = target:has_runtime("c++_shared", "c++_static") and {} or {}, - }, - clang = { - cxx = { - "-Wno-include-angled-in-module-purview", + cx = { + "/bigobj", + "/permissive-", + "/Zc:wchar_t", + "/Zc:inline", + "/Zc:preprocessor", + "/Zc:strictStrings", + "/analyze", + "/wd4251", -- Disable warning: class needs to have dll-interface to be used by clients of class blah blah blah + "/wd4297", + "/wd4996", + "/wd5063", + "/wd5260", + "/wd5050", + "/wd4005", + "/wd4611", -- Disable setjmp warning + }, + }, + gcc = { + cx = table.join( + { + "-fstrict-aliasing", + "-Wno-error=unknown-attributes", + "-Wno-error=sign-conversion", + "-Wno-error=shadow", + "-Wstrict-aliasing", + "-fanalyzer", + "-Wconversion", + "-Wshadow", + "-fdiagnostics-color=always", + "-fstack-protector-strong", + "-fstack-clash-protection", + "-fcf-protection=full", + "-ftrivial-auto-var-init=zero", + "-Wsuggest-attribute=pure", + "-Wsuggest-attribute=const", + }, + is_mode("debug", "releasedbg") + and { "-ggdb3", "-fno-omit-frame-pointer", "-fno-sanitize-merge" } + or {} + ), + ld = target:has_runtime("c++_shared", "c++_static") and {} or {}, + sh = target:has_runtime("c++_shared", "c++_static") and {} or {}, }, - cx = table.join( - { - "-fstrict-aliasing", - "-Wno-gnu-statement-expression-from-macro-expansion", - "-Wno-error=gnu-statement-expression-from-macro-expansion", - "-Wno-error=unknown-attributes", - "-Wstrict-aliasing", - "-Wno-error=sign-conversion", - "-Wno-error=shadow", - "-Wconversion", - "-Wshadow", - "-Wno-c23-extensions", - "-Wno-error=c23-extensions", - "-fretain-comments-from-system-headers", - "-fdiagnostics-color=always", - "-fcolor-diagnostics", - "-fansi-escape-codes", - "-fstack-protector-strong", - "-fstack-clash-protection", - "-ftrivial-auto-var-init=zero", + clang = { + cxx = { + "-Wno-include-angled-in-module-purview", }, - is_plat("linux") and { - "-fcf-protection=full", - } or {}, - is_mode("debug", "releasedbg") and { "-ggdb3", "-fno-omit-frame-pointer", "-fno-sanitize-merge" } + cx = table.join( + { + "-fstrict-aliasing", + "-Wno-gnu-statement-expression-from-macro-expansion", + "-Wno-error=gnu-statement-expression-from-macro-expansion", + "-Wno-error=unknown-attributes", + "-Wstrict-aliasing", + "-Wno-error=sign-conversion", + "-Wno-error=shadow", + "-Wconversion", + "-Wshadow", + "-Wno-c23-extensions", + "-Wno-error=c23-extensions", + "-fretain-comments-from-system-headers", + "-fdiagnostics-color=always", + "-fcolor-diagnostics", + "-fansi-escape-codes", + "-fstack-protector-strong", + "-fstack-clash-protection", + "-ftrivial-auto-var-init=zero", + }, + is_plat("linux") and { + "-fcf-protection=full", + } or {}, + is_mode("debug", "releasedbg") + and { "-ggdb3", "-fno-omit-frame-pointer", "-fno-sanitize-merge" } + or {}, + target:has_runtime("c++_shared", "c++_static") and { "-fexperimental-library" } or {} + ), + mx = is_mode("debug", "releasedbg") + and { "-ggdb3", "-fno-omit-frame-pointer", "-fno-sanitize-merge" } or {}, - target:has_runtime("c++_shared", "c++_static") and { "-fexperimental-library" } or {} - ), - mx = is_mode("debug", "releasedbg") and { "-ggdb3", "-fno-omit-frame-pointer", "-fno-sanitize-merge" } - or {}, - mxx = { - "-fexperimental-library", + mxx = { + "-fexperimental-library", + }, + ld = table.join( + target:has_runtime("c++_shared", "c++_static") and { "-fexperimental-library" } or {}, + ( + target:is_plat("windows") + and is_mode("release") + and target:has_runtime("c++_shared", "c++_static") + ) + and { "-Xlinker -NODEFAULTLIB:libcmt" } + or {} + ), + sh = target:has_runtime("c++_shared", "c++_static") and { "-fexperimental-library" } or {}, }, - ld = table.join( - target:has_runtime("c++_shared", "c++_static") and { "-fexperimental-library" } or {}, - ( - target:is_plat("windows") - and is_mode("release") - and target:has_runtime("c++_shared", "c++_static") - ) - and { "-Xlinker -NODEFAULTLIB:libcmt" } - or {} - ), - sh = target:has_runtime("c++_shared", "c++_static") and { "-fexperimental-library" } or {}, - }, - } - if target:has_tool("cxx", "clang", "clangxx") then - target:add("cxxflags", flags.clang.cxx or {}, { tools = { "clang", "clangxx" }, force = true }) - target:add("cxxflags", flags.clang.cx or {}, { tools = { "clang", "clangxx" }, force = true }) - target:add("cflags", flags.clang.cx or {}, { tools = { "clang" }, force = true }) - target:add("mxflags", flags.clang.mx or {}, { tools = { "clang" }, force = true }) - target:add("mxxflags", flags.clang.mxx or {}, { tools = { "clang", "clang++" }, force = true }) - target:add("ldflags", flags.clang.ld or {}, { tools = { "clang", "clangxx", "lld" }, force = true }) - target:add("shflags", flags.clang.sh or {}, { tools = { "clang", "clangxx", "lld" }, force = true }) - target:add("arflags", flags.clang.ar or {}, { tools = { "clang", "clangxx", "llvm-ar" }, force = true }) - if (is_plat("linux", "mingw")) and not target:has_runtime("c++_shared", "c++_static") then - target:add("syslinks", "stdc++exp", "stdc++fs") + } + if target:has_tool("cxx", "clang", "clangxx") then + target:add("cxxflags", flags.clang.cxx or {}, { tools = { "clang", "clangxx" }, force = true }) + target:add("cxxflags", flags.clang.cx or {}, { tools = { "clang", "clangxx" }, force = true }) + target:add("cflags", flags.clang.cx or {}, { tools = { "clang" }, force = true }) + target:add("mxflags", flags.clang.mx or {}, { tools = { "clang" }, force = true }) + target:add("mxxflags", flags.clang.mxx or {}, { tools = { "clang", "clang++" }, force = true }) + target:add("ldflags", flags.clang.ld or {}, { tools = { "clang", "clangxx", "lld" }, force = true }) + target:add("shflags", flags.clang.sh or {}, { tools = { "clang", "clangxx", "lld" }, force = true }) + target:add("arflags", flags.clang.ar or {}, { tools = { "clang", "clangxx", "llvm-ar" }, force = true }) + if (is_plat("linux", "mingw")) and not target:has_runtime("c++_shared", "c++_static") then + target:add("syslinks", "stdc++exp", "stdc++fs") + end end - end - if target:has_tool("cxx", "gcc", "gxx") then - target:add("cxxflags", flags.gcc.cxx or {}, { tools = { "gcc", "g++" }, force = true }) - target:add("cxxflags", flags.gcc.cx or {}, { tools = { "gcc", "g++" }, force = true }) - target:add("cflags", flags.gcc.cx or {}, { tools = { "gcc" }, force = true }) - target:add("ldflags", flags.gcc.ld or {}, { tools = { "gcc", "g++", "ld" }, force = true }) - target:add("shflags", flags.gcc.sh or {}, { tools = { "gcc", "g++", "ld" }, force = true }) - target:add("arflags", flags.gcc.ar or {}, { tools = { "gcc", "g++", "ar" }, force = true }) - target:add("syslinks", "stdc++exp", "stdc++fs") - end + if target:has_tool("cxx", "gcc", "gxx") then + target:add("cxxflags", flags.gcc.cxx or {}, { tools = { "gcc", "g++" }, force = true }) + target:add("cxxflags", flags.gcc.cx or {}, { tools = { "gcc", "g++" }, force = true }) + target:add("cflags", flags.gcc.cx or {}, { tools = { "gcc" }, force = true }) + target:add("ldflags", flags.gcc.ld or {}, { tools = { "gcc", "g++", "ld" }, force = true }) + target:add("shflags", flags.gcc.sh or {}, { tools = { "gcc", "g++", "ld" }, force = true }) + target:add("arflags", flags.gcc.ar or {}, { tools = { "gcc", "g++", "ar" }, force = true }) + target:add("syslinks", "stdc++exp", "stdc++fs") + end - if target:has_tool("cxx", "cl", "clang_cl") then - target:add("cxxflags", flags.cl.cxx or {}, { tools = { "cl", "clang_cl" }, force = true }) - target:add("cxxflags", flags.cl.cx or {}, { tools = { "cl", "clang_cl" }, force = true }) - target:add("cflags", flags.cl.cx or {}, { tools = { "cl", "clang_cl" }, force = true }) - target:add("ldflags", flags.cl.ld or {}, { tools = { "cl", "link" }, force = true }) - target:add("shflags", flags.cl.sh or {}, { tools = { "cl", "link" }, force = true }) - target:add("arflags", flags.cl.ar or {}, { tools = { "cl", "clang_cl" }, force = true }) - end + if target:has_tool("cxx", "cl", "clang_cl") then + target:add("cxxflags", flags.cl.cxx or {}, { tools = { "cl", "clang_cl" }, force = true }) + target:add("cxxflags", flags.cl.cx or {}, { tools = { "cl", "clang_cl" }, force = true }) + target:add("cflags", flags.cl.cx or {}, { tools = { "cl", "clang_cl" }, force = true }) + target:add("ldflags", flags.cl.ld or {}, { tools = { "cl", "link" }, force = true }) + target:add("shflags", flags.cl.sh or {}, { tools = { "cl", "link" }, force = true }) + target:add("arflags", flags.cl.ar or {}, { tools = { "cl", "clang_cl" }, force = true }) + end - if is_plat("windows") then - local runtimes = { is_mode("debug") and "MDd" or "MD" } + if is_plat("windows") then + local runtimes = { is_mode("debug") and "MDd" or "MD" } - local libcpp = target:has_runtime("c++_shared", "c++_static") - local libstdcpp = target:has_runtime("stdc++_shared", "stdc++_static") + local libcpp = target:has_runtime("c++_shared", "c++_static") + local libstdcpp = target:has_runtime("stdc++_shared", "stdc++_static") - if is_mode("debug") then - if libcpp then - target:add("defines", "_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG") - elseif libstdcpp then - target:add("defines", "_FORTIFY_SOURCE=3") - if get_config("devmode") then - target:add("defines", "_GLIBCXX_DEBUG") + if is_mode("debug") then + if libcpp then + target:add("defines", "_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG") + elseif libstdcpp then + target:add("defines", "_FORTIFY_SOURCE=3") + if get_config("devmode") then + target:add("defines", "_GLIBCXX_DEBUG") + else + target:add("defines", "_GLIBCXX_ASSERTIONS") + end else - target:add("defines", "_GLIBCXX_ASSERTIONS") + target:add("defines", "_MSVC_STL_HARDENING=1") + end + elseif is_mode("releasedbg") then + if libcpp then + target:add("defines", "_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE") + elseif libstdcpp then + target:add("defines", "_FORTIFY_SOURCE=2", "_GLIBCXX_ASSERTIONS") + else + target:add("defines", "_MSVC_STL_HARDENING=1") + end + elseif is_mode("release") then + if libcpp then + target:add("defines", "_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST") + elseif libstdcpp then + target:add("defines", "_FORTIFY_SOURCE=1") + else + target:add("defines", "_MSVC_STL_HARDENING=1") end - else - target:add("defines", "_MSVC_STL_HARDENING=1") - end - elseif is_mode("releasedbg") then - if libcpp then - target:add("defines", "_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE") - elseif libstdcpp then - target:add("defines", "_FORTIFY_SOURCE=2", "_GLIBCXX_ASSERTIONS") - else - target:add("defines", "_MSVC_STL_HARDENING=1") end - elseif is_mode("release") then - if libcpp then - target:add("defines", "_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST") - elseif libstdcpp then - target:add("defines", "_FORTIFY_SOURCE=1") - else - target:add("defines", "_MSVC_STL_HARDENING=1") + + if target:has_runtime("c++_shared") then + table.insert(runtimes, "c++_shared") + elseif target:has_runtime("c++_static") then + table.insert(runtimes, "c++_static") end + target:set("runtimes", table.unpack(runtimes)) end - - if target:has_runtime("c++_shared") then - table.insert(runtimes, "c++_shared") - elseif target:has_runtime("c++_static") then - table.insert(runtimes, "c++_static") + if is_mode("release") then + target:set("symbols", "hidden") + target:set("optimize", "fast") + elseif is_mode("debug") then + target:set("symbols", "debug") + target:add("cxflags", "-ggdb3", { tools = { "clang", "gcc" } }) + target:add("mxflags", "-ggdb3", { tools = { "clang", "gcc" } }) + elseif is_mode("releasedbg") then + target:set("optimize", "fast") + target:set("symbols", "debug", "hidden") + target:add("mxflags", "-ggdb3", { tools = { "clang", "gcc" } }) end - target:set("runtimes", table.unpack(runtimes)) - end - if is_mode("release") then - target:set("symbols", "hidden") - target:set("optimize", "fast") - elseif is_mode("debug") then - target:set("symbols", "debug") - target:add("cxflags", "-ggdb3", { tools = { "clang", "gcc" } }) - target:add("mxflags", "-ggdb3", { tools = { "clang", "gcc" } }) - elseif is_mode("releasedbg") then - target:set("optimize", "fast") - target:set("symbols", "debug", "hidden") - target:add("mxflags", "-ggdb3", { tools = { "clang", "gcc" } }) - end - target:set("fpmodels", "fast") - target:add("vectorexts", "fma") - target:add("vectorexts", "neon") - target:add("vectorexts", "avx", "avx2") - target:add("vectorexts", "sse", "sse2", "sse3", "ssse3", "sse4.2") + target:set("fpmodels", "fast") + target:add("vectorexts", "fma") + target:add("vectorexts", "neon") + target:add("vectorexts", "avx", "avx2") + target:add("vectorexts", "sse", "sse2", "sse3", "ssse3", "sse4.2") + end) end) end) diff --git a/xmake/rules/stormkit_library.xmake.lua b/xmake/rules/stormkit_library.xmake.lua new file mode 100644 index 000000000..d4c1f431b --- /dev/null +++ b/xmake/rules/stormkit_library.xmake.lua @@ -0,0 +1,12 @@ +namespace("stormkit", function() + rule("library", function() + add_deps("flags") + + on_config(function(target) + local stormkit_components = target:values("stormkit.components") or {} + if not target:kind() then target:set("kind", "$(kind)") end + target:set("languages", "cxxlatest", "clatest") + target:add("packages", "stormkit", { components = table.join("core", "main", stormkit_components) }) + end) + end) +end) diff --git a/xmake/targets.xmake.lua b/xmake/targets.xmake.lua deleted file mode 100644 index c782accb3..000000000 --- a/xmake/targets.xmake.lua +++ /dev/null @@ -1,127 +0,0 @@ -modules = { - test = { - modulename = "test", - public_deps = { "core" }, - has_headers = true, - }, - log = { - modulename = "log", - public_deps = table.join("core", get_config("luau") and "luau" or {}), - public_packages = get_config("luau") and { "luau", "luabridge3" } or {}, - has_headers = true, - }, - entities = { - modulename = "entities", - public_deps = table.join("core", get_config("luau") and "luau" or {}), - public_packages = get_config("luau") and { "luau", "luabridge3" } or {}, - }, - image = { - modulename = "image", - packages = { "libktx", "libpng", "libjpeg-turbo" }, - public_deps = table.join("core", get_config("luau") and "luau" or {}), - public_packages = get_config("luau") and { "luau", "luabridge3" } or {}, - }, - main = { - modulename = "main", - has_headers = true, - deps = { "core" }, - custom = function() - add_cxflags("-Wno-main") - set_strip("debug") - end, - frameworks = is_plat("macosx") and { "CoreFoundation" } or nil, - }, - luau = get_config("luau") and { - modulename = "luau", - has_headers = true, - public_deps = { "core" }, - public_packages = { "luau", "luabridge3" }, - public_defines = { "STORMKIT_LUA_BINDING", 'LUA_API=extern __attribute__((visibility("default")))' }, - } or nil, - wsi = { - modulename = "wsi", - public_deps = table.join("core", get_config("luau") and "luau" or {}), - deps = { "log" }, - public_packages = get_config("luau") and { "luau", "luabridge3" } or {}, - packages = is_plat("linux") and { - "libxcb", - "xcb-util-keysyms", - "xcb-util", - "xcb-util-image", - "xcb-util-wm", - "xcb-util-errors", - "wayland", - "wayland-protocols", - "libxkbcommon", - } or {}, - -- frameworks = is_plat("macosx") and { "CoreFoundation", "Foundation", "AppKit", "Metal", "IOKit", "QuartzCore" } - -- or nil, - custom = function() - if is_plat("macosx", "iphoneos", "tvos") then - if is_plat("macosx") then - add_files("src/wsi/macos/swift/*.swift", { public = true }) - add_files("src/wsi/macos/swift/*.m") - set_values("swift.modulename", "macOS") - add_scflags("-Isrc/wsi/macos/swift") - elseif is_plat("iphoneos") then - add_files("src/wsi/ios/swift/*.swift", { public = true }) - add_scflags("-Isrc/wsi/ios/swift") - set_values("swift.modulename", "iOS") - elseif is_plat("tvos") then - add_files("src/wsi/tvos/swift/*.swift", { public = true }) - add_scflags("-Isrc/wsi/tvos/swift") - set_values("swift.modulename", "tvOS") - end - set_values("swift.interop", "cxx") - elseif is_plat("linux") then - add_rules("wayland.protocols") - - on_load(function(target) - assert(target:pkg("wayland-protocols")) - local wayland_protocols_dir = - path.join(target:pkg("wayland-protocols"):installdir() or "/usr", "share", "wayland-protocols") - assert(wayland_protocols_dir, "wayland protocols directory not found") - - local protocols = { - path.join("stable", "xdg-shell", "xdg-shell.xml"), - path.join("stable", "tablet", "tablet-v2.xml"), - path.join("stable", "viewporter", "viewporter.xml"), - path.join("staging", "content-type", "content-type-v1.xml"), - path.join("staging", "pointer-warp", "pointer-warp-v1.xml"), - path.join("staging", "cursor-shape", "cursor-shape-v1.xml"), - path.join("staging", "single-pixel-buffer", "single-pixel-buffer-v1.xml"), - path.join("unstable", "xdg-decoration", "xdg-decoration-unstable-v1.xml"), - path.join("unstable", "pointer-constraints", "pointer-constraints-unstable-v1.xml"), - path.join("unstable", "relative-pointer", "relative-pointer-unstable-v1.xml"), - } - - for _, protocol in ipairs(protocols) do - target:add("files", path.join(wayland_protocols_dir, protocol)) - end - end) - elseif is_plat("windows", "mingw") then - add_syslinks("User32", "Shell32", "Gdi32", "Shcore", "Gdiplus") - end - end, - }, - gpu = { - modulename = "gpu", - has_headers = true, - public_packages = table.join({ - "frozen", - "volk", - "vulkan-headers", - "vulkan-memory-allocator", - }, get_config("luau") and { "luau", "luabridge3" } or {}), - public_deps = table.join("core", "wsi", "image", get_config("luau") and "luau" or {}), - deps = { "log" }, - packages = is_plat("linux") and { - "libxcb", - "wayland", - } or nil, - public_defines = { - "STORMKIT_GPU_VULKAN", - }, - custom = function() add_cxflags("clang::-Wno-missing-declarations") end, - }, -} diff --git a/src/core/xmake.lua b/xmake/targets/core.xmake.lua similarity index 51% rename from src/core/xmake.lua rename to xmake/targets/core.xmake.lua index db4410619..50c5ab8d8 100644 --- a/src/core/xmake.lua +++ b/xmake/targets/core.xmake.lua @@ -2,33 +2,39 @@ add_requires("frozen", { system = false, configs = { modules = true, std_import add_requires("unordered_dense", { system = false, configs = { modules = true, std_import = true } }) add_requires("tl_function_ref", { system = false, configs = { modules = true, std_import = true } }) +local src_core_dir = path.join(src_dir, "core") +local module_core_dir = path.join(module_dir, "core") + target("core", function() set_kind("$(kind)") + add_rules("flags") set_languages("cxxlatest", "clatest") - add_defines("STORMKIT_BUILD", { public = false }) + add_defines("ANKERL_UNORDERED_DENSE_STD_MODULE=1", "FROZEN_STD_MODULE=1", { public = true }) + add_defines("STORMKIT_CORE_BUILD", { public = false }) if is_mode("debug") then add_defines("STORMKIT_BUILD_DEBUG", { public = true }) end if is_kind("static") then add_defines("STORMKIT_STATIC", { public = true }) end - add_files("$(projectdir)/modules/stormkit/core.cppm", { public = true }) - add_files("$(projectdir)/modules/stormkit/core/**.cppm", { public = true }) - add_files("*.cpp", "*.cppm") + add_files(path.join(module_dir, "core.cppm"), path.join(module_core_dir, "**.cppm"), { public = true }) + add_files(path.join(src_core_dir, "*.cpp"), path.join(src_core_dir, "*.cppm")) - if is_plat("linux", "macosx", "ios", "tvos", "android") then add_files("posix/**.cpp") end - if is_plat("linux") then add_files("linux/**.cpp") end - if is_plat("windows") then add_files("win32/**.cpp") end - if is_plat("macosx", "ios", "tvos", "watchos") then add_files("darwin/**.cpp", "darwin/**.m") end + if is_plat("linux", "macosx", "iphoneos", "tvos", "android") then + add_files(path.join(src_core_dir, "posix/**.cpp")) + end + if is_plat("linux") then add_files(path.join(src_core_dir, "linux/**.cpp")) end + if is_plat("windows") then add_files(path.join(src_core_dir, "win32/**.cpp")) end + if is_plat("macosx", "iphoneos", "tvos", "watchos") then + add_files(path.join(src_core_dir, "darwin/**.cpp"), path.join(src_core_dir, "darwin/**.m")) + end set_configdir("$(builddir)/.gens/include/") - add_configfiles("$(projectdir)/include/(stormkit/core/config.hpp.in)") - add_headerfiles( - "$(builddir)/.gens/include/(stormkit/core/*.hpp)", - "$(projectdir)/include/(stormkit/core/**.inl)", - "$(projectdir)/include/(stormkit/core/**.hpp)" - ) - add_includedirs("$(projectdir)/include", { public = true }) + add_configfiles(path.join(include_dir, "(stormkit/core/config.hpp.in)")) + add_includedirs("$(builddir)/.gens/include", { public = true }) + + add_headerfiles(path.join(include_dir, "(stormkit/core/**.hpp)"), "$(builddir)/.gens/include/(stormkit/core/*.hpp)") + add_includedirs(include_dir, { public = true }) add_packages("frozen", "unordered_dense", "tl_function_ref", { public = true }) @@ -48,5 +54,7 @@ target("core", function() target:set("configvar", "STORMKIT_GIT_COMMIT_HASH", output:trim()) end) + add_options("sanitizers") + set_group("libraries") end) diff --git a/xmake/targets/entities.xmake.lua b/xmake/targets/entities.xmake.lua new file mode 100644 index 000000000..ea609e23f --- /dev/null +++ b/xmake/targets/entities.xmake.lua @@ -0,0 +1,22 @@ +local src_entities_dir = path.join(src_dir, "entities") + +target("entities", function() + set_kind("$(kind)") + add_rules("flags") + + set_languages("cxxlatest", "clatest") + + add_defines("STORMKIT_ENTITIES_BUILD", { public = false }) + + add_files(path.join(module_dir, "entities.cppm"), { public = true }) + add_files(path.join(src_entities_dir, "*.cpp")) + + add_headerfiles(path.join(include_dir, "(stormkit/entities/**.hpp)")) + add_includedirs(include_dir, { public = true }) + + add_options("sanitizers") + + add_deps("core") + + set_group("libraries") +end) diff --git a/xmake/targets/examples.xmake.lua b/xmake/targets/examples.xmake.lua new file mode 100644 index 000000000..dfc56471f --- /dev/null +++ b/xmake/targets/examples.xmake.lua @@ -0,0 +1,7 @@ +namespace("examples", function() + for _, name in ipairs({ "log", "entities", "gpu", "image", "wsi", "lua" }) do + if get_config("examples_" .. name) then + includes(path.join(os.projectdir(), "examples", name, "**/xmake.lua")) + end + end +end) diff --git a/xmake/targets/gpu.xmake.lua b/xmake/targets/gpu.xmake.lua new file mode 100644 index 000000000..a744393a1 --- /dev/null +++ b/xmake/targets/gpu.xmake.lua @@ -0,0 +1,29 @@ +local src_gpu_dir = path.join(src_dir, "gpu") +local module_gpu_dir = path.join(module_dir, "gpu") + +target("gpu", function() + set_kind("$(kind)") + add_rules("flags") + + set_languages("cxxlatest", "clatest") + + add_defines("STORMKIT_GPU_BUILD", { public = false }) + + add_files(path.join(module_dir, "gpu.cppm"), path.join(module_gpu_dir, "**.cppm"), { public = true }) + add_files(path.join(src_gpu_dir, "**.cpp")) + -- add_files(path.join(src_gpu_dir, "*.cpp"), path.join(src_gpu_dir, "*.cppm")) + + add_headerfiles(path.join(include_dir, "(stormkit/gpu/**.hpp)")) + add_includedirs(include_dir, { public = true }) + + add_defines("STORMKIT_GPU_VULKAN", { public = true }) + + add_deps("core", "wsi", "image") + add_deps("log", { public = false }) + + add_packages("volk", "vulkan-headers", "vulkan-memory-allocator") + + add_options("sanitizers") + + set_group("libraries") +end) diff --git a/xmake/targets/image.xmake.lua b/xmake/targets/image.xmake.lua new file mode 100644 index 000000000..ee96dd942 --- /dev/null +++ b/xmake/targets/image.xmake.lua @@ -0,0 +1,24 @@ +local src_image_dir = path.join(src_dir, "image") + +target("image", function() + set_kind("$(kind)") + add_rules("flags") + + set_languages("cxxlatest", "clatest") + + add_defines("STORMKIT_IMAGE_BUILD", { public = false }) + + add_files(path.join(module_dir, "image.cppm"), { public = true }) + add_files(path.join(src_image_dir, "*.cpp"), path.join(src_image_dir, "*.cppm")) + + add_headerfiles(path.join(include_dir, "(stormkit/image/**.hpp)")) + add_includedirs(include_dir, { public = true }) + + add_deps("core") + + add_packages("libktx", "libpng", "libjpeg-turbo") + + add_options("sanitizers") + + set_group("libraries") +end) diff --git a/xmake/targets/log.xmake.lua b/xmake/targets/log.xmake.lua new file mode 100644 index 000000000..bb42a8bf9 --- /dev/null +++ b/xmake/targets/log.xmake.lua @@ -0,0 +1,22 @@ +local src_log_dir = path.join(src_dir, "log") + +target("log", function() + set_kind("$(kind)") + add_rules("flags") + + set_languages("cxxlatest", "clatest") + + add_defines("STORMKIT_LOG_BUILD", { public = false }) + + add_files(path.join(module_dir, "log.cppm"), { public = true }) + add_files(path.join(src_log_dir, "*.cpp")) + + add_headerfiles(path.join(include_dir, "(stormkit/log/**.hpp)")) + add_includedirs(include_dir, { public = true }) + + add_deps("core") + + add_options("sanitizers") + + set_group("libraries") +end) diff --git a/xmake/targets/lua.xmake.lua b/xmake/targets/lua.xmake.lua new file mode 100644 index 000000000..1189eac6b --- /dev/null +++ b/xmake/targets/lua.xmake.lua @@ -0,0 +1,53 @@ +add_requires("luau", { + system = false, + version = "master", + configs = { + shared = false, + extern_c = true, + build_cli = false, + }, +}) +add_requires("luabridge3", { + system = false, + version = "master", +}) + +local src_lua_dir = path.join(src_dir, "lua") +local module_lua_dir = path.join(module_dir, "lua") + +target("lua", function() + set_kind("$(kind)") + add_rules("flags") + + set_languages("cxxlatest", "clatest") + + add_defines("STORMKIT_LUA_BUILD", { public = false }) + + add_files(path.join(module_dir, "lua.cppm"), { public = true }) + add_files(path.join(src_lua_dir, "lua.cpp")) + add_files(path.join(src_lua_dir, "core.cppm")) + add_files(path.join(src_lua_dir, "log.cppm"), { public = true }) + + if get_config("entities") then add_files(path.join(src_lua_dir, "entities.cppm"), { public = true }) end + if get_config("image") then add_files(path.join(src_lua_dir, "image.cppm"), { public = true }) end + if get_config("wsi") then + add_files(path.join(src_lua_dir, "wsi.cpp")) + add_files(path.join(src_lua_dir, "wsi.cppm"), { public = true }) + end + if get_config("gpu") then add_files(path.join(src_lua_dir, "gpu.cppm"), { public = true }) end + + add_headerfiles(path.join(include_dir, "(stormkit/lua/**.hpp)")) + add_includedirs(include_dir, { public = true }) + + add_deps("core", "log") + if get_config("image") then add_deps("image") end + if get_config("entities") then add_deps("entities") end + if get_config("wsi") then add_deps("wsi") end + if get_config("gpu") then add_deps("gpu") end + + add_packages("luau", "luabridge3", { public = true }) + + add_options("sanitizers") + + set_group("libraries") +end) diff --git a/xmake/targets/main.xmake.lua b/xmake/targets/main.xmake.lua new file mode 100644 index 000000000..111694709 --- /dev/null +++ b/xmake/targets/main.xmake.lua @@ -0,0 +1,31 @@ +local src_main_dir = path.join(src_dir, "main") + +target("main", function() + set_kind("static") + add_rules("flags") + + set_languages("cxxlatest", "clatest") + + add_defines("STORMKIT_MAIN_BUILD", { public = false }) + + add_files(path.join(module_dir, "main.cppm"), { public = true }) + if is_plat("linux") then add_files(path.join(src_main_dir, "linux/**.cpp")) end + if is_plat("windows") then add_files(path.join(src_main_dir, "win32/**.cpp")) end + if is_plat("macosx") then add_files(path.join(src_main_dir, "macos/**.cpp")) end + if is_plat("iphoneos") then add_files(path.join(src_main_dir, "ios/**.cpp")) end + if is_plat("tvos") then add_files(path.join(src_main_dir, "tvos/**.cpp")) end + if is_plat("android") then add_files(path.join(src_main_dir, "android/**.cpp")) end + + add_headerfiles("$(projectdir)/include/(stormkit/main/**.hpp)") + add_includedirs("$(projectdir)/include", { public = true }) + + add_cxflags("-Wno-main", { tools = { "clang", "gcc" } }) + + add_deps("core") + + if is_plat("macosx") then add_frameworks("CoreFoundation") end + + add_options("sanitizers") + + set_group("libraries") +end) diff --git a/xmake/targets/test.xmake.lua b/xmake/targets/test.xmake.lua new file mode 100644 index 000000000..3b205e949 --- /dev/null +++ b/xmake/targets/test.xmake.lua @@ -0,0 +1,20 @@ +local src_test_dir = path.join(src_dir, "test") + +target("test", function() + set_kind("static") + add_rules("flags") + + set_languages("cxxlatest", "clatest") + + add_files(path.join(module_dir, "test.cppm"), { public = true }) + add_files(path.join(src_test_dir, "*.cpp")) + + add_headerfiles(path.join(include_dir, "(stormkit/test/**.hpp)")) + add_includedirs(include_dir, { public = true }) + + add_deps("core") + + add_options("sanitizers") + + set_group("libraries") +end) diff --git a/xmake/targets/tests.xmake.lua b/xmake/targets/tests.xmake.lua new file mode 100644 index 000000000..2c84db293 --- /dev/null +++ b/xmake/targets/tests.xmake.lua @@ -0,0 +1,47 @@ +namespace("tests", function() + for _, name in ipairs({ "core", "log", "entities", "gpu", "image", "wsi", "lua" }) do + for _, file in ipairs(os.files(path.join(os.projectdir(), "tests", name, "**.cpp"))) do + local testname = path.basename(file) + + target(name .. "-" .. testname, function() + add_rules("stormkit::example") + + on_config(function(target) + function parseTestFile() + local code = io.readfile(file) + + local suite_name_regex = [[TestSuite%s-{.-"(.-)",]] + local test_name_regex = [[{%s-"(.-)"%s-,]] + + local suite_name = code:match(suite_name_regex) + + local test_names + for test_name in code:gmatch(test_name_regex) do + test_names = test_names or {} + if test_name ~= suite_name then table.insert(test_names, test_name) end + end + + return { suite_name = suite_name, test_names = test_names } + end + + local tests = parseTestFile() + for _, test_name in ipairs(tests.test_names) do + target:add( + "tests", + tests.suite_name .. "/" .. test_name, + { group = tests.suite_name, runargs = "--test_name=" .. test_name } + ) + end + end) + + add_files(file) + + add_deps("stormkit::test") + + add_options("sanitizers") + + set_group("tests") + end) + end + end +end) diff --git a/xmake/targets/tools.xmake.lua b/xmake/targets/tools.xmake.lua new file mode 100644 index 000000000..f1de021e0 --- /dev/null +++ b/xmake/targets/tools.xmake.lua @@ -0,0 +1 @@ +namespace("tools", function() includes(path.join(os.projectdir(), "tools/terra/xmake.lua")) end) diff --git a/xmake/targets/wsi.xmake.lua b/xmake/targets/wsi.xmake.lua new file mode 100644 index 000000000..a1be79339 --- /dev/null +++ b/xmake/targets/wsi.xmake.lua @@ -0,0 +1,91 @@ +local src_wsi_dir = path.join(src_dir, "wsi") +local module_wsi_dir = path.join(module_dir, "wsi") + +target("wsi", function() + set_kind("$(kind)") + add_rules("flags") + + set_languages("cxxlatest", "clatest") + + add_defines("STORMKIT_WSI_BUILD", { public = false }) + + add_files(path.join(module_dir, "wsi.cppm"), path.join(module_wsi_dir, "**.cppm"), { public = true }) + add_files(path.join(src_wsi_dir, "*.cpp"), path.join(src_wsi_dir, "common/*.cppm")) + + if is_plat("linux") then + add_files(path.join(src_wsi_dir, "linux/**.cpp")) + + add_rules("wayland.protocols") + + on_load(function(target) + assert(target:pkg("wayland-protocols")) + local wayland_protocols_dir = + path.join(target:pkg("wayland-protocols"):installdir() or "/usr", "share", "wayland-protocols") + assert(wayland_protocols_dir, "wayland protocols directory not found") + + local protocols = { + path.join("stable", "xdg-shell", "xdg-shell.xml"), + path.join("stable", "tablet", "tablet-v2.xml"), + path.join("stable", "viewporter", "viewporter.xml"), + path.join("staging", "content-type", "content-type-v1.xml"), + path.join("staging", "pointer-warp", "pointer-warp-v1.xml"), + path.join("staging", "cursor-shape", "cursor-shape-v1.xml"), + path.join("staging", "single-pixel-buffer", "single-pixel-buffer-v1.xml"), + path.join("unstable", "xdg-decoration", "xdg-decoration-unstable-v1.xml"), + path.join("unstable", "pointer-constraints", "pointer-constraints-unstable-v1.xml"), + path.join("unstable", "relative-pointer", "relative-pointer-unstable-v1.xml"), + } + + for _, protocol in ipairs(protocols) do + target:add("files", path.join(wayland_protocols_dir, protocol)) + end + end) + + add_packages( + "libxcb", + "xcb-util-keysyms", + "xcb-util", + "xcb-util-image", + "xcb-util-wm", + "xcb-util-errors", + "wayland", + "wayland-protocols", + "libxkbcommon" + ) + elseif is_plat("windows") then + add_files(path.join(src_wsi_dir, "win32/**.cpp"), path.join(src_wsi_dir, "win32/**.cppm")) + add_syslinks("User32", "Shell32", "Gdi32", "Shcore", "Gdiplus") + elseif is_plat("macosx") then + add_files(path.join(src_wsi_dir, "macos/**.cpp"), path.join(src_wsi_dir, "macos/**.m")) + add_files(path.join(src_wsi_dir, "macos/**.swift"), { public = true }) + set_values("swift.modulename", "macOS") + set_values("swift.interop", "cxx") + add_scflags("-I" .. path.join(src_wsi_dir, "macos/swift")) + elseif is_plat("iphoneos") then + add_files(path.join(src_wsi_dir, "ios/**.cpp"), path.join(src_wsi_dir, "ios/**.m")) + add_files(path.join(src_wsi_dir, "ios/**.swift"), { public = true }) + set_values("swift.modulename", "iOS") + set_values("swift.interop", "cxx") + add_scflags("-I" .. path.join(src_wsi_dir, "ios/swift")) + elseif is_plat("tvos") then + add_files( + path.join(src_wsi_dir, "tvos/**.cpp"), + path.join(src_wsi_dir, "tvos/**.m"), + path.join(src_wsi_dir, "tvos/**.swift") + ) + set_values("swift.modulename", "tvOS") + set_values("swift.interop", "cxx") + add_scflags("-I" .. path.join(src_wsi_dir, "tvos/swift")) + end + + add_headerfiles(path.join(include_dir, "(stormkit/wsi/**.hpp)")) + add_includedirs(include_dir, { public = true }) + + add_deps("core", "log") + + add_packages(packages, { public = false }) + + add_options("sanitizers") + + set_group("libraries") +end) diff --git a/xmake/tests.xmake.lua b/xmake/tests.xmake.lua deleted file mode 100644 index 856e15d69..000000000 --- a/xmake/tests.xmake.lua +++ /dev/null @@ -1,56 +0,0 @@ -includes("targets.xmake.lua") - -namespace("tests", function() - for name, _ in pairs(modules) do - if name ~= "test" then - for _, file in ipairs(os.files(path.join(os.projectdir(), "tests", name, "**.cpp"))) do - local testname = path.basename(file) - - target(name .. "-" .. testname, function() - set_group("tests") - set_kind("binary") - set_languages("cxxlatest", "clatest") - - on_config(function(target) - function parseTestFile() - local code = io.readfile(file) - - local suite_name_regex = [[TestSuite%s-{.-"(.-)",]] - local test_name_regex = [[{%s-"(.-)"%s-,]] - - local suite_name = code:match(suite_name_regex) - - local test_names - for test_name in code:gmatch(test_name_regex) do - test_names = test_names or {} - if test_name ~= suite_name then table.insert(test_names, test_name) end - end - - return { suite_name = suite_name, test_names = test_names } - end - - local tests = parseTestFile() - for _, test_name in ipairs(tests.test_names) do - target:add( - "tests", - tests.suite_name .. "/" .. test_name, - { group = tests.suite_name, runargs = "--test_name=" .. test_name } - ) - end - end) - - add_rules("stormkit.flags") - add_rules("platform.windows.subsystem.console") - - add_files(file) - - add_packages("frozen") - add_deps("stormkit::main", "stormkit::test") - add_deps("stormkit::" .. name) - - add_options("sanitizers") - end) - end - end - end -end) From 4b4a7b15e07653060b13c9c4d78391ae215c1acd Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 6 Feb 2026 01:33:44 +0100 Subject: [PATCH 069/194] (lua, core, wsi) use sol instead of luabridge3 --- examples/lua/wsi/events/lua/events.luau | 85 +++--- include/stormkit/lua/lua.hpp | 16 +- modules/stormkit/core/math/extent.cppm | 13 +- modules/stormkit/core/math/linear-vector.cppm | 37 ++- modules/stormkit/core/meta/type_query.cppm | 2 +- modules/stormkit/core/utils/color.cppm | 84 +++++- modules/stormkit/lua.cppm | 14 +- modules/stormkit/wsi/core.cppm | 8 + modules/stormkit/wsi/keyboard.cppm | 9 + modules/stormkit/wsi/monitor.cppm | 41 ++- modules/stormkit/wsi/mouse.cppm | 8 + modules/stormkit/wsi/window.cppm | 18 ++ src/lua/core.cpp | 25 ++ src/lua/core.cppm | 33 +-- src/lua/core/color.cpp | 105 ++++++++ src/lua/core/color.cppclear | 0 src/lua/core/math.cpp | 206 ++++++++++++++ src/lua/entities.cpp | 21 ++ src/lua/entities.cppm | 8 +- src/lua/gpu.cpp | 21 ++ src/lua/gpu.cppm | 8 +- src/lua/image.cpp | 19 ++ src/lua/image.cppm | 8 +- src/lua/log.cpp | 19 ++ src/lua/log.cppm | 6 +- src/lua/lua.cpp | 138 ++++------ src/lua/wsi.cpp | 119 +------- src/lua/wsi.cppm | 66 +++-- src/lua/wsi/core.cpp | 44 +++ src/lua/wsi/keyboard.cpp | 254 ++++++++++++++++++ src/lua/wsi/monitor.cpp | 43 +++ src/lua/wsi/mouse.cpp | 58 ++++ src/lua/wsi/window.cpp | 159 +++++++++++ xmake/targets/lua.xmake.lua | 31 ++- 34 files changed, 1360 insertions(+), 366 deletions(-) create mode 100644 src/lua/core.cpp create mode 100644 src/lua/core/color.cpp create mode 100644 src/lua/core/color.cppclear create mode 100644 src/lua/core/math.cpp create mode 100644 src/lua/entities.cpp create mode 100644 src/lua/gpu.cpp create mode 100644 src/lua/image.cpp create mode 100644 src/lua/log.cpp create mode 100644 src/lua/wsi/core.cpp create mode 100644 src/lua/wsi/keyboard.cpp create mode 100644 src/lua/wsi/monitor.cpp create mode 100644 src/lua/wsi/mouse.cpp create mode 100644 src/lua/wsi/window.cpp diff --git a/examples/lua/wsi/events/lua/events.luau b/examples/lua/wsi/events/lua/events.luau index 40a241007..c6b0c5d44 100644 --- a/examples/lua/wsi/events/lua/events.luau +++ b/examples/lua/wsi/events/lua/events.luau @@ -1,35 +1,33 @@ local function main() - local window = wsi.open_window("test", 800, 600, wsi.window_flag.RESIZEABLE) + local window = wsi.window.open("test", 800, 600, wsi.window_flag.RESIZEABLE) window:on_closed(function() print("Close event!") return true end) - local vec = vector.create(0, 1, 0) - window:on_resized(function(extent) - print("Resize event: %s", extent) + print("Resize event:\n ", extent) return true end) window:on_monitor_changed(function(monitor) - print("Monitor changed event: %s", monitor) + print("Monitor changed event:\n ", monitor) return true end) window:on_mouse_moved(function(_, position) - print("Mouse move event: %s", position) + print("Mouse move event:\n ", position) return true end) window:on_mouse_button_down(function(_, button, position) - print("Mouse button down event: %s %s", button, position) + print("Mouse button down event:\n ", button, "\n ", position) return true end) window:on_mouse_button_up(function(_, button, position) - print("Mouse button up event: %s %s", button, position) + print("Mouse button up event:\n ", button, "\n ", position) return true end) @@ -43,57 +41,62 @@ local function main() return true end) - window:on_activate(function() + window:on_activated(function() print("Activate event!") return true end) - window:on_deactivate(function() + window:on_deactivated(function() print("Deactivate event!") return true end) + local foo = 0 window:on_key_down(function(_, key, c) + print("Key down event:\n ", key, "\n '", c) + local closures = { - [wsi.Key.ESCAPE] = function() + [wsi.key.ESCAPE] = function() + print("Closing window!") window:close() - print("Closing window") end, - [wsi.Key.W] = function() - window:close() - print("Closing window") + [wsi.key.W] = function() + local extent = window:extent() + extent.width = extent.width + 10 + window:set_extent(extent) end, - [wsi.Key.T] = function() - window:close() - print("Closing window") + [wsi.key.T] = function() + foo = foo + 1 + window:set_title("StormKit Lua Events Example | T pressed " .. foo .. " times") end, - [wsi.Key.H] = function() - window:close() - print("Closing window") + [wsi.key.H] = function() + local extent = window:extent() + extent.height = extent.height + 10 + window:set_extent(extent) end, - [wsi.Key.F11] = function() - window:close() - print("Closing window") + [wsi.key.F11] = function() + window:toggle_fullscreen() + print("Toggling fullscreen to", window:fullscreen()) end, - [wsi.Key.F1] = function() - window:close() - print("Closing window") + [wsi.key.F1] = function() + window:toggle_hidden_mouse() + print("Toggling hidden mouse to", window:is_mouse_hidden()) end, - [wsi.Key.F2] = function() - window:close() - print("Closing window") + [wsi.key.F2] = function() + window:toggle_locked_mouse() + print("Toggling locked mouse to", window:is_mouse_locked()) end, - [wsi.Key.F3] = function() - window:close() - print("Closing window") + [wsi.key.F3] = function() + window:toggle_confined_mouse() + print("Toggling confined mouse to", window:is_mouse_confined()) end, - [wsi.Key.F4] = function() - window:close() - print("Closing window") + [wsi.key.F4] = function() + window:toggle_relative_mouse() + print("Toggling relative mouse to", window:is_mouse_relative()) end, - [wsi.Key.F5] = function() - window:close() - print("Closing window") + [wsi.key.F5] = function() + window:toggle_key_repeat() + print("Toggling key repeat to", window:is_key_repeat_enabled()) end, } @@ -103,12 +106,10 @@ local function main() break end end - - print("Key down --\n code: %s\n value: '%s'\n)", key, c); end) window:on_key_up(function(_, key, c) - print("Key up --\n code: %s\n value: '%s'\n)", key, c); + print("Key up event:\n ", key, "\n '", c) end) window:event_loop(function() diff --git a/include/stormkit/lua/lua.hpp b/include/stormkit/lua/lua.hpp index a97f139de..ae80422e0 100644 --- a/include/stormkit/lua/lua.hpp +++ b/include/stormkit/lua/lua.hpp @@ -3,9 +3,13 @@ #include +#include + STORMKIT_PUSH_WARNINGS -#define LUA_API extern __attribute__((visibility("default"))) +#define LUA_API extern "C" STORMKIT_LUA_API +#define LUACODE_API extern "C" STORMKIT_LUA_API +#define LUACODEGEN_API extern "C" STORMKIT_LUA_API extern "C" { #include @@ -14,10 +18,12 @@ extern "C" { #include } -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#undef lua_rawgetp -#undef lua_rawsetp -#include +// #pragma clang diagnostic ignored "-Wdeprecated-declarations" +#define SOL_USE_LUAU 1 +#define SOL_SAFE_STACK_CHECK 1 +#define SOL_LUA_BIT32_LIB 1 +#define LUA_VERSION_NUM 501 +#include #undef assert STORMKIT_POP_WARNINGS diff --git a/modules/stormkit/core/math/extent.cppm b/modules/stormkit/core/math/extent.cppm index ad391254c..8640f9092 100644 --- a/modules/stormkit/core/math/extent.cppm +++ b/modules/stormkit/core/math/extent.cppm @@ -155,7 +155,10 @@ export { constexpr auto operator/=(Extent& extent, typename Extent::ElementType factor) noexcept -> Extent&; template - auto to_string(Extent&& extent) noexcept -> std::string; + auto to_string(const Extent& extent) noexcept -> std::string; + + template + auto to_string(const Extent& extent) noexcept -> std::string; template auto format_as(const extent& extent, FormatContext& ctx) noexcept -> decltype(ctx.out()); @@ -337,7 +340,7 @@ namespace stormkit { inline namespace core { namespace math { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto to_string(Extent&& extent) noexcept -> std::string { + inline auto to_string(const Extent& extent) noexcept -> std::string { return std::format("{}", extent); } @@ -345,13 +348,14 @@ namespace stormkit { inline namespace core { namespace math { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto to_string(Extent&& extent) noexcept -> std::string { + inline auto to_string(const Extent& extent) noexcept -> std::string { return std::format("{}", extent); } ///////////////////////////////////// ///////////////////////////////////// template + STORMKIT_FORCE_INLINE inline auto format_as(const extent& extent, FormatContext& ctx) noexcept -> decltype(ctx.out()) { return std::format_to(ctx.out(), "[extent2 width: {}, height: {}]", extent.width, extent.height); } @@ -359,6 +363,7 @@ namespace stormkit { inline namespace core { namespace math { ///////////////////////////////////// ///////////////////////////////////// template + STORMKIT_FORCE_INLINE inline auto format_as(const extent& extent, FormatContext& ctx) noexcept -> decltype(ctx.out()) { return std::format_to(ctx.out(), "[extent3 width: {}, height: {}, depth: {}]", extent.width, extent.height, extent.depth); } @@ -366,6 +371,7 @@ namespace stormkit { inline namespace core { namespace math { ///////////////////////////////////// ///////////////////////////////////// template + STORMKIT_FORCE_INLINE constexpr auto hasher(const extent& extent) noexcept -> Ret { return hash(extent.width, extent.height); } @@ -373,6 +379,7 @@ namespace stormkit { inline namespace core { namespace math { ///////////////////////////////////// ///////////////////////////////////// template + STORMKIT_FORCE_INLINE constexpr auto hasher(const extent& extent) noexcept -> Ret { return hash(extent.width, extent.height, extent.depth); } diff --git a/modules/stormkit/core/math/linear-vector.cppm b/modules/stormkit/core/math/linear-vector.cppm index dddc43bd4..e727ee900 100644 --- a/modules/stormkit/core/math/linear-vector.cppm +++ b/modules/stormkit/core/math/linear-vector.cppm @@ -143,6 +143,15 @@ export namespace stormkit { inline namespace core { namespace math { [[nodiscard]] constexpr auto as_mdspan_mut(T& value) noexcept -> VectorSpan; + template + auto to_string(const vec2& value) noexcept -> std::string; + + template + auto to_string(const vec3& value) noexcept -> std::string; + + template + auto to_string(const vec4& value) noexcept -> std::string; + template constexpr auto hasher(const vec2& value) noexcept -> Ret; @@ -347,6 +356,30 @@ namespace stormkit { inline namespace core { namespace math { return VectorSpan { &value.x, T::EXTENT }; } + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + auto to_string(const vec2& value) noexcept -> std::string { + return std::format("{}", value); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + auto to_string(const vec3& value) noexcept -> std::string { + return std::format("{}", value); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + auto to_string(const vec4& value) noexcept -> std::string { + return std::format("{}", value); + } + //////////////////////////////////////// //////////////////////////////////////// template @@ -384,7 +417,7 @@ namespace stormkit { inline namespace core { namespace math { template STORMKIT_FORCE_INLINE inline auto format_as(const vec3& value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { - return std::format_to(ctx.out(), "[vec2 x: {}, y: {}, z: {}]", value.x, value.y, value.z); + return std::format_to(ctx.out(), "[vec3 x: {}, y: {}, z: {}]", value.x, value.y, value.z); } //////////////////////////////////////// @@ -392,6 +425,6 @@ namespace stormkit { inline namespace core { namespace math { template STORMKIT_FORCE_INLINE inline auto format_as(const vec4& value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { - return std::format_to(ctx.out(), "[vec2 x: {}, y: {}, z: {}, w: {}]", value.x, value.y, value.z, value.w); + return std::format_to(ctx.out(), "[vec4 x: {}, y: {}, z: {}, w: {}]", value.x, value.y, value.z, value.w); } }}} // namespace stormkit::core::math diff --git a/modules/stormkit/core/meta/type_query.cppm b/modules/stormkit/core/meta/type_query.cppm index 255874300..e88fc0078 100644 --- a/modules/stormkit/core/meta/type_query.cppm +++ b/modules/stormkit/core/meta/type_query.cppm @@ -78,7 +78,7 @@ namespace stormkit { inline namespace core { namespace meta { using UnderlyingType = details::UnderlyingType::Type; template - using ArithmeticOrderingType = Select, std::strong_ordering, std::weak_ordering>; + using ArithmeticOrderingType = Select, std::strong_ordering, std::partial_ordering>; template constexpr auto enumerate() noexcept -> decltype(auto) = delete; diff --git a/modules/stormkit/core/utils/color.cppm b/modules/stormkit/core/utils/color.cppm index 14e4f38ec..f3e72ba65 100644 --- a/modules/stormkit/core/utils/color.cppm +++ b/modules/stormkit/core/utils/color.cppm @@ -52,6 +52,9 @@ export namespace stormkit { inline namespace core { template struct color { + static constexpr auto LAYOUT = ColorLayout::R; + using Storage = T; + static constexpr auto COMPONENTS_COUNT = 1; T r; @@ -60,6 +63,9 @@ export namespace stormkit { inline namespace core { template struct color { + static constexpr auto LAYOUT = ColorLayout::RG; + using Storage = T; + static constexpr auto COMPONENTS_COUNT = 2; T r; T g; @@ -69,6 +75,9 @@ export namespace stormkit { inline namespace core { template struct color { + static constexpr auto LAYOUT = ColorLayout::RGB; + using Storage = T; + static constexpr auto COMPONENTS_COUNT = 3; T r; T g; @@ -79,6 +88,9 @@ export namespace stormkit { inline namespace core { template struct color { + static constexpr auto LAYOUT = ColorLayout::RGBA; + using Storage = T; + static constexpr auto COMPONENTS_COUNT = 4; T r; T g; @@ -90,6 +102,9 @@ export namespace stormkit { inline namespace core { template struct color { + static constexpr auto LAYOUT = ColorLayout::ARGB; + using Storage = T; + static constexpr auto COMPONENTS_COUNT = 4; T a; T r; @@ -101,6 +116,9 @@ export namespace stormkit { inline namespace core { template struct color { + static constexpr auto LAYOUT = ColorLayout::BGR; + using Storage = T; + static constexpr auto COMPONENTS_COUNT = 3; T b; T g; @@ -111,6 +129,9 @@ export namespace stormkit { inline namespace core { template struct color { + static constexpr auto LAYOUT = ColorLayout::BGRA; + using Storage = T; + static constexpr auto COMPONENTS_COUNT = 4; T b; T g; @@ -122,6 +143,9 @@ export namespace stormkit { inline namespace core { template struct color { + static constexpr auto LAYOUT = ColorLayout::ABGR; + using Storage = T; + static constexpr auto COMPONENTS_COUNT = 4; T a; T b; @@ -166,6 +190,12 @@ export namespace stormkit { inline namespace core { using bgracolor_u = bgracolor; using abgrcolor_u = abgrcolor; + constexpr auto as_string(ColorLayout layout) noexcept -> std::string_view; + constexpr auto to_string(ColorLayout layout) noexcept -> std::string; + + template + constexpr auto to_string(const color& color) noexcept -> std::string; + template auto format_as(const color& color, FormatContext& ctx) noexcept -> decltype(ctx.out()); @@ -302,6 +332,11 @@ export namespace stormkit { inline namespace core { .a = ColorComponent::max() } }; + template + inline constexpr auto FUSCHIA = details::ImplicitConverter { + .c = { .r = ColorComponent::max(), .g = 0, .b = ColorComponent::max(), .a = ColorComponent::max() } + }; + template inline constexpr auto TRANSPARENT = details::ImplicitConverter { .c = { .r = 0, .g = 0, .b = 0, .a = 0 } @@ -471,42 +506,75 @@ namespace stormkit { inline namespace core { return r == other.r and g == other.g and b == other.b and a == other.a; } + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_CONST + constexpr auto as_string(ColorLayout layout) noexcept -> std::string_view { + switch (layout) { + case ColorLayout::R: return "R"; + case ColorLayout::RG: return "RG"; + case ColorLayout::RGB: return "RGB"; + case ColorLayout::BGR: return "BGR"; + case ColorLayout::RGBA: return "RGBA"; + case ColorLayout::ARGB: return "ARGB"; + case ColorLayout::BGRA: return "BGRA"; + case ColorLayout::ABGR: return "ABGR"; + default: break; + } + std::unreachable(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto to_string(ColorLayout layout) noexcept -> std::string { + return std::string { as_string(layout) }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto to_string(const color& color) noexcept -> std::string { + return std::format("{}", color); + } + ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE inline auto format_as(const color& color, FormatContext& ctx) noexcept -> decltype(ctx.out()) { - if constexpr (LAYOUT == ColorLayout::R) return std::format_to(ctx.out(), "[color layout: R red: {}]", color.r); + if constexpr (LAYOUT == ColorLayout::R) return std::format_to(ctx.out(), "[color layout: R, red: {}]", color.r); else if constexpr (LAYOUT == ColorLayout::RG) - return std::format_to(ctx.out(), "[color layout: RG red: {}, green: {}]", color.r, color.g); + return std::format_to(ctx.out(), "[color layout: RG, red: {}, green: {}]", color.r, color.g); else if constexpr (LAYOUT == ColorLayout::RGB) - return std::format_to(ctx.out(), "[color layout: RGB red: {}, green: {}, blue: {}]", color.r, color.g, color.b); + return std::format_to(ctx.out(), "[color layout: RGB, red: {}, green: {}, blue: {}]", color.r, color.g, color.b); else if constexpr (LAYOUT == ColorLayout::BGR) - return std::format_to(ctx.out(), "[color layout: BGR blue: {}, green: {}, red: {}]", color.r, color.g); + return std::format_to(ctx.out(), "[color layout: BGR, blue: {}, green: {}, red: {}]", color.r, color.g); else if constexpr (LAYOUT == ColorLayout::RGBA) return std::format_to(ctx.out(), - "[color layout: RGBA red: {}, green: {}, blue: {}, alpha: {}]", + "[color layout: RGBA, red: {}, green: {}, blue: {}, alpha: {}]", color.r, color.g, color.b, color.a); else if constexpr (LAYOUT == ColorLayout::ARGB) return std::format_to(ctx.out(), - "[color layout: ARGB alpha: {}, red: {}, green: {}, blue: {}]", + "[color layout: ARGB, alpha: {}, red: {}, green: {}, blue: {}]", color.a, color.r, color.g, color.b); else if constexpr (LAYOUT == ColorLayout::BGRA) return std::format_to(ctx.out(), - "[color layout: BGRA bue: {}, green: {}, red: {}, alpha: {}]", + "[color layout: BGRA, bue: {}, green: {}, red: {}, alpha: {}]", color.b, color.g, color.r, color.a); else if constexpr (LAYOUT == ColorLayout::ABGR) return std::format_to(ctx.out(), - "[color layout: ABGR alpha: {}, blue: {}, green: {}, red: {}]", + "[color layout: ABGR, alpha: {}, blue: {}, green: {}, red: {}]", color.a, color.b, color.g, diff --git a/modules/stormkit/lua.cppm b/modules/stormkit/lua.cppm index 0f87f3c18..a45133ece 100644 --- a/modules/stormkit/lua.cppm +++ b/modules/stormkit/lua.cppm @@ -19,8 +19,6 @@ import stormkit.core; namespace stdfs = std::filesystem; -namespace lb = luabridge; - export namespace stormkit::lua { struct Modules { bool log = false; @@ -42,8 +40,6 @@ export namespace stormkit::lua { auto lua_main() noexcept -> std::expected; - auto global_namespace() noexcept -> lb::Namespace; - static auto create(const stdfs::path& file, Modules modules = {}) noexcept -> Engine; private: @@ -51,8 +47,8 @@ export namespace stormkit::lua { auto load(const stdfs::path&) noexcept -> void; - lua_State* m_global_state = nullptr; - lua_State* m_main_thread = nullptr; + sol::state m_global_state; + sol::load_result m_script; }; } // namespace stormkit::lua @@ -61,12 +57,6 @@ export namespace stormkit::lua { //////////////////////////////////////////////////////////////////// namespace stormkit::lua { - //////////////////////////////////////// - //////////////////////////////////////// - inline auto Engine::global_namespace() noexcept -> lb::Namespace { - return lb::getGlobalNamespace(m_global_state); - } - //////////////////////////////////////// //////////////////////////////////////// inline auto Engine::create(const stdfs::path& file, Modules modules) noexcept -> Engine { diff --git a/modules/stormkit/wsi/core.cppm b/modules/stormkit/wsi/core.cppm index 8a586a654..b27546f42 100644 --- a/modules/stormkit/wsi/core.cppm +++ b/modules/stormkit/wsi/core.cppm @@ -27,6 +27,7 @@ export namespace stormkit::wsi { }; constexpr auto as_string(WM wm) noexcept -> std::string_view; + constexpr auto to_string(WM wm) noexcept -> std::string; STORMKIT_WSI_API auto parse_args(std::span args) noexcept -> void; @@ -58,4 +59,11 @@ namespace stormkit::wsi { std::unreachable(); } + + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto to_string(WM wm) noexcept -> std::string { + return std::string { as_string(wm) }; + } } // namespace stormkit::wsi diff --git a/modules/stormkit/wsi/keyboard.cppm b/modules/stormkit/wsi/keyboard.cppm index a248fb5d9..65fef7783 100644 --- a/modules/stormkit/wsi/keyboard.cppm +++ b/modules/stormkit/wsi/keyboard.cppm @@ -143,6 +143,7 @@ export namespace stormkit::wsi { UNKNOWN = std::numeric_limits::max(), }; constexpr auto as_string(Key key) noexcept -> std::string_view; + constexpr auto to_string(Key key) noexcept -> std::string; } // namespace stormkit::wsi //////////////////////////////////////////////////////////////////// @@ -152,6 +153,7 @@ export namespace stormkit::wsi { namespace stormkit::wsi { //////////////////////////////////////// //////////////////////////////////////// + STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto as_string(Key key) noexcept -> std::string_view { switch (key) { case Key::A: return "Key::A"; @@ -282,4 +284,11 @@ namespace stormkit::wsi { } std::unreachable(); } + + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto to_string(Key key) noexcept -> std::string { + return std::string { as_string(key) }; + } } // namespace stormkit::wsi diff --git a/modules/stormkit/wsi/monitor.cppm b/modules/stormkit/wsi/monitor.cppm index 93640527d..fa7bde96c 100644 --- a/modules/stormkit/wsi/monitor.cppm +++ b/modules/stormkit/wsi/monitor.cppm @@ -32,10 +32,16 @@ export { [[nodiscard]] constexpr auto operator<=>(const Monitor& other) const noexcept -> std::strong_ordering; + [[nodiscard]] + constexpr auto operator==(const Monitor& other) const noexcept -> bool; + void* native_handle = nullptr; }; constexpr auto as_string(Monitor::Flags flags) noexcept -> std::string_view; + constexpr auto to_string(Monitor::Flags flags) noexcept -> std::string; + + auto to_string(const Monitor& monitor) noexcept -> std::string; template auto format_as(const Monitor& monitor, FormatContext& ctx) noexcept -> decltype(ctx.out()); @@ -81,11 +87,26 @@ namespace stormkit::wsi { return std::strong_ordering::equal; } + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_PURE + constexpr auto Monitor::operator==(const Monitor& other) const noexcept -> bool { + if (flags != other.flags) return false; + if (name != other.name) return false; + if (std::size(extents) != std::size(other.extents)) return false; + for (auto i : range(std::size(extents))) { + if (extents[i].width != other.extents[i].width) return false; + if (extents[i].height != other.extents[i].height) return false; + } + + return true; + } + //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto as_string(Monitor::Flags wm) noexcept -> std::string_view { - switch (wm) { + constexpr auto as_string(Monitor::Flags flags) noexcept -> std::string_view { + switch (flags) { case Monitor::Flags::NONE: return "Monitor::Flags::NONE"; case Monitor::Flags::PRIMARY: return "Monitor::Flags::PRIMARY"; default: break; @@ -94,13 +115,27 @@ namespace stormkit::wsi { std::unreachable(); } + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto to_string(Monitor::Flags flags) noexcept -> std::string { + return std::string { as_string(flags) }; + } + + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto to_string(const Monitor& monitor) noexcept -> std::string { + return std::format("{}", monitor); + } + //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_FORCE_INLINE inline auto format_as(const Monitor& monitor, FormatContext& ctx) noexcept -> decltype(ctx.out()) { return std::format_to(ctx.out(), - "{{ Monitor: .name = {}, .flags = {}, .extents = {}, .scale_factor = {} }}", + "[Monitor name: {}, flags: {}, extents: {}, scale_factor: {}]", monitor.name, monitor.flags, monitor.extents, diff --git a/modules/stormkit/wsi/mouse.cppm b/modules/stormkit/wsi/mouse.cppm index 7aa6573ec..d3785f005 100644 --- a/modules/stormkit/wsi/mouse.cppm +++ b/modules/stormkit/wsi/mouse.cppm @@ -34,6 +34,7 @@ export namespace stormkit::wsi { }; constexpr auto as_string(MouseButton button) noexcept -> std::string_view; + constexpr auto to_string(MouseButton button) noexcept -> std::string; } // namespace stormkit::wsi //////////////////////////////////////////////////////////////////// @@ -66,4 +67,11 @@ namespace stormkit::wsi { std::unreachable(); } + + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto to_string(MouseButton button) noexcept -> std::string { + return std::string { as_string(button) }; + } } // namespace stormkit::wsi diff --git a/modules/stormkit/wsi/window.cppm b/modules/stormkit/wsi/window.cppm index 10fae104d..91990a11e 100644 --- a/modules/stormkit/wsi/window.cppm +++ b/modules/stormkit/wsi/window.cppm @@ -39,6 +39,7 @@ export { EXTERNAL_CONTEXT = 0b1000, }; constexpr auto as_string(WindowFlag button) noexcept -> std::string_view; + constexpr auto to_string(WindowFlag button) noexcept -> std::string; enum class EventType : u8 { NONE = 0, @@ -56,6 +57,7 @@ export { DEACTIVATE, }; constexpr auto as_string(EventType type) noexcept -> std::string_view; + constexpr auto to_string(EventType type) noexcept -> std::string; using NativeHandle = void*; @@ -250,6 +252,8 @@ namespace stdr = std::ranges; using namespace std::literals; namespace stormkit::wsi { + //////////////////////////////////////// + //////////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto as_string(WindowFlag flag) noexcept -> std::string_view { using Pair = std::pair; @@ -267,6 +271,13 @@ namespace stormkit::wsi { return it->second; } + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto to_string(WindowFlag flag) noexcept -> std::string { + return std::string { as_string(flag) }; + } + //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST @@ -290,6 +301,13 @@ namespace stormkit::wsi { std::unreachable(); } + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto to_string(EventType type) noexcept -> std::string { + return std::string { as_string(type) }; + } + //////////////////////////////////////// //////////////////////////////////////// template diff --git a/src/lua/core.cpp b/src/lua/core.cpp new file mode 100644 index 000000000..b7a0ef415 --- /dev/null +++ b/src/lua/core.cpp @@ -0,0 +1,25 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +module stormkit.lua; + +import std; + +import stormkit.core; + +namespace stormkit::lua::core { + extern auto bind_math(sol::state& global_state) noexcept -> void; + extern auto bind_color(sol::state& global_state) noexcept -> void; + + //////////////////////////////////////// + //////////////////////////////////////// + auto init_lua(sol::state& global_state) noexcept -> void { + bind_color(global_state); + bind_math(global_state); + } +} // namespace stormkit::lua::core diff --git a/src/lua/core.cppm b/src/lua/core.cppm index 6447757fe..9b0d4fb06 100644 --- a/src/lua/core.cppm +++ b/src/lua/core.cppm @@ -12,35 +12,6 @@ import std; import stormkit.core; -namespace lb = luabridge; - -namespace stormkit::lua::core { - //////////////////////////////////////// - //////////////////////////////////////// - inline auto bind_color(lb::Namespace&& global_namespace) noexcept -> lb::Namespace { - return global_namespace.beginClass>("fcolor").endClass().beginClass>("ucolor").endClass(); - } - - //////////////////////////////////////// - //////////////////////////////////////// - inline auto bind_extent(lb::Namespace&& global_namespace) noexcept -> lb::Namespace { - return global_namespace.beginNamespace("math") - .beginClass("uextent2") - .endClass() - .beginClass("uextent3") - .endClass() - .beginClass>("fextent2") - .endClass() - .beginClass>("fextent3") - .endClass() - .endNamespace(); - } - - //////////////////////////////////////// - //////////////////////////////////////// - export inline auto init_lua(lb::Namespace&& global_namespace) noexcept -> lb::Namespace { - global_namespace = bind_color(std::move(global_namespace)); - global_namespace = bind_extent(std::move(global_namespace)); - return global_namespace; - } +export namespace stormkit::lua::core { + auto init_lua(sol::state& global_state) noexcept -> void; } // namespace stormkit::lua::core diff --git a/src/lua/core/color.cpp b/src/lua/core/color.cpp new file mode 100644 index 000000000..add2bff7c --- /dev/null +++ b/src/lua/core/color.cpp @@ -0,0 +1,105 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +module stormkit.lua; + +import std; + +import stormkit.core; + +namespace stormkit::lua::core { + namespace { + //////////////////////////////////////// + //////////////////////////////////////// + template + auto _bind_color(std::string_view name, auto& parent, auto... values) { + auto metatable = parent.template new_usertype(name, sol::constructors {}); + metatable[sol::meta_function::to_string] = &stormkit::to_string; + metatable[sol::meta_function::equal_to] = &T::operator==; + + metatable["component_count"] = sol::var(std::cref(T::COMPONENTS_COUNT)); + metatable["layout"] = sol::var(std::cref(T::LAYOUT)); + + ( + [metatable, &values] mutable { + auto&& [k, v] = std::forward(values); + metatable[k] = v; + }(), + ...); + + metatable["BLACK"] = sol::var(stormkit::to_layout(stormkit::colors::BLACK.c)); + metatable["GRAY"] = sol::var(stormkit::to_layout(stormkit::colors::GRAY.c)); + metatable["SILVER"] = sol::var(stormkit::to_layout(stormkit::colors::SILVER.c)); + metatable["WHITE"] = sol::var(stormkit::to_layout(stormkit::colors::WHITE.c)); + metatable["MAROON"] = sol::var(stormkit::to_layout(stormkit::colors::MAROON.c)); + metatable["RED"] = sol::var(stormkit::to_layout(stormkit::colors::RED.c)); + metatable["OLIVE"] = sol::var(stormkit::to_layout(stormkit::colors::OLIVE.c)); + metatable["YELLOW"] = sol::var(stormkit::to_layout(stormkit::colors::YELLOW.c)); + metatable["GREEN"] = sol::var(stormkit::to_layout(stormkit::colors::GREEN.c)); + metatable["LIME"] = sol::var(stormkit::to_layout(stormkit::colors::LIME.c)); + metatable["TEAL"] = sol::var(stormkit::to_layout(stormkit::colors::TEAL.c)); + metatable["AQUA"] = sol::var(stormkit::to_layout(stormkit::colors::AQUA.c)); + metatable["NAVY"] = sol::var(stormkit::to_layout(stormkit::colors::NAVY.c)); + metatable["BLUE"] = sol::var(stormkit::to_layout(stormkit::colors::PURPLE.c)); + metatable["PURPLE"] = sol::var(stormkit::to_layout(stormkit::colors::PURPLE.c)); + metatable["FUSCHIA"] = sol::var(stormkit::to_layout(stormkit::colors::FUSCHIA.c)); + metatable["TRANSPARENT"] = sol::var(stormkit::to_layout< + T::LAYOUT>(stormkit::colors::TRANSPARENT.c)); + } + } // namespace + + //////////////////////////////////////// + //////////////////////////////////////// + auto bind_color(sol::state& global_state) noexcept -> void { + global_state["color_layout"] = global_state.create_table_with( + sol::meta_function::to_string, + +[](ColorLayout layout) static noexcept { return to_string(layout); }, + "R", + ColorLayout::R, + "RG", + ColorLayout::RG, + "RGB", + ColorLayout::RGB, + "BGR", + ColorLayout::BGR, + "RGBA", + ColorLayout::RGBA, + "ARGB", + ColorLayout::ARGB, + "BGRA", + ColorLayout::BGRA, + "ABGR", + ColorLayout::ABGR); + + auto f32_metatable = global_state["fcolor"].get_or_create(); + _bind_color("rgb", + f32_metatable, + std::pair { "r", &rgbcolor_f::r }, + std::pair { "g", &rgbcolor_f::g }, + std::pair { "b", &rgbcolor_f::b }); + _bind_color("rgba", + f32_metatable, + std::pair { "r", &rgbacolor_f::r }, + std::pair { "g", &rgbacolor_f::g }, + std::pair { "b", &rgbacolor_f::b }, + std::pair { "a", &rgbacolor_f::a }); + + auto u8_metatable = global_state["ucolor"].get_or_create(); + _bind_color("rgb", + u8_metatable, + std::pair { "r", &rgbcolor_u::r }, + std::pair { "g", &rgbcolor_u::g }, + std::pair { "b", &rgbcolor_u::b }); + _bind_color("rgba", + u8_metatable, + std::pair { "r", &rgbacolor_u::r }, + std::pair { "g", &rgbacolor_u::g }, + std::pair { "b", &rgbacolor_u::b }, + std::pair { "a", &rgbacolor_u::a }); + } +} // namespace stormkit::lua::core diff --git a/src/lua/core/color.cppclear b/src/lua/core/color.cppclear new file mode 100644 index 000000000..e69de29bb diff --git a/src/lua/core/math.cpp b/src/lua/core/math.cpp new file mode 100644 index 000000000..62a4914bf --- /dev/null +++ b/src/lua/core/math.cpp @@ -0,0 +1,206 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +module stormkit.lua; + +import std; + +import stormkit.core; + +namespace stormkit::lua::core { + namespace { + //////////////////////////////////////// + //////////////////////////////////////// + template + auto _bind_extent(std::string_view name, auto& parent, auto... values) { + auto metatable = parent.template new_usertype(name, sol::constructors {}); + + metatable[sol::meta_function::to_string] = &math::to_string; + metatable[sol::meta_function::equal_to] = +[](const T& first, const T& second) static noexcept { + return first == second; + }; + + metatable["rank"] = sol::var(std::cref(T::RANK)); + + ( + [metatable, &values] mutable { + auto&& [k, v] = std::forward(values); + metatable[k] = v; + }(), + ...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto _bind_vector(std::string_view name, auto& parent, auto... values) { + auto metatable = parent.template new_usertype(name, sol::constructors {}); + + metatable[sol::meta_function::to_string] = +[](const T& value) static noexcept { return to_string(value); }; + // metatable[sol::meta_function::equal_to] = +[](const T& first, const T& second) static noexcept { + // return first == second; + // }; + + ( + [metatable, &values] mutable { + auto&& [k, v] = std::forward(values); + metatable[k] = v; + }(), + ...); + } + } // namespace + + //////////////////////////////////////// + //////////////////////////////////////// + auto bind_extent(sol::table& metatable) noexcept -> void { + _bind_extent("uextent2", + metatable, + std::pair { "width", &math::uextent2::width }, + std::pair { "height", &math::uextent2::height }); + _bind_extent("math::uextent3", + metatable, + std::pair { "width", &math::uextent3::width }, + std::pair { "height", &math::uextent3::height }, + std::pair { "depth", &math::uextent3::depth }); + _bind_extent("fextent2", + metatable, + std::pair { "width", &math::fextent2::width }, + std::pair { "height", &math::fextent2::height }); + _bind_extent("fextent3", + metatable, + std::pair { "width", &math::fextent3::width }, + std::pair { "height", &math::fextent3::height }, + std::pair { "depth", &math::fextent3::depth }); + _bind_extent("iextent2", + metatable, + std::pair { "width", &math::iextent2::width }, + std::pair { "height", &math::iextent2::height }); + _bind_extent("iextent3", + metatable, + std::pair { "width", &math::iextent3::width }, + std::pair { "height", &math::iextent3::height }, + std::pair { "depth", &math::iextent3::depth }); + } + + //////////////////////////////////////// + //////////////////////////////////////// + auto bind_linear_vector(sol::table& metatable) noexcept -> void { + _bind_vector("fvec2", + metatable, + std::pair { "x", &math::fvec2::x }, + std::pair { "y", &math::fvec2::y }); + _bind_vector("fvec3", + metatable, + std::pair { "x", &math::fvec3::x }, + std::pair { "y", &math::fvec3::y }, + std::pair { "z", &math::fvec3::z }); + // _bind_vector("fvec4", + // metatable, + // std::pair { "x", &math::fvec4::x }, + // std::pair { "y", &math::fvec4::y }, + // std::pair { "z", &math::fvec4::z }, + // std::pair { "w", &math::fvec4::w }); + _bind_vector("uvec2", + metatable, + std::pair { "x", &math::uvec2::x }, + std::pair { "y", &math::uvec2::y }); + _bind_vector("uvec3", + metatable, + std::pair { "x", &math::uvec3::x }, + std::pair { "y", &math::uvec3::y }, + std::pair { "z", &math::uvec3::z }); + // _bind_vector("uvec4", + // metatable, + // std::pair { "x", &math::uvec4::x }, + // std::pair { "y", &math::uvec4::y }, + // std::pair { "z", &math::uvec4::z }, + // std::pair { "w", &math::uvec4::w }); + _bind_vector("ivec2", + metatable, + std::pair { "x", &math::ivec2::x }, + std::pair { "y", &math::ivec2::y }); + _bind_vector("ivec3", + metatable, + std::pair { "x", &math::ivec3::x }, + std::pair { "y", &math::ivec3::y }, + std::pair { "z", &math::ivec3::z }); + // _bind_vector("ivec4", + // metatable, + // std::pair { "x", &math::ivec4::x }, + // std::pair { "y", &math::ivec4::y }, + // std::pair { "z", &math::ivec4::z }, + // std::pair { "w", &math::ivec4::w }); + + metatable["add"] = sol::overload(&math::add, + &math::add, + // &math::add, + &math::add, + &math::add, + // &math::add, + &math::add, + &math::add); + // &math::add); + metatable["sub"] = sol::overload(&math::sub, + &math::sub, + // &math::sub, + &math::sub, + &math::sub, + // &math::sub, + &math::sub, + &math::sub); + // &math::sub); + metatable["mul"] = sol::overload(&math::mul, + &math::mul, + // &math::mul, + &math::mul, + &math::mul, + // &math::mul, + &math::mul, + &math::mul); + // &math::mul); + metatable["div"] = sol::overload(&math::div, + &math::div, + // &math::div, + &math::div, + &math::div, + // &math::div, + &math::div, + &math::div); + // &math::div); + metatable["dot"] = sol::overload(&math::dot, + &math::dot, + // &math::dot, + &math::dot, + &math::dot, + // &math::dot, + &math::dot, + &math::dot); + // &math::dot); + metatable["cross"] = sol::overload( + +[](const math::fvec3& first, const math::fvec3& second) static noexcept { return math::cross(first, second); }, + +[](const math::uvec3& first, const math::uvec3& second) static noexcept { return math::cross(first, second); }, + +[](const math::ivec3& first, const math::ivec3& second) static noexcept { return math::cross(first, second); }); + + // &math::cross); + metatable["normalize"] = sol::overload(&math::normalize, + &math::normalize, + // &math::normalize, + &math::normalize, + &math::normalize, + // &math::normalize, + &math::normalize, + &math::normalize); + // &math::normalize); + } + + auto bind_math(sol::state& global_state) noexcept -> void { + auto math_metatable = global_state["math"].get_or_create(); + bind_extent(math_metatable); + bind_linear_vector(math_metatable); + } +} // namespace stormkit::lua::core diff --git a/src/lua/entities.cpp b/src/lua/entities.cpp new file mode 100644 index 000000000..cc2f597b8 --- /dev/null +++ b/src/lua/entities.cpp @@ -0,0 +1,21 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +module stormkit.lua; + +import std; + +import stormkit.core; +import stormkit.entities; + +namespace stormkit::lua::entities { + //////////////////////////////////////// + //////////////////////////////////////// + auto init_lua(sol::state&) noexcept -> void { + } +} // namespace stormkit::lua::entities diff --git a/src/lua/entities.cppm b/src/lua/entities.cppm index 497c16bb9..bfca90932 100644 --- a/src/lua/entities.cppm +++ b/src/lua/entities.cppm @@ -13,12 +13,6 @@ import std; import stormkit.core; import stormkit.entities; -namespace lb = luabridge; - export namespace stormkit::lua::entities { - //////////////////////////////////////// - //////////////////////////////////////// - inline auto init_lua(lb::Namespace&& global_namespace) noexcept -> lb::Namespace { - return global_namespace; - } + auto init_lua(sol::state& global_state) noexcept -> void; } // namespace stormkit::lua::entities diff --git a/src/lua/gpu.cpp b/src/lua/gpu.cpp new file mode 100644 index 000000000..d01cb1bcb --- /dev/null +++ b/src/lua/gpu.cpp @@ -0,0 +1,21 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +module stormkit.lua; + +import std; + +import stormkit.core; +import stormkit.gpu; + +namespace stormkit::lua::gpu { + //////////////////////////////////////// + //////////////////////////////////////// + auto init_lua(sol::state&) noexcept -> void { + } +} // namespace stormkit::lua::gpu diff --git a/src/lua/gpu.cppm b/src/lua/gpu.cppm index b0d2e9617..996cba31b 100644 --- a/src/lua/gpu.cppm +++ b/src/lua/gpu.cppm @@ -13,12 +13,6 @@ import std; import stormkit.core; import stormkit.gpu; -namespace lb = luabridge; - export namespace stormkit::lua::gpu { - //////////////////////////////////////// - //////////////////////////////////////// - inline auto init_lua(lb::Namespace&& global_namespace) noexcept -> lb::Namespace { - return global_namespace; - } + auto init_lua(sol::state& global_state) noexcept -> void; } // namespace stormkit::lua::gpu diff --git a/src/lua/image.cpp b/src/lua/image.cpp new file mode 100644 index 000000000..eb1f8ba36 --- /dev/null +++ b/src/lua/image.cpp @@ -0,0 +1,19 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +module stormkit.lua; + +import std; + +import stormkit.core; +import stormkit.image; + +namespace stormkit::lua::image { + auto init_lua(sol::state&) noexcept -> void { + } +} // namespace stormkit::lua::image diff --git a/src/lua/image.cppm b/src/lua/image.cppm index 6d94fd997..32ab13b62 100644 --- a/src/lua/image.cppm +++ b/src/lua/image.cppm @@ -13,12 +13,6 @@ import std; import stormkit.core; import stormkit.image; -namespace lb = luabridge; - export namespace stormkit::lua::image { - //////////////////////////////////////// - //////////////////////////////////////// - inline auto init_lua(lb::Namespace&& global_namespace) noexcept -> lb::Namespace { - return global_namespace; - } + auto init_lua(sol::state& global_state) noexcept -> void; } // namespace stormkit::lua::image diff --git a/src/lua/log.cpp b/src/lua/log.cpp new file mode 100644 index 000000000..67bb86ab8 --- /dev/null +++ b/src/lua/log.cpp @@ -0,0 +1,19 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +module stormkit.lua; + +import std; + +import stormkit.core; +import stormkit.log; + +namespace stormkit::lua::log { + auto init_lua(sol::state&) noexcept -> void { + } +} // namespace stormkit::lua::log diff --git a/src/lua/log.cppm b/src/lua/log.cppm index e719ee32b..e9191a08e 100644 --- a/src/lua/log.cppm +++ b/src/lua/log.cppm @@ -13,10 +13,6 @@ import std; import stormkit.core; import stormkit.log; -namespace lb = luabridge; - export namespace stormkit::lua::log { - inline auto init_lua(lb::Namespace&& global_namespace) noexcept -> lb::Namespace { - return global_namespace; - } + auto init_lua(sol::state& global_state) noexcept -> void; } // namespace stormkit::lua::log diff --git a/src/lua/lua.cpp b/src/lua/lua.cpp index 443ff34f8..ac709d5cd 100644 --- a/src/lua/lua.cpp +++ b/src/lua/lua.cpp @@ -43,24 +43,24 @@ import :gpu; namespace stdfs = std::filesystem; namespace stdr = std::ranges; -namespace lb = luabridge; - LOGGER("stormkit.lua") namespace stormkit::lua { //////////////////////////////////////// //////////////////////////////////////// Engine::Engine(Modules modules) noexcept { - m_global_state = luaL_newstate(); - luaL_openlibs(m_global_state); - - auto global_namespace = lb::getGlobalNamespace(m_global_state); - - global_namespace = core::init_lua(std::move(global_namespace)); + m_global_state.open_libraries(sol::lib::base); + m_global_state.open_libraries(sol::lib::bit32); + m_global_state.open_libraries(sol::lib::debug); + m_global_state.open_libraries(sol::lib::io); + m_global_state.open_libraries(sol::lib::os); + m_global_state.open_libraries(sol::lib::string); + m_global_state.open_libraries(sol::lib::table); + core::init_lua(m_global_state); if (modules.log) { #if STORMKIT_LIB_LOG_ENABLED dlog("Log module enabled"); - global_namespace = log::init_lua(std::move(global_namespace)); + log::init_lua(m_global_state); #else elog("Trying to bind log module while disabled in this stormkit distribution!"); #endif @@ -68,7 +68,7 @@ namespace stormkit::lua { if (modules.entities) { #if STORMKIT_LIB_ENTITIES_ENABLED dlog("Entities module enabled"); - global_namespace = entities::init_lua(std::move(global_namespace)); + entities::init_lua(m_global_state); #else elog("Trying to bind entities module while disabled in this stormkit distribution!"); #endif @@ -76,7 +76,7 @@ namespace stormkit::lua { if (modules.image) { #if STORMKIT_LIB_IMAGE_ENABLED dlog("Image module enabled"); - global_namespace = image::init_lua(std::move(global_namespace)); + image::init_lua(m_global_state); #else elog("Trying to bind image module while disabled in this stormkit distribution!"); #endif @@ -84,7 +84,7 @@ namespace stormkit::lua { if (modules.wsi) { #if STORMKIT_LIB_WSI_ENABLED dlog("Wsi module enabled"); - global_namespace = wsi::init_lua(std::move(global_namespace)); + wsi::init_lua(m_global_state); #else elog("Trying to bind wsi module while disabled in this stormkit distribution!"); #endif @@ -92,7 +92,7 @@ namespace stormkit::lua { if (modules.gpu) { #if STORMKIT_LIB_GPU_ENABLED dlog("Gpu module enabled"); - global_namespace = gpu::init_lua(std::move(global_namespace)); + gpu::init_lua(m_global_state); #else elog("Trying to bind gpu module while disabled in this stormkit distribution!"); #endif @@ -101,50 +101,35 @@ namespace stormkit::lua { //////////////////////////////////////// //////////////////////////////////////// - Engine::Engine(Engine&& other) noexcept - : m_global_state { std::exchange(other.m_global_state, nullptr) }, - m_main_thread { std::exchange(other.m_main_thread, nullptr) } { - } + Engine::Engine(Engine&& other) noexcept = default; //////////////////////////////////////// //////////////////////////////////////// - auto Engine::operator=(Engine&& other) noexcept -> Engine& { - if (&other == this) [[unlikely]] - return *this; - m_global_state = std::exchange(other.m_global_state, nullptr); - m_main_thread = std::exchange(other.m_main_thread, nullptr); - - return *this; - }; + auto Engine::operator=(Engine&& other) noexcept -> Engine& = default; //////////////////////////////////////// //////////////////////////////////////// - Engine::~Engine() noexcept { - if (m_main_thread) m_main_thread = nullptr; - - if (m_global_state) { - lua_close(m_global_state); - m_global_state = nullptr; - } - } + Engine::~Engine() noexcept = default; //////////////////////////////////////// //////////////////////////////////////// auto Engine::load(const stdfs::path& file) noexcept -> void { - auto data = TryAssert(io::read_text(file), std::format("Failed to load {}", file.string())); + const auto code = TryAssert(io::read_text(file), std::format("Failed to load {}", file.string())); - auto bytecode_size = 0_usize; - auto bytecode = luau_compile(stdr::data(data), stdr::size(data), nullptr, &bytecode_size); - auto result = luau_load(m_global_state, "main", bytecode, bytecode_size, 0); - std::free(bytecode); + m_script = m_global_state.load(std::string_view { stdr::data(code), stdr::size(code) }); - if (result != 0) { - auto len = usize { 0 }; - auto msg = lua_tolstring(m_global_state, -1, &len); + // auto bytecode_size = 0_usize; + // auto bytecode = luau_compile(stdr::data(data), stdr::size(data), nullptr, &bytecode_size); + // auto result = luau_load(m_global_state, "main", bytecode, bytecode_size, 0); + // std::free(bytecode); - ensures(result == 0, - std::format("Lua compilation error!\n-------------------------------\n{}", std::string_view { msg, len })); - } + // if (result != 0) { + // auto len = usize { 0 }; + // auto msg = lua_tolstring(m_global_state, -1, &len); + + // ensures(result == 0, + // std::format("Lua compilation error!\n-------------------------------\n{}", std::string_view { msg, len })); + // } // m_main_thread = lua_newthread(m_global_state); // ensures(m_main_thread); @@ -154,25 +139,6 @@ namespace stormkit::lua { // lua_xmove(m_global_state, m_main_thread, 1); } - static int traceback(lua_State* L) { - if (!lua_isstring(L, 1)) /* 'message' not a string? */ - return 1; /* keep it intact */ - lua_getfield(L, LUA_GLOBALSINDEX, "debug"); - if (!lua_istable(L, -1)) { - lua_pop(L, 1); - return 1; - } - lua_getfield(L, -1, "traceback"); - if (!lua_isfunction(L, -1)) { - lua_pop(L, 2); - return 1; - } - lua_pushvalue(L, 1); /* pass error message */ - lua_pushinteger(L, 2); /* skip this function and traceback */ - lua_call(L, 2, 1); /* call debug.traceback */ - return 1; - } - //////////////////////////////////////// //////////////////////////////////////// auto Engine::lua_main() noexcept -> std::expected { @@ -180,27 +146,33 @@ namespace stormkit::lua { auto out = std::expected {}; - traceback(m_global_state); - - luaL_sandbox(m_global_state); - luaL_sandboxthread(m_global_state); - - auto status = lua_resume(m_global_state, nullptr, 0); - if (status == 0) { - // if (const auto n = lua_gettop(m_global_state); n) { - // luaL_checkstack(m_global_state, LUA_MINSTACK, "too many results to print"); - // lua_getglobal(m_global_state, "print"); - // lua_insert(m_global_state, 1); - // lua_pcall(m_global_state, n, 0, 0); - // } - - // lua_pop(m_global_state, 1); - } else { - traceback(m_global_state); - auto error = std::string { lua_tostring(m_global_state, -1) }; - out = std::unexpected { std::move(error) }; + // traceback(m_global_state); + + // luaL_sandbox(m_global_state); + // luaL_sandboxthread(m_global_state); + + // auto status = lua_resume(m_global_state, nullptr, 0); + // if (status == 0) { + // // if (const auto n = lua_gettop(m_global_state); n) { + // // luaL_checkstack(m_global_state, LUA_MINSTACK, "too many results to print"); + // // lua_getglobal(m_global_state, "print"); + // // lua_insert(m_global_state, 1); + // // lua_pcall(m_global_state, n, 0, 0); + // // } + + // // lua_pop(m_global_state, 1); + // } else { + // traceback(m_global_state); + // auto error = std::string { lua_tostring(m_global_state, -1) }; + // out = std::unexpected { std::move(error) }; + // } + + // return out; + auto result = m_script(); + if (not result.valid()) { + const auto err = sol::error { result }; + out = std::unexpected { err.what() }; } - return out; } } // namespace stormkit::lua diff --git a/src/lua/wsi.cpp b/src/lua/wsi.cpp index 87000a9bb..7e12f8779 100644 --- a/src/lua/wsi.cpp +++ b/src/lua/wsi.cpp @@ -15,116 +15,21 @@ import std; import stormkit.core; import stormkit.wsi; -namespace lb = luabridge; - namespace stormkit::lua::wsi { - using stormkit::wsi::EventType; - using stormkit::wsi::Window; - using stormkit::wsi::WindowFlag; - using stormkit::wsi::WM; - - //////////////////////////////////////// - //////////////////////////////////////// - auto open_window(std::string name, u32 width, u32 height, wsi::WindowFlag flags) noexcept -> wsi::Window { - std::println("AAAAAAAAAAAAAAA"); - return wsi::Window::open(std::move(name), { width, height }, flags); - } - - namespace { - //////////////////////////////////////// - //////////////////////////////////////// - template - constexpr auto make_lua_closure() noexcept { - return [](Window* window, lb::LuaRef func) static noexcept { - window->on([func = std::move(func)](Args&&... args) noexcept { - const auto result = func(std::forward(args)...); - ensures(result.wasOk(), result.errorMessage()); - }); - }; - } - - //////////////////////////////////////// - //////////////////////////////////////// - auto bind_core(lb::Namespace&& global_namespace) noexcept -> lb::Namespace { - return global_namespace.beginNamespace("wsi") - .beginNamespace("wm") - .addProperty("WIN32", [] static noexcept { return WM::WIN32; }) - .addProperty("WAYLAND", [] static noexcept { return WM::WAYLAND; }) - .addProperty("X11", [] static noexcept { return WM::X11; }) - .addProperty("ANDROID", [] static noexcept { return WM::ANDROID; }) - .addProperty("MACOS", [] static noexcept { return WM::MACOS; }) - .addProperty("IOS", [] static noexcept { return WM::IOS; }) - .addProperty("TVOS", [] static noexcept { return WM::TVOS; }) - .addProperty("SWITCH", [] static noexcept { return WM::SWITCH; }) - .endNamespace() - .endNamespace(); - } - - //////////////////////////////////////// - //////////////////////////////////////// - auto bind_window(lb::Namespace&& global_namespace) noexcept -> lb::Namespace { - return global_namespace.beginNamespace("wsi") - .beginNamespace("window_flag") - .addProperty("DEFAULT", [] static noexcept { return WindowFlag::DEFAULT; }) - .addProperty("BORDERLESS", [] static noexcept { return WindowFlag::BORDERLESS; }) - .addProperty("RESIZEABLE", [] static noexcept { return WindowFlag::RESIZEABLE; }) - .addProperty("EXTERNAL_CONTEXT", [] static noexcept { return WindowFlag::EXTERNAL_CONTEXT; }) - .endNamespace() - .beginNamespace("EventType") - .addProperty("NONE", [] static noexcept { return EventType::NONE; }) - .addProperty("CLOSED", [] static noexcept { return EventType::CLOSED; }) - .addProperty("MONITOR_CHANGED", [] static noexcept { return EventType::MONITOR_CHANGED; }) - .addProperty("RESIZED", [] static noexcept { return EventType::RESIZED; }) - .addProperty("RESTORED", [] static noexcept { return EventType::RESTORED; }) - .addProperty("MINIMIZED", [] static noexcept { return EventType::MINIMIZED; }) - .addProperty("KEY_DOWN", [] static noexcept { return EventType::KEY_DOWN; }) - .addProperty("KEY_UP", [] static noexcept { return EventType::KEY_UP; }) - .addProperty("MOUSE_BUTTON_DOWN", [] static noexcept { return EventType::MOUSE_BUTTON_DOWN; }) - .addProperty("MOUSE_BUTTON_UP", [] static noexcept { return EventType::MOUSE_BUTTON_UP; }) - .addProperty("MOUSE_MOVED", [] static noexcept { return EventType::MOUSE_MOVED; }) - .addProperty("ACTIVATE", [] static noexcept { return EventType::ACTIVATE; }) - .addProperty("DEACTIVATE", [] static noexcept { return EventType::DEACTIVATE; }) - .endNamespace() - .beginClass("window") - .addFunction("wm", &Window::wm) - .addFunction("extent", &Window::extent) - .addFunction("clear", [](Window* window) static noexcept { window->clear(); }) - .addFunction("event_loop", - [](Window* window, lb::LuaRef func) static noexcept { - window->event_loop([func = std::move(func)] noexcept { - const auto result = func(); - ensures(result.wasOk(), result.errorMessage()); - }); - }) - .addFunction("on_closed", - [](Window* window, lb::LuaRef func) static noexcept { - expects(func.isCallable()); - - window->on([func = std::move(func)] noexcept { - const auto result = func(); - ensures(result.wasOk(), result.errorMessage()); - const auto return_value = result[0]; - ensures(return_value.isValid()); - ensures(return_value.isBool(), "on_closed closure must return a boolean value"); - return return_value.cast().value(); - }); - }) - .addFunction("on_resized", (make_lua_closure())) - .addFunction("on_restored", (make_lua_closure())) - .addFunction("on_minimized", (make_lua_closure())) - .addFunction("on_activate", (make_lua_closure())) - .addFunction("on_deactivate", (make_lua_closure())) - .endClass() - .addFunction("open_window", open_window) - .endNamespace(); - } - } // namespace + extern auto bind_core(sol::state&, sol::table&) noexcept -> void; + extern auto bind_window(sol::state&, sol::table&) noexcept -> void; + extern auto bind_monitor(sol::state&, sol::table&) noexcept -> void; + extern auto bind_keyboard(sol::state&, sol::table&) noexcept -> void; + extern auto bind_mouse(sol::state&, sol::table&) noexcept -> void; //////////////////////////////////////// //////////////////////////////////////// - auto init_lua(lb::Namespace&& global_namespace) noexcept -> lb::Namespace { - global_namespace = bind_core(std::move(global_namespace)); - global_namespace = bind_window(std::move(global_namespace)); - return global_namespace; + auto init_lua(sol::state& global_state) noexcept -> void { + auto wsi_metatable = global_state["wsi"].get_or_create(); + bind_core(global_state, wsi_metatable); + bind_window(global_state, wsi_metatable); + bind_monitor(global_state, wsi_metatable); + bind_keyboard(global_state, wsi_metatable); + bind_mouse(global_state, wsi_metatable); } } // namespace stormkit::lua::wsi diff --git a/src/lua/wsi.cppm b/src/lua/wsi.cppm index 15fc0cb9b..47f56c400 100644 --- a/src/lua/wsi.cppm +++ b/src/lua/wsi.cppm @@ -15,42 +15,40 @@ import std; import stormkit.core; import stormkit.wsi; -namespace lb = luabridge; - export { - template<> - struct lb::Stack: lb::Enum {}; - - template<> - struct lb::Stack - : lb::Enum {}; - - template<> - struct lb::Stack - : lb::Enum {}; + // template<> + // struct lb::Stack: lb::Enum {}; + + // template<> + // struct lb::Stack + // : lb::Enum {}; + + // template<> + // struct lb::Stack + // : lb::Enum {}; namespace stormkit::lua::wsi { - auto init_lua(lb::Namespace&& global_namespace) noexcept -> lb::Namespace; + auto init_lua(sol::state& global_state) noexcept -> void; } // namespace stormkit::lua::wsi } diff --git a/src/lua/wsi/core.cpp b/src/lua/wsi/core.cpp new file mode 100644 index 000000000..e84c86038 --- /dev/null +++ b/src/lua/wsi/core.cpp @@ -0,0 +1,44 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +module stormkit.lua; + +import std; + +import stormkit.core; +import stormkit.wsi; + +namespace stormkit::lua::wsi { + using stormkit::wsi::WM; + + //////////////////////////////////////// + //////////////////////////////////////// + auto bind_core(sol::state& global_state, sol::table& metatable) noexcept -> void { + metatable["window_manager"] = global_state.create_table_with( + sol::meta_function::to_string, + +[](WM wm) { return to_string(wm); }, + "WIN32", + WM::WIN32, + "WAYLAND", + WM::WAYLAND, + "X11", + WM::X11, + "ANDROID", + WM::ANDROID, + "MACOS", + WM::MACOS, + "IOS", + WM::IOS, + "TVOS", + WM::TVOS, + "SWITCH", + WM::SWITCH); + } +} // namespace stormkit::lua::wsi diff --git a/src/lua/wsi/keyboard.cpp b/src/lua/wsi/keyboard.cpp new file mode 100644 index 000000000..961a8ff50 --- /dev/null +++ b/src/lua/wsi/keyboard.cpp @@ -0,0 +1,254 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +module stormkit.lua; + +import std; + +import stormkit.core; +import stormkit.wsi; + +namespace stormkit::lua::wsi { + using stormkit::wsi::Key; + + //////////////////////////////////////// + //////////////////////////////////////// + auto bind_keyboard(sol::state& global_state, sol::table& metatable) noexcept -> void { + metatable["key"] = global_state.create_table_with( + sol::meta_function::to_string, + +[](Key key) { return to_string(key); }, + "A", + Key::A, + "B", + Key::B, + "C", + Key::C, + "D", + Key::D, + "E", + Key::E, + "F", + Key::F, + "G", + Key::G, + "H", + Key::H, + "I", + Key::I, + "J", + Key::J, + "K", + Key::K, + "L", + Key::L, + "M", + Key::M, + "N", + Key::N, + "O", + Key::O, + "P", + Key::P, + "Q", + Key::Q, + "R", + Key::R, + "S", + Key::S, + "T", + Key::T, + "U", + Key::U, + "V", + Key::V, + "W", + Key::W, + "X", + Key::X, + "Y", + Key::Y, + "Z", + Key::Z, + "NUM_0", + Key::NUM_0, + "NUM_1", + Key::NUM_1, + "NUM_2", + Key::NUM_2, + "NUM_3", + Key::NUM_3, + "NUM_4", + Key::NUM_4, + "NUM_5", + Key::NUM_5, + "NUM_6", + Key::NUM_6, + "NUM_7", + Key::NUM_7, + "NUM_8", + Key::NUM_8, + "NUM_9", + Key::NUM_9, + "LEFT", + Key::LEFT, + "RIGHT", + Key::RIGHT, + "UP", + Key::UP, + "DOWN", + Key::DOWN, + "L_CONTROL", + Key::L_CONTROL, + "L_SHIFT", + Key::L_SHIFT, + "L_ALT", + Key::L_ALT, + "L_META", + Key::L_META, + "R_CONTROL", + Key::R_CONTROL, + "R_SHIFT", + Key::R_SHIFT, + "R_ALT", + Key::R_ALT, + "R_META", + Key::R_META, + "ESCAPE", + Key::ESCAPE, + "TAB", + Key::TAB, + "MENU", + Key::MENU, + "QUOTE", + Key::QUOTE, + "BACK_SLASH", + Key::BACK_SLASH, + "COMMA", + Key::COMMA, + "EQUAL", + Key::EQUAL, + "GRAVE_ACCENT", + Key::GRAVE_ACCENT, + "L_BRACKET", + Key::L_BRACKET, + "MINUS", + Key::MINUS, + "PERIOD", + Key::PERIOD, + "R_BRACKET", + Key::R_BRACKET, + "SEMI_COLON", + Key::SEMI_COLON, + "SLASH", + Key::SLASH, + "ISO", + Key::ISO, + "BACK_SPACE", + Key::BACK_SPACE, + "CAPS_LOCK", + Key::CAPS_LOCK, + "ENTER", + Key::ENTER, + "SPACE", + Key::SPACE, + "F1", + Key::F1, + "F2", + Key::F2, + "F3", + Key::F3, + "F4", + Key::F4, + "F5", + Key::F5, + "F6", + Key::F6, + "F7", + Key::F7, + "F8", + Key::F8, + "F9", + Key::F9, + "F10", + Key::F10, + "F11", + Key::F11, + "F12", + Key::F12, + "F13", + Key::F13, + "F14", + Key::F14, + "F15", + Key::F15, + "F16", + Key::F16, + "F17", + Key::F17, + "F18", + Key::F18, + "F19", + Key::F19, + "F20", + Key::F20, + "PRINT_SCREEN", + Key::PRINT_SCREEN, + "INSERT", + Key::INSERT, + "DELETE", + Key::DELETE, + "HOME", + Key::HOME, + "END", + Key::END, + "PAGE_UP", + Key::PAGE_UP, + "PAGE_DOWN", + Key::PAGE_DOWN, + "NUMPAD_LOCK", + Key::NUMPAD_LOCK, + "NUMPAD_ADD", + Key::NUMPAD_ADD, + "NUMPAD_DECIMAL", + Key::NUMPAD_DECIMAL, + "NUMPAD_DIVIDE", + Key::NUMPAD_DIVIDE, + "NUMPAD_ENTER", + Key::NUMPAD_ENTER, + "NUMPAD_EQUAL", + Key::NUMPAD_EQUAL, + "NUMPAD_MULTIPLY", + Key::NUMPAD_MULTIPLY, + "NUMPAD_SUBTRACT", + Key::NUMPAD_SUBTRACT, + "NUMPAD_0", + Key::NUMPAD_0, + "NUMPAD_1", + Key::NUMPAD_1, + "NUMPAD_2", + Key::NUMPAD_2, + "NUMPAD_3", + Key::NUMPAD_3, + "NUMPAD_4", + Key::NUMPAD_4, + "NUMPAD_5", + Key::NUMPAD_5, + "NUMPAD_6", + Key::NUMPAD_6, + "NUMPAD_7", + Key::NUMPAD_7, + "NUMPAD_8", + Key::NUMPAD_8, + "NUMPAD_9", + Key::NUMPAD_9, + "UNKNOWN", + Key::UNKNOWN); + } +} // namespace stormkit::lua::wsi diff --git a/src/lua/wsi/monitor.cpp b/src/lua/wsi/monitor.cpp new file mode 100644 index 000000000..a5e184e75 --- /dev/null +++ b/src/lua/wsi/monitor.cpp @@ -0,0 +1,43 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +module stormkit.lua; + +import std; + +import stormkit.core; +import stormkit.wsi; + +namespace stormkit::lua::wsi { + using stormkit::wsi::Monitor; + + //////////////////////////////////////// + //////////////////////////////////////// + auto bind_monitor(sol::state& global_state, sol::table& metatable) noexcept -> void { + metatable["monitor_flag"] = global_state.create_table_with( + sol::meta_function::to_string, + +[](Monitor::Flags flags) { return to_string(flags); }, + "NONE", + Monitor::Flags::NONE, + "PRIMARY", + Monitor::Flags::PRIMARY); + + auto monitor = metatable.new_usertype("monitor"); + monitor[sol::meta_function::to_string] = +[](Monitor::Flags flags) { return to_string(flags); }, + monitor[sol::meta_function::equal_to] = &Monitor::operator==; + monitor[sol::meta_function::less_than] = +[](const Monitor& first, const Monitor& second) static noexcept { + return first < second; + }; + monitor["flags"] = &Monitor::flags; + monitor["name"] = &Monitor::name; + monitor["extents"] = &Monitor::extents; + monitor["scale_factor"] = &Monitor::scale_factor; + } +} // namespace stormkit::lua::wsi diff --git a/src/lua/wsi/mouse.cpp b/src/lua/wsi/mouse.cpp new file mode 100644 index 000000000..ae4695fd8 --- /dev/null +++ b/src/lua/wsi/mouse.cpp @@ -0,0 +1,58 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +module stormkit.lua; + +import std; + +import stormkit.core; +import stormkit.wsi; + +namespace stormkit::lua::wsi { + using stormkit::wsi::MouseButton; + + //////////////////////////////////////// + //////////////////////////////////////// + auto bind_mouse(sol::state& global_state, sol::table& metatable) noexcept -> void { + metatable["mouse_button"] = global_state.create_table_with( + sol::meta_function::to_string, + +[](MouseButton mouse_button) { return to_string(mouse_button); }, + "LEFT", + MouseButton::LEFT, + "RIGHT", + MouseButton::RIGHT, + "MIDDLE", + MouseButton::MIDDLE, + "BUTTON_1", + MouseButton::BUTTON_1, + "BUTTON_2", + MouseButton::BUTTON_2, + "BUTTON_3", + MouseButton::BUTTON_3, + "BUTTON_4", + MouseButton::BUTTON_4, + "BUTTON_5", + MouseButton::BUTTON_5, + "BUTTON_6", + MouseButton::BUTTON_6, + "BUTTON_7", + MouseButton::BUTTON_7, + "BUTTON_8", + MouseButton::BUTTON_8, + "BUTTON_9", + MouseButton::BUTTON_9, + "BUTTON_10", + MouseButton::BUTTON_10, + "BUTTON_11", + MouseButton::BUTTON_11, + "BUTTON_12", + MouseButton::BUTTON_12); + } +} // namespace stormkit::lua::wsi diff --git a/src/lua/wsi/window.cpp b/src/lua/wsi/window.cpp new file mode 100644 index 000000000..9908c5f68 --- /dev/null +++ b/src/lua/wsi/window.cpp @@ -0,0 +1,159 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +module stormkit.lua; + +import std; + +import stormkit.core; +import stormkit.wsi; + +namespace stormkit::lua::wsi { + using stormkit::wsi::EventType; + using stormkit::wsi::Key; + using stormkit::wsi::Monitor; + using stormkit::wsi::MouseButton; + using stormkit::wsi::Window; + using stormkit::wsi::WindowFlag; + + namespace { + //////////////////////////////////////// + //////////////////////////////////////// + template + constexpr auto make_lua_closure() noexcept { + return [](Window* window, sol::protected_function closure) static noexcept { + window->on([closure = std::move(closure)](Args&&... args) noexcept { + auto result = closure(std::forward(args)...); + if (not result.valid()) + ensures(false, + std::format("lua runtime error!\nlua callstack -------------------------\n{}", + sol::error { result }.what())); + }); + }; + } + } // namespace + + //////////////////////////////////////// + //////////////////////////////////////// + auto open_window(std::string name, u32 width, u32 height, wsi::WindowFlag flags) noexcept -> wsi::Window { + return wsi::Window::open(std::move(name), { width, height }, flags); + } + + //////////////////////////////////////// + //////////////////////////////////////// + auto bind_window(sol::state& global_state, sol::table& metatable) noexcept -> void { + metatable["window_flag"] = global_state.create_table_with( + sol::meta_function::to_string, + +[](WindowFlag flags) { return to_string(flags); }, + "DEFAULT", + WindowFlag::DEFAULT, + "BORDERLESS", + WindowFlag::BORDERLESS, + "RESIZEABLE", + WindowFlag::RESIZEABLE, + "EXTERNAL_CONTEXT", + WindowFlag::EXTERNAL_CONTEXT); + metatable["event_type"] = global_state.create_table_with( + sol::meta_function::to_string, + +[](EventType type) { return to_string(type); }, + "NONE", + EventType::NONE, + "CLOSED", + EventType::CLOSED, + "MONITOR_CHANGED", + EventType::MONITOR_CHANGED, + "RESIZED", + EventType::RESIZED, + "RESTORED", + EventType::RESTORED, + "MINIMIZED", + EventType::MINIMIZED, + "KEY_DOWN", + EventType::KEY_DOWN, + "KEY_UP", + EventType::KEY_UP, + "MOUSE_BUTTON_DOWN", + EventType::MOUSE_BUTTON_DOWN, + "MOUSE_BUTTON_UP", + EventType::MOUSE_BUTTON_UP, + "MOUSE_MOVED", + EventType::MOUSE_MOVED, + "ACTIVATE", + EventType::ACTIVATE, + "DEACTIVATE", + EventType::DEACTIVATE); + + auto window_metatable = metatable.new_usertype("window"); + window_metatable["open"] = &open_window; + window_metatable["window_manager"] = &Window::wm; + window_metatable["extent"] = &Window::extent; + window_metatable["set_extent"] = &Window::set_extent; + window_metatable["close"] = &Window::close; + window_metatable["title"] = &Window::title; + window_metatable["set_title"] = &Window::set_title; + window_metatable["fullscreen"] = &Window::fullscreen; + window_metatable["toggle_fullscreen"] = &Window::toggle_fullscreen; + + window_metatable["is_mouse_hidden"] = sol:: + overload(&Window::is_mouse_hidden, +[](Window* window) static noexcept { return window->is_mouse_hidden(); }); + window_metatable["toggle_hidden_mouse"] = sol:: + overload(&Window::toggle_hidden_mouse, +[](Window* window) static noexcept { return window->toggle_hidden_mouse(); }); + window_metatable["is_mouse_locked"] = sol:: + overload(&Window::is_mouse_locked, +[](Window* window) static noexcept { return window->is_mouse_locked(); }); + window_metatable["toggle_locked_mouse"] = sol:: + overload(&Window::toggle_locked_mouse, +[](Window* window) static noexcept { return window->toggle_locked_mouse(); }); + window_metatable["is_mouse_confined"] = sol:: + overload(&Window::is_mouse_confined, +[](Window* window) static noexcept { return window->is_mouse_confined(); }); + window_metatable["toggle_confined_mouse"] = sol::overload( + &Window::toggle_confined_mouse, + +[](Window* window) static noexcept { return window->toggle_confined_mouse(); }); + window_metatable["is_mouse_relative"] = sol:: + overload(&Window::is_mouse_relative, +[](Window* window) static noexcept { return window->is_mouse_relative(); }); + window_metatable["toggle_relative_mouse"] = sol::overload( + &Window::toggle_relative_mouse, + +[](Window* window) static noexcept { return window->toggle_relative_mouse(); }); + window_metatable["is_key_repeat_enabled"] = sol::overload( + &Window::is_key_repeat_enabled, + +[](Window* window) static noexcept { return window->is_key_repeat_enabled(); }); + window_metatable["toggle_key_repeat"] = sol:: + overload(&Window::toggle_key_repeat, +[](Window* window) static noexcept { return window->toggle_key_repeat(); }); + window_metatable["clear"] = sol:: + overload(&Window::clear, +[](Window* window) static noexcept { return window->clear(); }); + + window_metatable["event_loop"] = +[](Window* window, sol::protected_function closure) static noexcept { + window->event_loop([closure = std::move(closure)] noexcept { + auto result = closure(); + if (not result.valid()) ensures(false, sol::error { result }.what()); + }); + }; + window_metatable["on_closed"] = +[](Window* window, sol::protected_function closure) static noexcept { + window->on([closure = std::move(closure)] noexcept { + const auto result = closure(); + if (not result.valid()) ensures(false, sol::error { result }.what()); + auto value = sol::object { result }; + ensures(value.is(), "on_closed closure must return a boolean value"); + return value.as(); + }); + }; + window_metatable["on_monitor_changed"] = +make_lua_closure(); + window_metatable["on_resized"] = +make_lua_closure(); + window_metatable["on_restored"] = +make_lua_closure(); + window_metatable["on_minimized"] = +make_lua_closure(); + window_metatable["on_key_up"] = +make_lua_closure(); + window_metatable["on_key_down"] = +make_lua_closure(); + window_metatable + ["on_mouse_button_up"] = +make_lua_closure(); + window_metatable + ["on_mouse_button_down"] = +make_lua_closure(); + window_metatable["on_mouse_moved"] = +make_lua_closure(); + window_metatable["on_activated"] = +make_lua_closure(); + window_metatable["on_deactivated"] = +make_lua_closure(); + } +} // namespace stormkit::lua::wsi diff --git a/xmake/targets/lua.xmake.lua b/xmake/targets/lua.xmake.lua index 1189eac6b..a1beb9f39 100644 --- a/xmake/targets/lua.xmake.lua +++ b/xmake/targets/lua.xmake.lua @@ -1,15 +1,15 @@ add_requires("luau", { system = false, - version = "master", + version = "upstream", configs = { shared = false, extern_c = true, build_cli = false, }, }) -add_requires("luabridge3", { +add_requires("sol2", { system = false, - version = "master", + version = "develop", }) local src_lua_dir = path.join(src_dir, "lua") @@ -26,15 +26,28 @@ target("lua", function() add_files(path.join(module_dir, "lua.cppm"), { public = true }) add_files(path.join(src_lua_dir, "lua.cpp")) add_files(path.join(src_lua_dir, "core.cppm")) - add_files(path.join(src_lua_dir, "log.cppm"), { public = true }) + add_files(path.join(src_lua_dir, "core.cpp")) + add_files(path.join(src_lua_dir, "core/*.cpp")) + add_files(path.join(src_lua_dir, "log.cppm")) + add_files(path.join(src_lua_dir, "log.cpp")) - if get_config("entities") then add_files(path.join(src_lua_dir, "entities.cppm"), { public = true }) end - if get_config("image") then add_files(path.join(src_lua_dir, "image.cppm"), { public = true }) end + if get_config("entities") then + add_files(path.join(src_lua_dir, "entities.cppm")) + add_files(path.join(src_lua_dir, "entities.cpp")) + end + if get_config("image") then + add_files(path.join(src_lua_dir, "image.cppm")) + add_files(path.join(src_lua_dir, "image.cpp")) + end if get_config("wsi") then add_files(path.join(src_lua_dir, "wsi.cpp")) - add_files(path.join(src_lua_dir, "wsi.cppm"), { public = true }) + add_files(path.join(src_lua_dir, "wsi/*.cpp")) + add_files(path.join(src_lua_dir, "wsi.cppm")) + end + if get_config("gpu") then + add_files(path.join(src_lua_dir, "gpu.cppm")) + add_files(path.join(src_lua_dir, "gpu.cpp")) end - if get_config("gpu") then add_files(path.join(src_lua_dir, "gpu.cppm"), { public = true }) end add_headerfiles(path.join(include_dir, "(stormkit/lua/**.hpp)")) add_includedirs(include_dir, { public = true }) @@ -45,7 +58,7 @@ target("lua", function() if get_config("wsi") then add_deps("wsi") end if get_config("gpu") then add_deps("gpu") end - add_packages("luau", "luabridge3", { public = true }) + add_packages("luau", "sol2", { public = true }) add_options("sanitizers") From f782f38c180103650a46a47f1753c016d1e50460 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 6 Feb 2026 15:30:06 +0100 Subject: [PATCH 070/194] (core) implement lua bindings for math linear library --- examples/lua/wsi/events/lua/events.luau | 4 + modules/stormkit/core/math/linear-matrix.cppm | 617 +++++++++++++----- modules/stormkit/core/math/linear-vector.cppm | 320 ++++++--- modules/stormkit/core/math/linear.cppm | 31 +- .../stormkit/core/typesafe/strong_type.cppm | 2 +- src/lua/core/math.cpp | 325 +++++++-- 6 files changed, 958 insertions(+), 341 deletions(-) diff --git a/examples/lua/wsi/events/lua/events.luau b/examples/lua/wsi/events/lua/events.luau index c6b0c5d44..c1e9321e2 100644 --- a/examples/lua/wsi/events/lua/events.luau +++ b/examples/lua/wsi/events/lua/events.luau @@ -1,6 +1,10 @@ local function main() local window = wsi.window.open("test", 800, 600, wsi.window_flag.RESIZEABLE) + local mat = math.identity.fmat4 + + print(mat) + window:on_closed(function() print("Close event!") return true diff --git a/modules/stormkit/core/math/linear-matrix.cppm b/modules/stormkit/core/math/linear-matrix.cppm index 0562e7a02..9055b947f 100644 --- a/modules/stormkit/core/math/linear-matrix.cppm +++ b/modules/stormkit/core/math/linear-matrix.cppm @@ -4,6 +4,7 @@ module; +#include #include export module stormkit.core:math.linear.matrix; @@ -24,106 +25,108 @@ import :string.format; export { namespace stormkit { inline namespace core { namespace math { - template - struct alignas(std::array) mat { - using value_type = T; - using storage_type = std::array; - using size_type = usize; - using extent_type = u8; + inline namespace matrix { + template + struct alignas(std::array) mat { + using value_type = T; + using storage_type = std::array; + using size_type = usize; + using extent_type = u8; + + static constexpr auto EXTENTS = std::array { M, N }; + + storage_type values; + + template + [[nodiscard]] + constexpr auto operator[](this Self&& self, size_type i) noexcept -> core::meta::ForwardLike; + + template + [[nodiscard]] + constexpr auto operator[](this Self&& self, size_type i, size_type j) noexcept + -> core::meta::ForwardLike; + + template + [[nodiscard]] + constexpr auto begin(this Self& self) noexcept -> decltype(auto); + [[nodiscard]] + constexpr auto cbegin() const noexcept -> decltype(auto); + + template + [[nodiscard]] + constexpr auto end(this Self& self) noexcept -> decltype(auto); + [[nodiscard]] + constexpr auto cend() const noexcept -> decltype(auto); + + template + [[nodiscard]] + constexpr auto data(this Self& self) noexcept -> core::meta::ForwardConst*; + + [[nodiscard]] + constexpr auto size() const noexcept -> size_type; + [[nodiscard]] + static consteval auto max_size() noexcept -> size_type; + + [[nodiscard]] + static constexpr auto identity() noexcept -> mat + requires(M == N); + }; - static constexpr auto EXTENTS = std::array { M, N }; + template + using mat2x2 = mat; + template + using mat3x3 = mat; + template + using mat4x4 = mat; + template + using mat2x3 = mat; + template + using mat3x2 = mat; + template + using mat4x3 = mat; + template + using mat3x4 = mat; + template + using mat4x2 = mat; + template + using mat2x4 = mat; - storage_type values; + using fmat2 = mat2x2; + using imat2 = mat2x2; + using umat2 = mat2x2; - template - [[nodiscard]] - constexpr auto operator[](this Self&& self, size_type i) noexcept -> core::meta::ForwardLike; + using fmat3 = mat3x3; + using imat3 = mat3x3; + using umat3 = mat3x3; - template - [[nodiscard]] - constexpr auto operator[](this Self&& self, size_type i, size_type j) noexcept - -> core::meta::ForwardLike; + using fmat4 = mat4x4; + using imat4 = mat4x4; + using umat4 = mat4x4; - template - [[nodiscard]] - constexpr auto begin(this Self& self) noexcept -> decltype(auto); - [[nodiscard]] - constexpr auto cbegin() const noexcept -> decltype(auto); + using fmat2x3 = mat2x3; + using imat2x3 = mat2x3; + using umat2x3 = mat2x3; - template - [[nodiscard]] - constexpr auto end(this Self& self) noexcept -> decltype(auto); - [[nodiscard]] - constexpr auto cend() const noexcept -> decltype(auto); + using fmat3x2 = mat3x2; + using imat3x2 = mat3x2; + using umat3x2 = mat3x2; - template - [[nodiscard]] - constexpr auto data(this Self& self) noexcept -> core::meta::ForwardConst*; + using fmat4x3 = mat4x3; + using imat4x3 = mat4x3; + using umat4x3 = mat4x3; - [[nodiscard]] - constexpr auto size() const noexcept -> size_type; - [[nodiscard]] - static consteval auto max_size() noexcept -> size_type; + using fmat3x4 = mat3x4; + using imat3x4 = mat3x4; + using umat3x4 = mat3x4; - [[nodiscard]] - static consteval auto identity() noexcept -> mat - requires(M == N); - }; + using fmat4x2 = mat4x2; + using imat4x2 = mat4x2; + using umat4x2 = mat4x2; - template - using mat2x2 = mat; - template - using mat3x3 = mat; - template - using mat4x4 = mat; - template - using mat2x3 = mat; - template - using mat3x2 = mat; - template - using mat4x3 = mat; - template - using mat3x4 = mat; - template - using mat4x2 = mat; - template - using mat2x4 = mat; - - using fmat2 = mat2x2; - using imat2 = mat2x2; - using umat2 = mat2x2; - - using fmat3 = mat3x3; - using imat3 = mat3x3; - using umat3 = mat3x3; - - using fmat4 = mat4x4; - using imat4 = mat4x4; - using umat4 = mat4x4; - - using fmat2x3 = mat2x3; - using imat2x3 = mat2x3; - using umat2x3 = mat2x3; - - using fmat3x2 = mat3x2; - using imat3x2 = mat3x2; - using umat3x2 = mat3x2; - - using fmat4x3 = mat4x3; - using imat4x3 = mat4x3; - using umat4x3 = mat4x3; - - using fmat3x4 = mat3x4; - using imat3x4 = mat3x4; - using umat3x4 = mat3x4; - - using fmat4x2 = mat4x2; - using imat4x2 = mat4x2; - using umat4x2 = mat4x2; - - using fmat2x4 = mat2x4; - using imat2x4 = mat2x4; - using umat2x4 = mat2x4; + using fmat2x4 = mat2x4; + using imat2x4 = mat2x4; + using umat2x4 = mat2x4; + } // namespace matrix namespace meta { template @@ -147,89 +150,94 @@ export { or meta::IsMat; } // namespace meta - template - [[nodiscard]] - constexpr auto determinant(const T& mat) noexcept -> typename T::value_type; + inline namespace matrix { + template + [[nodiscard]] + constexpr auto determinant(const T& mat) noexcept -> typename T::value_type; + + template + constexpr auto transpose(const T& mat) noexcept -> T; - template - constexpr auto transpose(const T& mat) noexcept -> T; + template + [[nodiscard]] + constexpr auto is_inversible(const T& mat) noexcept -> bool; - template - [[nodiscard]] - constexpr auto is_inversible(const T& mat) noexcept -> bool; + template + constexpr auto inverse(const T& mat) noexcept -> T; - template - constexpr auto inverse(const T& mat) noexcept -> T; + template + [[nodiscard]] + constexpr auto is_orthogonal(const T& mat) noexcept -> bool; - template - [[nodiscard]] - constexpr auto is_orthogonal(const T& mat) noexcept -> bool; + template + [[nodiscard]] + constexpr auto mul(const T& a, typename T::value_type b) noexcept -> T; - template - [[nodiscard]] - constexpr auto mul(const T& a, typename T::value_type b) noexcept -> T; + template + [[nodiscard]] + constexpr auto div(const T& a, typename T::value_type b) noexcept -> T; - template - [[nodiscard]] - constexpr auto div(const T& a, typename T::value_type b) noexcept -> T; + template + [[nodiscard]] + constexpr auto mul(const T& a, const T& b) noexcept -> T; - template - [[nodiscard]] - constexpr auto mul(const T& a, const T& b) noexcept -> T; + template + requires(core::meta::IsStrict) + [[nodiscard]] + constexpr auto div(const T& a, const U& b) noexcept -> U; - template - requires(core::meta::IsStrict) - [[nodiscard]] - constexpr auto div(const T& a, const U& b) noexcept -> U; + template + [[nodiscard]] + constexpr auto translate(const mat4x4& mat, const vec3& translation) noexcept -> mat4x4; - template - [[nodiscard]] - constexpr auto translate(const mat4x4& mat, const vec3& translation) noexcept -> mat4x4; + template + [[nodiscard]] + constexpr auto scale(const mat4x4& mat, const vec3& scale) noexcept -> mat4x4; - template - [[nodiscard]] - constexpr auto scale(const mat4x4& mat, const vec3& scale) noexcept -> mat4x4; + template + [[nodiscard]] + constexpr auto rotate(const mat4x4& mat, angle::radian angle, const vec3& axis) noexcept -> mat4x4; - template - [[nodiscard]] - constexpr auto rotate(const mat4x4& mat, angle::radian angle, const vec3& axis) noexcept -> mat4x4; + template + [[nodiscard]] + constexpr auto orthographique(T left, T right, T bottom, T top, T near, T far) noexcept -> mat4x4; - template - [[nodiscard]] - constexpr auto orthographique(T left, T right, T bottom, T top, T near, T far) noexcept -> mat4x4; + template + [[nodiscard]] + constexpr auto orthographique(T left, T right, T bottom, T top) noexcept -> mat4x4; - template - [[nodiscard]] - constexpr auto orthographique(T left, T right, T bottom, T top) noexcept -> mat4x4; + template + [[nodiscard]] + constexpr auto perspective(angle::radian fov_y, T aspect, T near, T far) noexcept -> mat4x4; - template - [[nodiscard]] - constexpr auto perspective(angle::radian fov_y, T aspect, T near, T far) noexcept -> mat4x4; + template + [[nodiscard]] + constexpr auto look_at(const vec3& eye, const vec3& center, const vec3& up) noexcept -> mat4x4; - template - [[nodiscard]] - constexpr auto look_at(const vec3& eye, const vec3& center, const vec3& up) noexcept -> mat4x4; + template + [[nodiscard]] + constexpr auto as_span(T& value) noexcept + -> std::span, T::EXTENTS[0] * T::EXTENTS[1]>; - template - [[nodiscard]] - constexpr auto as_span(T& value) noexcept - -> std::span, T::EXTENTS[0] * T::EXTENTS[1]>; + template + [[nodiscard]] + constexpr auto as_mdspan(const T& value) noexcept + -> MatrixSpan; - template - [[nodiscard]] - constexpr auto as_mdspan(const T& value) noexcept - -> MatrixSpan; + template + requires(not core::meta::IsConst) + [[nodiscard]] + constexpr auto as_mdspan(T& value) noexcept -> MatrixSpan; - template - requires(not core::meta::IsConst) - [[nodiscard]] - constexpr auto as_mdspan(T& value) noexcept -> MatrixSpan; + template + auto to_string(const T& value) noexcept -> std::string; - template - constexpr auto hasher(const T& value) noexcept -> Ret; + template + constexpr auto hasher(const T& value) noexcept -> Ret; - template - auto format_as(const T& value, FormatContext& ctx) noexcept -> decltype(ctx.out); + template + auto format_as(const T& value, FormatContext& ctx) noexcept -> decltype(ctx.out()); + } // namespace matrix }}} // namespace stormkit::core::math namespace std { @@ -245,7 +253,7 @@ export { namespace stdr = std::ranges; namespace stdv = std::views; -namespace stormkit { inline namespace core { namespace math { +namespace stormkit { inline namespace core { namespace math { inline namespace matrix { static_assert(sizeof(mat2x2) == sizeof(i32) * 2 * 2); static_assert(sizeof(mat2x2) == sizeof(i64) * 2 * 2); static_assert(sizeof(mat2x2) == sizeof(u32) * 2 * 2); @@ -349,7 +357,7 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - consteval auto mat::identity() noexcept -> mat + constexpr auto mat::identity() noexcept -> mat requires(M == N) { auto matrix = mat {}; @@ -364,7 +372,7 @@ namespace stormkit { inline namespace core { namespace math { template STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto determinant(const T& mat) noexcept -> typename T::value_type { - return determinant(as_mdspan(mat)); + return math::determinant(as_mdspan(mat)); } //////////////////////////////////////// @@ -373,7 +381,7 @@ namespace stormkit { inline namespace core { namespace math { STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto transpose(const T& mat) noexcept -> T { auto out = T {}; - transpose(as_mdspan(mat), as_mdspan_mut(out)); + math::transpose(as_mdspan(mat), as_mdspan_mut(out)); return out; } @@ -382,7 +390,7 @@ namespace stormkit { inline namespace core { namespace math { template STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto is_inversible(const T& mat) noexcept -> bool { - return is_inversible(as_mdspan(mat)); + return math::is_inversible(as_mdspan(mat)); } //////////////////////////////////////// @@ -391,7 +399,7 @@ namespace stormkit { inline namespace core { namespace math { STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto inverse(const T& mat) noexcept -> T { auto out = T {}; - inverse(as_mdspan(mat), as_mdspan_mut(out)); + math::inverse(as_mdspan(mat), as_mdspan_mut(out)); return out; } @@ -400,7 +408,7 @@ namespace stormkit { inline namespace core { namespace math { template STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto is_orthogonal(const T& mat) noexcept -> bool { - return is_orthogonal(as_mdspan(mat)); + return math::is_orthogonal(as_mdspan(mat)); } //////////////////////////////////////// @@ -410,7 +418,7 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto mul(const T& a, typename T::value_type b) noexcept -> T { auto out = T {}; - mul(as_mdspan(a), b, as_mdspan_mut(out)); + math::mul(as_mdspan(a), b, as_mdspan_mut(out)); return out; } @@ -422,7 +430,7 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto div(const T& a, typename T::value_type b) noexcept -> T { auto out = T {}; - div(as_mdspan(a), b, as_mdspan_mut(out)); + math::div(as_mdspan(a), b, as_mdspan_mut(out)); return out; } @@ -434,7 +442,7 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto mul(const T& a, const T& b) noexcept -> T { auto out = T {}; - mul(as_mdspan(a), as_mdspan(b), as_mdspan_mut(out)); + math::mul(as_mdspan(a), as_mdspan(b), as_mdspan_mut(out)); return out; } @@ -447,7 +455,7 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto div(const T& a, const U& b) noexcept -> U { auto out = T {}; - div(as_mdspan(a), as_mdspan(b), as_mdspan_mut(out)); + math::div(as_mdspan(a), as_mdspan(b), as_mdspan_mut(out)); return out; } @@ -459,7 +467,7 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto translate(const mat4x4& mat, const vec3& translation) noexcept -> mat4x4 { auto out = mat4x4 {}; - translate(as_mdspan(mat), as_mdspan(translation), as_mdspan_mut(out)); + math::translate(as_mdspan(mat), as_mdspan(translation), as_mdspan_mut(out)); return out; } @@ -471,7 +479,7 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto scale(const mat4x4& mat, const vec3& scale_factors) noexcept -> mat4x4 { auto out = mat4x4 {}; - scale(as_mdspan(mat), as_mdspan(scale_factors), as_mdspan_mut(out)); + math::scale(as_mdspan(mat), as_mdspan(scale_factors), as_mdspan_mut(out)); return out; } @@ -483,7 +491,7 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto rotate(const mat4x4& mat, angle::radian angle, const vec3& axis) noexcept -> mat4x4 { auto out = mat4x4 {}; - rotate(as_mdspan(mat), angle, as_mdspan(axis), as_mdspan_mut(out)); + math::rotate(as_mdspan(mat), angle, as_mdspan(axis), as_mdspan_mut(out)); return out; } @@ -495,7 +503,7 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto orthographique(T left, T right, T bottom, T top, T near, T far) noexcept -> mat4x4 { auto out = mat4x4 {}; - orthographique(left, right, bottom, top, near, far, as_mdspan_mut(out)); + math::orthographique(left, right, bottom, top, near, far, as_mdspan_mut(out)); return out; } @@ -507,7 +515,7 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto orthographique(T left, T right, T bottom, T top) noexcept -> mat4x4 { auto out = mat4x4 {}; - orthographique(left, right, bottom, top, as_mdspan_mut(out)); + math::orthographique(left, right, bottom, top, as_mdspan_mut(out)); return out; } @@ -519,7 +527,7 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto perspective(angle::radian fov_y, T aspect, T near, T far) noexcept -> mat4x4 { auto out = mat4x4 {}; - perspective(fov_y, aspect, near, far, as_mdspan_mut(out)); + math::perspective(fov_y, aspect, near, far, as_mdspan_mut(out)); return out; } @@ -531,7 +539,7 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto look_at(const vec3& eye, const vec3& center, const vec3& up) noexcept -> mat4x4 { auto out = mat4x4 {}; - look_at(as_mdspan(eye), as_mdspan(center), as_mdspan(up), as_mdspan_mut(out)); + math::look_at(as_mdspan(eye), as_mdspan(center), as_mdspan(up), as_mdspan_mut(out)); return out; } @@ -565,6 +573,13 @@ namespace stormkit { inline namespace core { namespace math { return MatrixSpan { stdr::data(value), T::EXTENTS }; } + //////////////////////////////////////// + //////////////////////////////////////// + template + inline auto to_string(const T& value) noexcept -> std::string { + return std::format("{}", value); + } + //////////////////////////////////////// //////////////////////////////////////// template @@ -576,7 +591,7 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// //////////////////////////////////////// template - inline auto format_as(const T& mat, FormatContext& ctx) noexcept -> decltype(ctx.out) { + inline auto format_as(const T& mat, FormatContext& ctx) noexcept -> decltype(ctx.out()) { auto out = ctx.out(); auto i = 0; @@ -617,4 +632,260 @@ namespace stormkit { inline namespace core { namespace math { return out; } -}}} // namespace stormkit::core::math + + // DETERMINANT_INSTANCIATE(fmat2); + // DETERMINANT_INSTANCIATE(fmat2x3); + // DETERMINANT_INSTANCIATE(fmat2x4); + // DETERMINANT_INSTANCIATE(fmat3); + // DETERMINANT_INSTANCIATE(fmat3x2); + // DETERMINANT_INSTANCIATE(fmat3x4); + // DETERMINANT_INSTANCIATE(fmat4); + // DETERMINANT_INSTANCIATE(fmat4x2); + // DETERMINANT_INSTANCIATE(fmat4x3); + // DETERMINANT_INSTANCIATE(umat2); + // DETERMINANT_INSTANCIATE(umat2x3); + // DETERMINANT_INSTANCIATE(umat2x4); + // DETERMINANT_INSTANCIATE(umat3); + // DETERMINANT_INSTANCIATE(umat3x2); + // DETERMINANT_INSTANCIATE(umat3x4); + // DETERMINANT_INSTANCIATE(umat4); + // DETERMINANT_INSTANCIATE(umat4x2); + // DETERMINANT_INSTANCIATE(umat4x3); + // DETERMINANT_INSTANCIATE(imat2); + // DETERMINANT_INSTANCIATE(imat2x3); + // DETERMINANT_INSTANCIATE(imat2x4); + // DETERMINANT_INSTANCIATE(imat3); + // DETERMINANT_INSTANCIATE(imat3x2); + // DETERMINANT_INSTANCIATE(imat3x4); + // DETERMINANT_INSTANCIATE(imat4); + // DETERMINANT_INSTANCIATE(imat4x2); + // DETERMINANT_INSTANCIATE(imat4x3); + +#define DETERMINANT_INSTANCIATE(mat_type) \ + template STORMKIT_CORE_API auto determinant(const mat_type&) noexcept -> typename mat_type::value_type + + DETERMINANT_INSTANCIATE(fmat2); + DETERMINANT_INSTANCIATE(fmat3); + DETERMINANT_INSTANCIATE(fmat4); + DETERMINANT_INSTANCIATE(umat2); + DETERMINANT_INSTANCIATE(umat3); + DETERMINANT_INSTANCIATE(umat4); + DETERMINANT_INSTANCIATE(imat2); + DETERMINANT_INSTANCIATE(imat3); + DETERMINANT_INSTANCIATE(imat4); + +#undef DETERMINANT_INSTANCIATE + +#define TRANSPOSE_INSTANCIATE(mat_type) template STORMKIT_CORE_API auto transpose(const mat_type&) noexcept -> mat_type + + TRANSPOSE_INSTANCIATE(fmat2); + TRANSPOSE_INSTANCIATE(fmat3); + TRANSPOSE_INSTANCIATE(fmat4); + TRANSPOSE_INSTANCIATE(umat2); + TRANSPOSE_INSTANCIATE(umat3); + TRANSPOSE_INSTANCIATE(umat4); + TRANSPOSE_INSTANCIATE(imat2); + TRANSPOSE_INSTANCIATE(imat3); + TRANSPOSE_INSTANCIATE(imat4); + +#undef TRANSPOSE_INSTANCIATE + +#define IS_INVERSIBLE_INSTANCIATE(mat_type) \ + template STORMKIT_CORE_API auto is_inversible(const mat_type&) noexcept -> bool + + IS_INVERSIBLE_INSTANCIATE(fmat2); + IS_INVERSIBLE_INSTANCIATE(fmat2x3); + IS_INVERSIBLE_INSTANCIATE(fmat2x4); + IS_INVERSIBLE_INSTANCIATE(fmat3); + IS_INVERSIBLE_INSTANCIATE(fmat3x2); + IS_INVERSIBLE_INSTANCIATE(fmat3x4); + IS_INVERSIBLE_INSTANCIATE(fmat4); + IS_INVERSIBLE_INSTANCIATE(fmat4x2); + IS_INVERSIBLE_INSTANCIATE(fmat4x3); + IS_INVERSIBLE_INSTANCIATE(umat2); + IS_INVERSIBLE_INSTANCIATE(umat2x3); + IS_INVERSIBLE_INSTANCIATE(umat2x4); + IS_INVERSIBLE_INSTANCIATE(umat3); + IS_INVERSIBLE_INSTANCIATE(umat3x2); + IS_INVERSIBLE_INSTANCIATE(umat3x4); + IS_INVERSIBLE_INSTANCIATE(umat4); + IS_INVERSIBLE_INSTANCIATE(umat4x2); + IS_INVERSIBLE_INSTANCIATE(umat4x3); + IS_INVERSIBLE_INSTANCIATE(imat2); + IS_INVERSIBLE_INSTANCIATE(imat2x3); + IS_INVERSIBLE_INSTANCIATE(imat2x4); + IS_INVERSIBLE_INSTANCIATE(imat3); + IS_INVERSIBLE_INSTANCIATE(imat3x2); + IS_INVERSIBLE_INSTANCIATE(imat3x4); + IS_INVERSIBLE_INSTANCIATE(imat4); + IS_INVERSIBLE_INSTANCIATE(imat4x2); + IS_INVERSIBLE_INSTANCIATE(imat4x3); + +#undef IS_INVERSIBLE_INSTANCIATE + +#define INVERSE_INSTANCIATE(mat_type) template STORMKIT_CORE_API auto inverse(const mat_type&) noexcept -> mat_type + + INVERSE_INSTANCIATE(fmat2); + INVERSE_INSTANCIATE(fmat3); + INVERSE_INSTANCIATE(fmat4); + INVERSE_INSTANCIATE(umat2); + INVERSE_INSTANCIATE(umat3); + INVERSE_INSTANCIATE(umat4); + INVERSE_INSTANCIATE(imat2); + INVERSE_INSTANCIATE(imat3); + INVERSE_INSTANCIATE(imat4); + +#undef INVERSE_INSTANCIATE + +#define IS_ORTHOGONAL_INSTANCIATE(mat_type) \ + template STORMKIT_CORE_API auto is_orthogonal(const mat_type&) noexcept -> bool + + IS_ORTHOGONAL_INSTANCIATE(fmat2); + IS_ORTHOGONAL_INSTANCIATE(fmat2x3); + IS_ORTHOGONAL_INSTANCIATE(fmat2x4); + IS_ORTHOGONAL_INSTANCIATE(fmat3); + IS_ORTHOGONAL_INSTANCIATE(fmat3x2); + IS_ORTHOGONAL_INSTANCIATE(fmat3x4); + IS_ORTHOGONAL_INSTANCIATE(fmat4); + IS_ORTHOGONAL_INSTANCIATE(fmat4x2); + IS_ORTHOGONAL_INSTANCIATE(fmat4x3); + IS_ORTHOGONAL_INSTANCIATE(umat2); + IS_ORTHOGONAL_INSTANCIATE(umat2x3); + IS_ORTHOGONAL_INSTANCIATE(umat2x4); + IS_ORTHOGONAL_INSTANCIATE(umat3); + IS_ORTHOGONAL_INSTANCIATE(umat3x2); + IS_ORTHOGONAL_INSTANCIATE(umat3x4); + IS_ORTHOGONAL_INSTANCIATE(umat4); + IS_ORTHOGONAL_INSTANCIATE(umat4x2); + IS_ORTHOGONAL_INSTANCIATE(umat4x3); + IS_ORTHOGONAL_INSTANCIATE(imat2); + IS_ORTHOGONAL_INSTANCIATE(imat2x3); + IS_ORTHOGONAL_INSTANCIATE(imat2x4); + IS_ORTHOGONAL_INSTANCIATE(imat3); + IS_ORTHOGONAL_INSTANCIATE(imat3x2); + IS_ORTHOGONAL_INSTANCIATE(imat3x4); + IS_ORTHOGONAL_INSTANCIATE(imat4); + IS_ORTHOGONAL_INSTANCIATE(imat4x2); + IS_ORTHOGONAL_INSTANCIATE(imat4x3); + +#undef IS_ORTHOGONAL_INSTANCIATE + +#define MUL_INSTANCIATE(mat_type) \ + template STORMKIT_CORE_API auto mul(const mat_type&, typename mat_type::value_type) noexcept -> mat_type + + MUL_INSTANCIATE(fmat2); + MUL_INSTANCIATE(fmat2x3); + MUL_INSTANCIATE(fmat2x4); + MUL_INSTANCIATE(fmat3); + MUL_INSTANCIATE(fmat3x2); + MUL_INSTANCIATE(fmat3x4); + MUL_INSTANCIATE(fmat4); + MUL_INSTANCIATE(fmat4x2); + MUL_INSTANCIATE(fmat4x3); + MUL_INSTANCIATE(umat2); + MUL_INSTANCIATE(umat2x3); + MUL_INSTANCIATE(umat2x4); + MUL_INSTANCIATE(umat3); + MUL_INSTANCIATE(umat3x2); + MUL_INSTANCIATE(umat3x4); + MUL_INSTANCIATE(umat4); + MUL_INSTANCIATE(umat4x2); + MUL_INSTANCIATE(umat4x3); + MUL_INSTANCIATE(imat2); + MUL_INSTANCIATE(imat2x3); + MUL_INSTANCIATE(imat2x4); + MUL_INSTANCIATE(imat3); + MUL_INSTANCIATE(imat3x2); + MUL_INSTANCIATE(imat3x4); + MUL_INSTANCIATE(imat4); + MUL_INSTANCIATE(imat4x2); + MUL_INSTANCIATE(imat4x3); + +#undef MUL_INSTANCIATE + +#define DIV_INSTANCIATE(mat_type) \ + template STORMKIT_CORE_API auto div(const mat_type&, typename mat_type::value_type) noexcept -> mat_type + + DIV_INSTANCIATE(fmat2); + DIV_INSTANCIATE(fmat2x3); + DIV_INSTANCIATE(fmat2x4); + DIV_INSTANCIATE(fmat3); + DIV_INSTANCIATE(fmat3x2); + DIV_INSTANCIATE(fmat3x4); + DIV_INSTANCIATE(fmat4); + DIV_INSTANCIATE(fmat4x2); + DIV_INSTANCIATE(fmat4x3); + DIV_INSTANCIATE(umat2); + DIV_INSTANCIATE(umat2x3); + DIV_INSTANCIATE(umat2x4); + DIV_INSTANCIATE(umat3); + DIV_INSTANCIATE(umat3x2); + DIV_INSTANCIATE(umat3x4); + DIV_INSTANCIATE(umat4); + DIV_INSTANCIATE(umat4x2); + DIV_INSTANCIATE(umat4x3); + DIV_INSTANCIATE(imat2); + DIV_INSTANCIATE(imat2x3); + DIV_INSTANCIATE(imat2x4); + DIV_INSTANCIATE(imat3); + DIV_INSTANCIATE(imat3x2); + DIV_INSTANCIATE(imat3x4); + DIV_INSTANCIATE(imat4); + DIV_INSTANCIATE(imat4x2); + DIV_INSTANCIATE(imat4x3); + +#undef DIV_INSTANCIATE + +#define TRANSLATE_INSTANCIATE(type) \ + template STORMKIT_CORE_API auto translate(const mat4x4&, const vec3&) noexcept -> mat4x4 + + TRANSLATE_INSTANCIATE(f32); + TRANSLATE_INSTANCIATE(u32); + TRANSLATE_INSTANCIATE(i32); + +#undef TRANSLATE_INSTANCIATE + +#define SCALE_INSTANCIATE(type) \ + template STORMKIT_CORE_API auto scale(const mat4x4&, const vec3&) noexcept -> mat4x4 + + SCALE_INSTANCIATE(f32); + SCALE_INSTANCIATE(u32); + SCALE_INSTANCIATE(i32); + +#undef SCALE_INSTANCIATE + +#define ROTATE_INSTANCIATE(type) \ + template STORMKIT_CORE_API auto rotate(const mat4x4&, angle::radian, const vec3&) noexcept \ + -> mat4x4 + + ROTATE_INSTANCIATE(f32); + // ROTATE_INSTANCIATE(i32); + +#undef ROTATE_INSTANCIATE + +#define ORTHOGRAPHIQUE_INSTANCIATE(type) \ + template STORMKIT_CORE_API auto orthographique(type, type, type, type) noexcept -> mat4x4; \ + template STORMKIT_CORE_API auto orthographique(type, type, type, type, type, type) noexcept -> mat4x4 + + ORTHOGRAPHIQUE_INSTANCIATE(f32); + ORTHOGRAPHIQUE_INSTANCIATE(i32); + +#undef ORTHOGRAPHIQUE_INSTANCIATE + +#define PERSPECTIVE_INSTANCIATE(type) \ + template STORMKIT_CORE_API auto perspective(angle::radian, type, type, type) noexcept -> mat4x4 + + PERSPECTIVE_INSTANCIATE(f32); + // PERSPECTIVE_INSTANCIATE(i32); + +#undef PERSPECTIVE_INSTANCIATE + +#define LOOK_AT_INSTANCIATE(type) \ + template STORMKIT_CORE_API auto look_at(const vec3&, const vec3&, const vec3&) noexcept \ + -> mat4x4 + + LOOK_AT_INSTANCIATE(f32); + LOOK_AT_INSTANCIATE(i32); + +#undef LOOK_AT_INSTANCIATE +}}}} // namespace stormkit::core::math::matrix diff --git a/modules/stormkit/core/math/linear-vector.cppm b/modules/stormkit/core/math/linear-vector.cppm index e727ee900..566e2ff0b 100644 --- a/modules/stormkit/core/math/linear-vector.cppm +++ b/modules/stormkit/core/math/linear-vector.cppm @@ -4,6 +4,7 @@ module; +#include #include export module stormkit.core:math.linear.vector; @@ -22,83 +23,88 @@ import :hash.base; import :string.format; export namespace stormkit { inline namespace core { namespace math { - template - struct alignas(std::array) vec2 { - using value_type = T; - using size_type = usize; - using extent_type = u8; + inline namespace vector { + template + struct alignas(std::array) vec2 { + using value_type = T; + using size_type = usize; + using extent_type = u8; - static constexpr auto EXTENT = std::array { 2uz }; + static constexpr auto EXTENT = std::array { 2uz }; - T x; - T y; + T x; + T y; - template - constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst; + template + constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst; - template - constexpr auto to() const noexcept -> vec2; - }; + template + constexpr auto to() const noexcept -> vec2; + }; - using fvec2 = vec2; - using ivec2 = vec2; - using uvec2 = vec2; + using fvec2 = vec2; + using ivec2 = vec2; + using uvec2 = vec2; - template - struct alignas(std::array) vec3 { - using value_type = T; - using size_type = usize; - using extent_type = u8; + template + struct alignas(std::array) vec3 { + using value_type = T; + using size_type = usize; + using extent_type = u8; - static constexpr auto EXTENT = std::array { 3uz }; + static constexpr auto EXTENT = std::array { 3uz }; - T x; - T y; - T z; + T x; + T y; + T z; - template - constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst; + template + constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst; - template - constexpr auto to() const noexcept -> vec3; - }; + template + constexpr auto to() const noexcept -> vec3; + }; - using fvec3 = vec3; - using ivec3 = vec3; - using uvec3 = vec3; + using fvec3 = vec3; + using ivec3 = vec3; + using uvec3 = vec3; - template - struct alignas(std::array) vec4 { - using value_type = T; - using size_type = usize; - using extent_type = u8; + template + struct alignas(std::array) vec4 { + using value_type = T; + using size_type = usize; + using extent_type = u8; - static constexpr auto EXTENT = std::array { 4uz }; + static constexpr auto EXTENT = std::array { 4uz }; - T x; - T y; - T z; - T w; + T x; + T y; + T z; + T w; - template - constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst; + template + constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst; - template - constexpr auto to() const noexcept -> vec4; - }; + template + constexpr auto to() const noexcept -> vec4; + }; - using fvec4 = vec4; - using ivec4 = vec4; - using uvec4 = vec4; + using fvec4 = vec4; + using ivec4 = vec4; + using uvec4 = vec4; + + } // namespace vector namespace meta { template concept IsVec2 = core::meta::IsSpecializationOf; template concept IsVec3 = core::meta::IsSpecializationOf; + template + concept IsVec4 = core::meta::IsSpecializationOf; template - concept IsVec = IsVec2 || IsVec3; + concept IsVec = IsVec2 || IsVec3 || IsVec4; template concept HasOneVecType = not(core::meta::IsMdspanType and core::meta::IsMdspanType) @@ -106,69 +112,71 @@ export namespace stormkit { inline namespace core { namespace math { or meta::IsVec; } // namespace meta - template - [[nodiscard]] - constexpr auto add(const T& a, const T& b) noexcept -> T; + inline namespace vector { + template + [[nodiscard]] + constexpr auto add(const T& a, const T& b) noexcept -> T; - template - [[nodiscard]] - constexpr auto sub(const T& a, const T& b) noexcept -> T; + template + [[nodiscard]] + constexpr auto sub(const T& a, const T& b) noexcept -> T; - template - [[nodiscard]] - constexpr auto mul(const T& a, typename T::value_type b) noexcept -> T; + template + [[nodiscard]] + constexpr auto mul(const T& a, typename T::value_type b) noexcept -> T; - template - [[nodiscard]] - constexpr auto div(const T& a, typename T::value_type b) noexcept -> T; + template + [[nodiscard]] + constexpr auto div(const T& a, typename T::value_type b) noexcept -> T; - template - [[nodiscard]] - constexpr auto dot(const T& a, const T& b) noexcept -> typename T::value_type; + template + [[nodiscard]] + constexpr auto dot(const T& a, const T& b) noexcept -> typename T::value_type; - template - [[nodiscard]] - constexpr auto cross(const vec3& a, const vec3& b) noexcept -> vec3; + template + [[nodiscard]] + constexpr auto cross(const vec3& a, const vec3& b) noexcept -> vec3; - template - [[nodiscard]] - constexpr auto normalize(const T& a) noexcept -> T; + template + [[nodiscard]] + constexpr auto normalize(const T& a) noexcept -> T; - template - [[nodiscard]] - constexpr auto as_mdspan(const T& value) noexcept -> VectorSpan; + template + [[nodiscard]] + constexpr auto as_mdspan(const T& value) noexcept -> VectorSpan; - template - requires(not core::meta::IsConst) - [[nodiscard]] - constexpr auto as_mdspan_mut(T& value) noexcept -> VectorSpan; + template + requires(not core::meta::IsConst) + [[nodiscard]] + constexpr auto as_mdspan_mut(T& value) noexcept -> VectorSpan; - template - auto to_string(const vec2& value) noexcept -> std::string; + template + auto to_string(const vec2& value) noexcept -> std::string; - template - auto to_string(const vec3& value) noexcept -> std::string; + template + auto to_string(const vec3& value) noexcept -> std::string; - template - auto to_string(const vec4& value) noexcept -> std::string; + template + auto to_string(const vec4& value) noexcept -> std::string; - template - constexpr auto hasher(const vec2& value) noexcept -> Ret; + template + constexpr auto hasher(const vec2& value) noexcept -> Ret; - template - constexpr auto hasher(const vec3& value) noexcept -> Ret; + template + constexpr auto hasher(const vec3& value) noexcept -> Ret; - template - constexpr auto hasher(const vec4& value) noexcept -> Ret; + template + constexpr auto hasher(const vec4& value) noexcept -> Ret; - template - auto format_as(const vec2& value, FormatContext& ctx) noexcept -> decltype(ctx.out()); + template + auto format_as(const vec2& value, FormatContext& ctx) noexcept -> decltype(ctx.out()); - template - auto format_as(const vec3& value, FormatContext& ctx) noexcept -> decltype(ctx.out()); + template + auto format_as(const vec3& value, FormatContext& ctx) noexcept -> decltype(ctx.out()); - template - auto format_as(const vec4& value, FormatContext& ctx) noexcept -> decltype(ctx.out()); + template + auto format_as(const vec4& value, FormatContext& ctx) noexcept -> decltype(ctx.out()); + } // namespace vector }}} // namespace stormkit::core::math //////////////////////////////////////////////////////////////////// @@ -177,7 +185,7 @@ export namespace stormkit { inline namespace core { namespace math { namespace stdr = std::ranges; -namespace stormkit { inline namespace core { namespace math { +namespace stormkit { inline namespace core { namespace math { inline namespace vector { static_assert(sizeof(uvec2) == sizeof(u32) * 2); static_assert(sizeof(vec2) == sizeof(u64) * 2); static_assert(sizeof(ivec2) == sizeof(i32) * 2); @@ -266,7 +274,7 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto normalize(const T& a) noexcept -> T { auto out = T {}; - normalize(as_mdspan(a), as_mdspan_mut(out)); + math::normalize(as_mdspan(a), as_mdspan_mut(out)); return out; } @@ -278,7 +286,7 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto add(const T& a, const T& b) noexcept -> T { auto out = T {}; - add(as_mdspan(a), as_mdspan(b), as_mdspan_mut(out)); + math::add(as_mdspan(a), as_mdspan(b), as_mdspan_mut(out)); return out; } @@ -290,7 +298,7 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto sub(const T& a, const T& b) noexcept -> T { auto out = T {}; - sub(as_mdspan(a), as_mdspan(b), as_mdspan_mut(out)); + math::sub(as_mdspan(a), as_mdspan(b), as_mdspan_mut(out)); return out; } @@ -302,7 +310,7 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto mul(const T& a, typename T::value_type b) noexcept -> T { auto out = T {}; - mul(as_mdspan(a), b, as_mdspan_mut(out)); + math::mul(as_mdspan(a), b, as_mdspan_mut(out)); return out; } @@ -314,7 +322,7 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto div(const T& a, typename T::value_type b) noexcept -> T { auto out = T {}; - div(as_mdspan(a), b, as_mdspan_mut(out)); + math::div(as_mdspan(a), b, as_mdspan_mut(out)); return out; } @@ -324,7 +332,7 @@ namespace stormkit { inline namespace core { namespace math { template STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto dot(const T& a, const T& b) noexcept -> typename T::value_type { - return dot(as_mdspan(a), as_mdspan(b)); + return math::dot(as_mdspan(a), as_mdspan(b)); } //////////////////////////////////////// @@ -334,7 +342,7 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto cross(const vec3& a, const vec3& b) noexcept -> vec3 { auto out = vec3 {}; - cross(as_mdspan(a), as_mdspan(b), as_mdspan_mut(out)); + math::cross(as_mdspan(a), as_mdspan(b), as_mdspan_mut(out)); return out; } @@ -427,4 +435,102 @@ namespace stormkit { inline namespace core { namespace math { inline auto format_as(const vec4& value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { return std::format_to(ctx.out(), "[vec4 x: {}, y: {}, z: {}, w: {}]", value.x, value.y, value.z, value.w); } -}}} // namespace stormkit::core::math + +#define ADD_INSTANCIATE(vec_type) \ + template STORMKIT_CORE_API auto add(const vec_type&, const vec_type&) noexcept -> vec_type + + ADD_INSTANCIATE(fvec2); + ADD_INSTANCIATE(fvec3); + ADD_INSTANCIATE(fvec4); + ADD_INSTANCIATE(uvec2); + ADD_INSTANCIATE(uvec3); + ADD_INSTANCIATE(uvec4); + ADD_INSTANCIATE(ivec2); + ADD_INSTANCIATE(ivec3); + ADD_INSTANCIATE(ivec4); + +#undef ADD_INSTANCIATE + +#define SUB_INSTANCIATE(vec_type) \ + template STORMKIT_CORE_API auto sub(const vec_type&, const vec_type&) noexcept -> vec_type + + SUB_INSTANCIATE(fvec2); + SUB_INSTANCIATE(fvec3); + SUB_INSTANCIATE(fvec4); + SUB_INSTANCIATE(uvec2); + SUB_INSTANCIATE(uvec3); + SUB_INSTANCIATE(uvec4); + SUB_INSTANCIATE(ivec2); + SUB_INSTANCIATE(ivec3); + SUB_INSTANCIATE(ivec4); + +#undef SUB_INSTANCIATE + +#define MUL_INSTANCIATE(vec_type) \ + template STORMKIT_CORE_API auto mul(const vec_type&, typename vec_type::value_type) noexcept -> vec_type + + MUL_INSTANCIATE(fvec2); + MUL_INSTANCIATE(fvec3); + MUL_INSTANCIATE(fvec4); + MUL_INSTANCIATE(uvec2); + MUL_INSTANCIATE(uvec3); + MUL_INSTANCIATE(uvec4); + MUL_INSTANCIATE(ivec2); + MUL_INSTANCIATE(ivec3); + MUL_INSTANCIATE(ivec4); + +#undef MUL_INSTANCIATE + +#define DIV_INSTANCIATE(vec_type) \ + template STORMKIT_CORE_API auto div(const vec_type&, typename vec_type::value_type) noexcept -> vec_type + + DIV_INSTANCIATE(fvec2); + DIV_INSTANCIATE(fvec3); + DIV_INSTANCIATE(fvec4); + DIV_INSTANCIATE(uvec2); + DIV_INSTANCIATE(uvec3); + DIV_INSTANCIATE(uvec4); + DIV_INSTANCIATE(ivec2); + DIV_INSTANCIATE(ivec3); + DIV_INSTANCIATE(ivec4); + +#undef DIV_INSTANCIATE + +#define DOT_INSTANCIATE(vec_type) \ + template STORMKIT_CORE_API auto dot(const vec_type&, const vec_type&) noexcept -> typename vec_type::value_type + + DOT_INSTANCIATE(fvec2); + DOT_INSTANCIATE(fvec3); + DOT_INSTANCIATE(fvec4); + DOT_INSTANCIATE(uvec2); + DOT_INSTANCIATE(uvec3); + DOT_INSTANCIATE(uvec4); + DOT_INSTANCIATE(ivec2); + DOT_INSTANCIATE(ivec3); + DOT_INSTANCIATE(ivec4); + +#undef DOT_INSTANCIATE + +#define CROSS_INSTANCIATE(type) \ + template STORMKIT_CORE_API auto cross(const vec3&, const vec3&) noexcept -> vec3 + + CROSS_INSTANCIATE(f32); + CROSS_INSTANCIATE(u32); + CROSS_INSTANCIATE(i32); + +#undef CROSS_INSTANCIATE + +#define NORMALIZE_INSTANCIATE(vec_type) template STORMKIT_CORE_API auto normalize(const vec_type&) noexcept -> vec_type + + NORMALIZE_INSTANCIATE(fvec2); + NORMALIZE_INSTANCIATE(fvec3); + NORMALIZE_INSTANCIATE(fvec4); + NORMALIZE_INSTANCIATE(uvec2); + NORMALIZE_INSTANCIATE(uvec3); + NORMALIZE_INSTANCIATE(uvec4); + NORMALIZE_INSTANCIATE(ivec2); + NORMALIZE_INSTANCIATE(ivec3); + NORMALIZE_INSTANCIATE(ivec4); + +#undef NORMALIZE_INSTANCIATE +}}}} // namespace stormkit::core::math::vector diff --git a/modules/stormkit/core/math/linear.cppm b/modules/stormkit/core/math/linear.cppm index 581aa1e8d..1179e33b5 100644 --- a/modules/stormkit/core/math/linear.cppm +++ b/modules/stormkit/core/math/linear.cppm @@ -22,13 +22,13 @@ import :functional; // TODO improve template deduction export namespace stormkit { inline namespace core { namespace math { namespace angle { - template + template using euler = StrongType; - template + template using radian = StrongType; - template + template [[nodiscard]] constexpr auto radians(T degres) noexcept -> radian; } // namespace angle @@ -201,7 +201,7 @@ namespace stormkit { inline namespace core { namespace math { namespace angle { //////////////////////////////////////// //////////////////////////////////////// - template + template STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto radians(T degres) noexcept -> radian { static constexpr auto one_rad = std::numbers::pi_v / T { 180 }; @@ -398,7 +398,7 @@ namespace stormkit { inline namespace core { namespace math { } }); - out[i, j] = narrow(std::pow(T { -1 }, i + j)) * determinant(as_mdspan(submatrix)); + out[i, j] = narrow(std::pow(-1, i + j)) * determinant(as_mdspan(submatrix)); } } @@ -435,7 +435,7 @@ namespace stormkit { inline namespace core { namespace math { const auto det = determinant(as_mdspan(submatrix)); - result += mat[i, j] * narrow(std::pow(T { -1 }, i + j)) * det; + result += mat[i, j] * narrow(std::pow(-1, i + j)) * det; } return result; } @@ -608,8 +608,8 @@ namespace stormkit { inline namespace core { namespace math { EXPECTS(a.data_handle() != out.data_handle()); EXPECTS(axis.data_handle() != out.data_handle()); - const auto cos = std::cos(angle.get()); - const auto sin = std::sin(angle.get()); + const auto cos = narrow(std::cos(angle.get())); + const auto sin = narrow(std::sin(angle.get())); const auto axis_norm = [&axis] noexcept { auto axis_norm = vec3data {}; @@ -617,11 +617,14 @@ namespace stormkit { inline namespace core { namespace math { return axis_norm; }(); - const auto temp = [&axis_norm, &cos] noexcept { - auto temp = vec3data {}; - mul(as_mdspan<3>(axis_norm), T { 1 } - cos, as_mdspan_mut<3>(temp)); - return temp; - }(); + const auto temp = + [&axis_norm, &cos] noexcept { + auto temp = vec3data {}; + mul(as_mdspan<3>(axis_norm), T { 1 } - cos, as_mdspan_mut<3>(temp)); + return temp; + } + + (); auto rotation_matrix = SMatData {}; stdr::fill(rotation_matrix, 0); @@ -687,7 +690,7 @@ namespace stormkit { inline namespace core { namespace math { EXPECTS(not is_equal(aspect, T { 0 })); EXPECTS(not is_equal(near, far)); - const auto half_fov_y = std::tan(fov_y.get() / T { 2 }); + const auto half_fov_y = narrow(std::tan(fov_y.get() / T { 2 })); stdr::fill(as_span_mut(out), T { 0 }); out[0, 0] = T { 1 } / (aspect * half_fov_y); diff --git a/modules/stormkit/core/typesafe/strong_type.cppm b/modules/stormkit/core/typesafe/strong_type.cppm index 5fe4232cf..fdef23356 100644 --- a/modules/stormkit/core/typesafe/strong_type.cppm +++ b/modules/stormkit/core/typesafe/strong_type.cppm @@ -117,7 +117,7 @@ export { } template - class StrongType { + class StrongType: public Capabilities... { public: using ValueType = T; diff --git a/src/lua/core/math.cpp b/src/lua/core/math.cpp index 62a4914bf..52aa1e135 100644 --- a/src/lua/core/math.cpp +++ b/src/lua/core/math.cpp @@ -14,6 +14,23 @@ import stormkit.core; namespace stormkit::lua::core { namespace { + + //////////////////////////////////////// + //////////////////////////////////////// + template typename T, typename U> + auto _bind_angle(std::string_view name, auto& parent) { + auto metatable = parent.template new_usertype>(name, sol::constructors(U)> {}); + metatable["value"] = sol::property( + +[](T* angle) static noexcept { return angle->get(); }, + +[](T* angle, U val) static noexcept { return angle->get() = val; }); + metatable[sol::meta_function::addition] = +[](T first, T second) static noexcept { return first + second; }; + metatable[sol::meta_function::subtraction] = +[](T first, T second) static noexcept { return first - second; }; + metatable[sol::meta_function::multiplication] = +[](T first, T second) static noexcept { + return first * second; + }; + metatable[sol::meta_function::division] = +[](T first, T second) static noexcept { return first / second; }; + } + //////////////////////////////////////// //////////////////////////////////////// template @@ -28,7 +45,7 @@ namespace stormkit::lua::core { metatable["rank"] = sol::var(std::cref(T::RANK)); ( - [metatable, &values] mutable { + [&metatable, &values] mutable { auto&& [k, v] = std::forward(values); metatable[k] = v; }(), @@ -47,12 +64,32 @@ namespace stormkit::lua::core { // }; ( - [metatable, &values] mutable { + [&metatable, &values] mutable { auto&& [k, v] = std::forward(values); metatable[k] = v; }(), ...); } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto _bind_matrix(std::string_view name, auto& parent) { + auto metatable = parent.template new_usertype(name, sol::constructors {}); + + metatable[sol::meta_function::index] = +[](T* value, usize index) static noexcept { + return std::span { &((*value)[index, 0u]), T::EXTENTS[1] }; + }; + metatable[sol::meta_function::to_string] = +[](const T& value) static noexcept { return math::to_string(value); }; + + if constexpr (T::EXTENTS[0] == T::EXTENTS[1]) { + auto identity = parent["identity"].template get_or_create(); + identity[name] = T::identity(); + } + // metatable[sol::meta_function::equal_to] = +[](const T& first, const T& second) static noexcept { + // return first == second; + // }; + } } // namespace //////////////////////////////////////// @@ -99,12 +136,12 @@ namespace stormkit::lua::core { std::pair { "x", &math::fvec3::x }, std::pair { "y", &math::fvec3::y }, std::pair { "z", &math::fvec3::z }); - // _bind_vector("fvec4", - // metatable, - // std::pair { "x", &math::fvec4::x }, - // std::pair { "y", &math::fvec4::y }, - // std::pair { "z", &math::fvec4::z }, - // std::pair { "w", &math::fvec4::w }); + _bind_vector("fvec4", + metatable, + std::pair { "x", &math::fvec4::x }, + std::pair { "y", &math::fvec4::y }, + std::pair { "z", &math::fvec4::z }, + std::pair { "w", &math::fvec4::w }); _bind_vector("uvec2", metatable, std::pair { "x", &math::uvec2::x }, @@ -114,12 +151,12 @@ namespace stormkit::lua::core { std::pair { "x", &math::uvec3::x }, std::pair { "y", &math::uvec3::y }, std::pair { "z", &math::uvec3::z }); - // _bind_vector("uvec4", - // metatable, - // std::pair { "x", &math::uvec4::x }, - // std::pair { "y", &math::uvec4::y }, - // std::pair { "z", &math::uvec4::z }, - // std::pair { "w", &math::uvec4::w }); + _bind_vector("uvec4", + metatable, + std::pair { "x", &math::uvec4::x }, + std::pair { "y", &math::uvec4::y }, + std::pair { "z", &math::uvec4::z }, + std::pair { "w", &math::uvec4::w }); _bind_vector("ivec2", metatable, std::pair { "x", &math::ivec2::x }, @@ -129,78 +166,274 @@ namespace stormkit::lua::core { std::pair { "x", &math::ivec3::x }, std::pair { "y", &math::ivec3::y }, std::pair { "z", &math::ivec3::z }); - // _bind_vector("ivec4", - // metatable, - // std::pair { "x", &math::ivec4::x }, - // std::pair { "y", &math::ivec4::y }, - // std::pair { "z", &math::ivec4::z }, - // std::pair { "w", &math::ivec4::w }); + _bind_vector("ivec4", + metatable, + std::pair { "x", &math::ivec4::x }, + std::pair { "y", &math::ivec4::y }, + std::pair { "z", &math::ivec4::z }, + std::pair { "w", &math::ivec4::w }); + + // [](const auto&... args) static noexcept { return math::add(args...); }); metatable["add"] = sol::overload(&math::add, &math::add, - // &math::add, + &math::add, &math::add, &math::add, - // &math::add, + &math::add, &math::add, - &math::add); - // &math::add); + &math::add, + &math::add); metatable["sub"] = sol::overload(&math::sub, &math::sub, - // &math::sub, + &math::sub, &math::sub, &math::sub, - // &math::sub, + &math::sub, &math::sub, - &math::sub); - // &math::sub); + &math::sub, + &math::sub); + metatable["mul"] = sol::overload(&math::mul, &math::mul, - // &math::mul, + &math::mul, &math::mul, &math::mul, - // &math::mul, + &math::mul, &math::mul, - &math::mul); - // &math::mul); + &math::mul, + &math::mul); metatable["div"] = sol::overload(&math::div, &math::div, - // &math::div, + &math::div, &math::div, &math::div, - // &math::div, + &math::div, &math::div, - &math::div); - // &math::div); + &math::div, + &math::div); + metatable["dot"] = sol::overload(&math::dot, &math::dot, - // &math::dot, + &math::dot, &math::dot, &math::dot, - // &math::dot, + &math::dot, &math::dot, - &math::dot); - // &math::dot); + &math::dot, + &math::dot); + metatable["cross"] = sol::overload( +[](const math::fvec3& first, const math::fvec3& second) static noexcept { return math::cross(first, second); }, +[](const math::uvec3& first, const math::uvec3& second) static noexcept { return math::cross(first, second); }, +[](const math::ivec3& first, const math::ivec3& second) static noexcept { return math::cross(first, second); }); - // &math::cross); metatable["normalize"] = sol::overload(&math::normalize, &math::normalize, - // &math::normalize, + &math::normalize, &math::normalize, &math::normalize, - // &math::normalize, + &math::normalize, &math::normalize, - &math::normalize); - // &math::normalize); + &math::normalize, + &math::normalize); + } + + //////////////////////////////////////// + //////////////////////////////////////// + auto bind_linear_matrix(sol::table& metatable) noexcept -> void { + _bind_matrix("fmat2", metatable); + _bind_matrix("fmat2x3", metatable); + _bind_matrix("fmat2x4", metatable); + _bind_matrix("fmat3", metatable); + _bind_matrix("fmat3x2", metatable); + _bind_matrix("fmat3x4", metatable); + _bind_matrix("fmat4", metatable); + _bind_matrix("fmat4x2", metatable); + _bind_matrix("fmat4x3", metatable); + _bind_matrix("umat2", metatable); + _bind_matrix("umat2x3", metatable); + _bind_matrix("umat2x4", metatable); + _bind_matrix("umat3", metatable); + _bind_matrix("umat3x2", metatable); + _bind_matrix("umat3x4", metatable); + _bind_matrix("umat4", metatable); + _bind_matrix("umat4x2", metatable); + _bind_matrix("umat4x3", metatable); + _bind_matrix("imat2", metatable); + _bind_matrix("imat2x3", metatable); + _bind_matrix("imat2x4", metatable); + _bind_matrix("imat3", metatable); + _bind_matrix("imat3x2", metatable); + _bind_matrix("imat3x4", metatable); + _bind_matrix("imat4", metatable); + _bind_matrix("imat4x2", metatable); + _bind_matrix("imat4x3", metatable); + metatable["determinant"] = sol::overload(&math::determinant, + &math::determinant, + &math::determinant, + &math::determinant, + &math::determinant, + &math::determinant, + &math::determinant, + &math::determinant, + &math::determinant); + metatable["transpose"] = sol::overload(&math::transpose, + &math::transpose, + &math::transpose, + &math::transpose, + &math::transpose, + &math::transpose, + &math::transpose, + &math::transpose, + &math::transpose); + metatable["inverse"] = sol::overload(&math::inverse, + &math::inverse, + &math::inverse, + &math::inverse, + &math::inverse, + &math::inverse, + &math::inverse, + &math::inverse, + &math::inverse); + + metatable["is_inversible"] = sol:: + overload(&math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible, + &math::is_inversible); + metatable["is_orthogonal"] = sol:: + overload(&math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal, + &math::is_orthogonal); + metatable["mul"] = sol:: + overload(&math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul, + &math::mul); + // metatable["div"] = sol:: + // overload(&math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div, + // &math::div); + + // CONTINUER ICI + // metatable["translate"] = sol::overload(&math::translate, &math::translate); + // metatable["scale"] = sol::overload(&math::scale, &math::scale, &math::scale); + // metatable["rotate"] = sol::overload(&math::rotate, &math::rotate); + // metatable["orthographique"] = sol::overload(&math::orthographique, &math::orthographique); + // metatable["perspective"] = sol::overload(&math::perspective, &math::perspective); + // metatable["look_at"] = sol::overload(&math::look_at, &math::look_at); + } + + auto bind_linear(sol::table& parent) noexcept -> void { + auto angle = parent["angle"].get_or_create(); + + _bind_angle("euler", angle); + _bind_angle("radian", angle); + + angle["radians"] = sol::overload(&math::angle::radians); + + bind_linear_vector(parent); + bind_linear_matrix(parent); } auto bind_math(sol::state& global_state) noexcept -> void { auto math_metatable = global_state["math"].get_or_create(); bind_extent(math_metatable); - bind_linear_vector(math_metatable); + bind_linear(math_metatable); } } // namespace stormkit::lua::core From 39ddcb60c500166872ac1397d4b2696225b18426 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 6 Feb 2026 15:31:20 +0100 Subject: [PATCH 071/194] (xmake) remove useless file --- xmake/dependencies.xmake.lua | 177 ----------------------------------- 1 file changed, 177 deletions(-) delete mode 100644 xmake/dependencies.xmake.lua diff --git a/xmake/dependencies.xmake.lua b/xmake/dependencies.xmake.lua deleted file mode 100644 index 84453e5e3..000000000 --- a/xmake/dependencies.xmake.lua +++ /dev/null @@ -1,177 +0,0 @@ -local global_package_configs = { - configs = { - shared = get_config("shared_deps"), - runtimes = get_config("toolchain") == "llvm" and get_config("runtimes") or nil, - }, -} - -if get_config("on_ci") then global_package_configs.system = false end - -if not is_plat("windows") then add_requires("libdwarf") end - -local cxx_isystem = "--cxx-isystem" -local cxx_runtime = nil -if get_config("toolchain") == "llvm" then - if get_config("sdk") then - cxx_isystem = cxx_isystem .. path.join(get_config("sdk"), "include", "c++", "v1") - elseif is_plat("linux") or is_plat("darwin") then - cxx_isystem = cxx_isystem .. "/usr/include/c++/v1" - end - if get_config("runtimes") and get_config("runtimes"):startswith("c++") then cxx_runtime = "-stdlib=libc++" end -end - -local package_configs = { - ["libjpeg-turbo"] = { - windows = { - system = false, - configs = { - runtimes = "MD", - shared = true, - }, - }, - }, - luau = { - global = { - system = false, - version = "master", - configs = { - shared = false, - extern_c = true, - build_cli = false, - }, - }, - }, - luabridge3 = { - global = { - system = false, - version = "master", - }, - }, - libktx = { - llvm = { - configs = { - cxflags = "-Wno-overriding-option", - }, - }, - }, - libxkbcommon = { - global = { - system = false, - configs = { - wayland = true, - x11 = true, - }, - }, - }, - unordered_dense = { - global = { - system = false, - configs = { - modules = true, - std_import = true, - }, - }, - }, - tl_function_ref = { - global = { - system = false, - configs = { - modules = true, - std_import = true, - }, - }, - }, - frozen = { - global = { - system = false, - configs = { - modules = true, - std_import = true, - cpp = "latest", - }, - }, - }, - ["volk"] = { - global = { - version = "1.4.335", - system = false, - }, - }, - ["vulkan-headers"] = { - global = { - version = "1.4.335", - system = false, - configs = { - modules = false, - }, - }, - }, - ["vulkan-memory-allocator"] = { - global = { - version = "v3.3.0", - system = false, - }, - }, - -- nzsl = { - -- windows = { - -- configs = { - -- toolchains = "msvc", - -- runtimes = "MD", - -- }, - -- }, - -- global = { - -- override = true, - -- configs = { - -- kind = "binary", - -- fs_watcher = false, - -- }, - -- }, - -- }, -} - -function add_requires_with_conf(package) - local configs = package_configs[package] or {} - add_requires( - package, - table.join( - global_package_configs, - configs.global or {}, - is_plat("windows") and configs.windows or {}, - is_plat("linux") and configs.linux or {}, - is_plat("macosx") and configs.macos or {}, - get_config("toolchain") == "llvm" and configs.llvm or {}, - get_config("toolchain") == "msvc" and configs.msvc or {}, - get_config("toolchain") == "gcc" and configs.gcc or {} - ) - ) -end - -function add_requires_with_conf_transitive(package) - local configs = package_configs[package] or {} - add_requires( - package, - table.join( - global_package_configs, - configs.global or {}, - is_plat("windows") and configs.windows or {}, - is_plat("linux") and configs.linux or {}, - is_plat("macosx") and configs.macos or {}, - get_config("toolchain") == "llvm" and configs.llvm or {}, - get_config("toolchain") == "msvc" and configs.msvc or {}, - get_config("toolchain") == "gcc" and configs.gcc or {} - ) - ) - -- add_requireconfs( - -- package .. ".**", - -- table.join( - -- global_package_configs, - -- configs.global or {}, - -- is_plat("windows") and configs.windows or {}, - -- is_plat("linux") and configs.linux or {}, - -- is_plat("macosx") and configs.macos or {}, - -- get_config("toolchain") == "llvm" and configs.llvm or {}, - -- get_config("toolchain") == "msvc" and configs.msvc or {}, - -- get_config("toolchain") == "gcc" and configs.gcc or {} - -- ) - -- ) -end From bb0d8fa7bb4715a23cc1ee467befa870b7f7bdf3 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 6 Feb 2026 15:40:03 +0100 Subject: [PATCH 072/194] (xmake) remove old unused folder --- lua/src/core/xmake.lua | 0 lua/src/gpu/xmake.lua | 0 lua/src/image/xmake.lua | 0 lua/src/log/xmake.lua | 0 lua/src/wsi/xmake.lua | 0 lua/xmake.lua | 0 6 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 lua/src/core/xmake.lua delete mode 100644 lua/src/gpu/xmake.lua delete mode 100644 lua/src/image/xmake.lua delete mode 100644 lua/src/log/xmake.lua delete mode 100644 lua/src/wsi/xmake.lua delete mode 100644 lua/xmake.lua diff --git a/lua/src/core/xmake.lua b/lua/src/core/xmake.lua deleted file mode 100644 index e69de29bb..000000000 diff --git a/lua/src/gpu/xmake.lua b/lua/src/gpu/xmake.lua deleted file mode 100644 index e69de29bb..000000000 diff --git a/lua/src/image/xmake.lua b/lua/src/image/xmake.lua deleted file mode 100644 index e69de29bb..000000000 diff --git a/lua/src/log/xmake.lua b/lua/src/log/xmake.lua deleted file mode 100644 index e69de29bb..000000000 diff --git a/lua/src/wsi/xmake.lua b/lua/src/wsi/xmake.lua deleted file mode 100644 index e69de29bb..000000000 diff --git a/lua/xmake.lua b/lua/xmake.lua deleted file mode 100644 index e69de29bb..000000000 From 7b5e8c79b7c7dc83e99511d791b120192fd7098d Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 6 Feb 2026 15:53:50 +0100 Subject: [PATCH 073/194] (core) add missing matrix bindings --- src/lua/core/math.cpp | 133 ++++++++++++++++++++++-------------------- 1 file changed, 69 insertions(+), 64 deletions(-) diff --git a/src/lua/core/math.cpp b/src/lua/core/math.cpp index 52aa1e135..eb1903b79 100644 --- a/src/lua/core/math.cpp +++ b/src/lua/core/math.cpp @@ -353,70 +353,75 @@ namespace stormkit::lua::core { &math::is_orthogonal, &math::is_orthogonal, &math::is_orthogonal); - metatable["mul"] = sol:: - overload(&math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul, - &math::mul); - // metatable["div"] = sol:: - // overload(&math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div, - // &math::div); - - // CONTINUER ICI - // metatable["translate"] = sol::overload(&math::translate, &math::translate); - // metatable["scale"] = sol::overload(&math::scale, &math::scale, &math::scale); - // metatable["rotate"] = sol::overload(&math::rotate, &math::rotate); - // metatable["orthographique"] = sol::overload(&math::orthographique, &math::orthographique); - // metatable["perspective"] = sol::overload(&math::perspective, &math::perspective); - // metatable["look_at"] = sol::overload(&math::look_at, &math::look_at); + metatable["mul"] = sol::overload( + +[](const math::fmat2& a, typename math::fmat2::value_type b) static noexcept { return mul(a, b); }, + +[](const math::fmat2x3& a, typename math::fmat2x3::value_type b) static noexcept { return mul(a, b); }, + +[](const math::fmat2x4& a, typename math::fmat2x4::value_type b) static noexcept { return mul(a, b); }, + +[](const math::fmat3& a, typename math::fmat3::value_type b) static noexcept { return mul(a, b); }, + +[](const math::fmat3x2& a, typename math::fmat3x2::value_type b) static noexcept { return mul(a, b); }, + +[](const math::fmat3x4& a, typename math::fmat3x4::value_type b) static noexcept { return mul(a, b); }, + +[](const math::fmat4& a, typename math::fmat4::value_type b) static noexcept { return mul(a, b); }, + +[](const math::fmat4x2& a, typename math::fmat4x2::value_type b) static noexcept { return mul(a, b); }, + +[](const math::fmat4x3& a, typename math::fmat4x3::value_type b) static noexcept { return mul(a, b); }, + +[](const math::umat2& a, typename math::umat2::value_type b) static noexcept { return mul(a, b); }, + +[](const math::umat2x3& a, typename math::umat2x3::value_type b) static noexcept { return mul(a, b); }, + +[](const math::umat2x4& a, typename math::umat2x4::value_type b) static noexcept { return mul(a, b); }, + +[](const math::umat3& a, typename math::umat3::value_type b) static noexcept { return mul(a, b); }, + +[](const math::umat3x2& a, typename math::umat3x2::value_type b) static noexcept { return mul(a, b); }, + +[](const math::umat3x4& a, typename math::umat3x4::value_type b) static noexcept { return mul(a, b); }, + +[](const math::umat4& a, typename math::umat4::value_type b) static noexcept { return mul(a, b); }, + +[](const math::umat4x2& a, typename math::umat4x2::value_type b) static noexcept { return mul(a, b); }, + +[](const math::umat4x3& a, typename math::umat4x3::value_type b) static noexcept { return mul(a, b); }, + +[](const math::imat2& a, typename math::imat2::value_type b) static noexcept { return mul(a, b); }, + +[](const math::imat2x3& a, typename math::imat2x3::value_type b) static noexcept { return mul(a, b); }, + +[](const math::imat2x4& a, typename math::imat2x4::value_type b) static noexcept { return mul(a, b); }, + +[](const math::imat3& a, typename math::imat3::value_type b) static noexcept { return mul(a, b); }, + +[](const math::imat3x2& a, typename math::imat3x2::value_type b) static noexcept { return mul(a, b); }, + +[](const math::imat3x4& a, typename math::imat3x4::value_type b) static noexcept { return mul(a, b); }, + +[](const math::imat4& a, typename math::imat4::value_type b) static noexcept { return mul(a, b); }, + +[](const math::imat4x2& a, typename math::imat4x2::value_type b) static noexcept { return mul(a, b); }, + +[](const math::imat4x3& a, typename math::imat4x3::value_type b) static noexcept { return mul(a, b); }); + metatable["div"] = sol::overload( + +[](const math::fmat2& a, typename math::fmat2::value_type b) static noexcept { return div(a, b); }, + +[](const math::fmat2x3& a, typename math::fmat2x3::value_type b) static noexcept { return div(a, b); }, + +[](const math::fmat2x4& a, typename math::fmat2x4::value_type b) static noexcept { return div(a, b); }, + +[](const math::fmat3& a, typename math::fmat3::value_type b) static noexcept { return div(a, b); }, + +[](const math::fmat3x2& a, typename math::fmat3x2::value_type b) static noexcept { return div(a, b); }, + +[](const math::fmat3x4& a, typename math::fmat3x4::value_type b) static noexcept { return div(a, b); }, + +[](const math::fmat4& a, typename math::fmat4::value_type b) static noexcept { return div(a, b); }, + +[](const math::fmat4x2& a, typename math::fmat4x2::value_type b) static noexcept { return div(a, b); }, + +[](const math::fmat4x3& a, typename math::fmat4x3::value_type b) static noexcept { return div(a, b); }, + +[](const math::umat2& a, typename math::umat2::value_type b) static noexcept { return div(a, b); }, + +[](const math::umat2x3& a, typename math::umat2x3::value_type b) static noexcept { return div(a, b); }, + +[](const math::umat2x4& a, typename math::umat2x4::value_type b) static noexcept { return div(a, b); }, + +[](const math::umat3& a, typename math::umat3::value_type b) static noexcept { return div(a, b); }, + +[](const math::umat3x2& a, typename math::umat3x2::value_type b) static noexcept { return div(a, b); }, + +[](const math::umat3x4& a, typename math::umat3x4::value_type b) static noexcept { return div(a, b); }, + +[](const math::umat4& a, typename math::umat4::value_type b) static noexcept { return div(a, b); }, + +[](const math::umat4x2& a, typename math::umat4x2::value_type b) static noexcept { return div(a, b); }, + +[](const math::umat4x3& a, typename math::umat4x3::value_type b) static noexcept { return div(a, b); }, + +[](const math::imat2& a, typename math::imat2::value_type b) static noexcept { return div(a, b); }, + +[](const math::imat2x3& a, typename math::imat2x3::value_type b) static noexcept { return div(a, b); }, + +[](const math::imat2x4& a, typename math::imat2x4::value_type b) static noexcept { return div(a, b); }, + +[](const math::imat3& a, typename math::imat3::value_type b) static noexcept { return div(a, b); }, + +[](const math::imat3x2& a, typename math::imat3x2::value_type b) static noexcept { return div(a, b); }, + +[](const math::imat3x4& a, typename math::imat3x4::value_type b) static noexcept { return div(a, b); }, + +[](const math::imat4& a, typename math::imat4::value_type b) static noexcept { return div(a, b); }, + +[](const math::imat4x2& a, typename math::imat4x2::value_type b) static noexcept { return div(a, b); }, + +[](const math::imat4x3& a, typename math::imat4x3::value_type b) static noexcept { return div(a, b); }); + + metatable["translate"] = sol::overload(&math::matrix::translate, &math::matrix::translate); + metatable["scale"] = sol::overload(&math::matrix::scale, &math::matrix::scale, &math::matrix::scale); + metatable["rotate"] = &math::matrix::rotate; + metatable["orthographique"] = sol::overload( + +[](f32 left, f32 right, f32 bottom, f32 top, f32 near, f32 far) static noexcept { + return math::orthographique(left, right, bottom, top, near, far); + }, + +[](f32 left, f32 right, f32 bottom, f32 top) static noexcept { + return math::orthographique(left, right, bottom, top); + }); + metatable["perspective"] = &math::matrix::perspective; + metatable["look_at"] = &math::matrix::look_at; } auto bind_linear(sol::table& parent) noexcept -> void { From b6a33119867b5dec9b648cc072139ffe39169e39 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 6 Feb 2026 17:47:55 +0100 Subject: [PATCH 074/194] (log) fix compilation when lua module is enabled --- modules/stormkit/log.cppm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/stormkit/log.cppm b/modules/stormkit/log.cppm index 860efa92c..a6eb7749c 100644 --- a/modules/stormkit/log.cppm +++ b/modules/stormkit/log.cppm @@ -17,10 +17,6 @@ import frozen; import stormkit.core; -#ifdef STORMKIT_LUA_BINDING -export import :lua; -#endif - export { namespace stormkit::log { struct Module; From b42dc17def51cbf1a53cf636fbb434c9f7df7467 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 6 Feb 2026 19:36:45 +0100 Subject: [PATCH 075/194] (lua) expose sol global state --- modules/stormkit/lua.cppm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/modules/stormkit/lua.cppm b/modules/stormkit/lua.cppm index a45133ece..83a2cfd1a 100644 --- a/modules/stormkit/lua.cppm +++ b/modules/stormkit/lua.cppm @@ -40,6 +40,9 @@ export namespace stormkit::lua { auto lua_main() noexcept -> std::expected; + template + auto global_state(this T& self) noexcept -> decltype(auto); + static auto create(const stdfs::path& file, Modules modules = {}) noexcept -> Engine; private: @@ -64,4 +67,11 @@ namespace stormkit::lua { engine.load(file); return engine; } + + //////////////////////////////////////// + //////////////////////////////////////// + template + inline auto Engine::global_state(this T& self) noexcept -> decltype(auto) { + return std::forward_like(self.m_global_state); + } } // namespace stormkit::lua From f0b377625d16dc2067d8a73c93e9c712fd90b9d1 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 6 Feb 2026 19:53:18 +0100 Subject: [PATCH 076/194] (wsi) add allocate variant of window::open --- modules/stormkit/wsi/window.cppm | 2 ++ src/wsi/window.cpp | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/modules/stormkit/wsi/window.cppm b/modules/stormkit/wsi/window.cppm index 91990a11e..ff39d1094 100644 --- a/modules/stormkit/wsi/window.cppm +++ b/modules/stormkit/wsi/window.cppm @@ -133,6 +133,8 @@ export { auto operator=(Window&&) noexcept -> Window&; static auto open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> Window; + static auto allocate_and_open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept + -> Heap; auto close() noexcept -> void; [[nodiscard]] diff --git a/src/wsi/window.cpp b/src/wsi/window.cpp index ac294d7b6..7e296a45d 100644 --- a/src/wsi/window.cpp +++ b/src/wsi/window.cpp @@ -69,6 +69,14 @@ namespace stormkit::wsi { return window; } + ///////////////////////////////////// + ///////////////////////////////////// + auto Window::allocate_and_open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> Heap { + auto window = allocate_unsafe(Window {}); + window->m_impl->open(std::move(title), size, flags); + return window; + } + ///////////////////////////////////// ///////////////////////////////////// auto Window::close() noexcept -> void { From 3dc1c45dbfb1bbccb7f4a3357a6e0b78e36d4981 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sat, 7 Feb 2026 15:57:27 +0100 Subject: [PATCH 077/194] (wsi) cleanup wsi events lua binding --- examples/lua/wsi/events/lua/events.luau | 13 ------------- examples/lua/wsi/events/src/main.cpp | 4 ++-- src/lua/wsi.cpp | 12 ++++++------ 3 files changed, 8 insertions(+), 21 deletions(-) diff --git a/examples/lua/wsi/events/lua/events.luau b/examples/lua/wsi/events/lua/events.luau index c1e9321e2..b917ee336 100644 --- a/examples/lua/wsi/events/lua/events.luau +++ b/examples/lua/wsi/events/lua/events.luau @@ -1,10 +1,6 @@ local function main() local window = wsi.window.open("test", 800, 600, wsi.window_flag.RESIZEABLE) - local mat = math.identity.fmat4 - - print(mat) - window:on_closed(function() print("Close event!") return true @@ -12,47 +8,38 @@ local function main() window:on_resized(function(extent) print("Resize event:\n ", extent) - return true end) window:on_monitor_changed(function(monitor) print("Monitor changed event:\n ", monitor) - return true end) window:on_mouse_moved(function(_, position) print("Mouse move event:\n ", position) - return true end) window:on_mouse_button_down(function(_, button, position) print("Mouse button down event:\n ", button, "\n ", position) - return true end) window:on_mouse_button_up(function(_, button, position) print("Mouse button up event:\n ", button, "\n ", position) - return true end) window:on_restored(function() print("Restored event!") - return true end) window:on_minimized(function() print("Minimzed event!") - return true end) window:on_activated(function() print("Activate event!") - return true end) window:on_deactivated(function() print("Deactivate event!") - return true end) local foo = 0 diff --git a/examples/lua/wsi/events/src/main.cpp b/examples/lua/wsi/events/src/main.cpp index b417cecd1..2b29f0bb3 100644 --- a/examples/lua/wsi/events/src/main.cpp +++ b/examples/lua/wsi/events/src/main.cpp @@ -2,8 +2,6 @@ // This file is subject to the license terms in the LICENSE file // found in the top-level of this distribution -#include - import std; import stormkit; @@ -12,6 +10,8 @@ import stormkit; #include +#include + LOGGER("lua-Events"); #ifndef RESOURCE_DIR diff --git a/src/lua/wsi.cpp b/src/lua/wsi.cpp index 7e12f8779..4329b6cda 100644 --- a/src/lua/wsi.cpp +++ b/src/lua/wsi.cpp @@ -25,11 +25,11 @@ namespace stormkit::lua::wsi { //////////////////////////////////////// //////////////////////////////////////// auto init_lua(sol::state& global_state) noexcept -> void { - auto wsi_metatable = global_state["wsi"].get_or_create(); - bind_core(global_state, wsi_metatable); - bind_window(global_state, wsi_metatable); - bind_monitor(global_state, wsi_metatable); - bind_keyboard(global_state, wsi_metatable); - bind_mouse(global_state, wsi_metatable); + auto wsi = global_state["wsi"].get_or_create(); + bind_core(global_state, wsi); + bind_window(global_state, wsi); + bind_monitor(global_state, wsi); + bind_keyboard(global_state, wsi); + bind_mouse(global_state, wsi); } } // namespace stormkit::lua::wsi From 931a36ca00dc09106916a58596c8cbb888a05c03 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sat, 7 Feb 2026 16:14:14 +0100 Subject: [PATCH 078/194] (core, gpu, wsi) rename colors to match math convention --- modules/stormkit/core/utils/color.cppm | 52 +++++++++---------- modules/stormkit/gpu/core/structs.cppm | 2 +- .../gpu/execution/command_buffer.cppm | 8 +-- modules/stormkit/wsi/window.cppm | 4 +- src/lua/core/color.cpp | 36 ++++++------- src/wsi/linux/wayland/window.cpp | 4 +- src/wsi/linux/wayland/window.cppm | 4 +- src/wsi/linux/window.cppm | 8 +-- src/wsi/linux/x11/window.cpp | 4 +- src/wsi/linux/x11/window.cppm | 4 +- src/wsi/macos/window.cppm | 4 +- src/wsi/win32/window.cpp | 4 +- src/wsi/win32/window.cppm | 4 +- src/wsi/window.cpp | 4 +- 14 files changed, 71 insertions(+), 71 deletions(-) diff --git a/modules/stormkit/core/utils/color.cppm b/modules/stormkit/core/utils/color.cppm index f3e72ba65..47acd3eb0 100644 --- a/modules/stormkit/core/utils/color.cppm +++ b/modules/stormkit/core/utils/color.cppm @@ -156,39 +156,39 @@ export namespace stormkit { inline namespace core { }; template - using rcolor = color; + using color_r = color; template - using rgcolor = color; + using color_rg = color; template - using rgbcolor = color; + using color_rgb = color; template - using rgbacolor = color; + using color_rgba = color; template - using argbcolor = color; + using color_argb = color; template - using bgrcolor = color; + using color_bgr = color; template - using bgracolor = color; + using color_bgra = color; template - using abgrcolor = color; - - using rcolor_f = rcolor; - using rgcolor_f = rgcolor; - using rgbcolor_f = rgbcolor; - using rgbacolor_f = rgbacolor; - using argbcolor_f = argbcolor; - using bgrcolor_f = bgrcolor; - using bgracolor_f = bgracolor; - using abgrcolor_f = abgrcolor; - - using rcolor_u = rcolor; - using rgcolor_u = rgcolor; - using rgbcolor_u = rgbcolor; - using rgbacolor_u = rgbacolor; - using argbcolor_u = argbcolor; - using bgrcolor_u = bgrcolor; - using bgracolor_u = bgracolor; - using abgrcolor_u = abgrcolor; + using color_abgr = color; + + using fcolor_r = color_r; + using fcolor_rg = color_rg; + using fcolor_rgb = color_rgb; + using fcolor_rgba = color_rgba; + using fcolor_argb = color_argb; + using fcolor_bgr = color_bgr; + using fcolor_bgra = color_bgra; + using fcolor_abgr = color_abgr; + + using ucolor_r = color_r; + using ucolor_rg = color_rg; + using ucolor_rgb = color_rgb; + using ucolor_rgba = color_rgba; + using ucolor_argb = color_argb; + using ucolor_bgr = color_bgr; + using ucolor_bgra = color_bgra; + using ucolor_abgr = color_abgr; constexpr auto as_string(ColorLayout layout) noexcept -> std::string_view; constexpr auto to_string(ColorLayout layout) noexcept -> std::string; diff --git a/modules/stormkit/gpu/core/structs.cppm b/modules/stormkit/gpu/core/structs.cppm index 081ef0519..8c75ab26f 100644 --- a/modules/stormkit/gpu/core/structs.cppm +++ b/modules/stormkit/gpu/core/structs.cppm @@ -235,7 +235,7 @@ export { }; struct ClearColor { - rgbacolor_f color = stormkit::colors::SILVER; + fcolor_rgba color = stormkit::colors::SILVER; constexpr auto operator==(const ClearColor& other) const noexcept -> bool; }; diff --git a/modules/stormkit/gpu/execution/command_buffer.cppm b/modules/stormkit/gpu/execution/command_buffer.cppm index c69861413..a94353a45 100644 --- a/modules/stormkit/gpu/execution/command_buffer.cppm +++ b/modules/stormkit/gpu/execution/command_buffer.cppm @@ -153,8 +153,8 @@ export namespace stormkit::gpu { -> Expected>; auto end() noexcept -> Expected>; - auto begin_debug_region(std::string_view name, const rgbcolor_f& color = colors::WHITE) noexcept -> CommandBuffer&; - auto insert_debug_label(std::string_view name, const rgbcolor_f& color = colors::WHITE) noexcept -> CommandBuffer&; + auto begin_debug_region(std::string_view name, const fcolor_rgb& color = colors::WHITE) noexcept -> CommandBuffer&; + auto insert_debug_label(std::string_view name, const fcolor_rgb& color = colors::WHITE) noexcept -> CommandBuffer&; auto end_debug_region() noexcept -> CommandBuffer&; auto begin_rendering(const RenderingInfo& info) noexcept -> CommandBuffer&; @@ -529,7 +529,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::begin_debug_region(std::string_view name, const rgbcolor_f& color) noexcept -> CommandBuffer& { + inline auto CommandBuffer::begin_debug_region(std::string_view name, const fcolor_rgb& color) noexcept -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); if (not vkCmdBeginDebugUtilsLabelEXT) [[unlikely]] @@ -549,7 +549,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::insert_debug_label(std::string_view name, const rgbcolor_f& color) noexcept -> CommandBuffer& { + inline auto CommandBuffer::insert_debug_label(std::string_view name, const fcolor_rgb& color) noexcept -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); if (not vkCmdInsertDebugUtilsLabelEXT) [[unlikely]] diff --git a/modules/stormkit/wsi/window.cppm b/modules/stormkit/wsi/window.cppm index ff39d1094..a588513be 100644 --- a/modules/stormkit/wsi/window.cppm +++ b/modules/stormkit/wsi/window.cppm @@ -141,8 +141,8 @@ export { auto is_open() const noexcept -> bool; auto handle_events() noexcept -> void; - auto clear(const rgbcolor& color = colors::BLACK) noexcept -> void; - auto fill_framebuffer(std::span> colors) noexcept -> void; + auto clear(const ucolor_rgb& color = colors::BLACK) noexcept -> void; + auto fill_framebuffer(std::span colors) noexcept -> void; template auto on(T&& callback) noexcept -> void; diff --git a/src/lua/core/color.cpp b/src/lua/core/color.cpp index add2bff7c..674355a4e 100644 --- a/src/lua/core/color.cpp +++ b/src/lua/core/color.cpp @@ -77,29 +77,29 @@ namespace stormkit::lua::core { ColorLayout::ABGR); auto f32_metatable = global_state["fcolor"].get_or_create(); - _bind_color("rgb", + _bind_color("rgb", f32_metatable, - std::pair { "r", &rgbcolor_f::r }, - std::pair { "g", &rgbcolor_f::g }, - std::pair { "b", &rgbcolor_f::b }); - _bind_color("rgba", + std::pair { "r", &fcolor_rgb::r }, + std::pair { "g", &fcolor_rgb::g }, + std::pair { "b", &fcolor_rgb::b }); + _bind_color("rgba", f32_metatable, - std::pair { "r", &rgbacolor_f::r }, - std::pair { "g", &rgbacolor_f::g }, - std::pair { "b", &rgbacolor_f::b }, - std::pair { "a", &rgbacolor_f::a }); + std::pair { "r", &fcolor_rgba::r }, + std::pair { "g", &fcolor_rgba::g }, + std::pair { "b", &fcolor_rgba::b }, + std::pair { "a", &fcolor_rgba::a }); auto u8_metatable = global_state["ucolor"].get_or_create(); - _bind_color("rgb", + _bind_color("rgb", u8_metatable, - std::pair { "r", &rgbcolor_u::r }, - std::pair { "g", &rgbcolor_u::g }, - std::pair { "b", &rgbcolor_u::b }); - _bind_color("rgba", + std::pair { "r", &ucolor_rgb::r }, + std::pair { "g", &ucolor_rgb::g }, + std::pair { "b", &ucolor_rgb::b }); + _bind_color("rgba", u8_metatable, - std::pair { "r", &rgbacolor_u::r }, - std::pair { "g", &rgbacolor_u::g }, - std::pair { "b", &rgbacolor_u::b }, - std::pair { "a", &rgbacolor_u::a }); + std::pair { "r", &ucolor_rgba::r }, + std::pair { "g", &ucolor_rgba::g }, + std::pair { "b", &ucolor_rgba::b }, + std::pair { "a", &ucolor_rgba::a }); } } // namespace stormkit::lua::core diff --git a/src/wsi/linux/wayland/window.cpp b/src/wsi/linux/wayland/window.cpp index 8d9d3b007..7ed949f25 100644 --- a/src/wsi/linux/wayland/window.cpp +++ b/src/wsi/linux/wayland/window.cpp @@ -194,7 +194,7 @@ namespace stormkit::wsi::linux::wayland { ///////////////////////////////////// ///////////////////////////////////// - auto Window::clear(const rgbcolor& color) noexcept -> void { + auto Window::clear(const ucolor_rgb& color) noexcept -> void { const auto value = (255 << 24) + (color.r << 16) + (color.g << 8) + (color.b); auto view = std::span { std::bit_cast(m_shm_buffer.get().begin()), m_shm_buffer->size() / sizeof(i32) }; @@ -207,7 +207,7 @@ namespace stormkit::wsi::linux::wayland { ///////////////////////////////////// ///////////////////////////////////// - auto Window::fill_framebuffer(std::span> colors) noexcept -> void { + auto Window::fill_framebuffer(std::span colors) noexcept -> void { auto view = std::span { std::bit_cast(m_shm_buffer.get().begin()), m_shm_buffer->size() / sizeof(i32) }; stdr::copy(colors | stdv::transform([](const auto& color) static noexcept { return (255 << 24) + (color.r << 16) + (color.g << 8) + (color.b); diff --git a/src/wsi/linux/wayland/window.cppm b/src/wsi/linux/wayland/window.cppm index 97bf79191..c08c6511d 100644 --- a/src/wsi/linux/wayland/window.cppm +++ b/src/wsi/linux/wayland/window.cppm @@ -48,8 +48,8 @@ export { auto handle_events() noexcept -> void; - auto clear(const rgbcolor& color) noexcept -> void; - auto fill_framebuffer(std::span> colors) noexcept -> void; + auto clear(const ucolor_rgb& color) noexcept -> void; + auto fill_framebuffer(std::span colors) noexcept -> void; auto set_title(std::string title) noexcept -> void; auto set_extent(const math::uextent2& extent) noexcept -> void; diff --git a/src/wsi/linux/window.cppm b/src/wsi/linux/window.cppm index 3f0fd87a1..dd21a602a 100644 --- a/src/wsi/linux/window.cppm +++ b/src/wsi/linux/window.cppm @@ -49,8 +49,8 @@ export namespace stormkit::wsi::linux { auto handle_events() noexcept -> void; - auto clear(const rgbcolor& color) noexcept -> void; - auto fill_framebuffer(std::span> colors) noexcept -> void; + auto clear(const ucolor_rgb& color) noexcept -> void; + auto fill_framebuffer(std::span colors) noexcept -> void; auto set_title(std::string title) noexcept -> void; [[nodiscard]] @@ -221,7 +221,7 @@ namespace stormkit::wsi::linux { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Window::clear(const rgbcolor& color) noexcept -> void { + inline auto Window::clear(const ucolor_rgb& color) noexcept -> void { switch (m_wm) { case WM::X11: as(m_impl).clear(color); break; case WM::WAYLAND: as(m_impl).clear(color); break; @@ -233,7 +233,7 @@ namespace stormkit::wsi::linux { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Window::fill_framebuffer(std::span> colors) noexcept -> void { + inline auto Window::fill_framebuffer(std::span colors) noexcept -> void { switch (m_wm) { case WM::X11: as(m_impl).fill_framebuffer(colors); break; case WM::WAYLAND: as(m_impl).fill_framebuffer(colors); break; diff --git a/src/wsi/linux/x11/window.cpp b/src/wsi/linux/x11/window.cpp index 422b71df4..02c8b7b09 100644 --- a/src/wsi/linux/x11/window.cpp +++ b/src/wsi/linux/x11/window.cpp @@ -410,7 +410,7 @@ namespace stormkit::wsi::linux::x11 { ///////////////////////////////////// ///////////////////////////////////// - auto Window::clear(const rgbcolor& color) noexcept -> void { + auto Window::clear(const ucolor_rgb& color) noexcept -> void { expects(m_graphics_context, "clear called on a window opened with EXTERNAL_CONTEXT flag"); const auto _color = (255_u32 << 24) | as(color.r) << 16 | as(color.g) << 8 | color.b; stdr::fill(m_framebuffer, _color); @@ -424,7 +424,7 @@ namespace stormkit::wsi::linux::x11 { ///////////////////////////////////// ///////////////////////////////////// - auto Window::fill_framebuffer(std::span> pixels) noexcept -> void { + auto Window::fill_framebuffer(std::span pixels) noexcept -> void { expects(m_graphics_context, "fill_framebuffer called on a window opened with EXTERNAL_CONTEXT flag"); const auto count = std::min(stdr::size(pixels), stdr::size(m_framebuffer)); stdr::copy(pixels | stdv::take(count) | stdv::transform([](const auto& col) static noexcept { diff --git a/src/wsi/linux/x11/window.cppm b/src/wsi/linux/x11/window.cppm index 8642d9072..99bf3275e 100644 --- a/src/wsi/linux/x11/window.cppm +++ b/src/wsi/linux/x11/window.cppm @@ -77,8 +77,8 @@ export namespace stormkit::wsi::linux::x11 { auto handle_events() noexcept -> void; - auto clear(const rgbcolor& color) noexcept -> void; - auto fill_framebuffer(std::span> colors) noexcept -> void; + auto clear(const ucolor_rgb& color) noexcept -> void; + auto fill_framebuffer(std::span colors) noexcept -> void; auto set_title(std::string title) noexcept -> void; auto set_extent(const math::uextent2& extent) noexcept -> void; diff --git a/src/wsi/macos/window.cppm b/src/wsi/macos/window.cppm index 6e7a96901..55a7a796c 100644 --- a/src/wsi/macos/window.cppm +++ b/src/wsi/macos/window.cppm @@ -82,13 +82,13 @@ export namespace stormkit::wsi::macos { auto handle_events() noexcept -> void { macOS::processEvents(); } - auto clear([[maybe_unused]] const rgbcolor& color) noexcept -> void { + auto clear([[maybe_unused]] const ucolor_rgb& color) noexcept -> void { const auto value = as(color.r) << 16 | as(color.g) << 8 | color.b; stdr::fill(m_pixels, value); m_window->drawBitmap(std::bit_cast(stdr::data(m_pixels))); } - auto fill_framebuffer(std::span> pixels) noexcept -> void { + auto fill_framebuffer(std::span pixels) noexcept -> void { const auto [width, height] = extent(); const auto count = std::min(as(stdr::size(pixels)), height * width); if (stdr::size(pixels) > stdr::size(m_pixels)) m_pixels.resize(stdr::size(pixels)); diff --git a/src/wsi/win32/window.cpp b/src/wsi/win32/window.cpp index d6de96bfe..5171e5376 100644 --- a/src/wsi/win32/window.cpp +++ b/src/wsi/win32/window.cpp @@ -174,7 +174,7 @@ namespace stormkit::wsi::win32 { ///////////////////////////////////// ///////////////////////////////////// - auto Window::clear(const rgbcolor& color) noexcept -> void { + auto Window::clear(const ucolor_rgb& color) noexcept -> void { if (m_win32_state.external_context) return; auto hbrush = HBrush::create(RGB(color.r, color.g, color.b)); @@ -187,7 +187,7 @@ namespace stormkit::wsi::win32 { ///////////////////////////////////// ///////////////////////////////////// - auto Window::fill_framebuffer(std::span> pixels) noexcept -> void { + auto Window::fill_framebuffer(std::span pixels) noexcept -> void { if (m_win32_state.external_context) return; const auto [width, height] = extent(); diff --git a/src/wsi/win32/window.cppm b/src/wsi/win32/window.cppm index 36a742a19..b8e5329a9 100644 --- a/src/wsi/win32/window.cppm +++ b/src/wsi/win32/window.cppm @@ -40,8 +40,8 @@ export namespace stormkit::wsi::win32 { auto handle_events() noexcept -> void; - auto clear(const rgbcolor& color) noexcept -> void; - auto fill_framebuffer(std::span> colors) noexcept -> void; + auto clear(const ucolor_rgb& color) noexcept -> void; + auto fill_framebuffer(std::span colors) noexcept -> void; auto set_title(std::string title) noexcept -> void; auto set_extent(const math::uextent2& extent) noexcept -> void; diff --git a/src/wsi/window.cpp b/src/wsi/window.cpp index 7e296a45d..22ced5a93 100644 --- a/src/wsi/window.cpp +++ b/src/wsi/window.cpp @@ -85,13 +85,13 @@ namespace stormkit::wsi { ///////////////////////////////////// ///////////////////////////////////// - auto Window::clear(const rgbcolor& color) noexcept -> void { + auto Window::clear(const ucolor_rgb& color) noexcept -> void { m_impl->clear(color); } ///////////////////////////////////// ///////////////////////////////////// - auto Window::fill_framebuffer(std::span> colors) noexcept -> void { + auto Window::fill_framebuffer(std::span colors) noexcept -> void { m_impl->fill_framebuffer(colors); } From 608048171f3a5cac8749a51225265e7d26627266 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sat, 7 Feb 2026 16:54:40 +0100 Subject: [PATCH 079/194] (core) try to fix missing elements_of on apple platforms --- modules/stormkit/core/coroutines.cppm | 35 +++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/modules/stormkit/core/coroutines.cppm b/modules/stormkit/core/coroutines.cppm index 653d6931e..1ebbda94e 100644 --- a/modules/stormkit/core/coroutines.cppm +++ b/modules/stormkit/core/coroutines.cppm @@ -84,6 +84,41 @@ export namespace std { _T* __value_; }; + #if defined(__clang__) and (__clang_major__ < 22) + namespace ranges { + template + struct elements_of { + explicit constexpr elements_of(_Rng&& __rng) noexcept + requires std::is_default_constructible_v<_Allocator> + : __range(static_cast<_Rng&&>(__rng)) {} + + constexpr elements_of(_Rng&& __rng, _Allocator&& __alloc) noexcept + : __range((_Rng&&)__rng), __alloc((_Allocator&&)__alloc) {} + + constexpr elements_of(elements_of&&) noexcept = default; + + constexpr elements_of(const elements_of&) = delete; + constexpr elements_of& operator=(const elements_of&) = delete; + constexpr elements_of& operator=(elements_of&&) = delete; + + constexpr _Rng&& get() noexcept { return static_cast<_Rng&&>(__range); } + + constexpr _Allocator get_allocator() const noexcept { return __alloc; } + + private: + [[no_unique_address]] + _Allocator __alloc; // \expos + _Rng&& __range; // \expos + }; + + template + elements_of(_Rng&&) -> elements_of<_Rng>; + + template + elements_of(_Rng&&, Allocator&&) -> elements_of<_Rng, Allocator>; + } // namespace ranges + #endif + template inline constexpr bool __allocator_needs_to_be_stored = !allocator_traits<_Alloc>::is_always_equal::value || !is_default_constructible_v<_Alloc>; From 6a94cd180658ffe02853ea981e1770eb4a3625f7 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sat, 7 Feb 2026 16:54:59 +0100 Subject: [PATCH 080/194] (core) fix explicit instantiation of linear structures on non-windows platforms --- modules/stormkit/core/math/linear-matrix.cppm | 31 +++---------------- modules/stormkit/core/math/linear-vector.cppm | 5 +++ 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/modules/stormkit/core/math/linear-matrix.cppm b/modules/stormkit/core/math/linear-matrix.cppm index 9055b947f..557d6a603 100644 --- a/modules/stormkit/core/math/linear-matrix.cppm +++ b/modules/stormkit/core/math/linear-matrix.cppm @@ -633,33 +633,10 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m return out; } - // DETERMINANT_INSTANCIATE(fmat2); - // DETERMINANT_INSTANCIATE(fmat2x3); - // DETERMINANT_INSTANCIATE(fmat2x4); - // DETERMINANT_INSTANCIATE(fmat3); - // DETERMINANT_INSTANCIATE(fmat3x2); - // DETERMINANT_INSTANCIATE(fmat3x4); - // DETERMINANT_INSTANCIATE(fmat4); - // DETERMINANT_INSTANCIATE(fmat4x2); - // DETERMINANT_INSTANCIATE(fmat4x3); - // DETERMINANT_INSTANCIATE(umat2); - // DETERMINANT_INSTANCIATE(umat2x3); - // DETERMINANT_INSTANCIATE(umat2x4); - // DETERMINANT_INSTANCIATE(umat3); - // DETERMINANT_INSTANCIATE(umat3x2); - // DETERMINANT_INSTANCIATE(umat3x4); - // DETERMINANT_INSTANCIATE(umat4); - // DETERMINANT_INSTANCIATE(umat4x2); - // DETERMINANT_INSTANCIATE(umat4x3); - // DETERMINANT_INSTANCIATE(imat2); - // DETERMINANT_INSTANCIATE(imat2x3); - // DETERMINANT_INSTANCIATE(imat2x4); - // DETERMINANT_INSTANCIATE(imat3); - // DETERMINANT_INSTANCIATE(imat3x2); - // DETERMINANT_INSTANCIATE(imat3x4); - // DETERMINANT_INSTANCIATE(imat4); - // DETERMINANT_INSTANCIATE(imat4x2); - // DETERMINANT_INSTANCIATE(imat4x3); +#ifndef STORMKIT_OS_WINDOWS + #undef STORMKIT_CORE_API + #define STORMKIT_CORE_API +#endif #define DETERMINANT_INSTANCIATE(mat_type) \ template STORMKIT_CORE_API auto determinant(const mat_type&) noexcept -> typename mat_type::value_type diff --git a/modules/stormkit/core/math/linear-vector.cppm b/modules/stormkit/core/math/linear-vector.cppm index 566e2ff0b..407d7bf1d 100644 --- a/modules/stormkit/core/math/linear-vector.cppm +++ b/modules/stormkit/core/math/linear-vector.cppm @@ -436,6 +436,11 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v return std::format_to(ctx.out(), "[vec4 x: {}, y: {}, z: {}, w: {}]", value.x, value.y, value.z, value.w); } +#ifndef STORMKIT_OS_WINDOWS + #undef STORMKIT_CORE_API + #define STORMKIT_CORE_API +#endif + #define ADD_INSTANCIATE(vec_type) \ template STORMKIT_CORE_API auto add(const vec_type&, const vec_type&) noexcept -> vec_type From f521af4b91d92aa0cc8b7ff4b06a3aa5aeae276a Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sat, 7 Feb 2026 16:55:05 +0100 Subject: [PATCH 081/194] (xmake) cleanup --- xmake.lua | 62 ----------------------------------- xmake/targets/gpu.xmake.lua | 17 ++++++++++ xmake/targets/image.xmake.lua | 10 ++++++ xmake/targets/wsi.xmake.lua | 18 ++++++++++ 4 files changed, 45 insertions(+), 62 deletions(-) diff --git a/xmake.lua b/xmake.lua index de5ef2071..d7162b9e0 100644 --- a/xmake.lua +++ b/xmake.lua @@ -56,68 +56,6 @@ end if suffix then set_suffixname(suffix) end ----------------------------- dependencies ---------------------------- -includes("xmake/packages/*.xmake.lua") - --- core -- -add_requires("frozen", { system = false, configs = { modules = true, std_import = true, cpp = "latest" } }) -add_requires("unordered_dense", { system = false, configs = { modules = true, std_import = true } }) -add_requires("tl_function_ref", { system = false, configs = { modules = true, std_import = true } }) - --- wsi -- -if get_config("wsi") then - if is_plat("linux") then - add_requires("libxcb") - add_requires("xcb-util-keysyms") - add_requires("xcb-util") - add_requires("xcb-util-image") - add_requires("xcb-util-wm") - add_requires("xcb-util-errors") - add_requires("wayland") - add_requires("wayland-protocols") - add_requires("libxkbcommon", { - system = false, - configs = { - wayland = true, - x11 = true, - }, - }) - end -end - --- image -- -if get_config("image") then - add_requires("libktx") - add_requires("libpng") - add_requires("libjpeg-turbo", is_plat("windows") and { - system = false, - configs = { - runtimes = "MD", - shared = true, - }, - }) -end - --- gpu -- -if get_config("gpu") then - local vulkan_version = "1.4.335" - add_requires("volk", { - version = vulkan_version, - system = false, - }) - add_requires("vulkan-headers", { - version = vulkan_version, - system = false, - configs = { - modules = false, - }, - }) - add_requires("vulkan-memory-allocator", { - version = "v3.3.0", - system = false, - }) -end - ---------------------------- configvar ---------------------------- for _, name in ipairs({ "log", "entities", "image", "wsi", "gpu", "lua" }) do if get_config(name) then set_configvar("STORMKIT_LIB_" .. string.upper(name) .. "_ENABLED", true) end diff --git a/xmake/targets/gpu.xmake.lua b/xmake/targets/gpu.xmake.lua index a744393a1..fed88445f 100644 --- a/xmake/targets/gpu.xmake.lua +++ b/xmake/targets/gpu.xmake.lua @@ -1,3 +1,20 @@ +local vulkan_version = "1.4.335" +add_requires("volk", { + version = vulkan_version, + system = false, +}) +add_requires("vulkan-headers", { + version = vulkan_version, + system = false, + configs = { + modules = false, + }, +}) +add_requires("vulkan-memory-allocator", { + version = "v3.3.0", + system = false, +}) + local src_gpu_dir = path.join(src_dir, "gpu") local module_gpu_dir = path.join(module_dir, "gpu") diff --git a/xmake/targets/image.xmake.lua b/xmake/targets/image.xmake.lua index ee96dd942..cbe4fccf6 100644 --- a/xmake/targets/image.xmake.lua +++ b/xmake/targets/image.xmake.lua @@ -1,3 +1,13 @@ +add_requires("libktx") +add_requires("libpng") +add_requires("libjpeg-turbo", is_plat("windows") and { + system = false, + configs = { + runtimes = "MD", + shared = true, + }, +}) + local src_image_dir = path.join(src_dir, "image") target("image", function() diff --git a/xmake/targets/wsi.xmake.lua b/xmake/targets/wsi.xmake.lua index a1be79339..3876bd8b3 100644 --- a/xmake/targets/wsi.xmake.lua +++ b/xmake/targets/wsi.xmake.lua @@ -1,3 +1,21 @@ +if is_plat("linux") then + add_requires("libxcb") + add_requires("xcb-util-keysyms") + add_requires("xcb-util") + add_requires("xcb-util-image") + add_requires("xcb-util-wm") + add_requires("xcb-util-errors") + add_requires("wayland") + add_requires("wayland-protocols") + add_requires("libxkbcommon", { + system = false, + configs = { + wayland = true, + x11 = true, + }, + }) +end + local src_wsi_dir = path.join(src_dir, "wsi") local module_wsi_dir = path.join(module_dir, "wsi") From b800bcbdb919cad337705beb01a698220b8230ff Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sat, 7 Feb 2026 17:27:53 +0100 Subject: [PATCH 082/194] (xmake) fix image xmake.lua on non-windows platforms --- xmake/targets/image.xmake.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xmake/targets/image.xmake.lua b/xmake/targets/image.xmake.lua index cbe4fccf6..78b5e71b1 100644 --- a/xmake/targets/image.xmake.lua +++ b/xmake/targets/image.xmake.lua @@ -6,7 +6,7 @@ add_requires("libjpeg-turbo", is_plat("windows") and { runtimes = "MD", shared = true, }, -}) +} or {}) local src_image_dir = path.join(src_dir, "image") From c58864af6b3911f930c35d852b35d3437404c335 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sat, 7 Feb 2026 17:32:58 +0100 Subject: [PATCH 083/194] (xmake, wsi) fix missing module for stormkit::wsi on macOS --- xmake/targets/wsi.xmake.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/xmake/targets/wsi.xmake.lua b/xmake/targets/wsi.xmake.lua index 3876bd8b3..629f2f04f 100644 --- a/xmake/targets/wsi.xmake.lua +++ b/xmake/targets/wsi.xmake.lua @@ -74,7 +74,11 @@ target("wsi", function() add_files(path.join(src_wsi_dir, "win32/**.cpp"), path.join(src_wsi_dir, "win32/**.cppm")) add_syslinks("User32", "Shell32", "Gdi32", "Shcore", "Gdiplus") elseif is_plat("macosx") then - add_files(path.join(src_wsi_dir, "macos/**.cpp"), path.join(src_wsi_dir, "macos/**.m")) + add_files( + path.join(src_wsi_dir, "macos/**.cpp"), + path.join(src_wsi_dir, "macos/**.m"), + path.join(src_wsi_dir, "macos/**.cppm") + ) add_files(path.join(src_wsi_dir, "macos/**.swift"), { public = true }) set_values("swift.modulename", "macOS") set_values("swift.interop", "cxx") From a1559694da2401281e7a5a100d9fad9a2f0ad3e0 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sat, 7 Feb 2026 17:38:18 +0100 Subject: [PATCH 084/194] (gpu) fix explicit instantiation of to/from convertion function of vulkan enumerations --- modules/stormkit/gpu/core/vulkan/enums.cppm | 5 +++++ modules/stormkit/gpu/core/vulkan/enums.mpp.tpl | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/modules/stormkit/gpu/core/vulkan/enums.cppm b/modules/stormkit/gpu/core/vulkan/enums.cppm index 31545990d..473206f60 100644 --- a/modules/stormkit/gpu/core/vulkan/enums.cppm +++ b/modules/stormkit/gpu/core/vulkan/enums.cppm @@ -3590,6 +3590,11 @@ namespace stormkit::gpu { } } // namespace stormkit::gpu +#ifndef STORMKIT_OS_WINDOWS + #undef STORMKIT_GPU_API + #define STORMKIT_GPU_API +#endif + template stormkit::gpu::AccessFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); template stormkit::gpu::AccessFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkAccessFlagBits); diff --git a/modules/stormkit/gpu/core/vulkan/enums.mpp.tpl b/modules/stormkit/gpu/core/vulkan/enums.mpp.tpl index 3105dce81..152e76dc4 100644 --- a/modules/stormkit/gpu/core/vulkan/enums.mpp.tpl +++ b/modules/stormkit/gpu/core/vulkan/enums.mpp.tpl @@ -299,6 +299,10 @@ namespace stormkit::gpu { } } +#ifndef STORMKIT_OS_WINDOWS + #undef STORMKIT_GPU_API + #define STORMKIT_GPU_API +#endif {% for name, enumeration in table.orderpairs(json_data) do %} template From 180c53acc12034761fc2c3260630d3102bda2b97 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 8 Feb 2026 00:43:10 +0100 Subject: [PATCH 085/194] (gpu, examples) fix nzsl on non windows platform --- examples/gpu/textured_cube/xmake.lua | 2 ++ examples/gpu/triangle/xmake.lua | 2 ++ 2 files changed, 4 insertions(+) diff --git a/examples/gpu/textured_cube/xmake.lua b/examples/gpu/textured_cube/xmake.lua index f58a3f1dc..e30c23e7a 100644 --- a/examples/gpu/textured_cube/xmake.lua +++ b/examples/gpu/textured_cube/xmake.lua @@ -2,6 +2,8 @@ add_requires("nzsl", { configs = { fs_watcher = false, kind = "binary", + toolchain = is_plat("windows") and "cl" or nil, + runtimes = is_plat("windows") and "MD" or nil, }, }) diff --git a/examples/gpu/triangle/xmake.lua b/examples/gpu/triangle/xmake.lua index 5d823d55e..25681d8db 100644 --- a/examples/gpu/triangle/xmake.lua +++ b/examples/gpu/triangle/xmake.lua @@ -2,6 +2,8 @@ add_requires("nzsl", { configs = { fs_watcher = false, kind = "binary", + toolchain = is_plat("windows") and "cl" or nil, + runtimes = is_plat("windows") and "MD" or nil, }, }) From 794c969b08cba634926c7bafb02ee7f04a8f3bca Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 8 Feb 2026 00:43:43 +0100 Subject: [PATCH 086/194] (lua, entities) bind entities to lua --- examples/entities/gameoflife/xmake.lua | 46 +-- examples/lua/wsi/events/lua/events.luau | 29 +- examples/lua/wsi/events/src/main.cpp | 12 +- examples/lua/wsi/events/xmake.lua | 2 - examples/wsi/framebuffer/src/main.cpp | 4 +- modules/stormkit/entities.cppm | 365 +++++++++++++----------- modules/stormkit/lua.cppm | 18 +- src/entities/entity_manager.cpp | 104 ++++--- src/entities/system.cpp | 37 ++- src/lua/entities.cpp | 98 ++++++- src/lua/lua.cpp | 129 +++++---- 11 files changed, 521 insertions(+), 323 deletions(-) diff --git a/examples/entities/gameoflife/xmake.lua b/examples/entities/gameoflife/xmake.lua index 0ca9c398b..221d097be 100644 --- a/examples/entities/gameoflife/xmake.lua +++ b/examples/entities/gameoflife/xmake.lua @@ -1,29 +1,29 @@ -if has_config("enable_gpu") and has_config("enable_wsi") and has_config("enable-image") then - target("game_of_life") - do - set_kind("binary") - set_languages("cxxlatest", "clatest") +-- if has_config("enable_gpu") and has_config("enable_wsi") and has_config("enable-image") then +-- target("game_of_life") +-- do +-- set_kind("binary") +-- set_languages("cxxlatest", "clatest") - add_packages("nzsl") - add_deps("core", "main", "log", "wsi", "gpu", "image") +-- add_packages("nzsl") +-- add_deps("core", "main", "log", "wsi", "gpu", "image") - add_rules("stormkit.utils.nzsl2spv") +-- add_rules("stormkit.utils.nzsl2spv") - if is_mode("debug") then - add_defines("STORMKIT_BUILD_DEBUG") - add_defines("STORMKIT_ASSERT=1") - set_suffixname("-d") - else - add_defines("STORMKIT_ASSERT=0") - end +-- if is_mode("debug") then +-- add_defines("STORMKIT_BUILD_DEBUG") +-- add_defines("STORMKIT_ASSERT=1") +-- set_suffixname("-d") +-- else +-- add_defines("STORMKIT_ASSERT=0") +-- end - add_files("src/*.cpp") - add_files("src/*.cppm") - add_files("shaders/*.nzsl") - if is_plat("windows") then add_files("win32/*.manifest") end +-- add_files("src/*.cpp") +-- add_files("src/*.cppm") +-- add_files("shaders/*.nzsl") +-- if is_plat("windows") then add_files("win32/*.manifest") end - add_rules("platform.windows.subsystem.windows") +-- add_rules("platform.windows.subsystem.windows") - set_group("examples/stormkit-entities") - end -end +-- set_group("examples/stormkit-entities") +-- end +-- end diff --git a/examples/lua/wsi/events/lua/events.luau b/examples/lua/wsi/events/lua/events.luau index b917ee336..1d3d62694 100644 --- a/examples/lua/wsi/events/lua/events.luau +++ b/examples/lua/wsi/events/lua/events.luau @@ -1,3 +1,4 @@ + local function main() local window = wsi.window.open("test", 800, 600, wsi.window_flag.RESIZEABLE) @@ -7,23 +8,23 @@ local function main() end) window:on_resized(function(extent) - print("Resize event:\n ", extent) + print("Resize event:\n {}", extent) end) window:on_monitor_changed(function(monitor) - print("Monitor changed event:\n ", monitor) + print("Monitor changed event:\n {}", monitor) end) window:on_mouse_moved(function(_, position) - print("Mouse move event:\n ", position) + print("Mouse move event:\n {}", position) end) window:on_mouse_button_down(function(_, button, position) - print("Mouse button down event:\n ", button, "\n ", position) + print("Mouse button down event:\n {}\n {}", button, position) end) window:on_mouse_button_up(function(_, button, position) - print("Mouse button up event:\n ", button, "\n ", position) + print("Mouse button up event:\n {}\n {}", button, position) end) window:on_restored(function() @@ -44,7 +45,7 @@ local function main() local foo = 0 window:on_key_down(function(_, key, c) - print("Key down event:\n ", key, "\n '", c) + print("Key down event: {} {}", key, c) local closures = { [wsi.key.ESCAPE] = function() @@ -58,7 +59,7 @@ local function main() end, [wsi.key.T] = function() foo = foo + 1 - window:set_title("StormKit Lua Events Example | T pressed " .. foo .. " times") + window:set_title(format("StormKit Lua Events Example | T pressed {} times", foo)) end, [wsi.key.H] = function() local extent = window:extent() @@ -67,27 +68,27 @@ local function main() end, [wsi.key.F11] = function() window:toggle_fullscreen() - print("Toggling fullscreen to", window:fullscreen()) + print("Toggling fullscreen to {}", window:fullscreen()) end, [wsi.key.F1] = function() window:toggle_hidden_mouse() - print("Toggling hidden mouse to", window:is_mouse_hidden()) + print("Toggling hidden mouse to {}", window:is_mouse_hidden()) end, [wsi.key.F2] = function() window:toggle_locked_mouse() - print("Toggling locked mouse to", window:is_mouse_locked()) + print("Toggling locked mouse to {}", window:is_mouse_locked()) end, [wsi.key.F3] = function() window:toggle_confined_mouse() - print("Toggling confined mouse to", window:is_mouse_confined()) + print("Toggling confined mouse to {}", window:is_mouse_confined()) end, [wsi.key.F4] = function() window:toggle_relative_mouse() - print("Toggling relative mouse to", window:is_mouse_relative()) + print("Toggling relative mouse to {}", window:is_mouse_relative()) end, [wsi.key.F5] = function() window:toggle_key_repeat() - print("Toggling key repeat to", window:is_key_repeat_enabled()) + print("Toggling key repeat to {}", window:is_key_repeat_enabled()) end, } @@ -100,7 +101,7 @@ local function main() end) window:on_key_up(function(_, key, c) - print("Key up event:\n ", key, "\n '", c) + print("Key up event: {} {}", key, c) end) window:event_loop(function() diff --git a/examples/lua/wsi/events/src/main.cpp b/examples/lua/wsi/events/src/main.cpp index 2b29f0bb3..884efa854 100644 --- a/examples/lua/wsi/events/src/main.cpp +++ b/examples/lua/wsi/events/src/main.cpp @@ -2,16 +2,16 @@ // This file is subject to the license terms in the LICENSE file // found in the top-level of this distribution -import std; - -import stormkit; - #include #include #include +import std; + +import stormkit; + LOGGER("lua-Events"); #ifndef RESOURCE_DIR @@ -20,7 +20,7 @@ LOGGER("lua-Events"); namespace stdfs = std::filesystem; -static const auto LUA_FILE = stdfs::path { RESOURCE_DIR } / "lua/events.luau"; +static const auto LUA_FILE = stdfs::path { RESOURCE_DIR } / stdfs::path { "lua/events.luau" }; using namespace stormkit; @@ -33,7 +33,7 @@ auto main(std::span args) -> int { auto logger = log::Logger::create_logger_instance(); auto engine = lua::Engine::create(LUA_FILE, { .wsi = true }); - auto _ = engine.lua_main().transform_error(monadic::assert("lua runtime error!\n-------------------------------\n")); + engine.lua_main(); return 0; } diff --git a/examples/lua/wsi/events/xmake.lua b/examples/lua/wsi/events/xmake.lua index ad101a6d2..28f72c434 100644 --- a/examples/lua/wsi/events/xmake.lua +++ b/examples/lua/wsi/events/xmake.lua @@ -11,8 +11,6 @@ namespace("lua", function() if get_config("devmode") then set_rundir("$(projectdir)") end - add_packages("luau", "luabridge3") - set_group("examples/stormkit-lua") end) end) diff --git a/examples/wsi/framebuffer/src/main.cpp b/examples/wsi/framebuffer/src/main.cpp index b302fc140..bd65c273d 100644 --- a/examples/wsi/framebuffer/src/main.cpp +++ b/examples/wsi/framebuffer/src/main.cpp @@ -16,7 +16,7 @@ using namespace std::literals; namespace stdr = std::ranges; -auto update_pixels(stormkit::ThreadPool& pool, std::vector>& pixels, const auto& extent) noexcept { +auto update_pixels(stormkit::ThreadPool& pool, std::vector& pixels, const auto& extent) noexcept { const auto rect_width = extent.width / 5; const auto rect_height = extent.height / 5; @@ -64,7 +64,7 @@ auto main(std::span args) -> int { ilog("wm: {}", window.wm()); auto pool = core::ThreadPool {}; - auto pixels = std::vector> {}; + auto pixels = std::vector {}; update_pixels(pool, pixels, window.extent()); auto active = true; window.on(wsi::ResizedEventFunc { [&](const math::uextent2& extent) mutable noexcept { diff --git a/modules/stormkit/entities.cppm b/modules/stormkit/entities.cppm index bb9d7a3dc..69ed70c8e 100644 --- a/modules/stormkit/entities.cppm +++ b/modules/stormkit/entities.cppm @@ -34,30 +34,24 @@ export namespace stormkit::entities { #endif }; - struct Component { - using Type = u64; - - static constexpr Type INVALID_TYPE = 0; - static constexpr Type TYPE = INVALID_TYPE; - }; + using ComponentType = u64; namespace meta { template - concept IsComponentType = core::meta::Is and requires(T&& component) { T::TYPE; }; - - template - concept IsSystem = core::meta::Is; + concept IsComponentType = requires(T&& component) { + { component.type() } -> core::meta::Is; + }; } // namespace meta template constexpr auto component_hash(std::string_view str) noexcept -> Result; - constexpr auto component_hash(CZString str, usize size) noexcept -> Component::Type; + constexpr auto component_hash(CZString str, usize size) noexcept -> ComponentType; - constexpr auto component_hash(std::string_view str) noexcept -> Component::Type; + constexpr auto component_hash(std::string_view str) noexcept -> ComponentType; namespace literals { - constexpr auto operator""_component_type(CZString str, usize size) -> Component::Type; + constexpr auto operator""_component_type(CZString str, usize size) -> ComponentType; } // namespace literals struct Message { @@ -92,9 +86,22 @@ export namespace stormkit::entities { class STORMKIT_ENTITIES_API System { public: - using ComponentTypes = HashSet; + using ComponentTypes = std::vector; + using Entities = std::vector; + + using PreUpdateClosure = std::function; + using UpdateClosure = std::function; + using PostUpdateClosure = std::function; + using OnMessageReceived = std::function; + + struct Closures { + PreUpdateClosure pre_update = monadic::noop(); + UpdateClosure update; + PostUpdateClosure post_update = monadic::noop(); + OnMessageReceived on_message_received = monadic::noop(); + }; - System(EntityManager& manager, u32 priority, ComponentTypes types); + System(std::string name, ComponentTypes types, Closures&& closures) noexcept; System(const System&) = delete; auto operator=(const System&) -> System& = delete; @@ -102,103 +109,94 @@ export namespace stormkit::entities { System(System&&) noexcept; auto operator=(System&&) noexcept -> System&; - virtual ~System(); - - virtual auto pre_update() -> void; - virtual auto update(fsecond delta) -> void = 0; - virtual auto post_update() -> void; + ~System() noexcept; [[nodiscard]] - auto priority() const noexcept -> u32; + auto name() const noexcept -> const std::string&; [[nodiscard]] auto components_used() const noexcept -> const ComponentTypes&; - auto add_entity(Entity e) -> void; - auto remove_entity(Entity e) -> void; - - struct Predicate { -#ifdef STORMKIT_COMPILER_MSVC - [[nodiscard]] - auto operator()(const std::unique_ptr& s1, const std::unique_ptr& s2) const noexcept -#else - [[nodiscard]] - static auto operator()(const std::unique_ptr& s1, const std::unique_ptr& s2) noexcept -#endif - -> bool { - return s1->priority() < s2->priority(); - } - }; + private: + auto add_entity(Entity e) noexcept -> void; + auto remove_entity(Entity e) noexcept -> void; - protected: - virtual auto on_message_received(const Message& message) -> void = 0; + auto pre_update(EntityManager&) noexcept -> void; + auto update(EntityManager&, fsecond) noexcept -> void; + auto post_update(EntityManager&) noexcept -> void; - Ref m_manager; - HashSet m_entities; + auto on_message_received(EntityManager&, const Message&) noexcept -> void; - friend class EntityManager; + std::string m_name; - private: - u32 m_priority; ComponentTypes m_types; + + Closures m_closures; + + Entities m_entities; + + friend class EntityManager; }; + struct ComponentStore {}; + class STORMKIT_ENTITIES_API EntityManager { public: static constexpr auto ADDED_ENTITY_MESSAGE_ID = 1; static constexpr auto REMOVED_ENTITY_MESSAGE_ID = 2; - explicit EntityManager(); - ~EntityManager(); + EntityManager() noexcept; + ~EntityManager() noexcept; EntityManager(const EntityManager&) = delete; auto operator=(const EntityManager&) -> EntityManager& = delete; - EntityManager(EntityManager&&); - auto operator=(EntityManager&&) -> EntityManager&; - - auto make_entity() -> Entity; - auto destroy_entity(Entity entity) -> void; - auto destroy_all_entities() -> void; - auto has_entity(Entity entity) const -> bool; + EntityManager(EntityManager&&) noexcept; + auto operator=(EntityManager&&) noexcept -> EntityManager&; - template - auto add_component(Entity entity, Args&&... args) -> T&; + auto make_entity() noexcept -> Entity; + auto destroy_entity(Entity entity) noexcept -> void; + auto destroy_all_entities() noexcept -> void; + auto has_entity(Entity entity) const noexcept -> bool; template - auto destroy_component(Entity entity) -> void; + auto add_component(Entity entity, T&& component) noexcept -> T&; - template - auto has_component(Entity entity) const -> bool; + auto destroy_component(Entity entity, std::string_view name) noexcept -> void; + auto destroy_component(Entity entity, ComponentType type) noexcept -> void; - auto has_component(Entity entity, Component::Type type) const -> bool; + auto has_component(Entity entity, std::string_view name) const noexcept -> bool; + auto has_component(Entity entity, ComponentType type) const noexcept -> bool; auto entities() const noexcept -> const std::vector&; - template - auto entities_with_component() const -> std::vector; + auto entities_with_component(ComponentType type) const noexcept -> std::vector; + auto entities_with_component(std::string_view name) const noexcept -> std::vector; template - auto getComponent(this Self& self, Entity entity) -> core::meta::ForwardConst; - - template - auto components(this Self& self, Entity entity) -> std::vector>>; + auto get_component(this Self& self, Entity entity, ComponentType type) noexcept -> core::meta::ForwardConst; + template + auto get_component(this Self& self, Entity entity, std::string_view name) noexcept -> core::meta::ForwardConst; template - auto components_of_type(this Self& self) noexcept -> std::vector>>; + auto components_of_type(this Self& self, ComponentType type) noexcept + -> std::vector>>; + template + auto components_of_type(this Self& self, std::string_view name) noexcept + -> std::vector>>; - template - auto add_system(Args&&... args) -> T&; + auto components_types_of(Entity entity) const noexcept -> std::vector; - template - auto has_system() const noexcept -> bool; + auto add_system(std::string name, System::ComponentTypes types, System::Closures&& closures) noexcept -> System&; + auto has_system(std::string_view name) const noexcept -> bool; + auto remove_system(std::string_view name) noexcept -> void; template auto systems(this Self& self) noexcept -> std::vector>>; - template - auto get_system(this Self& self) noexcept -> core::meta::ForwardConst; + template + auto get_system(this Self& self, std::string_view name) noexcept -> core::meta::ForwardConst; - auto step(fsecond delta) -> void; + auto step(fsecond delta) noexcept -> void; auto entity_count() const noexcept -> usize; @@ -207,25 +205,33 @@ export namespace stormkit::entities { private: using ComponentKey = u64; - static constexpr auto component_key_for(Entity e, Component::Type type) noexcept -> ComponentKey; - static constexpr auto is_key_entity(Entity e, ComponentKey key) noexcept -> bool; + struct Store { + ComponentType type; + usize size; + std::vector entities; + std::vector data; + std::function delete_func; + }; + + using ComponentStore = std::vector; - auto purpose_to_systems(Entity e) -> void; - auto remove_from_systems(Entity e) -> void; - auto get_needed_entities(System& system) -> void; + auto purpose_to_systems(Entity e) noexcept -> void; + auto remove_from_systems(Entity e) noexcept -> void; + auto get_needed_entities(System& system) noexcept -> void; - Entity m_next_valid_entity = 1; - std::queue m_free_entities; + Entity m_next_valid_entity = 1; - HashSet m_entities; + std::vector m_entities; + + std::vector m_free_entities; HashSet m_added_entities; HashSet m_updated_entities; HashSet m_removed_entities; - HashMap> m_registered_components_for_entities; - std::set, System::Predicate> m_systems; - HashMap> m_components; + std::vector m_systems; + + ComponentStore m_components; MessageBus m_message_bus; }; @@ -253,21 +259,21 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - constexpr auto component_hash(CZString str, usize size) noexcept -> Component::Type { + constexpr auto component_hash(CZString str, usize size) noexcept -> ComponentType { return size == 0 ? 0xcbf29ce484222325UL : (as(str[0]) ^ component_hash(std::string_view { str + 1, size - 1 })) * 0x100000001b3UL; } ///////////////////////////////////// ///////////////////////////////////// - constexpr auto component_hash(std::string_view str) noexcept -> Component::Type { + constexpr auto component_hash(std::string_view str) noexcept -> ComponentType { return component_hash(std::data(str), std::size(str)); } namespace literals { ///////////////////////////////////// ///////////////////////////////////// - constexpr auto operator""_component_type(CZString str, usize size) -> Component::Type { + constexpr auto operator""_component_type(CZString str, usize size) -> ComponentType { return stormkit::entities::component_hash(str, size); } } // namespace literals @@ -280,8 +286,8 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - inline auto System::priority() const noexcept -> u32 { - return m_priority; + inline auto System::name() const noexcept -> const std::string& { + return m_name; } ///////////////////////////////////// @@ -292,104 +298,116 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - template - auto EntityManager::add_component(Entity entity, Args&&... args) -> T& { - static_assert(T::TYPE != Component::INVALID_TYPE, "T must have T::type defined"); - + template + auto EntityManager::add_component(Entity entity, T&& component) noexcept -> T& { + using PureT = core::meta::ToPlainType; EXPECTS(has_entity(entity)); - EXPECTS(not has_component(entity)); + EXPECTS(not has_component(entity, component.type())); + + auto it = stdr::find_if(m_components, [type = component.type()](const auto& pair) noexcept { return pair.type == type; }); + if (it == stdr::cend(m_components)) + it = m_components.emplace(stdr::cend(m_components), + Store { component.type(), sizeof(PureT), {}, {}, [](auto ptr) static noexcept { + std::bit_cast(ptr)->~PureT(); + } }); - auto component = std::make_unique(std::forward(args)...); + ENSURES(it != stdr::cend(m_components)); - auto type = T::TYPE; - m_components[component_key_for(entity, type)] = std::move(component); - m_registered_components_for_entities.at(entity).emplace_back(type); + auto& [_, size, entities, components, _] = *it; + ENSURES(size == sizeof(PureT)); + + const auto old_size = stdr::size(components); + components.resize(old_size + sizeof(Entity) + size); + new (stdr::data(components) + old_size) Entity { entity }; + auto* _component = new (stdr::data(components) + sizeof(Entity) + old_size) PureT { std::forward(component) }; + + entities.emplace_back(entity); m_updated_entities.emplace(entity); - return getComponent(entity); + return *_component; } ///////////////////////////////////// ///////////////////////////////////// - template - auto EntityManager::destroy_component(Entity entity) -> void { - static_assert(T::TYPE != Component::INVALID_TYPE, "T must have T::type defined"); - - EXPECTS(has_entity(entity)); - EXPECTS(has_component(entity)); - - const auto key = component_key_for(entity, T::TYPE); - - if (m_components.find(key) != stdr::cend(m_components)) m_components.erase(key); - - m_updated_entities.emplace(entity); + inline auto EntityManager::destroy_component(Entity entity, std::string_view name) noexcept -> void { + destroy_component(entity, component_hash(name)); } ///////////////////////////////////// ///////////////////////////////////// - template - auto EntityManager::has_component(Entity entity) const -> bool { - static_assert(T::TYPE != Component::INVALID_TYPE, "T must have T::type defined"); - - return has_component(entity, T::TYPE); + inline auto EntityManager::has_component(Entity entity, std::string_view name) const noexcept -> bool { + return has_component(entity, component_hash(name)); } ///////////////////////////////////// ///////////////////////////////////// inline auto EntityManager::entities() const noexcept -> const std::vector& { - return m_entities.values(); + return m_entities; } ///////////////////////////////////// ///////////////////////////////////// - template - auto EntityManager::entities_with_component() const -> std::vector { + inline auto EntityManager::entities_with_component(ComponentType type) const noexcept -> std::vector { // clang-format off return entities() - | stdv::filter([](auto&& entity) static noexcept { return stdr::any_of(entity, T::TYPE); }) + | stdv::filter([this, type](auto entity) noexcept { return has_component(entity, type); }) | stdr::to(); // clang-format on } + ///////////////////////////////////// + ///////////////////////////////////// + inline auto EntityManager::entities_with_component(std::string_view name) const noexcept -> std::vector { + return entities_with_component(component_hash(name)); + } + ///////////////////////////////////// ///////////////////////////////////// template - auto EntityManager::getComponent(this Self& self, Entity entity) -> core::meta::ForwardConst { - EXPECTS(self.template has_component(entity)); + auto EntityManager::get_component(this Self& self, Entity entity, ComponentType type) noexcept + -> core::meta::ForwardConst { EXPECTS(self.has_entity(entity)); + EXPECTS(self.has_component(entity, type)); + + auto it = stdr::find_if(self.m_components, [&type](const auto& pair) noexcept { return pair.type == type; }); + ENSURES(it != stdr::cend(self.m_components)); + + auto& [_, size, _, components, _] = *it; + + auto component_it = stdr::data(components); + for (;;) { + auto e = *std::bit_cast(component_it); + if (e != entity) { + component_it += sizeof(Entity) + size; + continue; + } + + component_it += sizeof(Entity); - const auto key = component_key_for(entity, T::TYPE); - return *std::bit_cast(self.m_components.at(key).get()); + break; + } + return std::forward_like(*std::bit_cast(component_it)); } ///////////////////////////////////// ///////////////////////////////////// - template - auto EntityManager::components(this Self& self, Entity entity) - -> std::vector>> { - if (not self.has_entity(entity)) [[unlikely]] - return {}; - // clang-format off - return self.m_components - | stdv::filter([entity](auto&& pair) noexcept { - return EntityManager::is_key_entity(entity, pair.first); - }) - | stdv::values - | stdv::transform(monadic::as_ref()) - | stdr::to(); - // clang-format on + template + auto EntityManager::get_component(this Self& self, Entity entity, std::string_view name) noexcept + -> core::meta::ForwardConst { + return self.template get_component(entity, component_hash(name)); } ///////////////////////////////////// ///////////////////////////////////// template - auto EntityManager::components_of_type(this Self& self) noexcept -> std::vector>> { + auto EntityManager::components_of_type(this Self& self, ComponentType type) noexcept + -> std::vector>> { // clang-format off return self.m_entities - | stdv::filter(bind_front(&EntityManager::has_component, &self)) - | stdv::transform(bind_front(&EntityManager::getComponent, &self)) - | stdv::transform(monadic::forward_like()) + | stdv::filter([&self, type](auto entity) noexcept { return self.has_component(entity, type); }) + | stdv::transform([&self, type](auto entity) noexcept { return self.template get_component(entity, type); }) + | stdv::transform(monadic::forward_like()) | stdv::transform(monadic::as_ref()) | stdr::to(); // clang-format on @@ -397,11 +415,33 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - template - auto EntityManager::add_system(Args&&... args) -> T& { - m_systems.emplace(std::make_unique(std::forward(args)..., *this)); + template + auto EntityManager::components_of_type(this Self& self, std::string_view name) noexcept + -> std::vector>> { + return self.template components_of_type(component_hash(name)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto EntityManager::components_types_of(Entity entity) const noexcept -> std::vector { + EXPECTS(has_entity(entity)); - auto& system = get_system(); + auto out = std::vector {}; + for (auto&& [type, _, entities, _, _] : m_components) { + for (auto e : entities) + if (e == entity) { + out.emplace_back(type); + break; + } + } + return out; + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto EntityManager::add_system(std::string name, System::ComponentTypes types, System::Closures&& closures) noexcept + -> System& { + auto& system = m_systems.emplace_back(std::move(name), std::move(types), std::move(closures)); get_needed_entities(system); @@ -410,9 +450,15 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - template - auto EntityManager::has_system() const noexcept -> bool { - return stdr::any_of(m_systems, monadic::is()); + inline auto EntityManager::has_system(std::string_view name) const noexcept -> bool { + return stdr::any_of(m_systems, [name](const auto& system) noexcept { return system.name() == name; }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + inline auto EntityManager::remove_system(std::string_view name) noexcept -> void { + auto&& [begin, end] = stdr::remove_if(m_systems, [&name](const auto& system) { return name == system.name(); }); + m_systems.erase(begin, end); } ///////////////////////////////////// @@ -430,13 +476,12 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - template - auto EntityManager::get_system(this Self& self) noexcept -> core::meta::ForwardConst { - EXPECTS(self.template has_system()); - - auto it = stdr::find_if(self.m_systems, monadic::is()); + template + auto EntityManager::get_system(this Self& self, std::string_view name) noexcept -> core::meta::ForwardConst { + EXPECTS(self.has_system(name)); - return as>(*it->get()); + auto it = stdr::find_if(self.m_systems, [name](const auto& system) noexcept { return system.name() == name; }); + return std::forward_like(*it->get()); } ///////////////////////////////////// @@ -444,16 +489,4 @@ namespace stormkit::entities { inline auto EntityManager::entity_count() const noexcept -> usize { return std::size(m_entities); } - - ///////////////////////////////////// - ///////////////////////////////////// - constexpr auto EntityManager::component_key_for(Entity e, Component::Type type) noexcept -> ComponentKey { - return (static_cast(e) << 32) | static_cast(type); - } - - ///////////////////////////////////// - ///////////////////////////////////// - constexpr auto EntityManager::is_key_entity(Entity e, ComponentKey type) noexcept -> bool { - return static_cast(e) == (type >> 32); - } } // namespace stormkit::entities diff --git a/modules/stormkit/lua.cppm b/modules/stormkit/lua.cppm index 83a2cfd1a..2aa6a45df 100644 --- a/modules/stormkit/lua.cppm +++ b/modules/stormkit/lua.cppm @@ -38,7 +38,7 @@ export namespace stormkit::lua { Engine(Engine&& other) noexcept; auto operator=(Engine&& other) noexcept -> Engine&; - auto lua_main() noexcept -> std::expected; + auto lua_main() noexcept -> void; template auto global_state(this T& self) noexcept -> decltype(auto); @@ -53,6 +53,9 @@ export namespace stormkit::lua { sol::state m_global_state; sol::load_result m_script; }; + + template + auto luacall(const sol::protected_function& function, Args&&... args) noexcept -> decltype(function()); } // namespace stormkit::lua //////////////////////////////////////////////////////////////////// @@ -74,4 +77,17 @@ namespace stormkit::lua { inline auto Engine::global_state(this T& self) noexcept -> decltype(auto) { return std::forward_like(self.m_global_state); } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto luacall(const sol::protected_function& function, Args&&... args) noexcept -> decltype(function()) { + auto result = function(std::forward(args)...); + if (not result.valid()) + ensures(false, + std::format("lua runtime error!\n-----------------------------------------\n{}", + sol::error { result }.what())); + return result; + } } // namespace stormkit::lua diff --git a/src/entities/entity_manager.cpp b/src/entities/entity_manager.cpp index b3619ddbb..92f27a8e3 100644 --- a/src/entities/entity_manager.cpp +++ b/src/entities/entity_manager.cpp @@ -18,35 +18,34 @@ namespace stdv = std::views; namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - EntityManager::EntityManager() = default; + EntityManager::EntityManager() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - EntityManager::EntityManager(EntityManager&&) = default; + EntityManager::EntityManager(EntityManager&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - auto EntityManager::operator=(EntityManager&&) -> EntityManager& = default; + auto EntityManager::operator=(EntityManager&&) noexcept -> EntityManager& = default; ///////////////////////////////////// ///////////////////////////////////// - EntityManager::~EntityManager() = default; + EntityManager::~EntityManager() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - auto EntityManager::make_entity() -> Entity { + auto EntityManager::make_entity() noexcept -> Entity { const auto entity = [this]() { if (stdr::empty(m_free_entities)) return m_next_valid_entity++; else { - auto entity = m_free_entities.front(); - m_free_entities.pop(); + auto entity = m_free_entities.back(); + m_free_entities.pop_back(); return entity; } }(); m_added_entities.emplace(entity); m_updated_entities.emplace(entity); - m_registered_components_for_entities[entity] = {}; m_message_bus.push(Message { ADDED_ENTITY_MESSAGE_ID, { entity } }); return entity; @@ -54,7 +53,7 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - auto EntityManager::destroy_entity(Entity entity) -> void { + auto EntityManager::destroy_entity(Entity entity) noexcept -> void { EXPECTS(entity != INVALID_ENTITY); if (has_entity(entity)) { @@ -65,7 +64,7 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - auto EntityManager::destroy_all_entities() -> void { + auto EntityManager::destroy_all_entities() noexcept -> void { for (auto&& e : entities()) { m_removed_entities.emplace(e); m_message_bus.push(Message { REMOVED_ENTITY_MESSAGE_ID, { e } }); @@ -74,7 +73,7 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - auto EntityManager::has_entity(Entity entity) const -> bool { + auto EntityManager::has_entity(Entity entity) const noexcept -> bool { EXPECTS(entity != INVALID_ENTITY); return stdr::any_of(entities(), monadic::is_equal(entity)) or stdr::any_of(m_added_entities, monadic::is_equal(entity)); @@ -82,50 +81,85 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - auto EntityManager::has_component(Entity entity, Component::Type type) const -> bool { - EXPECTS(entity != INVALID_ENTITY and type != Component::INVALID_TYPE); + auto EntityManager::destroy_component(Entity entity, ComponentType type) noexcept -> void { + EXPECTS(has_entity(entity)); + EXPECTS(has_component(entity, type)); - return stdr::any_of(m_registered_components_for_entities.at(entity), monadic::is_equal(type)); + auto it = stdr::find_if(m_components, [type](const auto& pair) noexcept { return pair.type == type; }); + ENSURES(it == stdr::cend(m_components)); + + auto& [_, size, entities, components, delete_func] = *it; + auto component_it = stdr::begin(components); + for (;;) { + auto e = *std::bit_cast(&*component_it); + if (e != entity) { + component_it += as(sizeof(Entity) + size); + continue; + } + + component_it += sizeof(Entity); + + break; + } + delete_func(&*component_it); + + components.erase(component_it - as(sizeof(Entity)), component_it + as(size)); + + auto&& [begin, end] = stdr::remove(entities, entity); + entities.erase(begin, end); + + m_updated_entities.emplace(entity); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto EntityManager::has_component(Entity entity, ComponentType type) const noexcept -> bool { + EXPECTS(entity != INVALID_ENTITY); + + auto it = stdr::find_if(m_components, [&type](const auto& pair) noexcept { return pair.type == type; }); + if (it == stdr::cend(m_components)) return false; + + auto& [_, size, entities, _, _] = *it; + + return stdr::any_of(entities, monadic::is_equal(entity)); } ///////////////////////////////////// ///////////////////////////////////// - auto EntityManager::step(fsecond delta) -> void { + auto EntityManager::step(fsecond delta) noexcept -> void { for (auto entity : m_removed_entities) { - auto it = m_registered_components_for_entities.find(entity); - // a this point, all entities should be valid - ensures(it != stdr::cend(m_registered_components_for_entities)); + const auto components_types = components_types_of(entity); - for (auto&& key : it->second | stdv::transform([entity](auto&& type) { return component_key_for(entity, type); })) - m_components.erase(key); + for (auto t : components_types) destroy_component(entity, t); - m_entities.erase(entity); + auto&& [begin, end] = stdr::remove(m_entities, entity); + m_entities.erase(begin, end); remove_from_systems(entity); - if (not stdr::any_of(m_added_entities, monadic::is_equal(entity))) m_free_entities.push(entity); + if (not stdr::any_of(m_added_entities, monadic::is_equal(entity))) m_free_entities.emplace_back(entity); } m_removed_entities.clear(); - stdr::for_each(m_added_entities, [this](auto&& entity) { m_entities.emplace(entity); }); + stdr::for_each(m_added_entities, [this](auto&& entity) noexcept { m_entities.emplace_back(entity); }); m_added_entities.clear(); - stdr::for_each(m_updated_entities, [this](auto&& entity) { purpose_to_systems(entity); }); + stdr::for_each(m_updated_entities, [this](auto&& entity) noexcept { purpose_to_systems(entity); }); m_updated_entities.clear(); while (!m_message_bus.empty()) { - for (auto& system : m_systems) system->on_message_received(m_message_bus.top()); + for (auto& system : m_systems) system.on_message_received(*this, m_message_bus.top()); m_message_bus.pop(); } - for (auto& system : m_systems) system->pre_update(); - for (auto& system : m_systems) system->update(delta); - for (auto& system : m_systems) system->post_update(); + for (auto& system : m_systems) system.pre_update(*this); + for (auto& system : m_systems) system.update(*this, delta); + for (auto& system : m_systems) system.post_update(*this); } ///////////////////////////////////// ///////////////////////////////////// - auto EntityManager::purpose_to_systems(Entity e) -> void { + auto EntityManager::purpose_to_systems(Entity e) noexcept -> void { EXPECTS(e != INVALID_ENTITY); const auto reliable_system_filter = [e, this](auto&& system) { @@ -135,27 +169,27 @@ namespace stormkit::entities { return true; }; - stdr::for_each(systems() | stdv::filter(reliable_system_filter), [e](auto&& system) { system->add_entity(e); }); + stdr::for_each(systems() | stdv::filter(reliable_system_filter), [e](auto&& system) noexcept { system->add_entity(e); }); } ///////////////////////////////////// ///////////////////////////////////// - auto EntityManager::remove_from_systems(Entity e) -> void { + auto EntityManager::remove_from_systems(Entity e) noexcept -> void { EXPECTS(e != INVALID_ENTITY); - for (auto& s : m_systems) { s->remove_entity(e); } + for (auto& s : m_systems) { s.remove_entity(e); } } ///////////////////////////////////// ///////////////////////////////////// - auto EntityManager::get_needed_entities(System& system) -> void { - const auto reliable_entity_filter = [&system, this](auto&& entity) { + auto EntityManager::get_needed_entities(System& system) noexcept -> void { + const auto reliable_entity_filter = [&system, this](auto&& entity) noexcept { for (auto component_type : system.components_used()) if (not has_component(entity, component_type)) return false; return true; }; - stdr::for_each(entities() | stdv::filter(reliable_entity_filter), [&system](auto&& e) { system.add_entity(e); }); + stdr::for_each(entities() | stdv::filter(reliable_entity_filter), [&system](auto&& e) noexcept { system.add_entity(e); }); } } // namespace stormkit::entities diff --git a/src/entities/system.cpp b/src/entities/system.cpp index 43f67c976..dc5257ff6 100644 --- a/src/entities/system.cpp +++ b/src/entities/system.cpp @@ -15,8 +15,8 @@ import stormkit.core; namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - System::System(EntityManager& manager, u32 priority, ComponentTypes types) - : m_manager { as_ref(manager) }, m_priority { priority }, m_types { std::move(types) } { + System::System(std::string name, ComponentTypes types, Closures&& closures) noexcept + : m_name { std::move(name) }, m_types { std::move(types) }, m_closures { std::move(closures) } { } ///////////////////////////////////// @@ -29,31 +29,46 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - System::~System() = default; + System::~System() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - auto System::pre_update() -> void { + auto System::add_entity(Entity e) noexcept -> void { + EXPECTS(e != INVALID_ENTITY); + + m_entities.emplace_back(e); } ///////////////////////////////////// ///////////////////////////////////// - auto System::post_update() -> void { + auto System::remove_entity(Entity e) noexcept -> void { + EXPECTS(e != INVALID_ENTITY); + + const auto [begin, end] = stdr::remove(m_entities, e); + m_entities.erase(begin, end); } ///////////////////////////////////// ///////////////////////////////////// - auto System::add_entity(Entity e) -> void { - EXPECTS(e != INVALID_ENTITY); + auto System::pre_update(EntityManager& manager) noexcept -> void { + m_closures.pre_update(manager, m_entities); + } - m_entities.insert(e); + ///////////////////////////////////// + ///////////////////////////////////// + auto System::update(EntityManager& manager, fsecond delta) noexcept -> void { + m_closures.update(manager, delta, m_entities); } ///////////////////////////////////// ///////////////////////////////////// - auto System::remove_entity(Entity e) -> void { - EXPECTS(e != INVALID_ENTITY); + auto System::post_update(EntityManager& manager) noexcept -> void { + m_closures.post_update(manager, m_entities); + } - m_entities.erase(e); + ///////////////////////////////////// + ///////////////////////////////////// + auto System::on_message_received(EntityManager& manager, const Message& message) noexcept -> void { + m_closures.on_message_received(manager, message, m_entities); } } // namespace stormkit::entities diff --git a/src/lua/entities.cpp b/src/lua/entities.cpp index cc2f597b8..90cd52645 100644 --- a/src/lua/entities.cpp +++ b/src/lua/entities.cpp @@ -13,9 +13,105 @@ import std; import stormkit.core; import stormkit.entities; +namespace stdr = std::ranges; +namespace stdv = std::views; + namespace stormkit::lua::entities { + using stormkit::entities::component_hash; + using stormkit::entities::ComponentType; + using stormkit::entities::Entity; + using stormkit::entities::EntityManager; + using stormkit::entities::System; + + struct LuaComponent { + sol::table data; + ComponentType _type; + + auto type() const noexcept -> ComponentType { return _type; } + }; + + //////////////////////////////////////// + //////////////////////////////////////// + auto bind_manager(sol::table& entities) noexcept -> void { + const auto engine = false; + + auto manager = [&entities, &engine]() { + if (engine) return entities.new_usertype("manager", sol::no_constructor); + else + return entities.new_usertype("manager"); + }(/*config.engine*/); + + manager["make_entity"] = &EntityManager::make_entity; + manager["destroy_entity"] = &EntityManager::destroy_entity; + manager["destroy_all_entities"] = &EntityManager::destroy_all_entities; + manager["has_entity"] = &EntityManager::has_entity; + manager["add_component"] = +[](EntityManager* manager, Entity entity, sol::table component) static noexcept { + const auto type_closure = component.get>("type"); + ensures(type_closure.has_value(), "Missing type() function on lua component"); + + const auto type = sol::protected_function { *type_closure }; + const auto result = luacall(type); + auto value = sol::object { result }; + ensures(value.is(), "type() function of lua component must return a string value"); + + const auto component_str = value.as(); + + manager->add_component(entity, + LuaComponent { .data = std::move(component), + ._type = component_hash(component_str) }); + }; + manager["get_component"] = +[](EntityManager* manager, Entity entity, std::string_view name) static noexcept { + return manager->get_component(entity, name).data; + }; + manager["has_component"] = +[](EntityManager* manager, Entity entity, std::string_view name) static noexcept { + return manager->has_component(entity, name); + }; + manager["entities"] = &EntityManager::entities; + manager["entity_count"] = &EntityManager::entity_count; + manager["components_types_of"] = &EntityManager::components_types_of; + manager["add_system"] = +[](EntityManager* manager, + std::string name, + std::vector types, + sol::table opt) static noexcept { + auto update = opt.get>("update"); + expects(update.has_value(), std::format("No update closure supplied for system {}", name)); + + auto _closures = System::Closures { + .update = + [update = *std::move(update)](auto& manager, auto delta, const auto& entities) { + luacall(update, manager, delta.count(), sol::as_table(entities)); + }, + }; + + auto pre_update = opt.get>("pre_update"); + if (pre_update.has_value()) + _closures.pre_update = [pre_update = *std::move(pre_update)](auto& manager, const auto& entities) { + luacall(pre_update, manager, sol::as_table(entities)); + }; + auto post_update = opt.get>("post_update"); + if (post_update.has_value()) + _closures.post_update = [post_update = *std::move(post_update)](auto& manager, const auto& entities) { + luacall(post_update, manager, sol::as_table(entities)); + }; + + manager->add_system(std::move(name), + types | stdv::transform([](const auto& type) static noexcept { + return component_hash(type); + }) | stdr::to(), + std::move(_closures)); + }; + manager["has_system"] = &EntityManager::has_system; + manager["remove_system"] = &EntityManager::remove_system; + + if (not engine) { + manager["step"] = +[](EntityManager* manager, float delta) static noexcept { manager->step(fsecond { delta }); }; + } + } + //////////////////////////////////////// //////////////////////////////////////// - auto init_lua(sol::state&) noexcept -> void { + auto init_lua(sol::state& global_state) noexcept -> void { + auto entities = global_state["entities"].get_or_create(); + bind_manager(entities); } } // namespace stormkit::lua::entities diff --git a/src/lua/lua.cpp b/src/lua/lua.cpp index ac709d5cd..3b7e3072a 100644 --- a/src/lua/lua.cpp +++ b/src/lua/lua.cpp @@ -49,13 +49,69 @@ namespace stormkit::lua { //////////////////////////////////////// //////////////////////////////////////// Engine::Engine(Modules modules) noexcept { - m_global_state.open_libraries(sol::lib::base); - m_global_state.open_libraries(sol::lib::bit32); - m_global_state.open_libraries(sol::lib::debug); - m_global_state.open_libraries(sol::lib::io); - m_global_state.open_libraries(sol::lib::os); - m_global_state.open_libraries(sol::lib::string); - m_global_state.open_libraries(sol::lib::table); + for (auto lib : { + sol::lib::base, + sol::lib::bit32, + sol::lib::debug, + sol::lib::io, + sol::lib::os, + sol::lib::string, + sol::lib::table, + }) + m_global_state.open_libraries(lib); + + auto tostring = sol::protected_function { m_global_state["tostring"] }; + m_global_state["tostring"] = [format = std::move(tostring)](sol::object v) noexcept { + if (not v.valid()) return std::string {}; + if (v.is()) { + auto out = std::string { "[lua_table " }; + for (auto&& [key, value] : v.as()) { + auto key_as_string = sol::object { luacall(format, key) }.as(); + auto value_as_string = sol::object { luacall(format, value) }.as(); + out += key_as_string; + out += ": "; + out += value_as_string; + out += ", "; + } + out = out.substr(0, stdr::size(out) - 2); + out += "]"; + return out; + } + return sol::object { luacall(format, v) }.as(); + }; + m_global_state["print"] = [this](std::string_view str, sol::variadic_args args) noexcept { + const auto format = sol::protected_function { m_global_state["format"] }; + const auto result = luacall(format, str, std::move(args)); + const auto out = sol::object { result }.as(); + std::println("{}", out); + }; + + m_global_state["format"] = [this](std::string_view str, sol::variadic_args args) noexcept { + auto slices = split(str, "{}"); + if (stdr::size(slices) == 1) { return std::format("{}", str); } + + expects(args.size() == stdr::size(slices) - 1, + std::format("Invalid count of args! should be {}, got {}", stdr::size(slices) - 1, args.size())); + + auto out = std::string {}; + out.reserve(stdr::size(str)); + auto it = stdr::begin(slices); + out += *it; + ++it; + for (auto v : args) { + auto format = sol::protected_function { m_global_state["tostring"] }; + const auto result = luacall(m_global_state["tostring"], v); + out += sol::object { result }.as(); + + out += *it; + ++it; + + if (it == stdr::cend(slices)) break; + } + + return out; + }; + core::init_lua(m_global_state); if (modules.log) { #if STORMKIT_LIB_LOG_ENABLED @@ -115,64 +171,13 @@ namespace stormkit::lua { //////////////////////////////////////// auto Engine::load(const stdfs::path& file) noexcept -> void { const auto code = TryAssert(io::read_text(file), std::format("Failed to load {}", file.string())); - - m_script = m_global_state.load(std::string_view { stdr::data(code), stdr::size(code) }); - - // auto bytecode_size = 0_usize; - // auto bytecode = luau_compile(stdr::data(data), stdr::size(data), nullptr, &bytecode_size); - // auto result = luau_load(m_global_state, "main", bytecode, bytecode_size, 0); - // std::free(bytecode); - - // if (result != 0) { - // auto len = usize { 0 }; - // auto msg = lua_tolstring(m_global_state, -1, &len); - - // ensures(result == 0, - // std::format("Lua compilation error!\n-------------------------------\n{}", std::string_view { msg, len })); - // } - - // m_main_thread = lua_newthread(m_global_state); - // ensures(m_main_thread); - - // lua_pushvalue(m_global_state, -2); - // lua_remove(m_global_state, -3); - // lua_xmove(m_global_state, m_main_thread, 1); + m_script = m_global_state.load(std::string_view { stdr::data(code), stdr::size(code) }); } //////////////////////////////////////// //////////////////////////////////////// - auto Engine::lua_main() noexcept -> std::expected { - // EXPECTS(m_main_thread); - - auto out = std::expected {}; - - // traceback(m_global_state); - - // luaL_sandbox(m_global_state); - // luaL_sandboxthread(m_global_state); - - // auto status = lua_resume(m_global_state, nullptr, 0); - // if (status == 0) { - // // if (const auto n = lua_gettop(m_global_state); n) { - // // luaL_checkstack(m_global_state, LUA_MINSTACK, "too many results to print"); - // // lua_getglobal(m_global_state, "print"); - // // lua_insert(m_global_state, 1); - // // lua_pcall(m_global_state, n, 0, 0); - // // } - - // // lua_pop(m_global_state, 1); - // } else { - // traceback(m_global_state); - // auto error = std::string { lua_tostring(m_global_state, -1) }; - // out = std::unexpected { std::move(error) }; - // } - - // return out; - auto result = m_script(); - if (not result.valid()) { - const auto err = sol::error { result }; - out = std::unexpected { err.what() }; - } - return out; + auto Engine::lua_main() noexcept -> void { + const auto function = sol::protected_function { m_script }; + luacall(function); } } // namespace stormkit::lua From 3dabf5d236d5d20296ecdf7431d866565b514b48 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 8 Feb 2026 01:30:01 +0100 Subject: [PATCH 087/194] (log, lua) bind log to lua engine --- examples/lua/wsi/events/src/main.cpp | 2 +- src/lua/log.cpp | 37 +++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/examples/lua/wsi/events/src/main.cpp b/examples/lua/wsi/events/src/main.cpp index 884efa854..3dcbe2cd4 100644 --- a/examples/lua/wsi/events/src/main.cpp +++ b/examples/lua/wsi/events/src/main.cpp @@ -32,7 +32,7 @@ auto main(std::span args) -> int { auto logger = log::Logger::create_logger_instance(); - auto engine = lua::Engine::create(LUA_FILE, { .wsi = true }); + auto engine = lua::Engine::create(LUA_FILE, { .log = true, .wsi = true }); engine.lua_main(); return 0; diff --git a/src/lua/log.cpp b/src/lua/log.cpp index 67bb86ab8..986ba74af 100644 --- a/src/lua/log.cpp +++ b/src/lua/log.cpp @@ -6,6 +6,8 @@ module; #include +#include + module stormkit.lua; import std; @@ -13,7 +15,40 @@ import std; import stormkit.core; import stormkit.log; +LOGGER("lua") + namespace stormkit::lua::log { - auto init_lua(sol::state&) noexcept -> void { + auto init_lua(sol::state& global_state) noexcept -> void { + auto log_table = global_state["log"].get_or_create(); + log_table["info"] = [&global_state](std::string_view str, sol::variadic_args args) noexcept { + const auto format = sol::protected_function { global_state["format"] }; + const auto result = luacall(format, str, std::move(args)); + const auto out = sol::object { result }.as(); + ilog("{}", out); + }; + log_table["debug"] = [&global_state](std::string_view str, sol::variadic_args args) noexcept { + const auto format = sol::protected_function { global_state["format"] }; + const auto result = luacall(format, str, std::move(args)); + const auto out = sol::object { result }.as(); + dlog("{}", out); + }; + log_table["error"] = [&global_state](std::string_view str, sol::variadic_args args) noexcept { + const auto format = sol::protected_function { global_state["format"] }; + const auto result = luacall(format, str, std::move(args)); + const auto out = sol::object { result }.as(); + elog("{}", out); + }; + log_table["fatal"] = [&global_state](std::string_view str, sol::variadic_args args) noexcept { + const auto format = sol::protected_function { global_state["format"] }; + const auto result = luacall(format, str, std::move(args)); + const auto out = sol::object { result }.as(); + flog("{}", out); + }; + log_table["warning"] = [&global_state](std::string_view str, sol::variadic_args args) noexcept { + const auto format = sol::protected_function { global_state["format"] }; + const auto result = luacall(format, str, std::move(args)); + const auto out = sol::object { result }.as(); + wlog("{}", out); + }; } } // namespace stormkit::lua::log From ebd238c167efe307f7f5d4dcd401697d327ebefe Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 8 Feb 2026 01:36:08 +0100 Subject: [PATCH 088/194] (entities, lua) fix warning --- src/lua/entities.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lua/entities.cpp b/src/lua/entities.cpp index 90cd52645..512f657c8 100644 --- a/src/lua/entities.cpp +++ b/src/lua/entities.cpp @@ -33,10 +33,10 @@ namespace stormkit::lua::entities { //////////////////////////////////////// //////////////////////////////////////// auto bind_manager(sol::table& entities) noexcept -> void { - const auto engine = false; + auto no_constructor = false; - auto manager = [&entities, &engine]() { - if (engine) return entities.new_usertype("manager", sol::no_constructor); + auto manager = [&entities, no_constructor]() { + if (no_constructor) return entities.new_usertype("manager", sol::no_constructor); else return entities.new_usertype("manager"); }(/*config.engine*/); @@ -103,7 +103,7 @@ namespace stormkit::lua::entities { manager["has_system"] = &EntityManager::has_system; manager["remove_system"] = &EntityManager::remove_system; - if (not engine) { + if (not no_constructor) { manager["step"] = +[](EntityManager* manager, float delta) static noexcept { manager->step(fsecond { delta }); }; } } From 21381101b71dee17f8ebd66c9c508537dcea8bf5 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 8 Feb 2026 02:19:40 +0100 Subject: [PATCH 089/194] (lua) fix pointer invalidation bugs --- modules/stormkit/lua.cppm | 43 ++++++++++++++---------- src/lua/lua.cpp | 71 +++++++++++++++++---------------------- 2 files changed, 55 insertions(+), 59 deletions(-) diff --git a/modules/stormkit/lua.cppm b/modules/stormkit/lua.cppm index 2aa6a45df..6e9f106cc 100644 --- a/modules/stormkit/lua.cppm +++ b/modules/stormkit/lua.cppm @@ -30,6 +30,7 @@ export namespace stormkit::lua { class STORMKIT_LUA_API Engine { public: + using InitUserLibrariesClosure = FunctionRef; ~Engine() noexcept; Engine(const Engine&) = delete; @@ -38,20 +39,16 @@ export namespace stormkit::lua { Engine(Engine&& other) noexcept; auto operator=(Engine&& other) noexcept -> Engine&; - auto lua_main() noexcept -> void; - - template - auto global_state(this T& self) noexcept -> decltype(auto); - - static auto create(const stdfs::path& file, Modules modules = {}) noexcept -> Engine; + static auto create(stdfs::path file, + Modules modules = {}, + InitUserLibrariesClosure init_user_libraries = monadic::noop()) noexcept -> Engine; private: - explicit Engine(Modules) noexcept; + Engine() noexcept; - auto load(const stdfs::path&) noexcept -> void; + auto load(stdfs::path&&, Modules&&, InitUserLibrariesClosure&&) noexcept -> void; - sol::state m_global_state; - sol::load_result m_script; + auto init_libraries(Modules&&, sol::state&) noexcept -> void; }; template @@ -65,17 +62,27 @@ export namespace stormkit::lua { namespace stormkit::lua { //////////////////////////////////////// //////////////////////////////////////// - inline auto Engine::create(const stdfs::path& file, Modules modules) noexcept -> Engine { - auto engine = Engine { std::move(modules) }; - engine.load(file); - return engine; - } + inline Engine::Engine() noexcept = default; + + //////////////////////////////////////// + //////////////////////////////////////// + inline Engine::Engine(Engine&& other) noexcept = default; //////////////////////////////////////// //////////////////////////////////////// - template - inline auto Engine::global_state(this T& self) noexcept -> decltype(auto) { - return std::forward_like(self.m_global_state); + inline auto Engine::operator=(Engine&& other) noexcept -> Engine& = default; + + //////////////////////////////////////// + //////////////////////////////////////// + inline Engine::~Engine() noexcept = default; + + //////////////////////////////////////// + //////////////////////////////////////// + inline auto Engine::create(stdfs::path file, Modules modules, InitUserLibrariesClosure init_user_libraries) noexcept + -> Engine { + auto engine = Engine {}; + engine.load(std::move(file), std::move(modules), std::move(init_user_libraries)); + return engine; } //////////////////////////////////////// diff --git a/src/lua/lua.cpp b/src/lua/lua.cpp index 3b7e3072a..299b67645 100644 --- a/src/lua/lua.cpp +++ b/src/lua/lua.cpp @@ -48,7 +48,22 @@ LOGGER("stormkit.lua") namespace stormkit::lua { //////////////////////////////////////// //////////////////////////////////////// - Engine::Engine(Modules modules) noexcept { + auto Engine::load(stdfs::path&& file, Modules&& modules, InitUserLibrariesClosure&& init_user_libraries) noexcept -> void { + auto global_state = sol::state {}; + + init_libraries(std::move(modules), global_state); + init_user_libraries(global_state); + + const auto code = TryAssert(io::read_text(file), std::format("Failed to load {}", file.string())); + const auto script = global_state.load(std::string_view { stdr::data(code), stdr::size(code) }); + const auto function = sol::protected_function { script }; + + luacall(function); + } + + //////////////////////////////////////// + //////////////////////////////////////// + auto Engine::init_libraries(Modules&& modules, sol::state& global_state) noexcept -> void { for (auto lib : { sol::lib::base, sol::lib::bit32, @@ -58,10 +73,10 @@ namespace stormkit::lua { sol::lib::string, sol::lib::table, }) - m_global_state.open_libraries(lib); + global_state.open_libraries(lib); - auto tostring = sol::protected_function { m_global_state["tostring"] }; - m_global_state["tostring"] = [format = std::move(tostring)](sol::object v) noexcept { + auto tostring = sol::protected_function { global_state["tostring"] }; + global_state["tostring"] = [format = std::move(tostring)](sol::object v) noexcept { if (not v.valid()) return std::string {}; if (v.is()) { auto out = std::string { "[lua_table " }; @@ -79,14 +94,14 @@ namespace stormkit::lua { } return sol::object { luacall(format, v) }.as(); }; - m_global_state["print"] = [this](std::string_view str, sol::variadic_args args) noexcept { - const auto format = sol::protected_function { m_global_state["format"] }; + global_state["print"] = [&global_state](std::string_view str, sol::variadic_args args) noexcept { + const auto format = sol::protected_function { global_state["format"] }; const auto result = luacall(format, str, std::move(args)); const auto out = sol::object { result }.as(); std::println("{}", out); }; - m_global_state["format"] = [this](std::string_view str, sol::variadic_args args) noexcept { + global_state["format"] = [&global_state](std::string_view str, sol::variadic_args args) noexcept { auto slices = split(str, "{}"); if (stdr::size(slices) == 1) { return std::format("{}", str); } @@ -99,8 +114,8 @@ namespace stormkit::lua { out += *it; ++it; for (auto v : args) { - auto format = sol::protected_function { m_global_state["tostring"] }; - const auto result = luacall(m_global_state["tostring"], v); + auto format = sol::protected_function { global_state["tostring"] }; + const auto result = luacall(global_state["tostring"], v); out += sol::object { result }.as(); out += *it; @@ -112,11 +127,11 @@ namespace stormkit::lua { return out; }; - core::init_lua(m_global_state); + core::init_lua(global_state); if (modules.log) { #if STORMKIT_LIB_LOG_ENABLED dlog("Log module enabled"); - log::init_lua(m_global_state); + log::init_lua(global_state); #else elog("Trying to bind log module while disabled in this stormkit distribution!"); #endif @@ -124,7 +139,7 @@ namespace stormkit::lua { if (modules.entities) { #if STORMKIT_LIB_ENTITIES_ENABLED dlog("Entities module enabled"); - entities::init_lua(m_global_state); + entities::init_lua(global_state); #else elog("Trying to bind entities module while disabled in this stormkit distribution!"); #endif @@ -132,7 +147,7 @@ namespace stormkit::lua { if (modules.image) { #if STORMKIT_LIB_IMAGE_ENABLED dlog("Image module enabled"); - image::init_lua(m_global_state); + image::init_lua(global_state); #else elog("Trying to bind image module while disabled in this stormkit distribution!"); #endif @@ -140,7 +155,7 @@ namespace stormkit::lua { if (modules.wsi) { #if STORMKIT_LIB_WSI_ENABLED dlog("Wsi module enabled"); - wsi::init_lua(m_global_state); + wsi::init_lua(global_state); #else elog("Trying to bind wsi module while disabled in this stormkit distribution!"); #endif @@ -148,36 +163,10 @@ namespace stormkit::lua { if (modules.gpu) { #if STORMKIT_LIB_GPU_ENABLED dlog("Gpu module enabled"); - gpu::init_lua(m_global_state); + gpu::init_lua(global_state); #else elog("Trying to bind gpu module while disabled in this stormkit distribution!"); #endif } } - - //////////////////////////////////////// - //////////////////////////////////////// - Engine::Engine(Engine&& other) noexcept = default; - - //////////////////////////////////////// - //////////////////////////////////////// - auto Engine::operator=(Engine&& other) noexcept -> Engine& = default; - - //////////////////////////////////////// - //////////////////////////////////////// - Engine::~Engine() noexcept = default; - - //////////////////////////////////////// - //////////////////////////////////////// - auto Engine::load(const stdfs::path& file) noexcept -> void { - const auto code = TryAssert(io::read_text(file), std::format("Failed to load {}", file.string())); - m_script = m_global_state.load(std::string_view { stdr::data(code), stdr::size(code) }); - } - - //////////////////////////////////////// - //////////////////////////////////////// - auto Engine::lua_main() noexcept -> void { - const auto function = sol::protected_function { m_script }; - luacall(function); - } } // namespace stormkit::lua From 2a6e66c2c7babab95ceee21fd83eb77b51a12c8d Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 8 Feb 2026 03:12:33 +0100 Subject: [PATCH 090/194] (entities, lua) fix add_component for C++ component --- src/lua/entities.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/lua/entities.cpp b/src/lua/entities.cpp index 512f657c8..bd7e956f8 100644 --- a/src/lua/entities.cpp +++ b/src/lua/entities.cpp @@ -50,15 +50,12 @@ namespace stormkit::lua::entities { ensures(type_closure.has_value(), "Missing type() function on lua component"); const auto type = sol::protected_function { *type_closure }; - const auto result = luacall(type); - auto value = sol::object { result }; - ensures(value.is(), "type() function of lua component must return a string value"); + const auto result = luacall(type, component); + const auto value = sol::object { result }; - const auto component_str = value.as(); - - manager->add_component(entity, - LuaComponent { .data = std::move(component), - ._type = component_hash(component_str) }); + ensures(value.is(), "Component type() must return a string or a component type"); + const auto _type = component_hash(value.as()); + manager->add_component(entity, LuaComponent { .data = std::move(component), ._type = _type }); }; manager["get_component"] = +[](EntityManager* manager, Entity entity, std::string_view name) static noexcept { return manager->get_component(entity, name).data; From f2f8f69c43996873c5dbe6c8bc024879c097da88 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 8 Feb 2026 18:58:57 +0100 Subject: [PATCH 091/194] (lua) rename create to run --- examples/lua/wsi/events/lua/events.luau | 1 - examples/lua/wsi/events/src/main.cpp | 3 +-- modules/stormkit/lua.cppm | 9 ++++----- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/examples/lua/wsi/events/lua/events.luau b/examples/lua/wsi/events/lua/events.luau index 1d3d62694..9f8ed39ef 100644 --- a/examples/lua/wsi/events/lua/events.luau +++ b/examples/lua/wsi/events/lua/events.luau @@ -1,4 +1,3 @@ - local function main() local window = wsi.window.open("test", 800, 600, wsi.window_flag.RESIZEABLE) diff --git a/examples/lua/wsi/events/src/main.cpp b/examples/lua/wsi/events/src/main.cpp index 3dcbe2cd4..b1374d93c 100644 --- a/examples/lua/wsi/events/src/main.cpp +++ b/examples/lua/wsi/events/src/main.cpp @@ -32,8 +32,7 @@ auto main(std::span args) -> int { auto logger = log::Logger::create_logger_instance(); - auto engine = lua::Engine::create(LUA_FILE, { .log = true, .wsi = true }); - engine.lua_main(); + lua::Engine::run(LUA_FILE, { .wsi = true }); return 0; } diff --git a/modules/stormkit/lua.cppm b/modules/stormkit/lua.cppm index 6e9f106cc..3d6da2cf2 100644 --- a/modules/stormkit/lua.cppm +++ b/modules/stormkit/lua.cppm @@ -39,9 +39,9 @@ export namespace stormkit::lua { Engine(Engine&& other) noexcept; auto operator=(Engine&& other) noexcept -> Engine&; - static auto create(stdfs::path file, - Modules modules = {}, - InitUserLibrariesClosure init_user_libraries = monadic::noop()) noexcept -> Engine; + static auto run(stdfs::path file, + Modules modules = {}, + InitUserLibrariesClosure init_user_libraries = monadic::noop()) noexcept -> Engine; private: Engine() noexcept; @@ -78,8 +78,7 @@ namespace stormkit::lua { //////////////////////////////////////// //////////////////////////////////////// - inline auto Engine::create(stdfs::path file, Modules modules, InitUserLibrariesClosure init_user_libraries) noexcept - -> Engine { + inline auto Engine::run(stdfs::path file, Modules modules, InitUserLibrariesClosure init_user_libraries) noexcept -> Engine { auto engine = Engine {}; engine.load(std::move(file), std::move(modules), std::move(init_user_libraries)); return engine; From d3c87b66796123af59212094d3b75ff01e70da48 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 8 Feb 2026 18:59:17 +0100 Subject: [PATCH 092/194] (gpu) update enums.cppm to include convertion from image::Image::Format --- modules/stormkit/gpu/core/vulkan/enums.cppm | 5528 +++++++++-------- .../vulkan/{enums.mpp.tpl => enums.cppm.tpl} | 81 +- 2 files changed, 2914 insertions(+), 2695 deletions(-) rename modules/stormkit/gpu/core/vulkan/{enums.mpp.tpl => enums.cppm.tpl} (65%) diff --git a/modules/stormkit/gpu/core/vulkan/enums.cppm b/modules/stormkit/gpu/core/vulkan/enums.cppm index 473206f60..0dcab474c 100644 --- a/modules/stormkit/gpu/core/vulkan/enums.cppm +++ b/modules/stormkit/gpu/core/vulkan/enums.cppm @@ -4,8 +4,8 @@ module; -#include #include +#include #include #include @@ -14,13 +14,15 @@ export module stormkit.gpu.core:vulkan.enums; import std; import stormkit.core; +import stormkit.image; import :vulkan.volk; + export { namespace stormkit::gpu { namespace details { - template + template inline constexpr auto IS_VULKAN_ENUMERATION = false; } @@ -30,724 +32,768 @@ export { } inline constexpr auto QUEUE_FAMILY_IGNORED = std::numeric_limits::max(); - + enum class AccessFlag : u32 { - COLOR_ATTACHMENT_READ = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, - COLOR_ATTACHMENT_WRITE = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - DEPTH_STENCIL_ATTACHMENT_READ = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, - DEPTH_STENCIL_ATTACHMENT_WRITE = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - HOST_READ = VK_ACCESS_HOST_READ_BIT, - HOST_WRITE = VK_ACCESS_HOST_WRITE_BIT, - INDIRECT_COMMAND_READ = VK_ACCESS_INDIRECT_COMMAND_READ_BIT, - INPUT_ATTACHMENT_READ = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, - MEMORY_READ = VK_ACCESS_MEMORY_READ_BIT, - MEMORY_WRITE = VK_ACCESS_MEMORY_WRITE_BIT, - NONE = 0, - SHADER_READ = VK_ACCESS_SHADER_READ_BIT, - SHADER_WRITE = VK_ACCESS_SHADER_WRITE_BIT, - TRANSFER_READ = VK_ACCESS_TRANSFER_READ_BIT, - TRANSFER_WRITE = VK_ACCESS_TRANSFER_WRITE_BIT, - UNIFORM_READ = VK_ACCESS_UNIFORM_READ_BIT, - VERTEX_ATTRIBUTE_READ = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, - }; - - template<> + COLOR_ATTACHMENT_READ = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, + COLOR_ATTACHMENT_WRITE = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + DEPTH_STENCIL_ATTACHMENT_READ = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, + DEPTH_STENCIL_ATTACHMENT_WRITE = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + HOST_READ = VK_ACCESS_HOST_READ_BIT, + HOST_WRITE = VK_ACCESS_HOST_WRITE_BIT, + INDIRECT_COMMAND_READ = VK_ACCESS_INDIRECT_COMMAND_READ_BIT, + INPUT_ATTACHMENT_READ = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, + MEMORY_READ = VK_ACCESS_MEMORY_READ_BIT, + MEMORY_WRITE = VK_ACCESS_MEMORY_WRITE_BIT, + NONE = 0, + SHADER_READ = VK_ACCESS_SHADER_READ_BIT, + SHADER_WRITE = VK_ACCESS_SHADER_WRITE_BIT, + TRANSFER_READ = VK_ACCESS_TRANSFER_READ_BIT, + TRANSFER_WRITE = VK_ACCESS_TRANSFER_WRITE_BIT, + UNIFORM_READ = VK_ACCESS_UNIFORM_READ_BIT, + VERTEX_ATTRIBUTE_READ = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class AttachmentLoadOperation : u8 { - CLEAR = VK_ATTACHMENT_LOAD_OP_CLEAR, - DONT_CARE = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - LOAD = VK_ATTACHMENT_LOAD_OP_LOAD, + CLEAR = VK_ATTACHMENT_LOAD_OP_CLEAR, + DONT_CARE = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + LOAD = VK_ATTACHMENT_LOAD_OP_LOAD, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class AttachmentStoreOperation : u8 { - DONT_CARE = VK_ATTACHMENT_STORE_OP_DONT_CARE, - STORE = VK_ATTACHMENT_STORE_OP_STORE, + DONT_CARE = VK_ATTACHMENT_STORE_OP_DONT_CARE, + STORE = VK_ATTACHMENT_STORE_OP_STORE, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class BlendFactor : u8 { - CONSTANT_ALPHA = VK_BLEND_FACTOR_CONSTANT_ALPHA, - CONSTANT_COLOR = VK_BLEND_FACTOR_CONSTANT_COLOR, - DST_ALPHA = VK_BLEND_FACTOR_DST_ALPHA, - DST_COLOR = VK_BLEND_FACTOR_DST_COLOR, - ONE = VK_BLEND_FACTOR_ONE, - ONE_MINUS_CONSTANT_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA, - ONE_MINUS_CONSTANT_COLOR = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, - ONE_MINUS_DST_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, - ONE_MINUS_DST_COLOR = VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, - ONE_MINUS_SRC1_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, - ONE_MINUS_SRC1_COLOR = VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, - ONE_MINUS_SRC_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, - ONE_MINUS_SRC_COLOR = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, - SRC1_ALPHA = VK_BLEND_FACTOR_SRC1_ALPHA, - SRC1_COLOR = VK_BLEND_FACTOR_SRC1_COLOR, - SRC_ALPHA = VK_BLEND_FACTOR_SRC_ALPHA, - SRC_ALPHA_SATURATE = VK_BLEND_FACTOR_SRC_ALPHA_SATURATE, - SRC_COLOR = VK_BLEND_FACTOR_SRC_COLOR, - ZERO = VK_BLEND_FACTOR_ZERO, - }; - - template<> + CONSTANT_ALPHA = VK_BLEND_FACTOR_CONSTANT_ALPHA, + CONSTANT_COLOR = VK_BLEND_FACTOR_CONSTANT_COLOR, + DST_ALPHA = VK_BLEND_FACTOR_DST_ALPHA, + DST_COLOR = VK_BLEND_FACTOR_DST_COLOR, + ONE = VK_BLEND_FACTOR_ONE, + ONE_MINUS_CONSTANT_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA, + ONE_MINUS_CONSTANT_COLOR = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, + ONE_MINUS_DST_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, + ONE_MINUS_DST_COLOR = VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, + ONE_MINUS_SRC1_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, + ONE_MINUS_SRC1_COLOR = VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, + ONE_MINUS_SRC_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + ONE_MINUS_SRC_COLOR = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, + SRC1_ALPHA = VK_BLEND_FACTOR_SRC1_ALPHA, + SRC1_COLOR = VK_BLEND_FACTOR_SRC1_COLOR, + SRC_ALPHA = VK_BLEND_FACTOR_SRC_ALPHA, + SRC_ALPHA_SATURATE = VK_BLEND_FACTOR_SRC_ALPHA_SATURATE, + SRC_COLOR = VK_BLEND_FACTOR_SRC_COLOR, + ZERO = VK_BLEND_FACTOR_ZERO, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class BlendOperation : u8 { - ADD = VK_BLEND_OP_ADD, - MAX = VK_BLEND_OP_MAX, - MIN = VK_BLEND_OP_MIN, - REVERSE_SUBTRACT = VK_BLEND_OP_REVERSE_SUBTRACT, - SUBTRACT = VK_BLEND_OP_SUBTRACT, + ADD = VK_BLEND_OP_ADD, + MAX = VK_BLEND_OP_MAX, + MIN = VK_BLEND_OP_MIN, + REVERSE_SUBTRACT = VK_BLEND_OP_REVERSE_SUBTRACT, + SUBTRACT = VK_BLEND_OP_SUBTRACT, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class BorderColor : u8 { - FLOAT_OPAQUE_BLACK = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK, - FLOAT_OPAQUE_WHITE = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE, - FLOAT_TRANSPARENT_BLACK = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, - INT_OPAQUE_BLACK = VK_BORDER_COLOR_INT_OPAQUE_BLACK, - INT_OPAQUE_WHITE = VK_BORDER_COLOR_INT_OPAQUE_WHITE, - INT_TRANSPARENT_BLACK = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK, + FLOAT_OPAQUE_BLACK = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK, + FLOAT_OPAQUE_WHITE = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE, + FLOAT_TRANSPARENT_BLACK = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, + INT_OPAQUE_BLACK = VK_BORDER_COLOR_INT_OPAQUE_BLACK, + INT_OPAQUE_WHITE = VK_BORDER_COLOR_INT_OPAQUE_WHITE, + INT_TRANSPARENT_BLACK = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class BufferUsageFlag : u16 { - INDEX = VK_BUFFER_USAGE_INDEX_BUFFER_BIT, - INDIRECT = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, - STORAGE = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, - STORAGE_TEXEL = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, - TRANSFER_DST = VK_BUFFER_USAGE_TRANSFER_DST_BIT, - TRANSFER_SRC = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - UNIFORM = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, - UNIFORM_TEXEL = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, - VERTEX = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, - }; - - template<> + INDEX = VK_BUFFER_USAGE_INDEX_BUFFER_BIT, + INDIRECT = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, + STORAGE = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, + STORAGE_TEXEL = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, + TRANSFER_DST = VK_BUFFER_USAGE_TRANSFER_DST_BIT, + TRANSFER_SRC = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + UNIFORM = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + UNIFORM_TEXEL = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, + VERTEX = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ColorComponentFlag : u8 { - A = VK_COLOR_COMPONENT_A_BIT, - B = VK_COLOR_COMPONENT_B_BIT, - G = VK_COLOR_COMPONENT_G_BIT, - NONE = 0, - R = VK_COLOR_COMPONENT_R_BIT, - RG = R | G, - RGB = RG | B, - RGBA = RGB | A, - }; - - template<> + A = VK_COLOR_COMPONENT_A_BIT, + B = VK_COLOR_COMPONENT_B_BIT, + G = VK_COLOR_COMPONENT_G_BIT, + NONE = 0, + R = VK_COLOR_COMPONENT_R_BIT, + RG = R | G, + RGB = RG | B, + RGBA = RGB | A, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ColorSpace : u32 { - ADOBERGB_LINEAR = VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT, - ADOBERGB_NONLINEAR = VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT, - BT2020_LINEAR = VK_COLOR_SPACE_BT2020_LINEAR_EXT, - BT709_LINEAR = VK_COLOR_SPACE_BT709_LINEAR_EXT, - BT709_NONLINEAR = VK_COLOR_SPACE_BT709_NONLINEAR_EXT, - DCI_P3_NONLINEAR = VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT, - DISPLAY_NATIVE_AMD = VK_COLOR_SPACE_DISPLAY_NATIVE_AMD, - DISPLAY_P3_LINEAR = VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT, - DISPLAY_P3_NONLINEAR = VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT, - DOLBYVISION = VK_COLOR_SPACE_DOLBYVISION_EXT, - EXTENDED_SRGB_LINEAR = VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT, - EXTENDED_SRGB_NONLINEAR = VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT, - HDR10_HLG = VK_COLOR_SPACE_HDR10_HLG_EXT, - HDR10_ST2084 = VK_COLOR_SPACE_HDR10_ST2084_EXT, - PASS_THROUGH = VK_COLOR_SPACE_PASS_THROUGH_EXT, - SRGB_NONLINEAR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, - }; - - template<> + ADOBERGB_LINEAR = VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT, + ADOBERGB_NONLINEAR = VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT, + BT2020_LINEAR = VK_COLOR_SPACE_BT2020_LINEAR_EXT, + BT709_LINEAR = VK_COLOR_SPACE_BT709_LINEAR_EXT, + BT709_NONLINEAR = VK_COLOR_SPACE_BT709_NONLINEAR_EXT, + DCI_P3_NONLINEAR = VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT, + DISPLAY_NATIVE_AMD = VK_COLOR_SPACE_DISPLAY_NATIVE_AMD, + DISPLAY_P3_LINEAR = VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT, + DISPLAY_P3_NONLINEAR = VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT, + DOLBYVISION = VK_COLOR_SPACE_DOLBYVISION_EXT, + EXTENDED_SRGB_LINEAR = VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT, + EXTENDED_SRGB_NONLINEAR = VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT, + HDR10_HLG = VK_COLOR_SPACE_HDR10_HLG_EXT, + HDR10_ST2084 = VK_COLOR_SPACE_HDR10_ST2084_EXT, + PASS_THROUGH = VK_COLOR_SPACE_PASS_THROUGH_EXT, + SRGB_NONLINEAR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class CommandBufferLevel : u8 { - PRIMARY = VK_COMMAND_BUFFER_LEVEL_PRIMARY, - SECONDARY = VK_COMMAND_BUFFER_LEVEL_SECONDARY, + PRIMARY = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + SECONDARY = VK_COMMAND_BUFFER_LEVEL_SECONDARY, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class CompareOperation : u8 { - ALWAYS = VK_COMPARE_OP_ALWAYS, - EQUAL = VK_COMPARE_OP_EQUAL, - GREATER = VK_COMPARE_OP_GREATER, - GREATER_OR_EQUAL = VK_COMPARE_OP_GREATER_OR_EQUAL, - LESS = VK_COMPARE_OP_LESS, - LESS_OR_EQUAL = VK_COMPARE_OP_LESS_OR_EQUAL, - NEVER = VK_COMPARE_OP_NEVER, - NOT_EQUAL = VK_COMPARE_OP_NOT_EQUAL, - }; - - template<> + ALWAYS = VK_COMPARE_OP_ALWAYS, + EQUAL = VK_COMPARE_OP_EQUAL, + GREATER = VK_COMPARE_OP_GREATER, + GREATER_OR_EQUAL = VK_COMPARE_OP_GREATER_OR_EQUAL, + LESS = VK_COMPARE_OP_LESS, + LESS_OR_EQUAL = VK_COMPARE_OP_LESS_OR_EQUAL, + NEVER = VK_COMPARE_OP_NEVER, + NOT_EQUAL = VK_COMPARE_OP_NOT_EQUAL, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class CullModeFlag : u8 { - BACK = VK_CULL_MODE_BACK_BIT, - FRONT = VK_CULL_MODE_FRONT_BIT, - FRONT_BACK = FRONT | BACK, - NONE = 0, + BACK = VK_CULL_MODE_BACK_BIT, + FRONT = VK_CULL_MODE_FRONT_BIT, + FRONT_BACK = FRONT | BACK, + NONE = 0, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class DebugObjectType : u32 { - BUFFER = VK_OBJECT_TYPE_BUFFER, - BUFFER_VIEW = VK_OBJECT_TYPE_BUFFER_VIEW, - COMMAND_BUFFER = VK_OBJECT_TYPE_COMMAND_BUFFER, - COMMAND_POOL = VK_OBJECT_TYPE_COMMAND_POOL, - DEBUG_REPORT_CALLBACK = VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT, - DESCRIPTOR_POOL = VK_OBJECT_TYPE_DESCRIPTOR_POOL, - DESCRIPTOR_SET = VK_OBJECT_TYPE_DESCRIPTOR_SET, - DESCRIPTOR_SET_LAYOUT = VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, - DEVICE = VK_OBJECT_TYPE_DEVICE, - DEVICE_MEMORY = VK_OBJECT_TYPE_DEVICE_MEMORY, - DISPLAY = VK_OBJECT_TYPE_DISPLAY_KHR, - EVENT = VK_OBJECT_TYPE_EVENT, - FENCE = VK_OBJECT_TYPE_FENCE, - FRAMEBUFFER = VK_OBJECT_TYPE_FRAMEBUFFER, - IMAGE = VK_OBJECT_TYPE_IMAGE, - IMAGE_VIEW = VK_OBJECT_TYPE_IMAGE_VIEW, - INSTANCE = VK_OBJECT_TYPE_INSTANCE, - PHYSICAL_DEVICE = VK_OBJECT_TYPE_PHYSICAL_DEVICE, - PIPELINE = VK_OBJECT_TYPE_PIPELINE, - PIPELINE_CACHE = VK_OBJECT_TYPE_PIPELINE_CACHE, - PIPELINE_LAYOUT = VK_OBJECT_TYPE_PIPELINE_LAYOUT, - QUERY_POOL = VK_OBJECT_TYPE_QUERY_POOL, - QUEUE = VK_OBJECT_TYPE_QUEUE, - RENDER_PASS = VK_OBJECT_TYPE_RENDER_PASS, - SAMPLER = VK_OBJECT_TYPE_SAMPLER, - SEMAPHORE = VK_OBJECT_TYPE_SEMAPHORE, - SHADER_MODULE = VK_OBJECT_TYPE_SHADER_MODULE, - SURFACE = VK_OBJECT_TYPE_SURFACE_KHR, - SWAPCHAIN = VK_OBJECT_TYPE_SWAPCHAIN_KHR, - UNKNOWN = VK_OBJECT_TYPE_UNKNOWN, - }; - - template<> + BUFFER = VK_OBJECT_TYPE_BUFFER, + BUFFER_VIEW = VK_OBJECT_TYPE_BUFFER_VIEW, + COMMAND_BUFFER = VK_OBJECT_TYPE_COMMAND_BUFFER, + COMMAND_POOL = VK_OBJECT_TYPE_COMMAND_POOL, + DEBUG_REPORT_CALLBACK = VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT, + DESCRIPTOR_POOL = VK_OBJECT_TYPE_DESCRIPTOR_POOL, + DESCRIPTOR_SET = VK_OBJECT_TYPE_DESCRIPTOR_SET, + DESCRIPTOR_SET_LAYOUT = VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, + DEVICE = VK_OBJECT_TYPE_DEVICE, + DEVICE_MEMORY = VK_OBJECT_TYPE_DEVICE_MEMORY, + DISPLAY = VK_OBJECT_TYPE_DISPLAY_KHR, + EVENT = VK_OBJECT_TYPE_EVENT, + FENCE = VK_OBJECT_TYPE_FENCE, + FRAMEBUFFER = VK_OBJECT_TYPE_FRAMEBUFFER, + IMAGE = VK_OBJECT_TYPE_IMAGE, + IMAGE_VIEW = VK_OBJECT_TYPE_IMAGE_VIEW, + INSTANCE = VK_OBJECT_TYPE_INSTANCE, + PHYSICAL_DEVICE = VK_OBJECT_TYPE_PHYSICAL_DEVICE, + PIPELINE = VK_OBJECT_TYPE_PIPELINE, + PIPELINE_CACHE = VK_OBJECT_TYPE_PIPELINE_CACHE, + PIPELINE_LAYOUT = VK_OBJECT_TYPE_PIPELINE_LAYOUT, + QUERY_POOL = VK_OBJECT_TYPE_QUERY_POOL, + QUEUE = VK_OBJECT_TYPE_QUEUE, + RENDER_PASS = VK_OBJECT_TYPE_RENDER_PASS, + SAMPLER = VK_OBJECT_TYPE_SAMPLER, + SEMAPHORE = VK_OBJECT_TYPE_SEMAPHORE, + SHADER_MODULE = VK_OBJECT_TYPE_SHADER_MODULE, + SURFACE = VK_OBJECT_TYPE_SURFACE_KHR, + SWAPCHAIN = VK_OBJECT_TYPE_SWAPCHAIN_KHR, + UNKNOWN = VK_OBJECT_TYPE_UNKNOWN, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class DependencyFlag : u8 { - BY_REGION = VK_DEPENDENCY_BY_REGION_BIT, - DEVICE_GROUP = VK_DEPENDENCY_DEVICE_GROUP_BIT, - NONE = 0, - VIEW_LOCAL = VK_DEPENDENCY_VIEW_LOCAL_BIT, + BY_REGION = VK_DEPENDENCY_BY_REGION_BIT, + DEVICE_GROUP = VK_DEPENDENCY_DEVICE_GROUP_BIT, + NONE = 0, + VIEW_LOCAL = VK_DEPENDENCY_VIEW_LOCAL_BIT, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class DescriptorType : u8 { - COMBINED_IMAGE_SAMPLER = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - INPUT_ATTACHMENT = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, - SAMPLED_IMAGE = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - SAMPLER = VK_DESCRIPTOR_TYPE_SAMPLER, - STORAGE_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - STORAGE_BUFFER_DYNAMIC = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, - STORAGE_IMAGE = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - STORAGE_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, - UNIFORM_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - UNIFORM_BUFFER_DYNAMIC = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, - UNIFORM_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, - }; - - template<> + COMBINED_IMAGE_SAMPLER = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + INPUT_ATTACHMENT = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, + SAMPLED_IMAGE = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + SAMPLER = VK_DESCRIPTOR_TYPE_SAMPLER, + STORAGE_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + STORAGE_BUFFER_DYNAMIC = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, + STORAGE_IMAGE = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + STORAGE_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, + UNIFORM_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + UNIFORM_BUFFER_DYNAMIC = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, + UNIFORM_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class DynamicState : u8 { - BLEND_CONSTANTS = VK_DYNAMIC_STATE_BLEND_CONSTANTS, - DEPTH_BIAS = VK_DYNAMIC_STATE_DEPTH_BIAS, - DEPTH_BOUNDS = VK_DYNAMIC_STATE_DEPTH_BOUNDS, - LINE_WIDTH = VK_DYNAMIC_STATE_LINE_WIDTH, - SCISSOR = VK_DYNAMIC_STATE_SCISSOR, - STENCIL_COMPARE_MASK = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, - STENCIL_REFERENCE = VK_DYNAMIC_STATE_STENCIL_REFERENCE, - STENCIL_WRITE_MASK = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, - VIEWPORT = VK_DYNAMIC_STATE_VIEWPORT, - }; - - template<> + BLEND_CONSTANTS = VK_DYNAMIC_STATE_BLEND_CONSTANTS, + DEPTH_BIAS = VK_DYNAMIC_STATE_DEPTH_BIAS, + DEPTH_BOUNDS = VK_DYNAMIC_STATE_DEPTH_BOUNDS, + LINE_WIDTH = VK_DYNAMIC_STATE_LINE_WIDTH, + SCISSOR = VK_DYNAMIC_STATE_SCISSOR, + STENCIL_COMPARE_MASK = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, + STENCIL_REFERENCE = VK_DYNAMIC_STATE_STENCIL_REFERENCE, + STENCIL_WRITE_MASK = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, + VIEWPORT = VK_DYNAMIC_STATE_VIEWPORT, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class Filter : u32 { - CUBIC_IMG = VK_FILTER_CUBIC_IMG, - LINEAR = VK_FILTER_LINEAR, - NEAREST = VK_FILTER_NEAREST, + CUBIC_IMG = VK_FILTER_CUBIC_IMG, + LINEAR = VK_FILTER_LINEAR, + NEAREST = VK_FILTER_NEAREST, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class FormatFeatureFlag : u32 { - BLIT_DST = VK_FORMAT_FEATURE_BLIT_DST_BIT, - BLIT_SRC = VK_FORMAT_FEATURE_BLIT_SRC_BIT, - COLOR_ATTACHMENT = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, - COLOR_ATTACHMENT_BLEND = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT, - COSITED_CHROMA_SAMPLES = VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT, - DEPTH_STENCIL_ATTACHMENT = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, - DISJOINT = VK_FORMAT_FEATURE_DISJOINT_BIT, - MIDPOINT_CHROMA_SAMPLES = VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT, - SAMPLED_IMAGE = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, - SAMPLED_IMAGE_FILTER_LINEAR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT, - SAMPLED_IMAGE_FILTER_MINMAX = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT, - SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT - = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT, - SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE - = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT, - SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT, - SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER - = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT, - STORAGE_IMAGE = VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT, - STORAGE_IMAGE_ATOMIC = VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT, - STORAGE_TEXEL_BUFFER = VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT, - STORAGE_TEXEL_BUFFER_ATOMIC = VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT, - TRANSFER_DST = VK_FORMAT_FEATURE_TRANSFER_DST_BIT, - TRANSFER_SRC = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT, - UNIFORM_TEXEL_BUFFER = VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT, - VERTEX_BUFFER = VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT, - }; - - template<> + BLIT_DST = VK_FORMAT_FEATURE_BLIT_DST_BIT, + BLIT_SRC = VK_FORMAT_FEATURE_BLIT_SRC_BIT, + COLOR_ATTACHMENT = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, + COLOR_ATTACHMENT_BLEND = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT, + COSITED_CHROMA_SAMPLES = VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT, + DEPTH_STENCIL_ATTACHMENT = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, + DISJOINT = VK_FORMAT_FEATURE_DISJOINT_BIT, + MIDPOINT_CHROMA_SAMPLES = VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT, + SAMPLED_IMAGE = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, + SAMPLED_IMAGE_FILTER_LINEAR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT, + SAMPLED_IMAGE_FILTER_MINMAX = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT, + SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT, + SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT, + SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT, + SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT, + STORAGE_IMAGE = VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT, + STORAGE_IMAGE_ATOMIC = VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT, + STORAGE_TEXEL_BUFFER = VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT, + STORAGE_TEXEL_BUFFER_ATOMIC = VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT, + TRANSFER_DST = VK_FORMAT_FEATURE_TRANSFER_DST_BIT, + TRANSFER_SRC = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT, + UNIFORM_TEXEL_BUFFER = VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT, + VERTEX_BUFFER = VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class FrontFace : u8 { - CLOCKWISE = VK_FRONT_FACE_CLOCKWISE, - COUNTER_CLOCKWISE = VK_FRONT_FACE_COUNTER_CLOCKWISE, + CLOCKWISE = VK_FRONT_FACE_CLOCKWISE, + COUNTER_CLOCKWISE = VK_FRONT_FACE_COUNTER_CLOCKWISE, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class GeometryFlag : u8 { - NO_DUPLICATE_ANY_HIT_INVOCATION = VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR, - OPAQUE = VK_GEOMETRY_OPAQUE_BIT_KHR, + NO_DUPLICATE_ANY_HIT_INVOCATION = VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR, + OPAQUE = VK_GEOMETRY_OPAQUE_BIT_KHR, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class GeometryType : u8 { - AABBS = VK_GEOMETRY_TYPE_AABBS_KHR, - INSTANCES = VK_GEOMETRY_TYPE_INSTANCES_KHR, - TRIANGLES = VK_GEOMETRY_TYPE_TRIANGLES_KHR, + AABBS = VK_GEOMETRY_TYPE_AABBS_KHR, + INSTANCES = VK_GEOMETRY_TYPE_INSTANCES_KHR, + TRIANGLES = VK_GEOMETRY_TYPE_TRIANGLES_KHR, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageAspectFlag : u8 { - COLOR = VK_IMAGE_ASPECT_COLOR_BIT, - DEPTH = VK_IMAGE_ASPECT_DEPTH_BIT, - NONE = VK_IMAGE_ASPECT_NONE_KHR, - STENCIL = VK_IMAGE_ASPECT_STENCIL_BIT, + COLOR = VK_IMAGE_ASPECT_COLOR_BIT, + DEPTH = VK_IMAGE_ASPECT_DEPTH_BIT, + NONE = VK_IMAGE_ASPECT_NONE_KHR, + STENCIL = VK_IMAGE_ASPECT_STENCIL_BIT, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageCreateFlag : u16 { - ALIAS = VK_IMAGE_CREATE_ALIAS_BIT, - ARRAY_2D_COMPATIBLE = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, - BLOCK_TEXEL_VIEW_COMPATIBLE = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, - CUBE_COMPATIBLE = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, - DISJOINT = VK_IMAGE_CREATE_DISJOINT_BIT, - EXTENDED_USAGE = VK_IMAGE_CREATE_EXTENDED_USAGE_BIT, - MUTABLE_FORMAT = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, - NONE = 0, - PROTECTED = VK_IMAGE_CREATE_PROTECTED_BIT, - SPARSE_ALIASED = VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, - SPARSE_BINDING = VK_IMAGE_CREATE_SPARSE_BINDING_BIT, - SPARSE_RESIDENCY = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, - SPLIT_INSTANCE_BIND_REGIONS = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT, - }; - - template<> + ALIAS = VK_IMAGE_CREATE_ALIAS_BIT, + ARRAY_2D_COMPATIBLE = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, + BLOCK_TEXEL_VIEW_COMPATIBLE = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, + CUBE_COMPATIBLE = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, + DISJOINT = VK_IMAGE_CREATE_DISJOINT_BIT, + EXTENDED_USAGE = VK_IMAGE_CREATE_EXTENDED_USAGE_BIT, + MUTABLE_FORMAT = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, + NONE = 0, + PROTECTED = VK_IMAGE_CREATE_PROTECTED_BIT, + SPARSE_ALIASED = VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, + SPARSE_BINDING = VK_IMAGE_CREATE_SPARSE_BINDING_BIT, + SPARSE_RESIDENCY = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, + SPLIT_INSTANCE_BIND_REGIONS = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageLayout : u32 { - ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, - COLOR_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, - DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, - DEPTH_STENCIL_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - DEPTH_STENCIL_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, - GENERAL = VK_IMAGE_LAYOUT_GENERAL, - PREINITIALIZED = VK_IMAGE_LAYOUT_PREINITIALIZED, - PRESENT_SRC = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - SHADER_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - SHARED_PRESENT = VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, - TRANSFER_DST_OPTIMAL = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - TRANSFER_SRC_OPTIMAL = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - UNDEFINED = VK_IMAGE_LAYOUT_UNDEFINED, - }; - - template<> + ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, + COLOR_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, + DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, + DEPTH_STENCIL_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + DEPTH_STENCIL_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, + GENERAL = VK_IMAGE_LAYOUT_GENERAL, + PREINITIALIZED = VK_IMAGE_LAYOUT_PREINITIALIZED, + PRESENT_SRC = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + SHADER_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + SHARED_PRESENT = VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, + TRANSFER_DST_OPTIMAL = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + TRANSFER_SRC_OPTIMAL = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + UNDEFINED = VK_IMAGE_LAYOUT_UNDEFINED, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageTiling : u8 { - LINEAR = VK_IMAGE_TILING_LINEAR, - OPTIMAL = VK_IMAGE_TILING_OPTIMAL, + LINEAR = VK_IMAGE_TILING_LINEAR, + OPTIMAL = VK_IMAGE_TILING_OPTIMAL, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageType : u8 { - T1D = VK_IMAGE_TYPE_1D, - T2D = VK_IMAGE_TYPE_2D, - T3D = VK_IMAGE_TYPE_3D, + T1D = VK_IMAGE_TYPE_1D, + T2D = VK_IMAGE_TYPE_2D, + T3D = VK_IMAGE_TYPE_3D, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageUsageFlag : u16 { - COLOR_ATTACHMENT = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, - DEPTH_STENCIL_ATTACHMENT = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, - INPUT_ATTACHMENT = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, - SAMPLED = VK_IMAGE_USAGE_SAMPLED_BIT, - STORAGE = VK_IMAGE_USAGE_STORAGE_BIT, - TRANSFER_DST = VK_IMAGE_USAGE_TRANSFER_DST_BIT, - TRANSFER_SRC = VK_IMAGE_USAGE_TRANSFER_SRC_BIT, - TRANSIENT_ATTACHMENT = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, - }; - - template<> + COLOR_ATTACHMENT = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + DEPTH_STENCIL_ATTACHMENT = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + INPUT_ATTACHMENT = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, + SAMPLED = VK_IMAGE_USAGE_SAMPLED_BIT, + STORAGE = VK_IMAGE_USAGE_STORAGE_BIT, + TRANSFER_DST = VK_IMAGE_USAGE_TRANSFER_DST_BIT, + TRANSFER_SRC = VK_IMAGE_USAGE_TRANSFER_SRC_BIT, + TRANSIENT_ATTACHMENT = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageViewType : u8 { - CUBE = VK_IMAGE_VIEW_TYPE_CUBE, - CUBE_ARRAY = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, - T1D = VK_IMAGE_VIEW_TYPE_1D, - T1D_ARRAY = VK_IMAGE_VIEW_TYPE_1D_ARRAY, - T2D = VK_IMAGE_VIEW_TYPE_2D, - T2D_ARRAY = VK_IMAGE_VIEW_TYPE_2D_ARRAY, - T3D = VK_IMAGE_VIEW_TYPE_3D, + CUBE = VK_IMAGE_VIEW_TYPE_CUBE, + CUBE_ARRAY = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, + T1D = VK_IMAGE_VIEW_TYPE_1D, + T1D_ARRAY = VK_IMAGE_VIEW_TYPE_1D_ARRAY, + T2D = VK_IMAGE_VIEW_TYPE_2D, + T2D_ARRAY = VK_IMAGE_VIEW_TYPE_2D_ARRAY, + T3D = VK_IMAGE_VIEW_TYPE_3D, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class LogicOperation : u8 { - AND = VK_LOGIC_OP_AND, - AND_INVERTED = VK_LOGIC_OP_AND_INVERTED, - AND_REVERSE = VK_LOGIC_OP_AND_REVERSE, - CLEAR = VK_LOGIC_OP_CLEAR, - COPY = VK_LOGIC_OP_COPY, - COPY_INVERTED = VK_LOGIC_OP_COPY_INVERTED, - EQUIVALENT = VK_LOGIC_OP_EQUIVALENT, - INVERT = VK_LOGIC_OP_INVERT, - NAND = VK_LOGIC_OP_NAND, - NOR = VK_LOGIC_OP_NOR, - NO_OP = VK_LOGIC_OP_NO_OP, - OR = VK_LOGIC_OP_OR, - OR_INVERTED = VK_LOGIC_OP_OR_INVERTED, - OR_REVERSE = VK_LOGIC_OP_OR_REVERSE, - SET = VK_LOGIC_OP_SET, - XOR = VK_LOGIC_OP_XOR, - }; - - template<> + AND = VK_LOGIC_OP_AND, + AND_INVERTED = VK_LOGIC_OP_AND_INVERTED, + AND_REVERSE = VK_LOGIC_OP_AND_REVERSE, + CLEAR = VK_LOGIC_OP_CLEAR, + COPY = VK_LOGIC_OP_COPY, + COPY_INVERTED = VK_LOGIC_OP_COPY_INVERTED, + EQUIVALENT = VK_LOGIC_OP_EQUIVALENT, + INVERT = VK_LOGIC_OP_INVERT, + NAND = VK_LOGIC_OP_NAND, + NOR = VK_LOGIC_OP_NOR, + NO_OP = VK_LOGIC_OP_NO_OP, + OR = VK_LOGIC_OP_OR, + OR_INVERTED = VK_LOGIC_OP_OR_INVERTED, + OR_REVERSE = VK_LOGIC_OP_OR_REVERSE, + SET = VK_LOGIC_OP_SET, + XOR = VK_LOGIC_OP_XOR, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class MemoryPropertyFlag : u8 { - DEVICE_LOCAL = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - HOST_CACHED = VK_MEMORY_PROPERTY_HOST_CACHED_BIT, - HOST_COHERENT = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - HOST_VISIBLE = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + DEVICE_LOCAL = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + HOST_CACHED = VK_MEMORY_PROPERTY_HOST_CACHED_BIT, + HOST_COHERENT = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + HOST_VISIBLE = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PhysicalDeviceType : u8 { - CPU = VK_PHYSICAL_DEVICE_TYPE_CPU, - DISCRETE_GPU = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, - INTEGRATED_GPU = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, - OTHER = VK_PHYSICAL_DEVICE_TYPE_OTHER, - VIRTUAL_GPU = VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, + CPU = VK_PHYSICAL_DEVICE_TYPE_CPU, + DISCRETE_GPU = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, + INTEGRATED_GPU = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, + OTHER = VK_PHYSICAL_DEVICE_TYPE_OTHER, + VIRTUAL_GPU = VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PipelineBindPoint : u8 { - COMPUTE = VK_PIPELINE_BIND_POINT_COMPUTE, - GRAPHICS = VK_PIPELINE_BIND_POINT_GRAPHICS, + COMPUTE = VK_PIPELINE_BIND_POINT_COMPUTE, + GRAPHICS = VK_PIPELINE_BIND_POINT_GRAPHICS, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PipelineStageFlag : u32 { - ALL_COMMANDS = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - ALL_GRAPHICS = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, - BOTTOM_OF_PIPE = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - COLOR_ATTACHMENT_OUTPUT = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - COMPUTE_SHADER = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - DRAW_INDIRECT = VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, - EARLY_FRAGMENT_TESTS = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, - FRAGMENT_SHADER = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - GEOMETRY_SHADER = VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, - HOST = VK_PIPELINE_STAGE_HOST_BIT, - LATE_FRAGMENT_TESTS = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - TESSELLATION_CONTROL_SHADER = VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, - TESSELLATION_EVALUATION_SHADER = VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, - TOP_OF_PIPE = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - TRANSFER = VK_PIPELINE_STAGE_TRANSFER_BIT, - VERTEX_INPUT = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, - VERTEX_SHADER = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, - }; - - template<> + ALL_COMMANDS = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + ALL_GRAPHICS = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, + BOTTOM_OF_PIPE = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + COLOR_ATTACHMENT_OUTPUT = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + COMPUTE_SHADER = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + DRAW_INDIRECT = VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, + EARLY_FRAGMENT_TESTS = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, + FRAGMENT_SHADER = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + GEOMETRY_SHADER = VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, + HOST = VK_PIPELINE_STAGE_HOST_BIT, + LATE_FRAGMENT_TESTS = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + TESSELLATION_CONTROL_SHADER = VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, + TESSELLATION_EVALUATION_SHADER = VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, + TOP_OF_PIPE = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + TRANSFER = VK_PIPELINE_STAGE_TRANSFER_BIT, + VERTEX_INPUT = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, + VERTEX_SHADER = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PixelFormat : u32 { - A1_RGB5_UNORM_PACK16 = VK_FORMAT_A1R5G5B5_UNORM_PACK16, - A2_RGB10I_PACK32 = VK_FORMAT_A2R10G10B10_SINT_PACK32, - A2_RGB10U_PACK32 = VK_FORMAT_A2R10G10B10_UINT_PACK32, - A2_RGB10_SNORM_PACK32 = VK_FORMAT_A2R10G10B10_SNORM_PACK32, - A2_RGB10_UNORM_PACK32 = VK_FORMAT_A2R10G10B10_UNORM_PACK32, - B10_GR11UF_PACK32 = VK_FORMAT_B10G11R11_UFLOAT_PACK32, - BGR8_UNORM = VK_FORMAT_B8G8R8_UNORM, - BGRA8_UNORM = VK_FORMAT_B8G8R8A8_UNORM, - DEPTH16_UNORM = VK_FORMAT_D16_UNORM, - DEPTH16_UNORM_STENCIL8U = VK_FORMAT_D16_UNORM_S8_UINT, - DEPTH24_UNORM_PACK32 = VK_FORMAT_X8_D24_UNORM_PACK32, - DEPTH24_UNORM_STENCIL8U = VK_FORMAT_D24_UNORM_S8_UINT, - DEPTH32F = VK_FORMAT_D32_SFLOAT, - DEPTH32F_STENCIL8U = VK_FORMAT_D32_SFLOAT_S8_UINT, - R16F = VK_FORMAT_R16_SFLOAT, - R16I = VK_FORMAT_R16_SINT, - R16U = VK_FORMAT_R16_UINT, - R16_SNORM = VK_FORMAT_R16_SNORM, - R16_UNORM = VK_FORMAT_R16_UNORM, - R32F = VK_FORMAT_R32_SFLOAT, - R32I = VK_FORMAT_R32_SINT, - R32U = VK_FORMAT_R32_UINT, - R5_G6_B5_UNORM_PACK16 = VK_FORMAT_R5G6B5_UNORM_PACK16, - R8I = VK_FORMAT_R8_SINT, - R8U = VK_FORMAT_R8_UINT, - R8_SNORM = VK_FORMAT_R8_SNORM, - R8_UNORM = VK_FORMAT_R8_UNORM, - RG16F = VK_FORMAT_R16G16_SFLOAT, - RG16I = VK_FORMAT_R16G16_SINT, - RG16U = VK_FORMAT_R16G16_UINT, - RG16_SNORM = VK_FORMAT_R16G16_SNORM, - RG16_UNORM = VK_FORMAT_R16G16_UNORM, - RG32F = VK_FORMAT_R32G32_SFLOAT, - RG32I = VK_FORMAT_R32G32_SINT, - RG32U = VK_FORMAT_R32G32_UINT, - RG8I = VK_FORMAT_R8G8_SINT, - RG8U = VK_FORMAT_R8G8_UINT, - RG8_SNORM = VK_FORMAT_R8G8_SNORM, - RG8_UNORM = VK_FORMAT_R8G8_UNORM, - RGB16F = VK_FORMAT_R16G16B16_SFLOAT, - RGB16I = VK_FORMAT_R16G16B16_SINT, - RGB16U = VK_FORMAT_R16G16B16_UINT, - RGB16_SNORM = VK_FORMAT_R16G16B16_SNORM, - RGB16_UNORM = VK_FORMAT_R16G16B16_UNORM, - RGB32F = VK_FORMAT_R32G32B32_SFLOAT, - RGB32I = VK_FORMAT_R32G32B32_SINT, - RGB32U = VK_FORMAT_R32G32B32_UINT, - RGB8I = VK_FORMAT_R8G8B8_SINT, - RGB8U = VK_FORMAT_R8G8B8_UINT, - RGB8_SNORM = VK_FORMAT_R8G8B8_SNORM, - RGB8_UNORM = VK_FORMAT_R8G8B8_UNORM, - RGBA16F = VK_FORMAT_R16G16B16A16_SFLOAT, - RGBA16I = VK_FORMAT_R16G16B16A16_SINT, - RGBA16U = VK_FORMAT_R16G16B16A16_UINT, - RGBA16_SNORM = VK_FORMAT_R16G16B16A16_SNORM, - RGBA16_UNORM = VK_FORMAT_R16G16B16A16_UNORM, - RGBA32F = VK_FORMAT_R32G32B32A32_SFLOAT, - RGBA32I = VK_FORMAT_R32G32B32A32_SINT, - RGBA32U = VK_FORMAT_R32G32B32A32_UINT, - RGBA4_UNORM_PACK16 = VK_FORMAT_R4G4B4A4_UNORM_PACK16, - RGBA8I = VK_FORMAT_R8G8B8A8_SINT, - RGBA8U = VK_FORMAT_R8G8B8A8_UINT, - RGBA8_SNORM = VK_FORMAT_R8G8B8A8_SNORM, - RGBA8_UNORM = VK_FORMAT_R8G8B8A8_UNORM, - SBGR8 = VK_FORMAT_B8G8R8_SRGB, - SBGRA8 = VK_FORMAT_B8G8R8A8_SRGB, - SR8 = VK_FORMAT_R8_SRGB, - SRG8 = VK_FORMAT_R8G8_SRGB, - SRGB8 = VK_FORMAT_R8G8B8_SRGB, - SRGBA8 = VK_FORMAT_R8G8B8A8_SRGB, - UNDEFINED = VK_FORMAT_UNDEFINED, - }; - - template<> + A1_RGB5_UNORM_PACK16 = VK_FORMAT_A1R5G5B5_UNORM_PACK16, + A2_RGB10I_PACK32 = VK_FORMAT_A2R10G10B10_SINT_PACK32, + A2_RGB10U_PACK32 = VK_FORMAT_A2R10G10B10_UINT_PACK32, + A2_RGB10_SNORM_PACK32 = VK_FORMAT_A2R10G10B10_SNORM_PACK32, + A2_RGB10_UNORM_PACK32 = VK_FORMAT_A2R10G10B10_UNORM_PACK32, + B10_GR11UF_PACK32 = VK_FORMAT_B10G11R11_UFLOAT_PACK32, + BGR8_UNORM = VK_FORMAT_B8G8R8_UNORM, + BGRA8_UNORM = VK_FORMAT_B8G8R8A8_UNORM, + DEPTH16_UNORM = VK_FORMAT_D16_UNORM, + DEPTH16_UNORM_STENCIL8U = VK_FORMAT_D16_UNORM_S8_UINT, + DEPTH24_UNORM_PACK32 = VK_FORMAT_X8_D24_UNORM_PACK32, + DEPTH24_UNORM_STENCIL8U = VK_FORMAT_D24_UNORM_S8_UINT, + DEPTH32F = VK_FORMAT_D32_SFLOAT, + DEPTH32F_STENCIL8U = VK_FORMAT_D32_SFLOAT_S8_UINT, + R16F = VK_FORMAT_R16_SFLOAT, + R16I = VK_FORMAT_R16_SINT, + R16U = VK_FORMAT_R16_UINT, + R16_SNORM = VK_FORMAT_R16_SNORM, + R16_UNORM = VK_FORMAT_R16_UNORM, + R32F = VK_FORMAT_R32_SFLOAT, + R32I = VK_FORMAT_R32_SINT, + R32U = VK_FORMAT_R32_UINT, + R5_G6_B5_UNORM_PACK16 = VK_FORMAT_R5G6B5_UNORM_PACK16, + R8I = VK_FORMAT_R8_SINT, + R8U = VK_FORMAT_R8_UINT, + R8_SNORM = VK_FORMAT_R8_SNORM, + R8_UNORM = VK_FORMAT_R8_UNORM, + RG16F = VK_FORMAT_R16G16_SFLOAT, + RG16I = VK_FORMAT_R16G16_SINT, + RG16U = VK_FORMAT_R16G16_UINT, + RG16_SNORM = VK_FORMAT_R16G16_SNORM, + RG16_UNORM = VK_FORMAT_R16G16_UNORM, + RG32F = VK_FORMAT_R32G32_SFLOAT, + RG32I = VK_FORMAT_R32G32_SINT, + RG32U = VK_FORMAT_R32G32_UINT, + RG8I = VK_FORMAT_R8G8_SINT, + RG8U = VK_FORMAT_R8G8_UINT, + RG8_SNORM = VK_FORMAT_R8G8_SNORM, + RG8_UNORM = VK_FORMAT_R8G8_UNORM, + RGB16F = VK_FORMAT_R16G16B16_SFLOAT, + RGB16I = VK_FORMAT_R16G16B16_SINT, + RGB16U = VK_FORMAT_R16G16B16_UINT, + RGB16_SNORM = VK_FORMAT_R16G16B16_SNORM, + RGB16_UNORM = VK_FORMAT_R16G16B16_UNORM, + RGB32F = VK_FORMAT_R32G32B32_SFLOAT, + RGB32I = VK_FORMAT_R32G32B32_SINT, + RGB32U = VK_FORMAT_R32G32B32_UINT, + RGB8I = VK_FORMAT_R8G8B8_SINT, + RGB8U = VK_FORMAT_R8G8B8_UINT, + RGB8_SNORM = VK_FORMAT_R8G8B8_SNORM, + RGB8_UNORM = VK_FORMAT_R8G8B8_UNORM, + RGBA16F = VK_FORMAT_R16G16B16A16_SFLOAT, + RGBA16I = VK_FORMAT_R16G16B16A16_SINT, + RGBA16U = VK_FORMAT_R16G16B16A16_UINT, + RGBA16_SNORM = VK_FORMAT_R16G16B16A16_SNORM, + RGBA16_UNORM = VK_FORMAT_R16G16B16A16_UNORM, + RGBA32F = VK_FORMAT_R32G32B32A32_SFLOAT, + RGBA32I = VK_FORMAT_R32G32B32A32_SINT, + RGBA32U = VK_FORMAT_R32G32B32A32_UINT, + RGBA4_UNORM_PACK16 = VK_FORMAT_R4G4B4A4_UNORM_PACK16, + RGBA8I = VK_FORMAT_R8G8B8A8_SINT, + RGBA8U = VK_FORMAT_R8G8B8A8_UINT, + RGBA8_SNORM = VK_FORMAT_R8G8B8A8_SNORM, + RGBA8_UNORM = VK_FORMAT_R8G8B8A8_UNORM, + SBGR8 = VK_FORMAT_B8G8R8_SRGB, + SBGRA8 = VK_FORMAT_B8G8R8A8_SRGB, + SR8 = VK_FORMAT_R8_SRGB, + SRG8 = VK_FORMAT_R8G8_SRGB, + SRGB8 = VK_FORMAT_R8G8B8_SRGB, + SRGBA8 = VK_FORMAT_R8G8B8A8_SRGB, + UNDEFINED = VK_FORMAT_UNDEFINED, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PolygonMode : u8 { - FILL = VK_POLYGON_MODE_FILL, - LINE = VK_POLYGON_MODE_LINE, - POINT = VK_POLYGON_MODE_POINT, + FILL = VK_POLYGON_MODE_FILL, + LINE = VK_POLYGON_MODE_LINE, + POINT = VK_POLYGON_MODE_POINT, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PresentMode : u32 { - FIFO = VK_PRESENT_MODE_FIFO_KHR, - FIFO_RELAXED = VK_PRESENT_MODE_FIFO_RELAXED_KHR, - IMMEDIATE = VK_PRESENT_MODE_IMMEDIATE_KHR, - MAILBOX = VK_PRESENT_MODE_MAILBOX_KHR, - SHARED_CONTINUOUS_REFRESH = VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR, - SHARED_DEMAND_REFRESH = VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR, + FIFO = VK_PRESENT_MODE_FIFO_KHR, + FIFO_RELAXED = VK_PRESENT_MODE_FIFO_RELAXED_KHR, + IMMEDIATE = VK_PRESENT_MODE_IMMEDIATE_KHR, + MAILBOX = VK_PRESENT_MODE_MAILBOX_KHR, + SHARED_CONTINUOUS_REFRESH = VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR, + SHARED_DEMAND_REFRESH = VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PrimitiveTopology : u8 { - LINE_LIST = VK_PRIMITIVE_TOPOLOGY_LINE_LIST, - LINE_STRIP = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, - POINT_LIST = VK_PRIMITIVE_TOPOLOGY_POINT_LIST, - TRIANGLE_FAN = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, - TRIANGLE_LIST = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, - TRIANGLE_STRIP = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, + LINE_LIST = VK_PRIMITIVE_TOPOLOGY_LINE_LIST, + LINE_STRIP = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, + POINT_LIST = VK_PRIMITIVE_TOPOLOGY_POINT_LIST, + TRIANGLE_FAN = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, + TRIANGLE_LIST = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + TRIANGLE_STRIP = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class QueueFlag : u8 { - COMPUTE = VK_QUEUE_COMPUTE_BIT, - GRAPHICS = VK_QUEUE_GRAPHICS_BIT, - NONE = 0, - PROTECTED = VK_QUEUE_PROTECTED_BIT, - SPARSE_BINDING = VK_QUEUE_SPARSE_BINDING_BIT, - TRANSFER = VK_QUEUE_TRANSFER_BIT, + COMPUTE = VK_QUEUE_COMPUTE_BIT, + GRAPHICS = VK_QUEUE_GRAPHICS_BIT, + NONE = 0, + PROTECTED = VK_QUEUE_PROTECTED_BIT, + SPARSE_BINDING = VK_QUEUE_SPARSE_BINDING_BIT, + TRANSFER = VK_QUEUE_TRANSFER_BIT, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ResolveModeFlag : u8 { - AVERAGE = VK_RESOLVE_MODE_AVERAGE_BIT, - EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID = VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID, - MAX = VK_RESOLVE_MODE_MAX_BIT, - MIN = VK_RESOLVE_MODE_MIN_BIT, - NONE = VK_RESOLVE_MODE_NONE, - SAMPLE_ZERO = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, + AVERAGE = VK_RESOLVE_MODE_AVERAGE_BIT, + EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID = VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID, + MAX = VK_RESOLVE_MODE_MAX_BIT, + MIN = VK_RESOLVE_MODE_MIN_BIT, + NONE = VK_RESOLVE_MODE_NONE, + SAMPLE_ZERO = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class Result : i32 { - ERROR_DEVICE_LOST = VK_ERROR_DEVICE_LOST, - ERROR_EXTENSION_NOT_PRESENT = VK_ERROR_EXTENSION_NOT_PRESENT, - ERROR_FEATURE_NOT_PRESENT = VK_ERROR_FEATURE_NOT_PRESENT, - ERROR_FORMAT_NOT_SUPPORTED = VK_ERROR_FORMAT_NOT_SUPPORTED, - ERROR_FRAGMENTATION = VK_ERROR_FRAGMENTATION, - ERROR_FRAGMENTED_POOL = VK_ERROR_FRAGMENTED_POOL, - ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST = VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT, - ERROR_INCOMPATIBLE_DISPLAY = VK_ERROR_INCOMPATIBLE_DISPLAY_KHR, - ERROR_INCOMPATIBLE_DRIVER = VK_ERROR_INCOMPATIBLE_DRIVER, - ERROR_INITIALIZATION_FAILED = VK_ERROR_INITIALIZATION_FAILED, - ERROR_INVALID_EXTERNAL_HANDLE = VK_ERROR_INVALID_EXTERNAL_HANDLE, - ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, - ERROR_LAYER_NOT_PRESENT = VK_ERROR_LAYER_NOT_PRESENT, - ERROR_MEMORY_MAP_FAILED = VK_ERROR_MEMORY_MAP_FAILED, - ERROR_NATIVE_WINDOW_IN_USE = VK_ERROR_NATIVE_WINDOW_IN_USE_KHR, - ERROR_NOT_PERMITTED = VK_ERROR_NOT_PERMITTED, - ERROR_OUT_OF_DATE = VK_ERROR_OUT_OF_DATE_KHR, - ERROR_OUT_OF_DEVICE_MEMORY = VK_ERROR_OUT_OF_DEVICE_MEMORY, - ERROR_OUT_OF_HOST_MEMORY = VK_ERROR_OUT_OF_HOST_MEMORY, - ERROR_OUT_OF_POOL_MEMORY = VK_ERROR_OUT_OF_POOL_MEMORY, - ERROR_SURFACE_LOST = VK_ERROR_SURFACE_LOST_KHR, - ERROR_TOO_MANY_OBJECTS = VK_ERROR_TOO_MANY_OBJECTS, - ERROR_UNKNOWN = VK_ERROR_UNKNOWN, - ERROR_VALIDATION_FAILED = VK_ERROR_VALIDATION_FAILED_EXT, - EVENT_RESET = VK_EVENT_RESET, - EVENT_SET = VK_EVENT_SET, - INCOMPLETE = VK_INCOMPLETE, - NOT_READY = VK_NOT_READY, - OPERATION_DEFERRED = VK_OPERATION_DEFERRED_KHR, - OPERATION_NOT_DEFERRED = VK_OPERATION_NOT_DEFERRED_KHR, - PIPELINE_COMPILE_REQUIRED = VK_PIPELINE_COMPILE_REQUIRED, - SUBOPTIMAL = VK_SUBOPTIMAL_KHR, - SUCCESS = VK_SUCCESS, - THREAD_DONE = VK_THREAD_DONE_KHR, - THREAD_IDLE = VK_THREAD_IDLE_KHR, - TIMEOUT = VK_TIMEOUT, - }; - - template<> + ERROR_DEVICE_LOST = VK_ERROR_DEVICE_LOST, + ERROR_EXTENSION_NOT_PRESENT = VK_ERROR_EXTENSION_NOT_PRESENT, + ERROR_FEATURE_NOT_PRESENT = VK_ERROR_FEATURE_NOT_PRESENT, + ERROR_FORMAT_NOT_SUPPORTED = VK_ERROR_FORMAT_NOT_SUPPORTED, + ERROR_FRAGMENTATION = VK_ERROR_FRAGMENTATION, + ERROR_FRAGMENTED_POOL = VK_ERROR_FRAGMENTED_POOL, + ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST = VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT, + ERROR_INCOMPATIBLE_DISPLAY = VK_ERROR_INCOMPATIBLE_DISPLAY_KHR, + ERROR_INCOMPATIBLE_DRIVER = VK_ERROR_INCOMPATIBLE_DRIVER, + ERROR_INITIALIZATION_FAILED = VK_ERROR_INITIALIZATION_FAILED, + ERROR_INVALID_EXTERNAL_HANDLE = VK_ERROR_INVALID_EXTERNAL_HANDLE, + ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, + ERROR_LAYER_NOT_PRESENT = VK_ERROR_LAYER_NOT_PRESENT, + ERROR_MEMORY_MAP_FAILED = VK_ERROR_MEMORY_MAP_FAILED, + ERROR_NATIVE_WINDOW_IN_USE = VK_ERROR_NATIVE_WINDOW_IN_USE_KHR, + ERROR_NOT_PERMITTED = VK_ERROR_NOT_PERMITTED, + ERROR_OUT_OF_DATE = VK_ERROR_OUT_OF_DATE_KHR, + ERROR_OUT_OF_DEVICE_MEMORY = VK_ERROR_OUT_OF_DEVICE_MEMORY, + ERROR_OUT_OF_HOST_MEMORY = VK_ERROR_OUT_OF_HOST_MEMORY, + ERROR_OUT_OF_POOL_MEMORY = VK_ERROR_OUT_OF_POOL_MEMORY, + ERROR_SURFACE_LOST = VK_ERROR_SURFACE_LOST_KHR, + ERROR_TOO_MANY_OBJECTS = VK_ERROR_TOO_MANY_OBJECTS, + ERROR_UNKNOWN = VK_ERROR_UNKNOWN, + ERROR_VALIDATION_FAILED = VK_ERROR_VALIDATION_FAILED_EXT, + EVENT_RESET = VK_EVENT_RESET, + EVENT_SET = VK_EVENT_SET, + INCOMPLETE = VK_INCOMPLETE, + NOT_READY = VK_NOT_READY, + OPERATION_DEFERRED = VK_OPERATION_DEFERRED_KHR, + OPERATION_NOT_DEFERRED = VK_OPERATION_NOT_DEFERRED_KHR, + PIPELINE_COMPILE_REQUIRED = VK_PIPELINE_COMPILE_REQUIRED, + SUBOPTIMAL = VK_SUBOPTIMAL_KHR, + SUCCESS = VK_SUCCESS, + THREAD_DONE = VK_THREAD_DONE_KHR, + THREAD_IDLE = VK_THREAD_IDLE_KHR, + TIMEOUT = VK_TIMEOUT, + + }; + + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class SampleCountFlag : u8 { - C1 = VK_SAMPLE_COUNT_1_BIT, - C16 = VK_SAMPLE_COUNT_16_BIT, - C2 = VK_SAMPLE_COUNT_2_BIT, - C32 = VK_SAMPLE_COUNT_32_BIT, - C4 = VK_SAMPLE_COUNT_4_BIT, - C64 = VK_SAMPLE_COUNT_64_BIT, - C8 = VK_SAMPLE_COUNT_8_BIT, + C1 = VK_SAMPLE_COUNT_1_BIT, + C16 = VK_SAMPLE_COUNT_16_BIT, + C2 = VK_SAMPLE_COUNT_2_BIT, + C32 = VK_SAMPLE_COUNT_32_BIT, + C4 = VK_SAMPLE_COUNT_4_BIT, + C64 = VK_SAMPLE_COUNT_64_BIT, + C8 = VK_SAMPLE_COUNT_8_BIT, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class SamplerAddressMode : u8 { - CLAMP_TO_BORDER = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, - CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, - MIRRORED_REPEAT = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, - MIRROR_CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, - REPEAT = VK_SAMPLER_ADDRESS_MODE_REPEAT, + CLAMP_TO_BORDER = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, + CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + MIRRORED_REPEAT = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, + MIRROR_CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, + REPEAT = VK_SAMPLER_ADDRESS_MODE_REPEAT, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class SamplerMipmapMode : u8 { - LINEAR = VK_SAMPLER_MIPMAP_MODE_LINEAR, - NEAREST = VK_SAMPLER_MIPMAP_MODE_NEAREST, + LINEAR = VK_SAMPLER_MIPMAP_MODE_LINEAR, + NEAREST = VK_SAMPLER_MIPMAP_MODE_NEAREST, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ShaderStageFlag : u8 { - COMPUTE = VK_SHADER_STAGE_COMPUTE_BIT, - FRAGMENT = VK_SHADER_STAGE_FRAGMENT_BIT, - GEOMETRY = VK_SHADER_STAGE_GEOMETRY_BIT, - NONE = 0, - VERTEX = VK_SHADER_STAGE_VERTEX_BIT, + COMPUTE = VK_SHADER_STAGE_COMPUTE_BIT, + FRAGMENT = VK_SHADER_STAGE_FRAGMENT_BIT, + GEOMETRY = VK_SHADER_STAGE_GEOMETRY_BIT, + NONE = 0, + VERTEX = VK_SHADER_STAGE_VERTEX_BIT, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class StencilFaceFlag : u8 { - BACK = VK_STENCIL_FACE_BACK_BIT, - FRONT = VK_STENCIL_FACE_FRONT_BIT, - FRONT_AND_BACK = FRONT | BACK, + BACK = VK_STENCIL_FACE_BACK_BIT, + FRONT = VK_STENCIL_FACE_FRONT_BIT, + FRONT_AND_BACK = FRONT | BACK, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class VertexInputRate : u8 { - INSTANCE = VK_VERTEX_INPUT_RATE_INSTANCE, - VERTEX = VK_VERTEX_INPUT_RATE_VERTEX, + INSTANCE = VK_VERTEX_INPUT_RATE_INSTANCE, + VERTEX = VK_VERTEX_INPUT_RATE_VERTEX, + }; - template<> + template <> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; + template requires(core::meta::IsPlainEnumeration or core::meta::Is) @@ -759,6 +805,9 @@ export { [[nodiscard]] constexpr auto from_vk(U value) noexcept -> T; + [[nodiscard]] + constexpr auto from_image(image::Image::Format format) -> PixelFormat; + [[nodiscard]] constexpr auto is_depth_only_format(PixelFormat format) noexcept -> bool; [[nodiscard]] @@ -770,2628 +819,2521 @@ export { constexpr auto get_format_channel_count(PixelFormat format) noexcept -> u8; [[nodiscard]] constexpr auto get_format_element_count(PixelFormat format) noexcept -> u8; - } // namespace stormkit::gpu + } FLAG_ENUM(stormkit::gpu::AccessFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ, - stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE, - stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ, - stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE, - stormkit::gpu::AccessFlag::HOST_READ, - stormkit::gpu::AccessFlag::HOST_WRITE, - stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ, - stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ, - stormkit::gpu::AccessFlag::MEMORY_READ, - stormkit::gpu::AccessFlag::MEMORY_WRITE, - stormkit::gpu::AccessFlag::NONE, - stormkit::gpu::AccessFlag::SHADER_READ, - stormkit::gpu::AccessFlag::SHADER_WRITE, - stormkit::gpu::AccessFlag::TRANSFER_READ, - stormkit::gpu::AccessFlag::TRANSFER_WRITE, - stormkit::gpu::AccessFlag::UNIFORM_READ, - stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ, - - }; - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::AccessFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: return "AccessFlag::COLOR_ATTACHMENT_WRITE"; - case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE"; - case stormkit::gpu::AccessFlag::HOST_READ: return "AccessFlag::HOST_READ"; - case stormkit::gpu::AccessFlag::HOST_WRITE: return "AccessFlag::HOST_WRITE"; - case stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ: return "AccessFlag::INDIRECT_COMMAND_READ"; - case stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ: return "AccessFlag::INPUT_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::MEMORY_READ: return "AccessFlag::MEMORY_READ"; - case stormkit::gpu::AccessFlag::MEMORY_WRITE: return "AccessFlag::MEMORY_WRITE"; - case stormkit::gpu::AccessFlag::NONE: return "AccessFlag::NONE"; - case stormkit::gpu::AccessFlag::SHADER_READ: return "AccessFlag::SHADER_READ"; - case stormkit::gpu::AccessFlag::SHADER_WRITE: return "AccessFlag::SHADER_WRITE"; - case stormkit::gpu::AccessFlag::TRANSFER_READ: return "AccessFlag::TRANSFER_READ"; - case stormkit::gpu::AccessFlag::TRANSFER_WRITE: return "AccessFlag::TRANSFER_WRITE"; - case stormkit::gpu::AccessFlag::UNIFORM_READ: return "AccessFlag::UNIFORM_READ"; - case stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ: return "AccessFlag::VERTEX_ATTRIBUTE_READ"; + stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ, + stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE, + stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ, + stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE, + stormkit::gpu::AccessFlag::HOST_READ, + stormkit::gpu::AccessFlag::HOST_WRITE, + stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ, + stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ, + stormkit::gpu::AccessFlag::MEMORY_READ, + stormkit::gpu::AccessFlag::MEMORY_WRITE, + stormkit::gpu::AccessFlag::NONE, + stormkit::gpu::AccessFlag::SHADER_READ, + stormkit::gpu::AccessFlag::SHADER_WRITE, + stormkit::gpu::AccessFlag::TRANSFER_READ, + stormkit::gpu::AccessFlag::TRANSFER_WRITE, + stormkit::gpu::AccessFlag::UNIFORM_READ, + stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ, + + }; + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::AccessFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: return "AccessFlag::COLOR_ATTACHMENT_WRITE"; + case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE"; + case stormkit::gpu::AccessFlag::HOST_READ: return "AccessFlag::HOST_READ"; + case stormkit::gpu::AccessFlag::HOST_WRITE: return "AccessFlag::HOST_WRITE"; + case stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ: return "AccessFlag::INDIRECT_COMMAND_READ"; + case stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ: return "AccessFlag::INPUT_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::MEMORY_READ: return "AccessFlag::MEMORY_READ"; + case stormkit::gpu::AccessFlag::MEMORY_WRITE: return "AccessFlag::MEMORY_WRITE"; + case stormkit::gpu::AccessFlag::NONE: return "AccessFlag::NONE"; + case stormkit::gpu::AccessFlag::SHADER_READ: return "AccessFlag::SHADER_READ"; + case stormkit::gpu::AccessFlag::SHADER_WRITE: return "AccessFlag::SHADER_WRITE"; + case stormkit::gpu::AccessFlag::TRANSFER_READ: return "AccessFlag::TRANSFER_READ"; + case stormkit::gpu::AccessFlag::TRANSFER_WRITE: return "AccessFlag::TRANSFER_WRITE"; + case stormkit::gpu::AccessFlag::UNIFORM_READ: return "AccessFlag::UNIFORM_READ"; + case stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ: return "AccessFlag::VERTEX_ATTRIBUTE_READ"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::AccessFlag value) noexcept -> std::string { - switch (value) { - case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: return "AccessFlag::COLOR_ATTACHMENT_WRITE"; - case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE"; - case stormkit::gpu::AccessFlag::HOST_READ: return "AccessFlag::HOST_READ"; - case stormkit::gpu::AccessFlag::HOST_WRITE: return "AccessFlag::HOST_WRITE"; - case stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ: return "AccessFlag::INDIRECT_COMMAND_READ"; - case stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ: return "AccessFlag::INPUT_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::MEMORY_READ: return "AccessFlag::MEMORY_READ"; - case stormkit::gpu::AccessFlag::MEMORY_WRITE: return "AccessFlag::MEMORY_WRITE"; - case stormkit::gpu::AccessFlag::NONE: return "AccessFlag::NONE"; - case stormkit::gpu::AccessFlag::SHADER_READ: return "AccessFlag::SHADER_READ"; - case stormkit::gpu::AccessFlag::SHADER_WRITE: return "AccessFlag::SHADER_WRITE"; - case stormkit::gpu::AccessFlag::TRANSFER_READ: return "AccessFlag::TRANSFER_READ"; - case stormkit::gpu::AccessFlag::TRANSFER_WRITE: return "AccessFlag::TRANSFER_WRITE"; - case stormkit::gpu::AccessFlag::UNIFORM_READ: return "AccessFlag::UNIFORM_READ"; - case stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ: return "AccessFlag::VERTEX_ATTRIBUTE_READ"; + switch(value) { + case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: return "AccessFlag::COLOR_ATTACHMENT_WRITE"; + case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE"; + case stormkit::gpu::AccessFlag::HOST_READ: return "AccessFlag::HOST_READ"; + case stormkit::gpu::AccessFlag::HOST_WRITE: return "AccessFlag::HOST_WRITE"; + case stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ: return "AccessFlag::INDIRECT_COMMAND_READ"; + case stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ: return "AccessFlag::INPUT_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::MEMORY_READ: return "AccessFlag::MEMORY_READ"; + case stormkit::gpu::AccessFlag::MEMORY_WRITE: return "AccessFlag::MEMORY_WRITE"; + case stormkit::gpu::AccessFlag::NONE: return "AccessFlag::NONE"; + case stormkit::gpu::AccessFlag::SHADER_READ: return "AccessFlag::SHADER_READ"; + case stormkit::gpu::AccessFlag::SHADER_WRITE: return "AccessFlag::SHADER_WRITE"; + case stormkit::gpu::AccessFlag::TRANSFER_READ: return "AccessFlag::TRANSFER_READ"; + case stormkit::gpu::AccessFlag::TRANSFER_WRITE: return "AccessFlag::TRANSFER_WRITE"; + case stormkit::gpu::AccessFlag::UNIFORM_READ: return "AccessFlag::UNIFORM_READ"; + case stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ: return "AccessFlag::VERTEX_ATTRIBUTE_READ"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::AttachmentLoadOperation) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::AttachmentLoadOperation::CLEAR, - stormkit::gpu::AttachmentLoadOperation::DONT_CARE, - stormkit::gpu::AttachmentLoadOperation::LOAD, - + stormkit::gpu::AttachmentLoadOperation::CLEAR, + stormkit::gpu::AttachmentLoadOperation::DONT_CARE, + stormkit::gpu::AttachmentLoadOperation::LOAD, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::AttachmentLoadOperation - value) noexcept -> std::string_view { - switch (value) { - case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; - case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; - case stormkit::gpu::AttachmentLoadOperation::LOAD: return "AttachmentLoadOperation::LOAD"; + constexpr auto stormkit::core::as_string(stormkit::gpu::AttachmentLoadOperation value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; + case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; + case stormkit::gpu::AttachmentLoadOperation::LOAD: return "AttachmentLoadOperation::LOAD"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentLoadOperation - value) noexcept -> std::string { - switch (value) { - case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; - case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; - case stormkit::gpu::AttachmentLoadOperation::LOAD: return "AttachmentLoadOperation::LOAD"; + constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentLoadOperation value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; + case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; + case stormkit::gpu::AttachmentLoadOperation::LOAD: return "AttachmentLoadOperation::LOAD"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::AttachmentStoreOperation) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::AttachmentStoreOperation::DONT_CARE, - stormkit::gpu::AttachmentStoreOperation::STORE, - + stormkit::gpu::AttachmentStoreOperation::DONT_CARE, + stormkit::gpu::AttachmentStoreOperation::STORE, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::AttachmentStoreOperation - value) noexcept -> std::string_view { - switch (value) { - case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; - case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; + constexpr auto stormkit::core::as_string(stormkit::gpu::AttachmentStoreOperation value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; + case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentStoreOperation - value) noexcept -> std::string { - switch (value) { - case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; - case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; + constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentStoreOperation value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; + case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::BlendFactor) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::BlendFactor::CONSTANT_ALPHA, - stormkit::gpu::BlendFactor::CONSTANT_COLOR, - stormkit::gpu::BlendFactor::DST_ALPHA, - stormkit::gpu::BlendFactor::DST_COLOR, - stormkit::gpu::BlendFactor::ONE, - stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA, - stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR, - stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA, - stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR, - stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA, - stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR, - stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA, - stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR, - stormkit::gpu::BlendFactor::SRC1_ALPHA, - stormkit::gpu::BlendFactor::SRC1_COLOR, - stormkit::gpu::BlendFactor::SRC_ALPHA, - stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE, - stormkit::gpu::BlendFactor::SRC_COLOR, - stormkit::gpu::BlendFactor::ZERO, - - }; - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::BlendFactor value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::BlendFactor::CONSTANT_ALPHA: return "BlendFactor::CONSTANT_ALPHA"; - case stormkit::gpu::BlendFactor::CONSTANT_COLOR: return "BlendFactor::CONSTANT_COLOR"; - case stormkit::gpu::BlendFactor::DST_ALPHA: return "BlendFactor::DST_ALPHA"; - case stormkit::gpu::BlendFactor::DST_COLOR: return "BlendFactor::DST_COLOR"; - case stormkit::gpu::BlendFactor::ONE: return "BlendFactor::ONE"; - case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: return "BlendFactor::ONE_MINUS_CONSTANT_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR: return "BlendFactor::ONE_MINUS_CONSTANT_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA: return "BlendFactor::ONE_MINUS_DST_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR: return "BlendFactor::ONE_MINUS_DST_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA: return "BlendFactor::ONE_MINUS_SRC1_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR: return "BlendFactor::ONE_MINUS_SRC1_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA: return "BlendFactor::ONE_MINUS_SRC_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR: return "BlendFactor::ONE_MINUS_SRC_COLOR"; - case stormkit::gpu::BlendFactor::SRC1_ALPHA: return "BlendFactor::SRC1_ALPHA"; - case stormkit::gpu::BlendFactor::SRC1_COLOR: return "BlendFactor::SRC1_COLOR"; - case stormkit::gpu::BlendFactor::SRC_ALPHA: return "BlendFactor::SRC_ALPHA"; - case stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE: return "BlendFactor::SRC_ALPHA_SATURATE"; - case stormkit::gpu::BlendFactor::SRC_COLOR: return "BlendFactor::SRC_COLOR"; - case stormkit::gpu::BlendFactor::ZERO: return "BlendFactor::ZERO"; - } - std::unreachable(); - } - - template<> - STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::BlendFactor value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::BlendFactor::CONSTANT_ALPHA: return "BlendFactor::CONSTANT_ALPHA"; - case stormkit::gpu::BlendFactor::CONSTANT_COLOR: return "BlendFactor::CONSTANT_COLOR"; - case stormkit::gpu::BlendFactor::DST_ALPHA: return "BlendFactor::DST_ALPHA"; - case stormkit::gpu::BlendFactor::DST_COLOR: return "BlendFactor::DST_COLOR"; - case stormkit::gpu::BlendFactor::ONE: return "BlendFactor::ONE"; - case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: return "BlendFactor::ONE_MINUS_CONSTANT_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR: return "BlendFactor::ONE_MINUS_CONSTANT_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA: return "BlendFactor::ONE_MINUS_DST_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR: return "BlendFactor::ONE_MINUS_DST_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA: return "BlendFactor::ONE_MINUS_SRC1_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR: return "BlendFactor::ONE_MINUS_SRC1_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA: return "BlendFactor::ONE_MINUS_SRC_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR: return "BlendFactor::ONE_MINUS_SRC_COLOR"; - case stormkit::gpu::BlendFactor::SRC1_ALPHA: return "BlendFactor::SRC1_ALPHA"; - case stormkit::gpu::BlendFactor::SRC1_COLOR: return "BlendFactor::SRC1_COLOR"; - case stormkit::gpu::BlendFactor::SRC_ALPHA: return "BlendFactor::SRC_ALPHA"; - case stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE: return "BlendFactor::SRC_ALPHA_SATURATE"; - case stormkit::gpu::BlendFactor::SRC_COLOR: return "BlendFactor::SRC_COLOR"; - case stormkit::gpu::BlendFactor::ZERO: return "BlendFactor::ZERO"; + stormkit::gpu::BlendFactor::CONSTANT_ALPHA, + stormkit::gpu::BlendFactor::CONSTANT_COLOR, + stormkit::gpu::BlendFactor::DST_ALPHA, + stormkit::gpu::BlendFactor::DST_COLOR, + stormkit::gpu::BlendFactor::ONE, + stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA, + stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR, + stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA, + stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR, + stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA, + stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR, + stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA, + stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR, + stormkit::gpu::BlendFactor::SRC1_ALPHA, + stormkit::gpu::BlendFactor::SRC1_COLOR, + stormkit::gpu::BlendFactor::SRC_ALPHA, + stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE, + stormkit::gpu::BlendFactor::SRC_COLOR, + stormkit::gpu::BlendFactor::ZERO, + + }; + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::BlendFactor value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::BlendFactor::CONSTANT_ALPHA: return "BlendFactor::CONSTANT_ALPHA"; + case stormkit::gpu::BlendFactor::CONSTANT_COLOR: return "BlendFactor::CONSTANT_COLOR"; + case stormkit::gpu::BlendFactor::DST_ALPHA: return "BlendFactor::DST_ALPHA"; + case stormkit::gpu::BlendFactor::DST_COLOR: return "BlendFactor::DST_COLOR"; + case stormkit::gpu::BlendFactor::ONE: return "BlendFactor::ONE"; + case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: return "BlendFactor::ONE_MINUS_CONSTANT_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR: return "BlendFactor::ONE_MINUS_CONSTANT_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA: return "BlendFactor::ONE_MINUS_DST_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR: return "BlendFactor::ONE_MINUS_DST_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA: return "BlendFactor::ONE_MINUS_SRC1_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR: return "BlendFactor::ONE_MINUS_SRC1_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA: return "BlendFactor::ONE_MINUS_SRC_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR: return "BlendFactor::ONE_MINUS_SRC_COLOR"; + case stormkit::gpu::BlendFactor::SRC1_ALPHA: return "BlendFactor::SRC1_ALPHA"; + case stormkit::gpu::BlendFactor::SRC1_COLOR: return "BlendFactor::SRC1_COLOR"; + case stormkit::gpu::BlendFactor::SRC_ALPHA: return "BlendFactor::SRC_ALPHA"; + case stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE: return "BlendFactor::SRC_ALPHA_SATURATE"; + case stormkit::gpu::BlendFactor::SRC_COLOR: return "BlendFactor::SRC_COLOR"; + case stormkit::gpu::BlendFactor::ZERO: return "BlendFactor::ZERO"; + + } + std::unreachable(); + } + template<> + STORMKIT_FORCE_INLINE + constexpr auto stormkit::core::to_string(stormkit::gpu::BlendFactor value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::BlendFactor::CONSTANT_ALPHA: return "BlendFactor::CONSTANT_ALPHA"; + case stormkit::gpu::BlendFactor::CONSTANT_COLOR: return "BlendFactor::CONSTANT_COLOR"; + case stormkit::gpu::BlendFactor::DST_ALPHA: return "BlendFactor::DST_ALPHA"; + case stormkit::gpu::BlendFactor::DST_COLOR: return "BlendFactor::DST_COLOR"; + case stormkit::gpu::BlendFactor::ONE: return "BlendFactor::ONE"; + case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: return "BlendFactor::ONE_MINUS_CONSTANT_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR: return "BlendFactor::ONE_MINUS_CONSTANT_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA: return "BlendFactor::ONE_MINUS_DST_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR: return "BlendFactor::ONE_MINUS_DST_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA: return "BlendFactor::ONE_MINUS_SRC1_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR: return "BlendFactor::ONE_MINUS_SRC1_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA: return "BlendFactor::ONE_MINUS_SRC_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR: return "BlendFactor::ONE_MINUS_SRC_COLOR"; + case stormkit::gpu::BlendFactor::SRC1_ALPHA: return "BlendFactor::SRC1_ALPHA"; + case stormkit::gpu::BlendFactor::SRC1_COLOR: return "BlendFactor::SRC1_COLOR"; + case stormkit::gpu::BlendFactor::SRC_ALPHA: return "BlendFactor::SRC_ALPHA"; + case stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE: return "BlendFactor::SRC_ALPHA_SATURATE"; + case stormkit::gpu::BlendFactor::SRC_COLOR: return "BlendFactor::SRC_COLOR"; + case stormkit::gpu::BlendFactor::ZERO: return "BlendFactor::ZERO"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::BlendOperation) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::BlendOperation::ADD, stormkit::gpu::BlendOperation::MAX, - stormkit::gpu::BlendOperation::MIN, stormkit::gpu::BlendOperation::REVERSE_SUBTRACT, - stormkit::gpu::BlendOperation::SUBTRACT, - + stormkit::gpu::BlendOperation::ADD, + stormkit::gpu::BlendOperation::MAX, + stormkit::gpu::BlendOperation::MIN, + stormkit::gpu::BlendOperation::REVERSE_SUBTRACT, + stormkit::gpu::BlendOperation::SUBTRACT, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::BlendOperation value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::BlendOperation::ADD: return "BlendOperation::ADD"; - case stormkit::gpu::BlendOperation::MAX: return "BlendOperation::MAX"; - case stormkit::gpu::BlendOperation::MIN: return "BlendOperation::MIN"; - case stormkit::gpu::BlendOperation::REVERSE_SUBTRACT: return "BlendOperation::REVERSE_SUBTRACT"; - case stormkit::gpu::BlendOperation::SUBTRACT: return "BlendOperation::SUBTRACT"; + constexpr auto stormkit::core::as_string(stormkit::gpu::BlendOperation value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::BlendOperation::ADD: return "BlendOperation::ADD"; + case stormkit::gpu::BlendOperation::MAX: return "BlendOperation::MAX"; + case stormkit::gpu::BlendOperation::MIN: return "BlendOperation::MIN"; + case stormkit::gpu::BlendOperation::REVERSE_SUBTRACT: return "BlendOperation::REVERSE_SUBTRACT"; + case stormkit::gpu::BlendOperation::SUBTRACT: return "BlendOperation::SUBTRACT"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::BlendOperation value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::BlendOperation::ADD: return "BlendOperation::ADD"; - case stormkit::gpu::BlendOperation::MAX: return "BlendOperation::MAX"; - case stormkit::gpu::BlendOperation::MIN: return "BlendOperation::MIN"; - case stormkit::gpu::BlendOperation::REVERSE_SUBTRACT: return "BlendOperation::REVERSE_SUBTRACT"; - case stormkit::gpu::BlendOperation::SUBTRACT: return "BlendOperation::SUBTRACT"; + constexpr auto stormkit::core::to_string(stormkit::gpu::BlendOperation value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::BlendOperation::ADD: return "BlendOperation::ADD"; + case stormkit::gpu::BlendOperation::MAX: return "BlendOperation::MAX"; + case stormkit::gpu::BlendOperation::MIN: return "BlendOperation::MIN"; + case stormkit::gpu::BlendOperation::REVERSE_SUBTRACT: return "BlendOperation::REVERSE_SUBTRACT"; + case stormkit::gpu::BlendOperation::SUBTRACT: return "BlendOperation::SUBTRACT"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::BorderColor) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK, stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE, - stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK, stormkit::gpu::BorderColor::INT_OPAQUE_BLACK, - stormkit::gpu::BorderColor::INT_OPAQUE_WHITE, stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK, - + stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK, + stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE, + stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK, + stormkit::gpu::BorderColor::INT_OPAQUE_BLACK, + stormkit::gpu::BorderColor::INT_OPAQUE_WHITE, + stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::BorderColor value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: return "BorderColor::FLOAT_OPAQUE_BLACK"; - case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: return "BorderColor::FLOAT_OPAQUE_WHITE"; - case stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK: return "BorderColor::FLOAT_TRANSPARENT_BLACK"; - case stormkit::gpu::BorderColor::INT_OPAQUE_BLACK: return "BorderColor::INT_OPAQUE_BLACK"; - case stormkit::gpu::BorderColor::INT_OPAQUE_WHITE: return "BorderColor::INT_OPAQUE_WHITE"; - case stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK: return "BorderColor::INT_TRANSPARENT_BLACK"; + constexpr auto stormkit::core::as_string(stormkit::gpu::BorderColor value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: return "BorderColor::FLOAT_OPAQUE_BLACK"; + case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: return "BorderColor::FLOAT_OPAQUE_WHITE"; + case stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK: return "BorderColor::FLOAT_TRANSPARENT_BLACK"; + case stormkit::gpu::BorderColor::INT_OPAQUE_BLACK: return "BorderColor::INT_OPAQUE_BLACK"; + case stormkit::gpu::BorderColor::INT_OPAQUE_WHITE: return "BorderColor::INT_OPAQUE_WHITE"; + case stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK: return "BorderColor::INT_TRANSPARENT_BLACK"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::BorderColor value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: return "BorderColor::FLOAT_OPAQUE_BLACK"; - case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: return "BorderColor::FLOAT_OPAQUE_WHITE"; - case stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK: return "BorderColor::FLOAT_TRANSPARENT_BLACK"; - case stormkit::gpu::BorderColor::INT_OPAQUE_BLACK: return "BorderColor::INT_OPAQUE_BLACK"; - case stormkit::gpu::BorderColor::INT_OPAQUE_WHITE: return "BorderColor::INT_OPAQUE_WHITE"; - case stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK: return "BorderColor::INT_TRANSPARENT_BLACK"; + constexpr auto stormkit::core::to_string(stormkit::gpu::BorderColor value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: return "BorderColor::FLOAT_OPAQUE_BLACK"; + case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: return "BorderColor::FLOAT_OPAQUE_WHITE"; + case stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK: return "BorderColor::FLOAT_TRANSPARENT_BLACK"; + case stormkit::gpu::BorderColor::INT_OPAQUE_BLACK: return "BorderColor::INT_OPAQUE_BLACK"; + case stormkit::gpu::BorderColor::INT_OPAQUE_WHITE: return "BorderColor::INT_OPAQUE_WHITE"; + case stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK: return "BorderColor::INT_TRANSPARENT_BLACK"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::BufferUsageFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::BufferUsageFlag::INDEX, stormkit::gpu::BufferUsageFlag::INDIRECT, - stormkit::gpu::BufferUsageFlag::STORAGE, stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL, - stormkit::gpu::BufferUsageFlag::TRANSFER_DST, stormkit::gpu::BufferUsageFlag::TRANSFER_SRC, - stormkit::gpu::BufferUsageFlag::UNIFORM, stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL, - stormkit::gpu::BufferUsageFlag::VERTEX, - + stormkit::gpu::BufferUsageFlag::INDEX, + stormkit::gpu::BufferUsageFlag::INDIRECT, + stormkit::gpu::BufferUsageFlag::STORAGE, + stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL, + stormkit::gpu::BufferUsageFlag::TRANSFER_DST, + stormkit::gpu::BufferUsageFlag::TRANSFER_SRC, + stormkit::gpu::BufferUsageFlag::UNIFORM, + stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL, + stormkit::gpu::BufferUsageFlag::VERTEX, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::BufferUsageFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::BufferUsageFlag::INDEX: return "BufferUsageFlag::INDEX"; - case stormkit::gpu::BufferUsageFlag::INDIRECT: return "BufferUsageFlag::INDIRECT"; - case stormkit::gpu::BufferUsageFlag::STORAGE: return "BufferUsageFlag::STORAGE"; - case stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL: return "BufferUsageFlag::STORAGE_TEXEL"; - case stormkit::gpu::BufferUsageFlag::TRANSFER_DST: return "BufferUsageFlag::TRANSFER_DST"; - case stormkit::gpu::BufferUsageFlag::TRANSFER_SRC: return "BufferUsageFlag::TRANSFER_SRC"; - case stormkit::gpu::BufferUsageFlag::UNIFORM: return "BufferUsageFlag::UNIFORM"; - case stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL: return "BufferUsageFlag::UNIFORM_TEXEL"; - case stormkit::gpu::BufferUsageFlag::VERTEX: return "BufferUsageFlag::VERTEX"; + constexpr auto stormkit::core::as_string(stormkit::gpu::BufferUsageFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::BufferUsageFlag::INDEX: return "BufferUsageFlag::INDEX"; + case stormkit::gpu::BufferUsageFlag::INDIRECT: return "BufferUsageFlag::INDIRECT"; + case stormkit::gpu::BufferUsageFlag::STORAGE: return "BufferUsageFlag::STORAGE"; + case stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL: return "BufferUsageFlag::STORAGE_TEXEL"; + case stormkit::gpu::BufferUsageFlag::TRANSFER_DST: return "BufferUsageFlag::TRANSFER_DST"; + case stormkit::gpu::BufferUsageFlag::TRANSFER_SRC: return "BufferUsageFlag::TRANSFER_SRC"; + case stormkit::gpu::BufferUsageFlag::UNIFORM: return "BufferUsageFlag::UNIFORM"; + case stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL: return "BufferUsageFlag::UNIFORM_TEXEL"; + case stormkit::gpu::BufferUsageFlag::VERTEX: return "BufferUsageFlag::VERTEX"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::BufferUsageFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::BufferUsageFlag::INDEX: return "BufferUsageFlag::INDEX"; - case stormkit::gpu::BufferUsageFlag::INDIRECT: return "BufferUsageFlag::INDIRECT"; - case stormkit::gpu::BufferUsageFlag::STORAGE: return "BufferUsageFlag::STORAGE"; - case stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL: return "BufferUsageFlag::STORAGE_TEXEL"; - case stormkit::gpu::BufferUsageFlag::TRANSFER_DST: return "BufferUsageFlag::TRANSFER_DST"; - case stormkit::gpu::BufferUsageFlag::TRANSFER_SRC: return "BufferUsageFlag::TRANSFER_SRC"; - case stormkit::gpu::BufferUsageFlag::UNIFORM: return "BufferUsageFlag::UNIFORM"; - case stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL: return "BufferUsageFlag::UNIFORM_TEXEL"; - case stormkit::gpu::BufferUsageFlag::VERTEX: return "BufferUsageFlag::VERTEX"; + constexpr auto stormkit::core::to_string(stormkit::gpu::BufferUsageFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::BufferUsageFlag::INDEX: return "BufferUsageFlag::INDEX"; + case stormkit::gpu::BufferUsageFlag::INDIRECT: return "BufferUsageFlag::INDIRECT"; + case stormkit::gpu::BufferUsageFlag::STORAGE: return "BufferUsageFlag::STORAGE"; + case stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL: return "BufferUsageFlag::STORAGE_TEXEL"; + case stormkit::gpu::BufferUsageFlag::TRANSFER_DST: return "BufferUsageFlag::TRANSFER_DST"; + case stormkit::gpu::BufferUsageFlag::TRANSFER_SRC: return "BufferUsageFlag::TRANSFER_SRC"; + case stormkit::gpu::BufferUsageFlag::UNIFORM: return "BufferUsageFlag::UNIFORM"; + case stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL: return "BufferUsageFlag::UNIFORM_TEXEL"; + case stormkit::gpu::BufferUsageFlag::VERTEX: return "BufferUsageFlag::VERTEX"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ColorComponentFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ColorComponentFlag::A, stormkit::gpu::ColorComponentFlag::B, - stormkit::gpu::ColorComponentFlag::G, stormkit::gpu::ColorComponentFlag::NONE, - stormkit::gpu::ColorComponentFlag::R, stormkit::gpu::ColorComponentFlag::RG, - stormkit::gpu::ColorComponentFlag::RGB, stormkit::gpu::ColorComponentFlag::RGBA, - + stormkit::gpu::ColorComponentFlag::A, + stormkit::gpu::ColorComponentFlag::B, + stormkit::gpu::ColorComponentFlag::G, + stormkit::gpu::ColorComponentFlag::NONE, + stormkit::gpu::ColorComponentFlag::R, + stormkit::gpu::ColorComponentFlag::RG, + stormkit::gpu::ColorComponentFlag::RGB, + stormkit::gpu::ColorComponentFlag::RGBA, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ColorComponentFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ColorComponentFlag::A: return "ColorComponentFlag::A"; - case stormkit::gpu::ColorComponentFlag::B: return "ColorComponentFlag::B"; - case stormkit::gpu::ColorComponentFlag::G: return "ColorComponentFlag::G"; - case stormkit::gpu::ColorComponentFlag::NONE: return "ColorComponentFlag::NONE"; - case stormkit::gpu::ColorComponentFlag::R: return "ColorComponentFlag::R"; - case stormkit::gpu::ColorComponentFlag::RG: return "ColorComponentFlag::RG"; - case stormkit::gpu::ColorComponentFlag::RGB: return "ColorComponentFlag::RGB"; - case stormkit::gpu::ColorComponentFlag::RGBA: return "ColorComponentFlag::RGBA"; + constexpr auto stormkit::core::as_string(stormkit::gpu::ColorComponentFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ColorComponentFlag::A: return "ColorComponentFlag::A"; + case stormkit::gpu::ColorComponentFlag::B: return "ColorComponentFlag::B"; + case stormkit::gpu::ColorComponentFlag::G: return "ColorComponentFlag::G"; + case stormkit::gpu::ColorComponentFlag::NONE: return "ColorComponentFlag::NONE"; + case stormkit::gpu::ColorComponentFlag::R: return "ColorComponentFlag::R"; + case stormkit::gpu::ColorComponentFlag::RG: return "ColorComponentFlag::RG"; + case stormkit::gpu::ColorComponentFlag::RGB: return "ColorComponentFlag::RGB"; + case stormkit::gpu::ColorComponentFlag::RGBA: return "ColorComponentFlag::RGBA"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ColorComponentFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::ColorComponentFlag::A: return "ColorComponentFlag::A"; - case stormkit::gpu::ColorComponentFlag::B: return "ColorComponentFlag::B"; - case stormkit::gpu::ColorComponentFlag::G: return "ColorComponentFlag::G"; - case stormkit::gpu::ColorComponentFlag::NONE: return "ColorComponentFlag::NONE"; - case stormkit::gpu::ColorComponentFlag::R: return "ColorComponentFlag::R"; - case stormkit::gpu::ColorComponentFlag::RG: return "ColorComponentFlag::RG"; - case stormkit::gpu::ColorComponentFlag::RGB: return "ColorComponentFlag::RGB"; - case stormkit::gpu::ColorComponentFlag::RGBA: return "ColorComponentFlag::RGBA"; + constexpr auto stormkit::core::to_string(stormkit::gpu::ColorComponentFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::ColorComponentFlag::A: return "ColorComponentFlag::A"; + case stormkit::gpu::ColorComponentFlag::B: return "ColorComponentFlag::B"; + case stormkit::gpu::ColorComponentFlag::G: return "ColorComponentFlag::G"; + case stormkit::gpu::ColorComponentFlag::NONE: return "ColorComponentFlag::NONE"; + case stormkit::gpu::ColorComponentFlag::R: return "ColorComponentFlag::R"; + case stormkit::gpu::ColorComponentFlag::RG: return "ColorComponentFlag::RG"; + case stormkit::gpu::ColorComponentFlag::RGB: return "ColorComponentFlag::RGB"; + case stormkit::gpu::ColorComponentFlag::RGBA: return "ColorComponentFlag::RGBA"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ColorSpace) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ColorSpace::ADOBERGB_LINEAR, - stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR, - stormkit::gpu::ColorSpace::BT2020_LINEAR, - stormkit::gpu::ColorSpace::BT709_LINEAR, - stormkit::gpu::ColorSpace::BT709_NONLINEAR, - stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR, - stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD, - stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR, - stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR, - stormkit::gpu::ColorSpace::DOLBYVISION, - stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR, - stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR, - stormkit::gpu::ColorSpace::HDR10_HLG, - stormkit::gpu::ColorSpace::HDR10_ST2084, - stormkit::gpu::ColorSpace::PASS_THROUGH, - stormkit::gpu::ColorSpace::SRGB_NONLINEAR, - - }; - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ColorSpace value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; - case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: return "ColorSpace::ADOBERGB_NONLINEAR"; - case stormkit::gpu::ColorSpace::BT2020_LINEAR: return "ColorSpace::BT2020_LINEAR"; - case stormkit::gpu::ColorSpace::BT709_LINEAR: return "ColorSpace::BT709_LINEAR"; - case stormkit::gpu::ColorSpace::BT709_NONLINEAR: return "ColorSpace::BT709_NONLINEAR"; - case stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR: return "ColorSpace::DCI_P3_NONLINEAR"; - case stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD: return "ColorSpace::DISPLAY_NATIVE_AMD"; - case stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR: return "ColorSpace::DISPLAY_P3_LINEAR"; - case stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR: return "ColorSpace::DISPLAY_P3_NONLINEAR"; - case stormkit::gpu::ColorSpace::DOLBYVISION: return "ColorSpace::DOLBYVISION"; - case stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR: return "ColorSpace::EXTENDED_SRGB_LINEAR"; - case stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR: return "ColorSpace::EXTENDED_SRGB_NONLINEAR"; - case stormkit::gpu::ColorSpace::HDR10_HLG: return "ColorSpace::HDR10_HLG"; - case stormkit::gpu::ColorSpace::HDR10_ST2084: return "ColorSpace::HDR10_ST2084"; - case stormkit::gpu::ColorSpace::PASS_THROUGH: return "ColorSpace::PASS_THROUGH"; - case stormkit::gpu::ColorSpace::SRGB_NONLINEAR: return "ColorSpace::SRGB_NONLINEAR"; + stormkit::gpu::ColorSpace::ADOBERGB_LINEAR, + stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR, + stormkit::gpu::ColorSpace::BT2020_LINEAR, + stormkit::gpu::ColorSpace::BT709_LINEAR, + stormkit::gpu::ColorSpace::BT709_NONLINEAR, + stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR, + stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD, + stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR, + stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR, + stormkit::gpu::ColorSpace::DOLBYVISION, + stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR, + stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR, + stormkit::gpu::ColorSpace::HDR10_HLG, + stormkit::gpu::ColorSpace::HDR10_ST2084, + stormkit::gpu::ColorSpace::PASS_THROUGH, + stormkit::gpu::ColorSpace::SRGB_NONLINEAR, + + }; + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::ColorSpace value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; + case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: return "ColorSpace::ADOBERGB_NONLINEAR"; + case stormkit::gpu::ColorSpace::BT2020_LINEAR: return "ColorSpace::BT2020_LINEAR"; + case stormkit::gpu::ColorSpace::BT709_LINEAR: return "ColorSpace::BT709_LINEAR"; + case stormkit::gpu::ColorSpace::BT709_NONLINEAR: return "ColorSpace::BT709_NONLINEAR"; + case stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR: return "ColorSpace::DCI_P3_NONLINEAR"; + case stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD: return "ColorSpace::DISPLAY_NATIVE_AMD"; + case stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR: return "ColorSpace::DISPLAY_P3_LINEAR"; + case stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR: return "ColorSpace::DISPLAY_P3_NONLINEAR"; + case stormkit::gpu::ColorSpace::DOLBYVISION: return "ColorSpace::DOLBYVISION"; + case stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR: return "ColorSpace::EXTENDED_SRGB_LINEAR"; + case stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR: return "ColorSpace::EXTENDED_SRGB_NONLINEAR"; + case stormkit::gpu::ColorSpace::HDR10_HLG: return "ColorSpace::HDR10_HLG"; + case stormkit::gpu::ColorSpace::HDR10_ST2084: return "ColorSpace::HDR10_ST2084"; + case stormkit::gpu::ColorSpace::PASS_THROUGH: return "ColorSpace::PASS_THROUGH"; + case stormkit::gpu::ColorSpace::SRGB_NONLINEAR: return "ColorSpace::SRGB_NONLINEAR"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::ColorSpace value) noexcept -> std::string { - switch (value) { - case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; - case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: return "ColorSpace::ADOBERGB_NONLINEAR"; - case stormkit::gpu::ColorSpace::BT2020_LINEAR: return "ColorSpace::BT2020_LINEAR"; - case stormkit::gpu::ColorSpace::BT709_LINEAR: return "ColorSpace::BT709_LINEAR"; - case stormkit::gpu::ColorSpace::BT709_NONLINEAR: return "ColorSpace::BT709_NONLINEAR"; - case stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR: return "ColorSpace::DCI_P3_NONLINEAR"; - case stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD: return "ColorSpace::DISPLAY_NATIVE_AMD"; - case stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR: return "ColorSpace::DISPLAY_P3_LINEAR"; - case stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR: return "ColorSpace::DISPLAY_P3_NONLINEAR"; - case stormkit::gpu::ColorSpace::DOLBYVISION: return "ColorSpace::DOLBYVISION"; - case stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR: return "ColorSpace::EXTENDED_SRGB_LINEAR"; - case stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR: return "ColorSpace::EXTENDED_SRGB_NONLINEAR"; - case stormkit::gpu::ColorSpace::HDR10_HLG: return "ColorSpace::HDR10_HLG"; - case stormkit::gpu::ColorSpace::HDR10_ST2084: return "ColorSpace::HDR10_ST2084"; - case stormkit::gpu::ColorSpace::PASS_THROUGH: return "ColorSpace::PASS_THROUGH"; - case stormkit::gpu::ColorSpace::SRGB_NONLINEAR: return "ColorSpace::SRGB_NONLINEAR"; + switch(value) { + case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; + case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: return "ColorSpace::ADOBERGB_NONLINEAR"; + case stormkit::gpu::ColorSpace::BT2020_LINEAR: return "ColorSpace::BT2020_LINEAR"; + case stormkit::gpu::ColorSpace::BT709_LINEAR: return "ColorSpace::BT709_LINEAR"; + case stormkit::gpu::ColorSpace::BT709_NONLINEAR: return "ColorSpace::BT709_NONLINEAR"; + case stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR: return "ColorSpace::DCI_P3_NONLINEAR"; + case stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD: return "ColorSpace::DISPLAY_NATIVE_AMD"; + case stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR: return "ColorSpace::DISPLAY_P3_LINEAR"; + case stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR: return "ColorSpace::DISPLAY_P3_NONLINEAR"; + case stormkit::gpu::ColorSpace::DOLBYVISION: return "ColorSpace::DOLBYVISION"; + case stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR: return "ColorSpace::EXTENDED_SRGB_LINEAR"; + case stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR: return "ColorSpace::EXTENDED_SRGB_NONLINEAR"; + case stormkit::gpu::ColorSpace::HDR10_HLG: return "ColorSpace::HDR10_HLG"; + case stormkit::gpu::ColorSpace::HDR10_ST2084: return "ColorSpace::HDR10_ST2084"; + case stormkit::gpu::ColorSpace::PASS_THROUGH: return "ColorSpace::PASS_THROUGH"; + case stormkit::gpu::ColorSpace::SRGB_NONLINEAR: return "ColorSpace::SRGB_NONLINEAR"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::CommandBufferLevel) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::CommandBufferLevel::PRIMARY, - stormkit::gpu::CommandBufferLevel::SECONDARY, - + stormkit::gpu::CommandBufferLevel::PRIMARY, + stormkit::gpu::CommandBufferLevel::SECONDARY, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::CommandBufferLevel value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::CommandBufferLevel::PRIMARY: return "CommandBufferLevel::PRIMARY"; - case stormkit::gpu::CommandBufferLevel::SECONDARY: return "CommandBufferLevel::SECONDARY"; + constexpr auto stormkit::core::as_string(stormkit::gpu::CommandBufferLevel value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::CommandBufferLevel::PRIMARY: return "CommandBufferLevel::PRIMARY"; + case stormkit::gpu::CommandBufferLevel::SECONDARY: return "CommandBufferLevel::SECONDARY"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::CommandBufferLevel value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::CommandBufferLevel::PRIMARY: return "CommandBufferLevel::PRIMARY"; - case stormkit::gpu::CommandBufferLevel::SECONDARY: return "CommandBufferLevel::SECONDARY"; + constexpr auto stormkit::core::to_string(stormkit::gpu::CommandBufferLevel value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::CommandBufferLevel::PRIMARY: return "CommandBufferLevel::PRIMARY"; + case stormkit::gpu::CommandBufferLevel::SECONDARY: return "CommandBufferLevel::SECONDARY"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::CompareOperation) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::CompareOperation::ALWAYS, stormkit::gpu::CompareOperation::EQUAL, - stormkit::gpu::CompareOperation::GREATER, stormkit::gpu::CompareOperation::GREATER_OR_EQUAL, - stormkit::gpu::CompareOperation::LESS, stormkit::gpu::CompareOperation::LESS_OR_EQUAL, - stormkit::gpu::CompareOperation::NEVER, stormkit::gpu::CompareOperation::NOT_EQUAL, - + stormkit::gpu::CompareOperation::ALWAYS, + stormkit::gpu::CompareOperation::EQUAL, + stormkit::gpu::CompareOperation::GREATER, + stormkit::gpu::CompareOperation::GREATER_OR_EQUAL, + stormkit::gpu::CompareOperation::LESS, + stormkit::gpu::CompareOperation::LESS_OR_EQUAL, + stormkit::gpu::CompareOperation::NEVER, + stormkit::gpu::CompareOperation::NOT_EQUAL, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::CompareOperation value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::CompareOperation::ALWAYS: return "CompareOperation::ALWAYS"; - case stormkit::gpu::CompareOperation::EQUAL: return "CompareOperation::EQUAL"; - case stormkit::gpu::CompareOperation::GREATER: return "CompareOperation::GREATER"; - case stormkit::gpu::CompareOperation::GREATER_OR_EQUAL: return "CompareOperation::GREATER_OR_EQUAL"; - case stormkit::gpu::CompareOperation::LESS: return "CompareOperation::LESS"; - case stormkit::gpu::CompareOperation::LESS_OR_EQUAL: return "CompareOperation::LESS_OR_EQUAL"; - case stormkit::gpu::CompareOperation::NEVER: return "CompareOperation::NEVER"; - case stormkit::gpu::CompareOperation::NOT_EQUAL: return "CompareOperation::NOT_EQUAL"; + constexpr auto stormkit::core::as_string(stormkit::gpu::CompareOperation value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::CompareOperation::ALWAYS: return "CompareOperation::ALWAYS"; + case stormkit::gpu::CompareOperation::EQUAL: return "CompareOperation::EQUAL"; + case stormkit::gpu::CompareOperation::GREATER: return "CompareOperation::GREATER"; + case stormkit::gpu::CompareOperation::GREATER_OR_EQUAL: return "CompareOperation::GREATER_OR_EQUAL"; + case stormkit::gpu::CompareOperation::LESS: return "CompareOperation::LESS"; + case stormkit::gpu::CompareOperation::LESS_OR_EQUAL: return "CompareOperation::LESS_OR_EQUAL"; + case stormkit::gpu::CompareOperation::NEVER: return "CompareOperation::NEVER"; + case stormkit::gpu::CompareOperation::NOT_EQUAL: return "CompareOperation::NOT_EQUAL"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::CompareOperation value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::CompareOperation::ALWAYS: return "CompareOperation::ALWAYS"; - case stormkit::gpu::CompareOperation::EQUAL: return "CompareOperation::EQUAL"; - case stormkit::gpu::CompareOperation::GREATER: return "CompareOperation::GREATER"; - case stormkit::gpu::CompareOperation::GREATER_OR_EQUAL: return "CompareOperation::GREATER_OR_EQUAL"; - case stormkit::gpu::CompareOperation::LESS: return "CompareOperation::LESS"; - case stormkit::gpu::CompareOperation::LESS_OR_EQUAL: return "CompareOperation::LESS_OR_EQUAL"; - case stormkit::gpu::CompareOperation::NEVER: return "CompareOperation::NEVER"; - case stormkit::gpu::CompareOperation::NOT_EQUAL: return "CompareOperation::NOT_EQUAL"; + constexpr auto stormkit::core::to_string(stormkit::gpu::CompareOperation value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::CompareOperation::ALWAYS: return "CompareOperation::ALWAYS"; + case stormkit::gpu::CompareOperation::EQUAL: return "CompareOperation::EQUAL"; + case stormkit::gpu::CompareOperation::GREATER: return "CompareOperation::GREATER"; + case stormkit::gpu::CompareOperation::GREATER_OR_EQUAL: return "CompareOperation::GREATER_OR_EQUAL"; + case stormkit::gpu::CompareOperation::LESS: return "CompareOperation::LESS"; + case stormkit::gpu::CompareOperation::LESS_OR_EQUAL: return "CompareOperation::LESS_OR_EQUAL"; + case stormkit::gpu::CompareOperation::NEVER: return "CompareOperation::NEVER"; + case stormkit::gpu::CompareOperation::NOT_EQUAL: return "CompareOperation::NOT_EQUAL"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::CullModeFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::CullModeFlag::BACK, - stormkit::gpu::CullModeFlag::FRONT, - stormkit::gpu::CullModeFlag::FRONT_BACK, - stormkit::gpu::CullModeFlag::NONE, - + stormkit::gpu::CullModeFlag::BACK, + stormkit::gpu::CullModeFlag::FRONT, + stormkit::gpu::CullModeFlag::FRONT_BACK, + stormkit::gpu::CullModeFlag::NONE, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::CullModeFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::CullModeFlag::BACK: return "CullModeFlag::BACK"; - case stormkit::gpu::CullModeFlag::FRONT: return "CullModeFlag::FRONT"; - case stormkit::gpu::CullModeFlag::FRONT_BACK: return "CullModeFlag::FRONT_BACK"; - case stormkit::gpu::CullModeFlag::NONE: return "CullModeFlag::NONE"; + constexpr auto stormkit::core::as_string(stormkit::gpu::CullModeFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::CullModeFlag::BACK: return "CullModeFlag::BACK"; + case stormkit::gpu::CullModeFlag::FRONT: return "CullModeFlag::FRONT"; + case stormkit::gpu::CullModeFlag::FRONT_BACK: return "CullModeFlag::FRONT_BACK"; + case stormkit::gpu::CullModeFlag::NONE: return "CullModeFlag::NONE"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::CullModeFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::CullModeFlag::BACK: return "CullModeFlag::BACK"; - case stormkit::gpu::CullModeFlag::FRONT: return "CullModeFlag::FRONT"; - case stormkit::gpu::CullModeFlag::FRONT_BACK: return "CullModeFlag::FRONT_BACK"; - case stormkit::gpu::CullModeFlag::NONE: return "CullModeFlag::NONE"; + constexpr auto stormkit::core::to_string(stormkit::gpu::CullModeFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::CullModeFlag::BACK: return "CullModeFlag::BACK"; + case stormkit::gpu::CullModeFlag::FRONT: return "CullModeFlag::FRONT"; + case stormkit::gpu::CullModeFlag::FRONT_BACK: return "CullModeFlag::FRONT_BACK"; + case stormkit::gpu::CullModeFlag::NONE: return "CullModeFlag::NONE"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::DebugObjectType) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::DebugObjectType::BUFFER, - stormkit::gpu::DebugObjectType::BUFFER_VIEW, - stormkit::gpu::DebugObjectType::COMMAND_BUFFER, - stormkit::gpu::DebugObjectType::COMMAND_POOL, - stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK, - stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL, - stormkit::gpu::DebugObjectType::DESCRIPTOR_SET, - stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT, - stormkit::gpu::DebugObjectType::DEVICE, - stormkit::gpu::DebugObjectType::DEVICE_MEMORY, - stormkit::gpu::DebugObjectType::DISPLAY, - stormkit::gpu::DebugObjectType::EVENT, - stormkit::gpu::DebugObjectType::FENCE, - stormkit::gpu::DebugObjectType::FRAMEBUFFER, - stormkit::gpu::DebugObjectType::IMAGE, - stormkit::gpu::DebugObjectType::IMAGE_VIEW, - stormkit::gpu::DebugObjectType::INSTANCE, - stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE, - stormkit::gpu::DebugObjectType::PIPELINE, - stormkit::gpu::DebugObjectType::PIPELINE_CACHE, - stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT, - stormkit::gpu::DebugObjectType::QUERY_POOL, - stormkit::gpu::DebugObjectType::QUEUE, - stormkit::gpu::DebugObjectType::RENDER_PASS, - stormkit::gpu::DebugObjectType::SAMPLER, - stormkit::gpu::DebugObjectType::SEMAPHORE, - stormkit::gpu::DebugObjectType::SHADER_MODULE, - stormkit::gpu::DebugObjectType::SURFACE, - stormkit::gpu::DebugObjectType::SWAPCHAIN, - stormkit::gpu::DebugObjectType::UNKNOWN, - - }; - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::DebugObjectType value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::DebugObjectType::BUFFER: return "DebugObjectType::BUFFER"; - case stormkit::gpu::DebugObjectType::BUFFER_VIEW: return "DebugObjectType::BUFFER_VIEW"; - case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: return "DebugObjectType::COMMAND_BUFFER"; - case stormkit::gpu::DebugObjectType::COMMAND_POOL: return "DebugObjectType::COMMAND_POOL"; - case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: return "DebugObjectType::DEBUG_REPORT_CALLBACK"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: return "DebugObjectType::DESCRIPTOR_POOL"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: return "DebugObjectType::DESCRIPTOR_SET"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; - case stormkit::gpu::DebugObjectType::DEVICE: return "DebugObjectType::DEVICE"; - case stormkit::gpu::DebugObjectType::DEVICE_MEMORY: return "DebugObjectType::DEVICE_MEMORY"; - case stormkit::gpu::DebugObjectType::DISPLAY: return "DebugObjectType::DISPLAY"; - case stormkit::gpu::DebugObjectType::EVENT: return "DebugObjectType::EVENT"; - case stormkit::gpu::DebugObjectType::FENCE: return "DebugObjectType::FENCE"; - case stormkit::gpu::DebugObjectType::FRAMEBUFFER: return "DebugObjectType::FRAMEBUFFER"; - case stormkit::gpu::DebugObjectType::IMAGE: return "DebugObjectType::IMAGE"; - case stormkit::gpu::DebugObjectType::IMAGE_VIEW: return "DebugObjectType::IMAGE_VIEW"; - case stormkit::gpu::DebugObjectType::INSTANCE: return "DebugObjectType::INSTANCE"; - case stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE: return "DebugObjectType::PHYSICAL_DEVICE"; - case stormkit::gpu::DebugObjectType::PIPELINE: return "DebugObjectType::PIPELINE"; - case stormkit::gpu::DebugObjectType::PIPELINE_CACHE: return "DebugObjectType::PIPELINE_CACHE"; - case stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT: return "DebugObjectType::PIPELINE_LAYOUT"; - case stormkit::gpu::DebugObjectType::QUERY_POOL: return "DebugObjectType::QUERY_POOL"; - case stormkit::gpu::DebugObjectType::QUEUE: return "DebugObjectType::QUEUE"; - case stormkit::gpu::DebugObjectType::RENDER_PASS: return "DebugObjectType::RENDER_PASS"; - case stormkit::gpu::DebugObjectType::SAMPLER: return "DebugObjectType::SAMPLER"; - case stormkit::gpu::DebugObjectType::SEMAPHORE: return "DebugObjectType::SEMAPHORE"; - case stormkit::gpu::DebugObjectType::SHADER_MODULE: return "DebugObjectType::SHADER_MODULE"; - case stormkit::gpu::DebugObjectType::SURFACE: return "DebugObjectType::SURFACE"; - case stormkit::gpu::DebugObjectType::SWAPCHAIN: return "DebugObjectType::SWAPCHAIN"; - case stormkit::gpu::DebugObjectType::UNKNOWN: return "DebugObjectType::UNKNOWN"; - } - std::unreachable(); - } - - template<> - STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::DebugObjectType value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::DebugObjectType::BUFFER: return "DebugObjectType::BUFFER"; - case stormkit::gpu::DebugObjectType::BUFFER_VIEW: return "DebugObjectType::BUFFER_VIEW"; - case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: return "DebugObjectType::COMMAND_BUFFER"; - case stormkit::gpu::DebugObjectType::COMMAND_POOL: return "DebugObjectType::COMMAND_POOL"; - case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: return "DebugObjectType::DEBUG_REPORT_CALLBACK"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: return "DebugObjectType::DESCRIPTOR_POOL"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: return "DebugObjectType::DESCRIPTOR_SET"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; - case stormkit::gpu::DebugObjectType::DEVICE: return "DebugObjectType::DEVICE"; - case stormkit::gpu::DebugObjectType::DEVICE_MEMORY: return "DebugObjectType::DEVICE_MEMORY"; - case stormkit::gpu::DebugObjectType::DISPLAY: return "DebugObjectType::DISPLAY"; - case stormkit::gpu::DebugObjectType::EVENT: return "DebugObjectType::EVENT"; - case stormkit::gpu::DebugObjectType::FENCE: return "DebugObjectType::FENCE"; - case stormkit::gpu::DebugObjectType::FRAMEBUFFER: return "DebugObjectType::FRAMEBUFFER"; - case stormkit::gpu::DebugObjectType::IMAGE: return "DebugObjectType::IMAGE"; - case stormkit::gpu::DebugObjectType::IMAGE_VIEW: return "DebugObjectType::IMAGE_VIEW"; - case stormkit::gpu::DebugObjectType::INSTANCE: return "DebugObjectType::INSTANCE"; - case stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE: return "DebugObjectType::PHYSICAL_DEVICE"; - case stormkit::gpu::DebugObjectType::PIPELINE: return "DebugObjectType::PIPELINE"; - case stormkit::gpu::DebugObjectType::PIPELINE_CACHE: return "DebugObjectType::PIPELINE_CACHE"; - case stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT: return "DebugObjectType::PIPELINE_LAYOUT"; - case stormkit::gpu::DebugObjectType::QUERY_POOL: return "DebugObjectType::QUERY_POOL"; - case stormkit::gpu::DebugObjectType::QUEUE: return "DebugObjectType::QUEUE"; - case stormkit::gpu::DebugObjectType::RENDER_PASS: return "DebugObjectType::RENDER_PASS"; - case stormkit::gpu::DebugObjectType::SAMPLER: return "DebugObjectType::SAMPLER"; - case stormkit::gpu::DebugObjectType::SEMAPHORE: return "DebugObjectType::SEMAPHORE"; - case stormkit::gpu::DebugObjectType::SHADER_MODULE: return "DebugObjectType::SHADER_MODULE"; - case stormkit::gpu::DebugObjectType::SURFACE: return "DebugObjectType::SURFACE"; - case stormkit::gpu::DebugObjectType::SWAPCHAIN: return "DebugObjectType::SWAPCHAIN"; - case stormkit::gpu::DebugObjectType::UNKNOWN: return "DebugObjectType::UNKNOWN"; + stormkit::gpu::DebugObjectType::BUFFER, + stormkit::gpu::DebugObjectType::BUFFER_VIEW, + stormkit::gpu::DebugObjectType::COMMAND_BUFFER, + stormkit::gpu::DebugObjectType::COMMAND_POOL, + stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK, + stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL, + stormkit::gpu::DebugObjectType::DESCRIPTOR_SET, + stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT, + stormkit::gpu::DebugObjectType::DEVICE, + stormkit::gpu::DebugObjectType::DEVICE_MEMORY, + stormkit::gpu::DebugObjectType::DISPLAY, + stormkit::gpu::DebugObjectType::EVENT, + stormkit::gpu::DebugObjectType::FENCE, + stormkit::gpu::DebugObjectType::FRAMEBUFFER, + stormkit::gpu::DebugObjectType::IMAGE, + stormkit::gpu::DebugObjectType::IMAGE_VIEW, + stormkit::gpu::DebugObjectType::INSTANCE, + stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE, + stormkit::gpu::DebugObjectType::PIPELINE, + stormkit::gpu::DebugObjectType::PIPELINE_CACHE, + stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT, + stormkit::gpu::DebugObjectType::QUERY_POOL, + stormkit::gpu::DebugObjectType::QUEUE, + stormkit::gpu::DebugObjectType::RENDER_PASS, + stormkit::gpu::DebugObjectType::SAMPLER, + stormkit::gpu::DebugObjectType::SEMAPHORE, + stormkit::gpu::DebugObjectType::SHADER_MODULE, + stormkit::gpu::DebugObjectType::SURFACE, + stormkit::gpu::DebugObjectType::SWAPCHAIN, + stormkit::gpu::DebugObjectType::UNKNOWN, + + }; + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::DebugObjectType value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::DebugObjectType::BUFFER: return "DebugObjectType::BUFFER"; + case stormkit::gpu::DebugObjectType::BUFFER_VIEW: return "DebugObjectType::BUFFER_VIEW"; + case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: return "DebugObjectType::COMMAND_BUFFER"; + case stormkit::gpu::DebugObjectType::COMMAND_POOL: return "DebugObjectType::COMMAND_POOL"; + case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: return "DebugObjectType::DEBUG_REPORT_CALLBACK"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: return "DebugObjectType::DESCRIPTOR_POOL"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: return "DebugObjectType::DESCRIPTOR_SET"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; + case stormkit::gpu::DebugObjectType::DEVICE: return "DebugObjectType::DEVICE"; + case stormkit::gpu::DebugObjectType::DEVICE_MEMORY: return "DebugObjectType::DEVICE_MEMORY"; + case stormkit::gpu::DebugObjectType::DISPLAY: return "DebugObjectType::DISPLAY"; + case stormkit::gpu::DebugObjectType::EVENT: return "DebugObjectType::EVENT"; + case stormkit::gpu::DebugObjectType::FENCE: return "DebugObjectType::FENCE"; + case stormkit::gpu::DebugObjectType::FRAMEBUFFER: return "DebugObjectType::FRAMEBUFFER"; + case stormkit::gpu::DebugObjectType::IMAGE: return "DebugObjectType::IMAGE"; + case stormkit::gpu::DebugObjectType::IMAGE_VIEW: return "DebugObjectType::IMAGE_VIEW"; + case stormkit::gpu::DebugObjectType::INSTANCE: return "DebugObjectType::INSTANCE"; + case stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE: return "DebugObjectType::PHYSICAL_DEVICE"; + case stormkit::gpu::DebugObjectType::PIPELINE: return "DebugObjectType::PIPELINE"; + case stormkit::gpu::DebugObjectType::PIPELINE_CACHE: return "DebugObjectType::PIPELINE_CACHE"; + case stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT: return "DebugObjectType::PIPELINE_LAYOUT"; + case stormkit::gpu::DebugObjectType::QUERY_POOL: return "DebugObjectType::QUERY_POOL"; + case stormkit::gpu::DebugObjectType::QUEUE: return "DebugObjectType::QUEUE"; + case stormkit::gpu::DebugObjectType::RENDER_PASS: return "DebugObjectType::RENDER_PASS"; + case stormkit::gpu::DebugObjectType::SAMPLER: return "DebugObjectType::SAMPLER"; + case stormkit::gpu::DebugObjectType::SEMAPHORE: return "DebugObjectType::SEMAPHORE"; + case stormkit::gpu::DebugObjectType::SHADER_MODULE: return "DebugObjectType::SHADER_MODULE"; + case stormkit::gpu::DebugObjectType::SURFACE: return "DebugObjectType::SURFACE"; + case stormkit::gpu::DebugObjectType::SWAPCHAIN: return "DebugObjectType::SWAPCHAIN"; + case stormkit::gpu::DebugObjectType::UNKNOWN: return "DebugObjectType::UNKNOWN"; + + } + std::unreachable(); + } + template<> + STORMKIT_FORCE_INLINE + constexpr auto stormkit::core::to_string(stormkit::gpu::DebugObjectType value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::DebugObjectType::BUFFER: return "DebugObjectType::BUFFER"; + case stormkit::gpu::DebugObjectType::BUFFER_VIEW: return "DebugObjectType::BUFFER_VIEW"; + case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: return "DebugObjectType::COMMAND_BUFFER"; + case stormkit::gpu::DebugObjectType::COMMAND_POOL: return "DebugObjectType::COMMAND_POOL"; + case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: return "DebugObjectType::DEBUG_REPORT_CALLBACK"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: return "DebugObjectType::DESCRIPTOR_POOL"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: return "DebugObjectType::DESCRIPTOR_SET"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; + case stormkit::gpu::DebugObjectType::DEVICE: return "DebugObjectType::DEVICE"; + case stormkit::gpu::DebugObjectType::DEVICE_MEMORY: return "DebugObjectType::DEVICE_MEMORY"; + case stormkit::gpu::DebugObjectType::DISPLAY: return "DebugObjectType::DISPLAY"; + case stormkit::gpu::DebugObjectType::EVENT: return "DebugObjectType::EVENT"; + case stormkit::gpu::DebugObjectType::FENCE: return "DebugObjectType::FENCE"; + case stormkit::gpu::DebugObjectType::FRAMEBUFFER: return "DebugObjectType::FRAMEBUFFER"; + case stormkit::gpu::DebugObjectType::IMAGE: return "DebugObjectType::IMAGE"; + case stormkit::gpu::DebugObjectType::IMAGE_VIEW: return "DebugObjectType::IMAGE_VIEW"; + case stormkit::gpu::DebugObjectType::INSTANCE: return "DebugObjectType::INSTANCE"; + case stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE: return "DebugObjectType::PHYSICAL_DEVICE"; + case stormkit::gpu::DebugObjectType::PIPELINE: return "DebugObjectType::PIPELINE"; + case stormkit::gpu::DebugObjectType::PIPELINE_CACHE: return "DebugObjectType::PIPELINE_CACHE"; + case stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT: return "DebugObjectType::PIPELINE_LAYOUT"; + case stormkit::gpu::DebugObjectType::QUERY_POOL: return "DebugObjectType::QUERY_POOL"; + case stormkit::gpu::DebugObjectType::QUEUE: return "DebugObjectType::QUEUE"; + case stormkit::gpu::DebugObjectType::RENDER_PASS: return "DebugObjectType::RENDER_PASS"; + case stormkit::gpu::DebugObjectType::SAMPLER: return "DebugObjectType::SAMPLER"; + case stormkit::gpu::DebugObjectType::SEMAPHORE: return "DebugObjectType::SEMAPHORE"; + case stormkit::gpu::DebugObjectType::SHADER_MODULE: return "DebugObjectType::SHADER_MODULE"; + case stormkit::gpu::DebugObjectType::SURFACE: return "DebugObjectType::SURFACE"; + case stormkit::gpu::DebugObjectType::SWAPCHAIN: return "DebugObjectType::SWAPCHAIN"; + case stormkit::gpu::DebugObjectType::UNKNOWN: return "DebugObjectType::UNKNOWN"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::DependencyFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::DependencyFlag::BY_REGION, - stormkit::gpu::DependencyFlag::DEVICE_GROUP, - stormkit::gpu::DependencyFlag::NONE, - stormkit::gpu::DependencyFlag::VIEW_LOCAL, - + stormkit::gpu::DependencyFlag::BY_REGION, + stormkit::gpu::DependencyFlag::DEVICE_GROUP, + stormkit::gpu::DependencyFlag::NONE, + stormkit::gpu::DependencyFlag::VIEW_LOCAL, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::DependencyFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::DependencyFlag::BY_REGION: return "DependencyFlag::BY_REGION"; - case stormkit::gpu::DependencyFlag::DEVICE_GROUP: return "DependencyFlag::DEVICE_GROUP"; - case stormkit::gpu::DependencyFlag::NONE: return "DependencyFlag::NONE"; - case stormkit::gpu::DependencyFlag::VIEW_LOCAL: return "DependencyFlag::VIEW_LOCAL"; + constexpr auto stormkit::core::as_string(stormkit::gpu::DependencyFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::DependencyFlag::BY_REGION: return "DependencyFlag::BY_REGION"; + case stormkit::gpu::DependencyFlag::DEVICE_GROUP: return "DependencyFlag::DEVICE_GROUP"; + case stormkit::gpu::DependencyFlag::NONE: return "DependencyFlag::NONE"; + case stormkit::gpu::DependencyFlag::VIEW_LOCAL: return "DependencyFlag::VIEW_LOCAL"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::DependencyFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::DependencyFlag::BY_REGION: return "DependencyFlag::BY_REGION"; - case stormkit::gpu::DependencyFlag::DEVICE_GROUP: return "DependencyFlag::DEVICE_GROUP"; - case stormkit::gpu::DependencyFlag::NONE: return "DependencyFlag::NONE"; - case stormkit::gpu::DependencyFlag::VIEW_LOCAL: return "DependencyFlag::VIEW_LOCAL"; + constexpr auto stormkit::core::to_string(stormkit::gpu::DependencyFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::DependencyFlag::BY_REGION: return "DependencyFlag::BY_REGION"; + case stormkit::gpu::DependencyFlag::DEVICE_GROUP: return "DependencyFlag::DEVICE_GROUP"; + case stormkit::gpu::DependencyFlag::NONE: return "DependencyFlag::NONE"; + case stormkit::gpu::DependencyFlag::VIEW_LOCAL: return "DependencyFlag::VIEW_LOCAL"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::DescriptorType) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, stormkit::gpu::DescriptorType::INPUT_ATTACHMENT, - stormkit::gpu::DescriptorType::SAMPLED_IMAGE, stormkit::gpu::DescriptorType::SAMPLER, - stormkit::gpu::DescriptorType::STORAGE_BUFFER, stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC, - stormkit::gpu::DescriptorType::STORAGE_IMAGE, stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER, - stormkit::gpu::DescriptorType::UNIFORM_BUFFER, stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC, - stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER, - + stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, + stormkit::gpu::DescriptorType::INPUT_ATTACHMENT, + stormkit::gpu::DescriptorType::SAMPLED_IMAGE, + stormkit::gpu::DescriptorType::SAMPLER, + stormkit::gpu::DescriptorType::STORAGE_BUFFER, + stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC, + stormkit::gpu::DescriptorType::STORAGE_IMAGE, + stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER, + stormkit::gpu::DescriptorType::UNIFORM_BUFFER, + stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC, + stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::DescriptorType value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: return "DescriptorType::COMBINED_IMAGE_SAMPLER"; - case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: return "DescriptorType::INPUT_ATTACHMENT"; - case stormkit::gpu::DescriptorType::SAMPLED_IMAGE: return "DescriptorType::SAMPLED_IMAGE"; - case stormkit::gpu::DescriptorType::SAMPLER: return "DescriptorType::SAMPLER"; - case stormkit::gpu::DescriptorType::STORAGE_BUFFER: return "DescriptorType::STORAGE_BUFFER"; - case stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC: return "DescriptorType::STORAGE_BUFFER_DYNAMIC"; - case stormkit::gpu::DescriptorType::STORAGE_IMAGE: return "DescriptorType::STORAGE_IMAGE"; - case stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER: return "DescriptorType::STORAGE_TEXEL_BUFFER"; - case stormkit::gpu::DescriptorType::UNIFORM_BUFFER: return "DescriptorType::UNIFORM_BUFFER"; - case stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC: return "DescriptorType::UNIFORM_BUFFER_DYNAMIC"; - case stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER: return "DescriptorType::UNIFORM_TEXEL_BUFFER"; + constexpr auto stormkit::core::as_string(stormkit::gpu::DescriptorType value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: return "DescriptorType::COMBINED_IMAGE_SAMPLER"; + case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: return "DescriptorType::INPUT_ATTACHMENT"; + case stormkit::gpu::DescriptorType::SAMPLED_IMAGE: return "DescriptorType::SAMPLED_IMAGE"; + case stormkit::gpu::DescriptorType::SAMPLER: return "DescriptorType::SAMPLER"; + case stormkit::gpu::DescriptorType::STORAGE_BUFFER: return "DescriptorType::STORAGE_BUFFER"; + case stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC: return "DescriptorType::STORAGE_BUFFER_DYNAMIC"; + case stormkit::gpu::DescriptorType::STORAGE_IMAGE: return "DescriptorType::STORAGE_IMAGE"; + case stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER: return "DescriptorType::STORAGE_TEXEL_BUFFER"; + case stormkit::gpu::DescriptorType::UNIFORM_BUFFER: return "DescriptorType::UNIFORM_BUFFER"; + case stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC: return "DescriptorType::UNIFORM_BUFFER_DYNAMIC"; + case stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER: return "DescriptorType::UNIFORM_TEXEL_BUFFER"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::DescriptorType value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: return "DescriptorType::COMBINED_IMAGE_SAMPLER"; - case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: return "DescriptorType::INPUT_ATTACHMENT"; - case stormkit::gpu::DescriptorType::SAMPLED_IMAGE: return "DescriptorType::SAMPLED_IMAGE"; - case stormkit::gpu::DescriptorType::SAMPLER: return "DescriptorType::SAMPLER"; - case stormkit::gpu::DescriptorType::STORAGE_BUFFER: return "DescriptorType::STORAGE_BUFFER"; - case stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC: return "DescriptorType::STORAGE_BUFFER_DYNAMIC"; - case stormkit::gpu::DescriptorType::STORAGE_IMAGE: return "DescriptorType::STORAGE_IMAGE"; - case stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER: return "DescriptorType::STORAGE_TEXEL_BUFFER"; - case stormkit::gpu::DescriptorType::UNIFORM_BUFFER: return "DescriptorType::UNIFORM_BUFFER"; - case stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC: return "DescriptorType::UNIFORM_BUFFER_DYNAMIC"; - case stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER: return "DescriptorType::UNIFORM_TEXEL_BUFFER"; + constexpr auto stormkit::core::to_string(stormkit::gpu::DescriptorType value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: return "DescriptorType::COMBINED_IMAGE_SAMPLER"; + case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: return "DescriptorType::INPUT_ATTACHMENT"; + case stormkit::gpu::DescriptorType::SAMPLED_IMAGE: return "DescriptorType::SAMPLED_IMAGE"; + case stormkit::gpu::DescriptorType::SAMPLER: return "DescriptorType::SAMPLER"; + case stormkit::gpu::DescriptorType::STORAGE_BUFFER: return "DescriptorType::STORAGE_BUFFER"; + case stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC: return "DescriptorType::STORAGE_BUFFER_DYNAMIC"; + case stormkit::gpu::DescriptorType::STORAGE_IMAGE: return "DescriptorType::STORAGE_IMAGE"; + case stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER: return "DescriptorType::STORAGE_TEXEL_BUFFER"; + case stormkit::gpu::DescriptorType::UNIFORM_BUFFER: return "DescriptorType::UNIFORM_BUFFER"; + case stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC: return "DescriptorType::UNIFORM_BUFFER_DYNAMIC"; + case stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER: return "DescriptorType::UNIFORM_TEXEL_BUFFER"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::DynamicState) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::DynamicState::BLEND_CONSTANTS, stormkit::gpu::DynamicState::DEPTH_BIAS, - stormkit::gpu::DynamicState::DEPTH_BOUNDS, stormkit::gpu::DynamicState::LINE_WIDTH, - stormkit::gpu::DynamicState::SCISSOR, stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK, - stormkit::gpu::DynamicState::STENCIL_REFERENCE, stormkit::gpu::DynamicState::STENCIL_WRITE_MASK, - stormkit::gpu::DynamicState::VIEWPORT, - + stormkit::gpu::DynamicState::BLEND_CONSTANTS, + stormkit::gpu::DynamicState::DEPTH_BIAS, + stormkit::gpu::DynamicState::DEPTH_BOUNDS, + stormkit::gpu::DynamicState::LINE_WIDTH, + stormkit::gpu::DynamicState::SCISSOR, + stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK, + stormkit::gpu::DynamicState::STENCIL_REFERENCE, + stormkit::gpu::DynamicState::STENCIL_WRITE_MASK, + stormkit::gpu::DynamicState::VIEWPORT, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::DynamicState value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::DynamicState::BLEND_CONSTANTS: return "DynamicState::BLEND_CONSTANTS"; - case stormkit::gpu::DynamicState::DEPTH_BIAS: return "DynamicState::DEPTH_BIAS"; - case stormkit::gpu::DynamicState::DEPTH_BOUNDS: return "DynamicState::DEPTH_BOUNDS"; - case stormkit::gpu::DynamicState::LINE_WIDTH: return "DynamicState::LINE_WIDTH"; - case stormkit::gpu::DynamicState::SCISSOR: return "DynamicState::SCISSOR"; - case stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK: return "DynamicState::STENCIL_COMPARE_MASK"; - case stormkit::gpu::DynamicState::STENCIL_REFERENCE: return "DynamicState::STENCIL_REFERENCE"; - case stormkit::gpu::DynamicState::STENCIL_WRITE_MASK: return "DynamicState::STENCIL_WRITE_MASK"; - case stormkit::gpu::DynamicState::VIEWPORT: return "DynamicState::VIEWPORT"; + constexpr auto stormkit::core::as_string(stormkit::gpu::DynamicState value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::DynamicState::BLEND_CONSTANTS: return "DynamicState::BLEND_CONSTANTS"; + case stormkit::gpu::DynamicState::DEPTH_BIAS: return "DynamicState::DEPTH_BIAS"; + case stormkit::gpu::DynamicState::DEPTH_BOUNDS: return "DynamicState::DEPTH_BOUNDS"; + case stormkit::gpu::DynamicState::LINE_WIDTH: return "DynamicState::LINE_WIDTH"; + case stormkit::gpu::DynamicState::SCISSOR: return "DynamicState::SCISSOR"; + case stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK: return "DynamicState::STENCIL_COMPARE_MASK"; + case stormkit::gpu::DynamicState::STENCIL_REFERENCE: return "DynamicState::STENCIL_REFERENCE"; + case stormkit::gpu::DynamicState::STENCIL_WRITE_MASK: return "DynamicState::STENCIL_WRITE_MASK"; + case stormkit::gpu::DynamicState::VIEWPORT: return "DynamicState::VIEWPORT"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::DynamicState value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::DynamicState::BLEND_CONSTANTS: return "DynamicState::BLEND_CONSTANTS"; - case stormkit::gpu::DynamicState::DEPTH_BIAS: return "DynamicState::DEPTH_BIAS"; - case stormkit::gpu::DynamicState::DEPTH_BOUNDS: return "DynamicState::DEPTH_BOUNDS"; - case stormkit::gpu::DynamicState::LINE_WIDTH: return "DynamicState::LINE_WIDTH"; - case stormkit::gpu::DynamicState::SCISSOR: return "DynamicState::SCISSOR"; - case stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK: return "DynamicState::STENCIL_COMPARE_MASK"; - case stormkit::gpu::DynamicState::STENCIL_REFERENCE: return "DynamicState::STENCIL_REFERENCE"; - case stormkit::gpu::DynamicState::STENCIL_WRITE_MASK: return "DynamicState::STENCIL_WRITE_MASK"; - case stormkit::gpu::DynamicState::VIEWPORT: return "DynamicState::VIEWPORT"; + constexpr auto stormkit::core::to_string(stormkit::gpu::DynamicState value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::DynamicState::BLEND_CONSTANTS: return "DynamicState::BLEND_CONSTANTS"; + case stormkit::gpu::DynamicState::DEPTH_BIAS: return "DynamicState::DEPTH_BIAS"; + case stormkit::gpu::DynamicState::DEPTH_BOUNDS: return "DynamicState::DEPTH_BOUNDS"; + case stormkit::gpu::DynamicState::LINE_WIDTH: return "DynamicState::LINE_WIDTH"; + case stormkit::gpu::DynamicState::SCISSOR: return "DynamicState::SCISSOR"; + case stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK: return "DynamicState::STENCIL_COMPARE_MASK"; + case stormkit::gpu::DynamicState::STENCIL_REFERENCE: return "DynamicState::STENCIL_REFERENCE"; + case stormkit::gpu::DynamicState::STENCIL_WRITE_MASK: return "DynamicState::STENCIL_WRITE_MASK"; + case stormkit::gpu::DynamicState::VIEWPORT: return "DynamicState::VIEWPORT"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::Filter) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::Filter::CUBIC_IMG, - stormkit::gpu::Filter::LINEAR, - stormkit::gpu::Filter::NEAREST, - + stormkit::gpu::Filter::CUBIC_IMG, + stormkit::gpu::Filter::LINEAR, + stormkit::gpu::Filter::NEAREST, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::Filter value) noexcept -> std::string_view { - switch (value) { - case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; - case stormkit::gpu::Filter::LINEAR: return "Filter::LINEAR"; - case stormkit::gpu::Filter::NEAREST: return "Filter::NEAREST"; + switch(value) { + case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; + case stormkit::gpu::Filter::LINEAR: return "Filter::LINEAR"; + case stormkit::gpu::Filter::NEAREST: return "Filter::NEAREST"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::Filter value) noexcept -> std::string { - switch (value) { - case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; - case stormkit::gpu::Filter::LINEAR: return "Filter::LINEAR"; - case stormkit::gpu::Filter::NEAREST: return "Filter::NEAREST"; + switch(value) { + case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; + case stormkit::gpu::Filter::LINEAR: return "Filter::LINEAR"; + case stormkit::gpu::Filter::NEAREST: return "Filter::NEAREST"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::FormatFeatureFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::FormatFeatureFlag::BLIT_DST, - stormkit::gpu::FormatFeatureFlag::BLIT_SRC, - stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT, - stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND, - stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES, - stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT, - stormkit::gpu::FormatFeatureFlag::DISJOINT, - stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER, - stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE, - stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC, - stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER, - stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC, - stormkit::gpu::FormatFeatureFlag::TRANSFER_DST, - stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC, - stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER, - stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER, - - }; - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::FormatFeatureFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::FormatFeatureFlag::BLIT_DST: return "FormatFeatureFlag::BLIT_DST"; - case stormkit::gpu::FormatFeatureFlag::BLIT_SRC: return "FormatFeatureFlag::BLIT_SRC"; - case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT: return "FormatFeatureFlag::COLOR_ATTACHMENT"; - case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND: return "FormatFeatureFlag::COLOR_ATTACHMENT_BLEND"; - case stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES: return "FormatFeatureFlag::COSITED_CHROMA_SAMPLES"; - case stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT: return "FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT"; - case stormkit::gpu::FormatFeatureFlag::DISJOINT: return "FormatFeatureFlag::DISJOINT"; - case stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES: return "FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE: return "FormatFeatureFlag::SAMPLED_IMAGE"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR: - return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX: - return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT: - return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE: - return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER: - return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER: - return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE: return "FormatFeatureFlag::STORAGE_IMAGE"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC: return "FormatFeatureFlag::STORAGE_IMAGE_ATOMIC"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC: - return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC"; - case stormkit::gpu::FormatFeatureFlag::TRANSFER_DST: return "FormatFeatureFlag::TRANSFER_DST"; - case stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC: return "FormatFeatureFlag::TRANSFER_SRC"; - case stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER: return "FormatFeatureFlag::UNIFORM_TEXEL_BUFFER"; - case stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER: return "FormatFeatureFlag::VERTEX_BUFFER"; - } - std::unreachable(); - } - - template<> - STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::FormatFeatureFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::FormatFeatureFlag::BLIT_DST: return "FormatFeatureFlag::BLIT_DST"; - case stormkit::gpu::FormatFeatureFlag::BLIT_SRC: return "FormatFeatureFlag::BLIT_SRC"; - case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT: return "FormatFeatureFlag::COLOR_ATTACHMENT"; - case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND: return "FormatFeatureFlag::COLOR_ATTACHMENT_BLEND"; - case stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES: return "FormatFeatureFlag::COSITED_CHROMA_SAMPLES"; - case stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT: return "FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT"; - case stormkit::gpu::FormatFeatureFlag::DISJOINT: return "FormatFeatureFlag::DISJOINT"; - case stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES: return "FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE: return "FormatFeatureFlag::SAMPLED_IMAGE"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR: - return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX: - return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT: - return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE: - return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER: - return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER: - return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE: return "FormatFeatureFlag::STORAGE_IMAGE"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC: return "FormatFeatureFlag::STORAGE_IMAGE_ATOMIC"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC: - return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC"; - case stormkit::gpu::FormatFeatureFlag::TRANSFER_DST: return "FormatFeatureFlag::TRANSFER_DST"; - case stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC: return "FormatFeatureFlag::TRANSFER_SRC"; - case stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER: return "FormatFeatureFlag::UNIFORM_TEXEL_BUFFER"; - case stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER: return "FormatFeatureFlag::VERTEX_BUFFER"; + stormkit::gpu::FormatFeatureFlag::BLIT_DST, + stormkit::gpu::FormatFeatureFlag::BLIT_SRC, + stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT, + stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND, + stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES, + stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT, + stormkit::gpu::FormatFeatureFlag::DISJOINT, + stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER, + stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE, + stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC, + stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER, + stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC, + stormkit::gpu::FormatFeatureFlag::TRANSFER_DST, + stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC, + stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER, + stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER, + + }; + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::FormatFeatureFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::FormatFeatureFlag::BLIT_DST: return "FormatFeatureFlag::BLIT_DST"; + case stormkit::gpu::FormatFeatureFlag::BLIT_SRC: return "FormatFeatureFlag::BLIT_SRC"; + case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT: return "FormatFeatureFlag::COLOR_ATTACHMENT"; + case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND: return "FormatFeatureFlag::COLOR_ATTACHMENT_BLEND"; + case stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES: return "FormatFeatureFlag::COSITED_CHROMA_SAMPLES"; + case stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT: return "FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT"; + case stormkit::gpu::FormatFeatureFlag::DISJOINT: return "FormatFeatureFlag::DISJOINT"; + case stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES: return "FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE: return "FormatFeatureFlag::SAMPLED_IMAGE"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR: return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX: return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE: return "FormatFeatureFlag::STORAGE_IMAGE"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC: return "FormatFeatureFlag::STORAGE_IMAGE_ATOMIC"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC"; + case stormkit::gpu::FormatFeatureFlag::TRANSFER_DST: return "FormatFeatureFlag::TRANSFER_DST"; + case stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC: return "FormatFeatureFlag::TRANSFER_SRC"; + case stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER: return "FormatFeatureFlag::UNIFORM_TEXEL_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER: return "FormatFeatureFlag::VERTEX_BUFFER"; + + } + std::unreachable(); + } + template<> + STORMKIT_FORCE_INLINE + constexpr auto stormkit::core::to_string(stormkit::gpu::FormatFeatureFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::FormatFeatureFlag::BLIT_DST: return "FormatFeatureFlag::BLIT_DST"; + case stormkit::gpu::FormatFeatureFlag::BLIT_SRC: return "FormatFeatureFlag::BLIT_SRC"; + case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT: return "FormatFeatureFlag::COLOR_ATTACHMENT"; + case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND: return "FormatFeatureFlag::COLOR_ATTACHMENT_BLEND"; + case stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES: return "FormatFeatureFlag::COSITED_CHROMA_SAMPLES"; + case stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT: return "FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT"; + case stormkit::gpu::FormatFeatureFlag::DISJOINT: return "FormatFeatureFlag::DISJOINT"; + case stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES: return "FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE: return "FormatFeatureFlag::SAMPLED_IMAGE"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR: return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX: return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE: return "FormatFeatureFlag::STORAGE_IMAGE"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC: return "FormatFeatureFlag::STORAGE_IMAGE_ATOMIC"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC"; + case stormkit::gpu::FormatFeatureFlag::TRANSFER_DST: return "FormatFeatureFlag::TRANSFER_DST"; + case stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC: return "FormatFeatureFlag::TRANSFER_SRC"; + case stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER: return "FormatFeatureFlag::UNIFORM_TEXEL_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER: return "FormatFeatureFlag::VERTEX_BUFFER"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::FrontFace) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::FrontFace::CLOCKWISE, - stormkit::gpu::FrontFace::COUNTER_CLOCKWISE, - + stormkit::gpu::FrontFace::CLOCKWISE, + stormkit::gpu::FrontFace::COUNTER_CLOCKWISE, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::FrontFace value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; - case stormkit::gpu::FrontFace::COUNTER_CLOCKWISE: return "FrontFace::COUNTER_CLOCKWISE"; + constexpr auto stormkit::core::as_string(stormkit::gpu::FrontFace value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; + case stormkit::gpu::FrontFace::COUNTER_CLOCKWISE: return "FrontFace::COUNTER_CLOCKWISE"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::FrontFace value) noexcept -> std::string { - switch (value) { - case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; - case stormkit::gpu::FrontFace::COUNTER_CLOCKWISE: return "FrontFace::COUNTER_CLOCKWISE"; + switch(value) { + case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; + case stormkit::gpu::FrontFace::COUNTER_CLOCKWISE: return "FrontFace::COUNTER_CLOCKWISE"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::GeometryFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION, - stormkit::gpu::GeometryFlag::OPAQUE, - + stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION, + stormkit::gpu::GeometryFlag::OPAQUE, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::GeometryFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION: - return "GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION"; - case stormkit::gpu::GeometryFlag::OPAQUE: return "GeometryFlag::OPAQUE"; + constexpr auto stormkit::core::as_string(stormkit::gpu::GeometryFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION: return "GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION"; + case stormkit::gpu::GeometryFlag::OPAQUE: return "GeometryFlag::OPAQUE"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION: - return "GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION"; - case stormkit::gpu::GeometryFlag::OPAQUE: return "GeometryFlag::OPAQUE"; + constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION: return "GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION"; + case stormkit::gpu::GeometryFlag::OPAQUE: return "GeometryFlag::OPAQUE"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::GeometryType) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::GeometryType::AABBS, - stormkit::gpu::GeometryType::INSTANCES, - stormkit::gpu::GeometryType::TRIANGLES, - + stormkit::gpu::GeometryType::AABBS, + stormkit::gpu::GeometryType::INSTANCES, + stormkit::gpu::GeometryType::TRIANGLES, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::GeometryType value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::GeometryType::AABBS: return "GeometryType::AABBS"; - case stormkit::gpu::GeometryType::INSTANCES: return "GeometryType::INSTANCES"; - case stormkit::gpu::GeometryType::TRIANGLES: return "GeometryType::TRIANGLES"; + constexpr auto stormkit::core::as_string(stormkit::gpu::GeometryType value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::GeometryType::AABBS: return "GeometryType::AABBS"; + case stormkit::gpu::GeometryType::INSTANCES: return "GeometryType::INSTANCES"; + case stormkit::gpu::GeometryType::TRIANGLES: return "GeometryType::TRIANGLES"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryType value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::GeometryType::AABBS: return "GeometryType::AABBS"; - case stormkit::gpu::GeometryType::INSTANCES: return "GeometryType::INSTANCES"; - case stormkit::gpu::GeometryType::TRIANGLES: return "GeometryType::TRIANGLES"; + constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryType value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::GeometryType::AABBS: return "GeometryType::AABBS"; + case stormkit::gpu::GeometryType::INSTANCES: return "GeometryType::INSTANCES"; + case stormkit::gpu::GeometryType::TRIANGLES: return "GeometryType::TRIANGLES"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageAspectFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageAspectFlag::COLOR, - stormkit::gpu::ImageAspectFlag::DEPTH, - stormkit::gpu::ImageAspectFlag::NONE, - stormkit::gpu::ImageAspectFlag::STENCIL, - + stormkit::gpu::ImageAspectFlag::COLOR, + stormkit::gpu::ImageAspectFlag::DEPTH, + stormkit::gpu::ImageAspectFlag::NONE, + stormkit::gpu::ImageAspectFlag::STENCIL, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageAspectFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ImageAspectFlag::COLOR: return "ImageAspectFlag::COLOR"; - case stormkit::gpu::ImageAspectFlag::DEPTH: return "ImageAspectFlag::DEPTH"; - case stormkit::gpu::ImageAspectFlag::NONE: return "ImageAspectFlag::NONE"; - case stormkit::gpu::ImageAspectFlag::STENCIL: return "ImageAspectFlag::STENCIL"; + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageAspectFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ImageAspectFlag::COLOR: return "ImageAspectFlag::COLOR"; + case stormkit::gpu::ImageAspectFlag::DEPTH: return "ImageAspectFlag::DEPTH"; + case stormkit::gpu::ImageAspectFlag::NONE: return "ImageAspectFlag::NONE"; + case stormkit::gpu::ImageAspectFlag::STENCIL: return "ImageAspectFlag::STENCIL"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageAspectFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::ImageAspectFlag::COLOR: return "ImageAspectFlag::COLOR"; - case stormkit::gpu::ImageAspectFlag::DEPTH: return "ImageAspectFlag::DEPTH"; - case stormkit::gpu::ImageAspectFlag::NONE: return "ImageAspectFlag::NONE"; - case stormkit::gpu::ImageAspectFlag::STENCIL: return "ImageAspectFlag::STENCIL"; + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageAspectFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::ImageAspectFlag::COLOR: return "ImageAspectFlag::COLOR"; + case stormkit::gpu::ImageAspectFlag::DEPTH: return "ImageAspectFlag::DEPTH"; + case stormkit::gpu::ImageAspectFlag::NONE: return "ImageAspectFlag::NONE"; + case stormkit::gpu::ImageAspectFlag::STENCIL: return "ImageAspectFlag::STENCIL"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageCreateFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageCreateFlag::ALIAS, - stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE, - stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE, - stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE, - stormkit::gpu::ImageCreateFlag::DISJOINT, - stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE, - stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT, - stormkit::gpu::ImageCreateFlag::NONE, - stormkit::gpu::ImageCreateFlag::PROTECTED, - stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED, - stormkit::gpu::ImageCreateFlag::SPARSE_BINDING, - stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY, - stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS, - - }; - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageCreateFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ImageCreateFlag::ALIAS: return "ImageCreateFlag::ALIAS"; - case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE: - return "ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE: return "ImageCreateFlag::CUBE_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::DISJOINT: return "ImageCreateFlag::DISJOINT"; - case stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE: return "ImageCreateFlag::EXTENDED_USAGE"; - case stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT: return "ImageCreateFlag::MUTABLE_FORMAT"; - case stormkit::gpu::ImageCreateFlag::NONE: return "ImageCreateFlag::NONE"; - case stormkit::gpu::ImageCreateFlag::PROTECTED: return "ImageCreateFlag::PROTECTED"; - case stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED: return "ImageCreateFlag::SPARSE_ALIASED"; - case stormkit::gpu::ImageCreateFlag::SPARSE_BINDING: return "ImageCreateFlag::SPARSE_BINDING"; - case stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY: return "ImageCreateFlag::SPARSE_RESIDENCY"; - case stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS: - return "ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS"; - } - std::unreachable(); - } - - template<> - STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageCreateFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::ImageCreateFlag::ALIAS: return "ImageCreateFlag::ALIAS"; - case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE: - return "ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE: return "ImageCreateFlag::CUBE_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::DISJOINT: return "ImageCreateFlag::DISJOINT"; - case stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE: return "ImageCreateFlag::EXTENDED_USAGE"; - case stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT: return "ImageCreateFlag::MUTABLE_FORMAT"; - case stormkit::gpu::ImageCreateFlag::NONE: return "ImageCreateFlag::NONE"; - case stormkit::gpu::ImageCreateFlag::PROTECTED: return "ImageCreateFlag::PROTECTED"; - case stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED: return "ImageCreateFlag::SPARSE_ALIASED"; - case stormkit::gpu::ImageCreateFlag::SPARSE_BINDING: return "ImageCreateFlag::SPARSE_BINDING"; - case stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY: return "ImageCreateFlag::SPARSE_RESIDENCY"; - case stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS: - return "ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS"; + stormkit::gpu::ImageCreateFlag::ALIAS, + stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE, + stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE, + stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE, + stormkit::gpu::ImageCreateFlag::DISJOINT, + stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE, + stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT, + stormkit::gpu::ImageCreateFlag::NONE, + stormkit::gpu::ImageCreateFlag::PROTECTED, + stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED, + stormkit::gpu::ImageCreateFlag::SPARSE_BINDING, + stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY, + stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS, + + }; + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageCreateFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ImageCreateFlag::ALIAS: return "ImageCreateFlag::ALIAS"; + case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE: return "ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE: return "ImageCreateFlag::CUBE_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::DISJOINT: return "ImageCreateFlag::DISJOINT"; + case stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE: return "ImageCreateFlag::EXTENDED_USAGE"; + case stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT: return "ImageCreateFlag::MUTABLE_FORMAT"; + case stormkit::gpu::ImageCreateFlag::NONE: return "ImageCreateFlag::NONE"; + case stormkit::gpu::ImageCreateFlag::PROTECTED: return "ImageCreateFlag::PROTECTED"; + case stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED: return "ImageCreateFlag::SPARSE_ALIASED"; + case stormkit::gpu::ImageCreateFlag::SPARSE_BINDING: return "ImageCreateFlag::SPARSE_BINDING"; + case stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY: return "ImageCreateFlag::SPARSE_RESIDENCY"; + case stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS: return "ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS"; + + } + std::unreachable(); + } + template<> + STORMKIT_FORCE_INLINE + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageCreateFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::ImageCreateFlag::ALIAS: return "ImageCreateFlag::ALIAS"; + case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE: return "ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE: return "ImageCreateFlag::CUBE_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::DISJOINT: return "ImageCreateFlag::DISJOINT"; + case stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE: return "ImageCreateFlag::EXTENDED_USAGE"; + case stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT: return "ImageCreateFlag::MUTABLE_FORMAT"; + case stormkit::gpu::ImageCreateFlag::NONE: return "ImageCreateFlag::NONE"; + case stormkit::gpu::ImageCreateFlag::PROTECTED: return "ImageCreateFlag::PROTECTED"; + case stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED: return "ImageCreateFlag::SPARSE_ALIASED"; + case stormkit::gpu::ImageCreateFlag::SPARSE_BINDING: return "ImageCreateFlag::SPARSE_BINDING"; + case stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY: return "ImageCreateFlag::SPARSE_RESIDENCY"; + case stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS: return "ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageLayout) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL, - stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL, - stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, - stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, - stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL, - stormkit::gpu::ImageLayout::GENERAL, - stormkit::gpu::ImageLayout::PREINITIALIZED, - stormkit::gpu::ImageLayout::PRESENT_SRC, - stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL, - stormkit::gpu::ImageLayout::SHARED_PRESENT, - stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL, - stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL, - stormkit::gpu::ImageLayout::UNDEFINED, - - }; - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageLayout value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL: return "ImageLayout::ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: - return "ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: - return "ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL: - return "ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL: - return "ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::GENERAL: return "ImageLayout::GENERAL"; - case stormkit::gpu::ImageLayout::PREINITIALIZED: return "ImageLayout::PREINITIALIZED"; - case stormkit::gpu::ImageLayout::PRESENT_SRC: return "ImageLayout::PRESENT_SRC"; - case stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL: return "ImageLayout::SHADER_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::SHARED_PRESENT: return "ImageLayout::SHARED_PRESENT"; - case stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL: return "ImageLayout::TRANSFER_DST_OPTIMAL"; - case stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL: return "ImageLayout::TRANSFER_SRC_OPTIMAL"; - case stormkit::gpu::ImageLayout::UNDEFINED: return "ImageLayout::UNDEFINED"; - } - std::unreachable(); - } - - template<> - STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageLayout value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL: return "ImageLayout::ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: - return "ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: - return "ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL: - return "ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL: - return "ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::GENERAL: return "ImageLayout::GENERAL"; - case stormkit::gpu::ImageLayout::PREINITIALIZED: return "ImageLayout::PREINITIALIZED"; - case stormkit::gpu::ImageLayout::PRESENT_SRC: return "ImageLayout::PRESENT_SRC"; - case stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL: return "ImageLayout::SHADER_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::SHARED_PRESENT: return "ImageLayout::SHARED_PRESENT"; - case stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL: return "ImageLayout::TRANSFER_DST_OPTIMAL"; - case stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL: return "ImageLayout::TRANSFER_SRC_OPTIMAL"; - case stormkit::gpu::ImageLayout::UNDEFINED: return "ImageLayout::UNDEFINED"; + stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL, + stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL, + stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, + stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, + stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL, + stormkit::gpu::ImageLayout::GENERAL, + stormkit::gpu::ImageLayout::PREINITIALIZED, + stormkit::gpu::ImageLayout::PRESENT_SRC, + stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL, + stormkit::gpu::ImageLayout::SHARED_PRESENT, + stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL, + stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL, + stormkit::gpu::ImageLayout::UNDEFINED, + + }; + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageLayout value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL: return "ImageLayout::ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: return "ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: return "ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL: return "ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL: return "ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::GENERAL: return "ImageLayout::GENERAL"; + case stormkit::gpu::ImageLayout::PREINITIALIZED: return "ImageLayout::PREINITIALIZED"; + case stormkit::gpu::ImageLayout::PRESENT_SRC: return "ImageLayout::PRESENT_SRC"; + case stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL: return "ImageLayout::SHADER_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::SHARED_PRESENT: return "ImageLayout::SHARED_PRESENT"; + case stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL: return "ImageLayout::TRANSFER_DST_OPTIMAL"; + case stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL: return "ImageLayout::TRANSFER_SRC_OPTIMAL"; + case stormkit::gpu::ImageLayout::UNDEFINED: return "ImageLayout::UNDEFINED"; + + } + std::unreachable(); + } + template<> + STORMKIT_FORCE_INLINE + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageLayout value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL: return "ImageLayout::ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: return "ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: return "ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL: return "ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL: return "ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::GENERAL: return "ImageLayout::GENERAL"; + case stormkit::gpu::ImageLayout::PREINITIALIZED: return "ImageLayout::PREINITIALIZED"; + case stormkit::gpu::ImageLayout::PRESENT_SRC: return "ImageLayout::PRESENT_SRC"; + case stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL: return "ImageLayout::SHADER_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::SHARED_PRESENT: return "ImageLayout::SHARED_PRESENT"; + case stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL: return "ImageLayout::TRANSFER_DST_OPTIMAL"; + case stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL: return "ImageLayout::TRANSFER_SRC_OPTIMAL"; + case stormkit::gpu::ImageLayout::UNDEFINED: return "ImageLayout::UNDEFINED"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageTiling) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageTiling::LINEAR, - stormkit::gpu::ImageTiling::OPTIMAL, - + stormkit::gpu::ImageTiling::LINEAR, + stormkit::gpu::ImageTiling::OPTIMAL, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageTiling value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ImageTiling::LINEAR: return "ImageTiling::LINEAR"; - case stormkit::gpu::ImageTiling::OPTIMAL: return "ImageTiling::OPTIMAL"; + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageTiling value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ImageTiling::LINEAR: return "ImageTiling::LINEAR"; + case stormkit::gpu::ImageTiling::OPTIMAL: return "ImageTiling::OPTIMAL"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageTiling value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::ImageTiling::LINEAR: return "ImageTiling::LINEAR"; - case stormkit::gpu::ImageTiling::OPTIMAL: return "ImageTiling::OPTIMAL"; + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageTiling value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::ImageTiling::LINEAR: return "ImageTiling::LINEAR"; + case stormkit::gpu::ImageTiling::OPTIMAL: return "ImageTiling::OPTIMAL"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageType) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageType::T1D, - stormkit::gpu::ImageType::T2D, - stormkit::gpu::ImageType::T3D, - + stormkit::gpu::ImageType::T1D, + stormkit::gpu::ImageType::T2D, + stormkit::gpu::ImageType::T3D, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageType value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; - case stormkit::gpu::ImageType::T2D: return "ImageType::T2D"; - case stormkit::gpu::ImageType::T3D: return "ImageType::T3D"; + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageType value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; + case stormkit::gpu::ImageType::T2D: return "ImageType::T2D"; + case stormkit::gpu::ImageType::T3D: return "ImageType::T3D"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::ImageType value) noexcept -> std::string { - switch (value) { - case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; - case stormkit::gpu::ImageType::T2D: return "ImageType::T2D"; - case stormkit::gpu::ImageType::T3D: return "ImageType::T3D"; + switch(value) { + case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; + case stormkit::gpu::ImageType::T2D: return "ImageType::T2D"; + case stormkit::gpu::ImageType::T3D: return "ImageType::T3D"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageUsageFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT, stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT, - stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT, stormkit::gpu::ImageUsageFlag::SAMPLED, - stormkit::gpu::ImageUsageFlag::STORAGE, stormkit::gpu::ImageUsageFlag::TRANSFER_DST, - stormkit::gpu::ImageUsageFlag::TRANSFER_SRC, stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT, - + stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT, + stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT, + stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT, + stormkit::gpu::ImageUsageFlag::SAMPLED, + stormkit::gpu::ImageUsageFlag::STORAGE, + stormkit::gpu::ImageUsageFlag::TRANSFER_DST, + stormkit::gpu::ImageUsageFlag::TRANSFER_SRC, + stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageUsageFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: return "ImageUsageFlag::COLOR_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT: return "ImageUsageFlag::INPUT_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::SAMPLED: return "ImageUsageFlag::SAMPLED"; - case stormkit::gpu::ImageUsageFlag::STORAGE: return "ImageUsageFlag::STORAGE"; - case stormkit::gpu::ImageUsageFlag::TRANSFER_DST: return "ImageUsageFlag::TRANSFER_DST"; - case stormkit::gpu::ImageUsageFlag::TRANSFER_SRC: return "ImageUsageFlag::TRANSFER_SRC"; - case stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT: return "ImageUsageFlag::TRANSIENT_ATTACHMENT"; + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageUsageFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: return "ImageUsageFlag::COLOR_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT: return "ImageUsageFlag::INPUT_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::SAMPLED: return "ImageUsageFlag::SAMPLED"; + case stormkit::gpu::ImageUsageFlag::STORAGE: return "ImageUsageFlag::STORAGE"; + case stormkit::gpu::ImageUsageFlag::TRANSFER_DST: return "ImageUsageFlag::TRANSFER_DST"; + case stormkit::gpu::ImageUsageFlag::TRANSFER_SRC: return "ImageUsageFlag::TRANSFER_SRC"; + case stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT: return "ImageUsageFlag::TRANSIENT_ATTACHMENT"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageUsageFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: return "ImageUsageFlag::COLOR_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT: return "ImageUsageFlag::INPUT_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::SAMPLED: return "ImageUsageFlag::SAMPLED"; - case stormkit::gpu::ImageUsageFlag::STORAGE: return "ImageUsageFlag::STORAGE"; - case stormkit::gpu::ImageUsageFlag::TRANSFER_DST: return "ImageUsageFlag::TRANSFER_DST"; - case stormkit::gpu::ImageUsageFlag::TRANSFER_SRC: return "ImageUsageFlag::TRANSFER_SRC"; - case stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT: return "ImageUsageFlag::TRANSIENT_ATTACHMENT"; + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageUsageFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: return "ImageUsageFlag::COLOR_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT: return "ImageUsageFlag::INPUT_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::SAMPLED: return "ImageUsageFlag::SAMPLED"; + case stormkit::gpu::ImageUsageFlag::STORAGE: return "ImageUsageFlag::STORAGE"; + case stormkit::gpu::ImageUsageFlag::TRANSFER_DST: return "ImageUsageFlag::TRANSFER_DST"; + case stormkit::gpu::ImageUsageFlag::TRANSFER_SRC: return "ImageUsageFlag::TRANSFER_SRC"; + case stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT: return "ImageUsageFlag::TRANSIENT_ATTACHMENT"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageViewType) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageViewType::CUBE, stormkit::gpu::ImageViewType::CUBE_ARRAY, - stormkit::gpu::ImageViewType::T1D, stormkit::gpu::ImageViewType::T1D_ARRAY, - stormkit::gpu::ImageViewType::T2D, stormkit::gpu::ImageViewType::T2D_ARRAY, - stormkit::gpu::ImageViewType::T3D, - + stormkit::gpu::ImageViewType::CUBE, + stormkit::gpu::ImageViewType::CUBE_ARRAY, + stormkit::gpu::ImageViewType::T1D, + stormkit::gpu::ImageViewType::T1D_ARRAY, + stormkit::gpu::ImageViewType::T2D, + stormkit::gpu::ImageViewType::T2D_ARRAY, + stormkit::gpu::ImageViewType::T3D, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageViewType value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ImageViewType::CUBE: return "ImageViewType::CUBE"; - case stormkit::gpu::ImageViewType::CUBE_ARRAY: return "ImageViewType::CUBE_ARRAY"; - case stormkit::gpu::ImageViewType::T1D: return "ImageViewType::T1D"; - case stormkit::gpu::ImageViewType::T1D_ARRAY: return "ImageViewType::T1D_ARRAY"; - case stormkit::gpu::ImageViewType::T2D: return "ImageViewType::T2D"; - case stormkit::gpu::ImageViewType::T2D_ARRAY: return "ImageViewType::T2D_ARRAY"; - case stormkit::gpu::ImageViewType::T3D: return "ImageViewType::T3D"; + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageViewType value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ImageViewType::CUBE: return "ImageViewType::CUBE"; + case stormkit::gpu::ImageViewType::CUBE_ARRAY: return "ImageViewType::CUBE_ARRAY"; + case stormkit::gpu::ImageViewType::T1D: return "ImageViewType::T1D"; + case stormkit::gpu::ImageViewType::T1D_ARRAY: return "ImageViewType::T1D_ARRAY"; + case stormkit::gpu::ImageViewType::T2D: return "ImageViewType::T2D"; + case stormkit::gpu::ImageViewType::T2D_ARRAY: return "ImageViewType::T2D_ARRAY"; + case stormkit::gpu::ImageViewType::T3D: return "ImageViewType::T3D"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageViewType value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::ImageViewType::CUBE: return "ImageViewType::CUBE"; - case stormkit::gpu::ImageViewType::CUBE_ARRAY: return "ImageViewType::CUBE_ARRAY"; - case stormkit::gpu::ImageViewType::T1D: return "ImageViewType::T1D"; - case stormkit::gpu::ImageViewType::T1D_ARRAY: return "ImageViewType::T1D_ARRAY"; - case stormkit::gpu::ImageViewType::T2D: return "ImageViewType::T2D"; - case stormkit::gpu::ImageViewType::T2D_ARRAY: return "ImageViewType::T2D_ARRAY"; - case stormkit::gpu::ImageViewType::T3D: return "ImageViewType::T3D"; + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageViewType value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::ImageViewType::CUBE: return "ImageViewType::CUBE"; + case stormkit::gpu::ImageViewType::CUBE_ARRAY: return "ImageViewType::CUBE_ARRAY"; + case stormkit::gpu::ImageViewType::T1D: return "ImageViewType::T1D"; + case stormkit::gpu::ImageViewType::T1D_ARRAY: return "ImageViewType::T1D_ARRAY"; + case stormkit::gpu::ImageViewType::T2D: return "ImageViewType::T2D"; + case stormkit::gpu::ImageViewType::T2D_ARRAY: return "ImageViewType::T2D_ARRAY"; + case stormkit::gpu::ImageViewType::T3D: return "ImageViewType::T3D"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::LogicOperation) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::LogicOperation::AND, stormkit::gpu::LogicOperation::AND_INVERTED, - stormkit::gpu::LogicOperation::AND_REVERSE, stormkit::gpu::LogicOperation::CLEAR, - stormkit::gpu::LogicOperation::COPY, stormkit::gpu::LogicOperation::COPY_INVERTED, - stormkit::gpu::LogicOperation::EQUIVALENT, stormkit::gpu::LogicOperation::INVERT, - stormkit::gpu::LogicOperation::NAND, stormkit::gpu::LogicOperation::NOR, - stormkit::gpu::LogicOperation::NO_OP, stormkit::gpu::LogicOperation::OR, - stormkit::gpu::LogicOperation::OR_INVERTED, stormkit::gpu::LogicOperation::OR_REVERSE, - stormkit::gpu::LogicOperation::SET, stormkit::gpu::LogicOperation::XOR, - - }; - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::LogicOperation value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::LogicOperation::AND: return "LogicOperation::AND"; - case stormkit::gpu::LogicOperation::AND_INVERTED: return "LogicOperation::AND_INVERTED"; - case stormkit::gpu::LogicOperation::AND_REVERSE: return "LogicOperation::AND_REVERSE"; - case stormkit::gpu::LogicOperation::CLEAR: return "LogicOperation::CLEAR"; - case stormkit::gpu::LogicOperation::COPY: return "LogicOperation::COPY"; - case stormkit::gpu::LogicOperation::COPY_INVERTED: return "LogicOperation::COPY_INVERTED"; - case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; - case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; - case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; - case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; - case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; - case stormkit::gpu::LogicOperation::OR: return "LogicOperation::OR"; - case stormkit::gpu::LogicOperation::OR_INVERTED: return "LogicOperation::OR_INVERTED"; - case stormkit::gpu::LogicOperation::OR_REVERSE: return "LogicOperation::OR_REVERSE"; - case stormkit::gpu::LogicOperation::SET: return "LogicOperation::SET"; - case stormkit::gpu::LogicOperation::XOR: return "LogicOperation::XOR"; - } - std::unreachable(); - } - - template<> - STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::LogicOperation value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::LogicOperation::AND: return "LogicOperation::AND"; - case stormkit::gpu::LogicOperation::AND_INVERTED: return "LogicOperation::AND_INVERTED"; - case stormkit::gpu::LogicOperation::AND_REVERSE: return "LogicOperation::AND_REVERSE"; - case stormkit::gpu::LogicOperation::CLEAR: return "LogicOperation::CLEAR"; - case stormkit::gpu::LogicOperation::COPY: return "LogicOperation::COPY"; - case stormkit::gpu::LogicOperation::COPY_INVERTED: return "LogicOperation::COPY_INVERTED"; - case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; - case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; - case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; - case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; - case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; - case stormkit::gpu::LogicOperation::OR: return "LogicOperation::OR"; - case stormkit::gpu::LogicOperation::OR_INVERTED: return "LogicOperation::OR_INVERTED"; - case stormkit::gpu::LogicOperation::OR_REVERSE: return "LogicOperation::OR_REVERSE"; - case stormkit::gpu::LogicOperation::SET: return "LogicOperation::SET"; - case stormkit::gpu::LogicOperation::XOR: return "LogicOperation::XOR"; + stormkit::gpu::LogicOperation::AND, + stormkit::gpu::LogicOperation::AND_INVERTED, + stormkit::gpu::LogicOperation::AND_REVERSE, + stormkit::gpu::LogicOperation::CLEAR, + stormkit::gpu::LogicOperation::COPY, + stormkit::gpu::LogicOperation::COPY_INVERTED, + stormkit::gpu::LogicOperation::EQUIVALENT, + stormkit::gpu::LogicOperation::INVERT, + stormkit::gpu::LogicOperation::NAND, + stormkit::gpu::LogicOperation::NOR, + stormkit::gpu::LogicOperation::NO_OP, + stormkit::gpu::LogicOperation::OR, + stormkit::gpu::LogicOperation::OR_INVERTED, + stormkit::gpu::LogicOperation::OR_REVERSE, + stormkit::gpu::LogicOperation::SET, + stormkit::gpu::LogicOperation::XOR, + + }; + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::LogicOperation value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::LogicOperation::AND: return "LogicOperation::AND"; + case stormkit::gpu::LogicOperation::AND_INVERTED: return "LogicOperation::AND_INVERTED"; + case stormkit::gpu::LogicOperation::AND_REVERSE: return "LogicOperation::AND_REVERSE"; + case stormkit::gpu::LogicOperation::CLEAR: return "LogicOperation::CLEAR"; + case stormkit::gpu::LogicOperation::COPY: return "LogicOperation::COPY"; + case stormkit::gpu::LogicOperation::COPY_INVERTED: return "LogicOperation::COPY_INVERTED"; + case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; + case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; + case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; + case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; + case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; + case stormkit::gpu::LogicOperation::OR: return "LogicOperation::OR"; + case stormkit::gpu::LogicOperation::OR_INVERTED: return "LogicOperation::OR_INVERTED"; + case stormkit::gpu::LogicOperation::OR_REVERSE: return "LogicOperation::OR_REVERSE"; + case stormkit::gpu::LogicOperation::SET: return "LogicOperation::SET"; + case stormkit::gpu::LogicOperation::XOR: return "LogicOperation::XOR"; + + } + std::unreachable(); + } + template<> + STORMKIT_FORCE_INLINE + constexpr auto stormkit::core::to_string(stormkit::gpu::LogicOperation value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::LogicOperation::AND: return "LogicOperation::AND"; + case stormkit::gpu::LogicOperation::AND_INVERTED: return "LogicOperation::AND_INVERTED"; + case stormkit::gpu::LogicOperation::AND_REVERSE: return "LogicOperation::AND_REVERSE"; + case stormkit::gpu::LogicOperation::CLEAR: return "LogicOperation::CLEAR"; + case stormkit::gpu::LogicOperation::COPY: return "LogicOperation::COPY"; + case stormkit::gpu::LogicOperation::COPY_INVERTED: return "LogicOperation::COPY_INVERTED"; + case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; + case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; + case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; + case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; + case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; + case stormkit::gpu::LogicOperation::OR: return "LogicOperation::OR"; + case stormkit::gpu::LogicOperation::OR_INVERTED: return "LogicOperation::OR_INVERTED"; + case stormkit::gpu::LogicOperation::OR_REVERSE: return "LogicOperation::OR_REVERSE"; + case stormkit::gpu::LogicOperation::SET: return "LogicOperation::SET"; + case stormkit::gpu::LogicOperation::XOR: return "LogicOperation::XOR"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::MemoryPropertyFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL, - stormkit::gpu::MemoryPropertyFlag::HOST_CACHED, - stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT, - stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE, - + stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL, + stormkit::gpu::MemoryPropertyFlag::HOST_CACHED, + stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT, + stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::MemoryPropertyFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: return "MemoryPropertyFlag::DEVICE_LOCAL"; - case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: return "MemoryPropertyFlag::HOST_CACHED"; - case stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT: return "MemoryPropertyFlag::HOST_COHERENT"; - case stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE: return "MemoryPropertyFlag::HOST_VISIBLE"; + constexpr auto stormkit::core::as_string(stormkit::gpu::MemoryPropertyFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: return "MemoryPropertyFlag::DEVICE_LOCAL"; + case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: return "MemoryPropertyFlag::HOST_CACHED"; + case stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT: return "MemoryPropertyFlag::HOST_COHERENT"; + case stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE: return "MemoryPropertyFlag::HOST_VISIBLE"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::MemoryPropertyFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: return "MemoryPropertyFlag::DEVICE_LOCAL"; - case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: return "MemoryPropertyFlag::HOST_CACHED"; - case stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT: return "MemoryPropertyFlag::HOST_COHERENT"; - case stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE: return "MemoryPropertyFlag::HOST_VISIBLE"; + constexpr auto stormkit::core::to_string(stormkit::gpu::MemoryPropertyFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: return "MemoryPropertyFlag::DEVICE_LOCAL"; + case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: return "MemoryPropertyFlag::HOST_CACHED"; + case stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT: return "MemoryPropertyFlag::HOST_COHERENT"; + case stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE: return "MemoryPropertyFlag::HOST_VISIBLE"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PhysicalDeviceType) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PhysicalDeviceType::CPU, - stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU, - stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU, - stormkit::gpu::PhysicalDeviceType::OTHER, - stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU, - + stormkit::gpu::PhysicalDeviceType::CPU, + stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU, + stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU, + stormkit::gpu::PhysicalDeviceType::OTHER, + stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PhysicalDeviceType value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::PhysicalDeviceType::CPU: return "PhysicalDeviceType::CPU"; - case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: return "PhysicalDeviceType::DISCRETE_GPU"; - case stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU: return "PhysicalDeviceType::INTEGRATED_GPU"; - case stormkit::gpu::PhysicalDeviceType::OTHER: return "PhysicalDeviceType::OTHER"; - case stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU: return "PhysicalDeviceType::VIRTUAL_GPU"; + constexpr auto stormkit::core::as_string(stormkit::gpu::PhysicalDeviceType value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::PhysicalDeviceType::CPU: return "PhysicalDeviceType::CPU"; + case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: return "PhysicalDeviceType::DISCRETE_GPU"; + case stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU: return "PhysicalDeviceType::INTEGRATED_GPU"; + case stormkit::gpu::PhysicalDeviceType::OTHER: return "PhysicalDeviceType::OTHER"; + case stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU: return "PhysicalDeviceType::VIRTUAL_GPU"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::PhysicalDeviceType value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::PhysicalDeviceType::CPU: return "PhysicalDeviceType::CPU"; - case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: return "PhysicalDeviceType::DISCRETE_GPU"; - case stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU: return "PhysicalDeviceType::INTEGRATED_GPU"; - case stormkit::gpu::PhysicalDeviceType::OTHER: return "PhysicalDeviceType::OTHER"; - case stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU: return "PhysicalDeviceType::VIRTUAL_GPU"; + constexpr auto stormkit::core::to_string(stormkit::gpu::PhysicalDeviceType value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::PhysicalDeviceType::CPU: return "PhysicalDeviceType::CPU"; + case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: return "PhysicalDeviceType::DISCRETE_GPU"; + case stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU: return "PhysicalDeviceType::INTEGRATED_GPU"; + case stormkit::gpu::PhysicalDeviceType::OTHER: return "PhysicalDeviceType::OTHER"; + case stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU: return "PhysicalDeviceType::VIRTUAL_GPU"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PipelineBindPoint) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PipelineBindPoint::COMPUTE, - stormkit::gpu::PipelineBindPoint::GRAPHICS, - + stormkit::gpu::PipelineBindPoint::COMPUTE, + stormkit::gpu::PipelineBindPoint::GRAPHICS, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PipelineBindPoint value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::PipelineBindPoint::COMPUTE: return "PipelineBindPoint::COMPUTE"; - case stormkit::gpu::PipelineBindPoint::GRAPHICS: return "PipelineBindPoint::GRAPHICS"; + constexpr auto stormkit::core::as_string(stormkit::gpu::PipelineBindPoint value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::PipelineBindPoint::COMPUTE: return "PipelineBindPoint::COMPUTE"; + case stormkit::gpu::PipelineBindPoint::GRAPHICS: return "PipelineBindPoint::GRAPHICS"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineBindPoint value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::PipelineBindPoint::COMPUTE: return "PipelineBindPoint::COMPUTE"; - case stormkit::gpu::PipelineBindPoint::GRAPHICS: return "PipelineBindPoint::GRAPHICS"; + constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineBindPoint value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::PipelineBindPoint::COMPUTE: return "PipelineBindPoint::COMPUTE"; + case stormkit::gpu::PipelineBindPoint::GRAPHICS: return "PipelineBindPoint::GRAPHICS"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PipelineStageFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PipelineStageFlag::ALL_COMMANDS, - stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS, - stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE, - stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT, - stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER, - stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT, - stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS, - stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER, - stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER, - stormkit::gpu::PipelineStageFlag::HOST, - stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS, - stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER, - stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER, - stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE, - stormkit::gpu::PipelineStageFlag::TRANSFER, - stormkit::gpu::PipelineStageFlag::VERTEX_INPUT, - stormkit::gpu::PipelineStageFlag::VERTEX_SHADER, - - }; - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PipelineStageFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: return "PipelineStageFlag::ALL_COMMANDS"; - case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: return "PipelineStageFlag::ALL_GRAPHICS"; - case stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE: return "PipelineStageFlag::BOTTOM_OF_PIPE"; - case stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT: return "PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT"; - case stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER: return "PipelineStageFlag::COMPUTE_SHADER"; - case stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT: return "PipelineStageFlag::DRAW_INDIRECT"; - case stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS: return "PipelineStageFlag::EARLY_FRAGMENT_TESTS"; - case stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER: return "PipelineStageFlag::FRAGMENT_SHADER"; - case stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER: return "PipelineStageFlag::GEOMETRY_SHADER"; - case stormkit::gpu::PipelineStageFlag::HOST: return "PipelineStageFlag::HOST"; - case stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS: return "PipelineStageFlag::LATE_FRAGMENT_TESTS"; - case stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER: - return "PipelineStageFlag::TESSELLATION_CONTROL_SHADER"; - case stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER: - return "PipelineStageFlag::TESSELLATION_EVALUATION_SHADER"; - case stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE: return "PipelineStageFlag::TOP_OF_PIPE"; - case stormkit::gpu::PipelineStageFlag::TRANSFER: return "PipelineStageFlag::TRANSFER"; - case stormkit::gpu::PipelineStageFlag::VERTEX_INPUT: return "PipelineStageFlag::VERTEX_INPUT"; - case stormkit::gpu::PipelineStageFlag::VERTEX_SHADER: return "PipelineStageFlag::VERTEX_SHADER"; - } - std::unreachable(); - } - - template<> - STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineStageFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: return "PipelineStageFlag::ALL_COMMANDS"; - case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: return "PipelineStageFlag::ALL_GRAPHICS"; - case stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE: return "PipelineStageFlag::BOTTOM_OF_PIPE"; - case stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT: return "PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT"; - case stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER: return "PipelineStageFlag::COMPUTE_SHADER"; - case stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT: return "PipelineStageFlag::DRAW_INDIRECT"; - case stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS: return "PipelineStageFlag::EARLY_FRAGMENT_TESTS"; - case stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER: return "PipelineStageFlag::FRAGMENT_SHADER"; - case stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER: return "PipelineStageFlag::GEOMETRY_SHADER"; - case stormkit::gpu::PipelineStageFlag::HOST: return "PipelineStageFlag::HOST"; - case stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS: return "PipelineStageFlag::LATE_FRAGMENT_TESTS"; - case stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER: - return "PipelineStageFlag::TESSELLATION_CONTROL_SHADER"; - case stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER: - return "PipelineStageFlag::TESSELLATION_EVALUATION_SHADER"; - case stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE: return "PipelineStageFlag::TOP_OF_PIPE"; - case stormkit::gpu::PipelineStageFlag::TRANSFER: return "PipelineStageFlag::TRANSFER"; - case stormkit::gpu::PipelineStageFlag::VERTEX_INPUT: return "PipelineStageFlag::VERTEX_INPUT"; - case stormkit::gpu::PipelineStageFlag::VERTEX_SHADER: return "PipelineStageFlag::VERTEX_SHADER"; + stormkit::gpu::PipelineStageFlag::ALL_COMMANDS, + stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS, + stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE, + stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT, + stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER, + stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT, + stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS, + stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER, + stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER, + stormkit::gpu::PipelineStageFlag::HOST, + stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS, + stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER, + stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER, + stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE, + stormkit::gpu::PipelineStageFlag::TRANSFER, + stormkit::gpu::PipelineStageFlag::VERTEX_INPUT, + stormkit::gpu::PipelineStageFlag::VERTEX_SHADER, + + }; + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::PipelineStageFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: return "PipelineStageFlag::ALL_COMMANDS"; + case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: return "PipelineStageFlag::ALL_GRAPHICS"; + case stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE: return "PipelineStageFlag::BOTTOM_OF_PIPE"; + case stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT: return "PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT"; + case stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER: return "PipelineStageFlag::COMPUTE_SHADER"; + case stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT: return "PipelineStageFlag::DRAW_INDIRECT"; + case stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS: return "PipelineStageFlag::EARLY_FRAGMENT_TESTS"; + case stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER: return "PipelineStageFlag::FRAGMENT_SHADER"; + case stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER: return "PipelineStageFlag::GEOMETRY_SHADER"; + case stormkit::gpu::PipelineStageFlag::HOST: return "PipelineStageFlag::HOST"; + case stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS: return "PipelineStageFlag::LATE_FRAGMENT_TESTS"; + case stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER: return "PipelineStageFlag::TESSELLATION_CONTROL_SHADER"; + case stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER: return "PipelineStageFlag::TESSELLATION_EVALUATION_SHADER"; + case stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE: return "PipelineStageFlag::TOP_OF_PIPE"; + case stormkit::gpu::PipelineStageFlag::TRANSFER: return "PipelineStageFlag::TRANSFER"; + case stormkit::gpu::PipelineStageFlag::VERTEX_INPUT: return "PipelineStageFlag::VERTEX_INPUT"; + case stormkit::gpu::PipelineStageFlag::VERTEX_SHADER: return "PipelineStageFlag::VERTEX_SHADER"; + + } + std::unreachable(); + } + template<> + STORMKIT_FORCE_INLINE + constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineStageFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: return "PipelineStageFlag::ALL_COMMANDS"; + case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: return "PipelineStageFlag::ALL_GRAPHICS"; + case stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE: return "PipelineStageFlag::BOTTOM_OF_PIPE"; + case stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT: return "PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT"; + case stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER: return "PipelineStageFlag::COMPUTE_SHADER"; + case stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT: return "PipelineStageFlag::DRAW_INDIRECT"; + case stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS: return "PipelineStageFlag::EARLY_FRAGMENT_TESTS"; + case stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER: return "PipelineStageFlag::FRAGMENT_SHADER"; + case stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER: return "PipelineStageFlag::GEOMETRY_SHADER"; + case stormkit::gpu::PipelineStageFlag::HOST: return "PipelineStageFlag::HOST"; + case stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS: return "PipelineStageFlag::LATE_FRAGMENT_TESTS"; + case stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER: return "PipelineStageFlag::TESSELLATION_CONTROL_SHADER"; + case stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER: return "PipelineStageFlag::TESSELLATION_EVALUATION_SHADER"; + case stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE: return "PipelineStageFlag::TOP_OF_PIPE"; + case stormkit::gpu::PipelineStageFlag::TRANSFER: return "PipelineStageFlag::TRANSFER"; + case stormkit::gpu::PipelineStageFlag::VERTEX_INPUT: return "PipelineStageFlag::VERTEX_INPUT"; + case stormkit::gpu::PipelineStageFlag::VERTEX_SHADER: return "PipelineStageFlag::VERTEX_SHADER"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PixelFormat) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16, - stormkit::gpu::PixelFormat::A2_RGB10I_PACK32, - stormkit::gpu::PixelFormat::A2_RGB10U_PACK32, - stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32, - stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32, - stormkit::gpu::PixelFormat::B10_GR11UF_PACK32, - stormkit::gpu::PixelFormat::BGR8_UNORM, - stormkit::gpu::PixelFormat::BGRA8_UNORM, - stormkit::gpu::PixelFormat::DEPTH16_UNORM, - stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U, - stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32, - stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U, - stormkit::gpu::PixelFormat::DEPTH32F, - stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U, - stormkit::gpu::PixelFormat::R16F, - stormkit::gpu::PixelFormat::R16I, - stormkit::gpu::PixelFormat::R16U, - stormkit::gpu::PixelFormat::R16_SNORM, - stormkit::gpu::PixelFormat::R16_UNORM, - stormkit::gpu::PixelFormat::R32F, - stormkit::gpu::PixelFormat::R32I, - stormkit::gpu::PixelFormat::R32U, - stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16, - stormkit::gpu::PixelFormat::R8I, - stormkit::gpu::PixelFormat::R8U, - stormkit::gpu::PixelFormat::R8_SNORM, - stormkit::gpu::PixelFormat::R8_UNORM, - stormkit::gpu::PixelFormat::RG16F, - stormkit::gpu::PixelFormat::RG16I, - stormkit::gpu::PixelFormat::RG16U, - stormkit::gpu::PixelFormat::RG16_SNORM, - stormkit::gpu::PixelFormat::RG16_UNORM, - stormkit::gpu::PixelFormat::RG32F, - stormkit::gpu::PixelFormat::RG32I, - stormkit::gpu::PixelFormat::RG32U, - stormkit::gpu::PixelFormat::RG8I, - stormkit::gpu::PixelFormat::RG8U, - stormkit::gpu::PixelFormat::RG8_SNORM, - stormkit::gpu::PixelFormat::RG8_UNORM, - stormkit::gpu::PixelFormat::RGB16F, - stormkit::gpu::PixelFormat::RGB16I, - stormkit::gpu::PixelFormat::RGB16U, - stormkit::gpu::PixelFormat::RGB16_SNORM, - stormkit::gpu::PixelFormat::RGB16_UNORM, - stormkit::gpu::PixelFormat::RGB32F, - stormkit::gpu::PixelFormat::RGB32I, - stormkit::gpu::PixelFormat::RGB32U, - stormkit::gpu::PixelFormat::RGB8I, - stormkit::gpu::PixelFormat::RGB8U, - stormkit::gpu::PixelFormat::RGB8_SNORM, - stormkit::gpu::PixelFormat::RGB8_UNORM, - stormkit::gpu::PixelFormat::RGBA16F, - stormkit::gpu::PixelFormat::RGBA16I, - stormkit::gpu::PixelFormat::RGBA16U, - stormkit::gpu::PixelFormat::RGBA16_SNORM, - stormkit::gpu::PixelFormat::RGBA16_UNORM, - stormkit::gpu::PixelFormat::RGBA32F, - stormkit::gpu::PixelFormat::RGBA32I, - stormkit::gpu::PixelFormat::RGBA32U, - stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16, - stormkit::gpu::PixelFormat::RGBA8I, - stormkit::gpu::PixelFormat::RGBA8U, - stormkit::gpu::PixelFormat::RGBA8_SNORM, - stormkit::gpu::PixelFormat::RGBA8_UNORM, - stormkit::gpu::PixelFormat::SBGR8, - stormkit::gpu::PixelFormat::SBGRA8, - stormkit::gpu::PixelFormat::SR8, - stormkit::gpu::PixelFormat::SRG8, - stormkit::gpu::PixelFormat::SRGB8, - stormkit::gpu::PixelFormat::SRGBA8, - stormkit::gpu::PixelFormat::UNDEFINED, - - }; - } - - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PixelFormat value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; - case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; - case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; - case stormkit::gpu::PixelFormat::DEPTH16_UNORM: return "PixelFormat::DEPTH16_UNORM"; - case stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U: return "PixelFormat::DEPTH16_UNORM_STENCIL8U"; - case stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32: return "PixelFormat::DEPTH24_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U: return "PixelFormat::DEPTH24_UNORM_STENCIL8U"; - case stormkit::gpu::PixelFormat::DEPTH32F: return "PixelFormat::DEPTH32F"; - case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; - case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; - case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; - case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; - case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; - case stormkit::gpu::PixelFormat::R16_UNORM: return "PixelFormat::R16_UNORM"; - case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; - case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; - case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; - case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; - case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; - case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; - case stormkit::gpu::PixelFormat::R8_UNORM: return "PixelFormat::R8_UNORM"; - case stormkit::gpu::PixelFormat::RG16F: return "PixelFormat::RG16F"; - case stormkit::gpu::PixelFormat::RG16I: return "PixelFormat::RG16I"; - case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; - case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; - case stormkit::gpu::PixelFormat::RG16_UNORM: return "PixelFormat::RG16_UNORM"; - case stormkit::gpu::PixelFormat::RG32F: return "PixelFormat::RG32F"; - case stormkit::gpu::PixelFormat::RG32I: return "PixelFormat::RG32I"; - case stormkit::gpu::PixelFormat::RG32U: return "PixelFormat::RG32U"; - case stormkit::gpu::PixelFormat::RG8I: return "PixelFormat::RG8I"; - case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; - case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; - case stormkit::gpu::PixelFormat::RG8_UNORM: return "PixelFormat::RG8_UNORM"; - case stormkit::gpu::PixelFormat::RGB16F: return "PixelFormat::RGB16F"; - case stormkit::gpu::PixelFormat::RGB16I: return "PixelFormat::RGB16I"; - case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; - case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; - case stormkit::gpu::PixelFormat::RGB16_UNORM: return "PixelFormat::RGB16_UNORM"; - case stormkit::gpu::PixelFormat::RGB32F: return "PixelFormat::RGB32F"; - case stormkit::gpu::PixelFormat::RGB32I: return "PixelFormat::RGB32I"; - case stormkit::gpu::PixelFormat::RGB32U: return "PixelFormat::RGB32U"; - case stormkit::gpu::PixelFormat::RGB8I: return "PixelFormat::RGB8I"; - case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; - case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; - case stormkit::gpu::PixelFormat::RGB8_UNORM: return "PixelFormat::RGB8_UNORM"; - case stormkit::gpu::PixelFormat::RGBA16F: return "PixelFormat::RGBA16F"; - case stormkit::gpu::PixelFormat::RGBA16I: return "PixelFormat::RGBA16I"; - case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; - case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; - case stormkit::gpu::PixelFormat::RGBA16_UNORM: return "PixelFormat::RGBA16_UNORM"; - case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; - case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; - case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; - case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; - case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; - case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; - case stormkit::gpu::PixelFormat::RGBA8_UNORM: return "PixelFormat::RGBA8_UNORM"; - case stormkit::gpu::PixelFormat::SBGR8: return "PixelFormat::SBGR8"; - case stormkit::gpu::PixelFormat::SBGRA8: return "PixelFormat::SBGRA8"; - case stormkit::gpu::PixelFormat::SR8: return "PixelFormat::SR8"; - case stormkit::gpu::PixelFormat::SRG8: return "PixelFormat::SRG8"; - case stormkit::gpu::PixelFormat::SRGB8: return "PixelFormat::SRGB8"; - case stormkit::gpu::PixelFormat::SRGBA8: return "PixelFormat::SRGBA8"; - case stormkit::gpu::PixelFormat::UNDEFINED: return "PixelFormat::UNDEFINED"; - } - std::unreachable(); - } - - template<> - STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::PixelFormat value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; - case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; - case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; - case stormkit::gpu::PixelFormat::DEPTH16_UNORM: return "PixelFormat::DEPTH16_UNORM"; - case stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U: return "PixelFormat::DEPTH16_UNORM_STENCIL8U"; - case stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32: return "PixelFormat::DEPTH24_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U: return "PixelFormat::DEPTH24_UNORM_STENCIL8U"; - case stormkit::gpu::PixelFormat::DEPTH32F: return "PixelFormat::DEPTH32F"; - case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; - case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; - case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; - case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; - case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; - case stormkit::gpu::PixelFormat::R16_UNORM: return "PixelFormat::R16_UNORM"; - case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; - case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; - case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; - case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; - case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; - case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; - case stormkit::gpu::PixelFormat::R8_UNORM: return "PixelFormat::R8_UNORM"; - case stormkit::gpu::PixelFormat::RG16F: return "PixelFormat::RG16F"; - case stormkit::gpu::PixelFormat::RG16I: return "PixelFormat::RG16I"; - case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; - case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; - case stormkit::gpu::PixelFormat::RG16_UNORM: return "PixelFormat::RG16_UNORM"; - case stormkit::gpu::PixelFormat::RG32F: return "PixelFormat::RG32F"; - case stormkit::gpu::PixelFormat::RG32I: return "PixelFormat::RG32I"; - case stormkit::gpu::PixelFormat::RG32U: return "PixelFormat::RG32U"; - case stormkit::gpu::PixelFormat::RG8I: return "PixelFormat::RG8I"; - case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; - case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; - case stormkit::gpu::PixelFormat::RG8_UNORM: return "PixelFormat::RG8_UNORM"; - case stormkit::gpu::PixelFormat::RGB16F: return "PixelFormat::RGB16F"; - case stormkit::gpu::PixelFormat::RGB16I: return "PixelFormat::RGB16I"; - case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; - case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; - case stormkit::gpu::PixelFormat::RGB16_UNORM: return "PixelFormat::RGB16_UNORM"; - case stormkit::gpu::PixelFormat::RGB32F: return "PixelFormat::RGB32F"; - case stormkit::gpu::PixelFormat::RGB32I: return "PixelFormat::RGB32I"; - case stormkit::gpu::PixelFormat::RGB32U: return "PixelFormat::RGB32U"; - case stormkit::gpu::PixelFormat::RGB8I: return "PixelFormat::RGB8I"; - case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; - case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; - case stormkit::gpu::PixelFormat::RGB8_UNORM: return "PixelFormat::RGB8_UNORM"; - case stormkit::gpu::PixelFormat::RGBA16F: return "PixelFormat::RGBA16F"; - case stormkit::gpu::PixelFormat::RGBA16I: return "PixelFormat::RGBA16I"; - case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; - case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; - case stormkit::gpu::PixelFormat::RGBA16_UNORM: return "PixelFormat::RGBA16_UNORM"; - case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; - case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; - case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; - case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; - case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; - case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; - case stormkit::gpu::PixelFormat::RGBA8_UNORM: return "PixelFormat::RGBA8_UNORM"; - case stormkit::gpu::PixelFormat::SBGR8: return "PixelFormat::SBGR8"; - case stormkit::gpu::PixelFormat::SBGRA8: return "PixelFormat::SBGRA8"; - case stormkit::gpu::PixelFormat::SR8: return "PixelFormat::SR8"; - case stormkit::gpu::PixelFormat::SRG8: return "PixelFormat::SRG8"; - case stormkit::gpu::PixelFormat::SRGB8: return "PixelFormat::SRGB8"; - case stormkit::gpu::PixelFormat::SRGBA8: return "PixelFormat::SRGBA8"; - case stormkit::gpu::PixelFormat::UNDEFINED: return "PixelFormat::UNDEFINED"; + stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16, + stormkit::gpu::PixelFormat::A2_RGB10I_PACK32, + stormkit::gpu::PixelFormat::A2_RGB10U_PACK32, + stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32, + stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32, + stormkit::gpu::PixelFormat::B10_GR11UF_PACK32, + stormkit::gpu::PixelFormat::BGR8_UNORM, + stormkit::gpu::PixelFormat::BGRA8_UNORM, + stormkit::gpu::PixelFormat::DEPTH16_UNORM, + stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U, + stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32, + stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U, + stormkit::gpu::PixelFormat::DEPTH32F, + stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U, + stormkit::gpu::PixelFormat::R16F, + stormkit::gpu::PixelFormat::R16I, + stormkit::gpu::PixelFormat::R16U, + stormkit::gpu::PixelFormat::R16_SNORM, + stormkit::gpu::PixelFormat::R16_UNORM, + stormkit::gpu::PixelFormat::R32F, + stormkit::gpu::PixelFormat::R32I, + stormkit::gpu::PixelFormat::R32U, + stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16, + stormkit::gpu::PixelFormat::R8I, + stormkit::gpu::PixelFormat::R8U, + stormkit::gpu::PixelFormat::R8_SNORM, + stormkit::gpu::PixelFormat::R8_UNORM, + stormkit::gpu::PixelFormat::RG16F, + stormkit::gpu::PixelFormat::RG16I, + stormkit::gpu::PixelFormat::RG16U, + stormkit::gpu::PixelFormat::RG16_SNORM, + stormkit::gpu::PixelFormat::RG16_UNORM, + stormkit::gpu::PixelFormat::RG32F, + stormkit::gpu::PixelFormat::RG32I, + stormkit::gpu::PixelFormat::RG32U, + stormkit::gpu::PixelFormat::RG8I, + stormkit::gpu::PixelFormat::RG8U, + stormkit::gpu::PixelFormat::RG8_SNORM, + stormkit::gpu::PixelFormat::RG8_UNORM, + stormkit::gpu::PixelFormat::RGB16F, + stormkit::gpu::PixelFormat::RGB16I, + stormkit::gpu::PixelFormat::RGB16U, + stormkit::gpu::PixelFormat::RGB16_SNORM, + stormkit::gpu::PixelFormat::RGB16_UNORM, + stormkit::gpu::PixelFormat::RGB32F, + stormkit::gpu::PixelFormat::RGB32I, + stormkit::gpu::PixelFormat::RGB32U, + stormkit::gpu::PixelFormat::RGB8I, + stormkit::gpu::PixelFormat::RGB8U, + stormkit::gpu::PixelFormat::RGB8_SNORM, + stormkit::gpu::PixelFormat::RGB8_UNORM, + stormkit::gpu::PixelFormat::RGBA16F, + stormkit::gpu::PixelFormat::RGBA16I, + stormkit::gpu::PixelFormat::RGBA16U, + stormkit::gpu::PixelFormat::RGBA16_SNORM, + stormkit::gpu::PixelFormat::RGBA16_UNORM, + stormkit::gpu::PixelFormat::RGBA32F, + stormkit::gpu::PixelFormat::RGBA32I, + stormkit::gpu::PixelFormat::RGBA32U, + stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16, + stormkit::gpu::PixelFormat::RGBA8I, + stormkit::gpu::PixelFormat::RGBA8U, + stormkit::gpu::PixelFormat::RGBA8_SNORM, + stormkit::gpu::PixelFormat::RGBA8_UNORM, + stormkit::gpu::PixelFormat::SBGR8, + stormkit::gpu::PixelFormat::SBGRA8, + stormkit::gpu::PixelFormat::SR8, + stormkit::gpu::PixelFormat::SRG8, + stormkit::gpu::PixelFormat::SRGB8, + stormkit::gpu::PixelFormat::SRGBA8, + stormkit::gpu::PixelFormat::UNDEFINED, + + }; + } + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::PixelFormat value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; + case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; + case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; + case stormkit::gpu::PixelFormat::DEPTH16_UNORM: return "PixelFormat::DEPTH16_UNORM"; + case stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U: return "PixelFormat::DEPTH16_UNORM_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32: return "PixelFormat::DEPTH24_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U: return "PixelFormat::DEPTH24_UNORM_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH32F: return "PixelFormat::DEPTH32F"; + case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; + case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; + case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; + case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; + case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; + case stormkit::gpu::PixelFormat::R16_UNORM: return "PixelFormat::R16_UNORM"; + case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; + case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; + case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; + case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; + case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; + case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; + case stormkit::gpu::PixelFormat::R8_UNORM: return "PixelFormat::R8_UNORM"; + case stormkit::gpu::PixelFormat::RG16F: return "PixelFormat::RG16F"; + case stormkit::gpu::PixelFormat::RG16I: return "PixelFormat::RG16I"; + case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; + case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; + case stormkit::gpu::PixelFormat::RG16_UNORM: return "PixelFormat::RG16_UNORM"; + case stormkit::gpu::PixelFormat::RG32F: return "PixelFormat::RG32F"; + case stormkit::gpu::PixelFormat::RG32I: return "PixelFormat::RG32I"; + case stormkit::gpu::PixelFormat::RG32U: return "PixelFormat::RG32U"; + case stormkit::gpu::PixelFormat::RG8I: return "PixelFormat::RG8I"; + case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; + case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; + case stormkit::gpu::PixelFormat::RG8_UNORM: return "PixelFormat::RG8_UNORM"; + case stormkit::gpu::PixelFormat::RGB16F: return "PixelFormat::RGB16F"; + case stormkit::gpu::PixelFormat::RGB16I: return "PixelFormat::RGB16I"; + case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; + case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; + case stormkit::gpu::PixelFormat::RGB16_UNORM: return "PixelFormat::RGB16_UNORM"; + case stormkit::gpu::PixelFormat::RGB32F: return "PixelFormat::RGB32F"; + case stormkit::gpu::PixelFormat::RGB32I: return "PixelFormat::RGB32I"; + case stormkit::gpu::PixelFormat::RGB32U: return "PixelFormat::RGB32U"; + case stormkit::gpu::PixelFormat::RGB8I: return "PixelFormat::RGB8I"; + case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; + case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; + case stormkit::gpu::PixelFormat::RGB8_UNORM: return "PixelFormat::RGB8_UNORM"; + case stormkit::gpu::PixelFormat::RGBA16F: return "PixelFormat::RGBA16F"; + case stormkit::gpu::PixelFormat::RGBA16I: return "PixelFormat::RGBA16I"; + case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; + case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; + case stormkit::gpu::PixelFormat::RGBA16_UNORM: return "PixelFormat::RGBA16_UNORM"; + case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; + case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; + case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; + case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; + case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; + case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; + case stormkit::gpu::PixelFormat::RGBA8_UNORM: return "PixelFormat::RGBA8_UNORM"; + case stormkit::gpu::PixelFormat::SBGR8: return "PixelFormat::SBGR8"; + case stormkit::gpu::PixelFormat::SBGRA8: return "PixelFormat::SBGRA8"; + case stormkit::gpu::PixelFormat::SR8: return "PixelFormat::SR8"; + case stormkit::gpu::PixelFormat::SRG8: return "PixelFormat::SRG8"; + case stormkit::gpu::PixelFormat::SRGB8: return "PixelFormat::SRGB8"; + case stormkit::gpu::PixelFormat::SRGBA8: return "PixelFormat::SRGBA8"; + case stormkit::gpu::PixelFormat::UNDEFINED: return "PixelFormat::UNDEFINED"; + + } + std::unreachable(); + } + template<> + STORMKIT_FORCE_INLINE + constexpr auto stormkit::core::to_string(stormkit::gpu::PixelFormat value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; + case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; + case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; + case stormkit::gpu::PixelFormat::DEPTH16_UNORM: return "PixelFormat::DEPTH16_UNORM"; + case stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U: return "PixelFormat::DEPTH16_UNORM_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32: return "PixelFormat::DEPTH24_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U: return "PixelFormat::DEPTH24_UNORM_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH32F: return "PixelFormat::DEPTH32F"; + case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; + case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; + case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; + case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; + case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; + case stormkit::gpu::PixelFormat::R16_UNORM: return "PixelFormat::R16_UNORM"; + case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; + case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; + case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; + case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; + case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; + case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; + case stormkit::gpu::PixelFormat::R8_UNORM: return "PixelFormat::R8_UNORM"; + case stormkit::gpu::PixelFormat::RG16F: return "PixelFormat::RG16F"; + case stormkit::gpu::PixelFormat::RG16I: return "PixelFormat::RG16I"; + case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; + case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; + case stormkit::gpu::PixelFormat::RG16_UNORM: return "PixelFormat::RG16_UNORM"; + case stormkit::gpu::PixelFormat::RG32F: return "PixelFormat::RG32F"; + case stormkit::gpu::PixelFormat::RG32I: return "PixelFormat::RG32I"; + case stormkit::gpu::PixelFormat::RG32U: return "PixelFormat::RG32U"; + case stormkit::gpu::PixelFormat::RG8I: return "PixelFormat::RG8I"; + case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; + case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; + case stormkit::gpu::PixelFormat::RG8_UNORM: return "PixelFormat::RG8_UNORM"; + case stormkit::gpu::PixelFormat::RGB16F: return "PixelFormat::RGB16F"; + case stormkit::gpu::PixelFormat::RGB16I: return "PixelFormat::RGB16I"; + case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; + case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; + case stormkit::gpu::PixelFormat::RGB16_UNORM: return "PixelFormat::RGB16_UNORM"; + case stormkit::gpu::PixelFormat::RGB32F: return "PixelFormat::RGB32F"; + case stormkit::gpu::PixelFormat::RGB32I: return "PixelFormat::RGB32I"; + case stormkit::gpu::PixelFormat::RGB32U: return "PixelFormat::RGB32U"; + case stormkit::gpu::PixelFormat::RGB8I: return "PixelFormat::RGB8I"; + case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; + case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; + case stormkit::gpu::PixelFormat::RGB8_UNORM: return "PixelFormat::RGB8_UNORM"; + case stormkit::gpu::PixelFormat::RGBA16F: return "PixelFormat::RGBA16F"; + case stormkit::gpu::PixelFormat::RGBA16I: return "PixelFormat::RGBA16I"; + case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; + case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; + case stormkit::gpu::PixelFormat::RGBA16_UNORM: return "PixelFormat::RGBA16_UNORM"; + case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; + case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; + case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; + case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; + case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; + case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; + case stormkit::gpu::PixelFormat::RGBA8_UNORM: return "PixelFormat::RGBA8_UNORM"; + case stormkit::gpu::PixelFormat::SBGR8: return "PixelFormat::SBGR8"; + case stormkit::gpu::PixelFormat::SBGRA8: return "PixelFormat::SBGRA8"; + case stormkit::gpu::PixelFormat::SR8: return "PixelFormat::SR8"; + case stormkit::gpu::PixelFormat::SRG8: return "PixelFormat::SRG8"; + case stormkit::gpu::PixelFormat::SRGB8: return "PixelFormat::SRGB8"; + case stormkit::gpu::PixelFormat::SRGBA8: return "PixelFormat::SRGBA8"; + case stormkit::gpu::PixelFormat::UNDEFINED: return "PixelFormat::UNDEFINED"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PolygonMode) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PolygonMode::FILL, - stormkit::gpu::PolygonMode::LINE, - stormkit::gpu::PolygonMode::POINT, - + stormkit::gpu::PolygonMode::FILL, + stormkit::gpu::PolygonMode::LINE, + stormkit::gpu::PolygonMode::POINT, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PolygonMode value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::PolygonMode::FILL: return "PolygonMode::FILL"; - case stormkit::gpu::PolygonMode::LINE: return "PolygonMode::LINE"; - case stormkit::gpu::PolygonMode::POINT: return "PolygonMode::POINT"; + constexpr auto stormkit::core::as_string(stormkit::gpu::PolygonMode value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::PolygonMode::FILL: return "PolygonMode::FILL"; + case stormkit::gpu::PolygonMode::LINE: return "PolygonMode::LINE"; + case stormkit::gpu::PolygonMode::POINT: return "PolygonMode::POINT"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::PolygonMode value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::PolygonMode::FILL: return "PolygonMode::FILL"; - case stormkit::gpu::PolygonMode::LINE: return "PolygonMode::LINE"; - case stormkit::gpu::PolygonMode::POINT: return "PolygonMode::POINT"; + constexpr auto stormkit::core::to_string(stormkit::gpu::PolygonMode value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::PolygonMode::FILL: return "PolygonMode::FILL"; + case stormkit::gpu::PolygonMode::LINE: return "PolygonMode::LINE"; + case stormkit::gpu::PolygonMode::POINT: return "PolygonMode::POINT"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PresentMode) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PresentMode::FIFO, - stormkit::gpu::PresentMode::FIFO_RELAXED, - stormkit::gpu::PresentMode::IMMEDIATE, - stormkit::gpu::PresentMode::MAILBOX, - stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH, - stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH, - + stormkit::gpu::PresentMode::FIFO, + stormkit::gpu::PresentMode::FIFO_RELAXED, + stormkit::gpu::PresentMode::IMMEDIATE, + stormkit::gpu::PresentMode::MAILBOX, + stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH, + stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PresentMode value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::PresentMode::FIFO: return "PresentMode::FIFO"; - case stormkit::gpu::PresentMode::FIFO_RELAXED: return "PresentMode::FIFO_RELAXED"; - case stormkit::gpu::PresentMode::IMMEDIATE: return "PresentMode::IMMEDIATE"; - case stormkit::gpu::PresentMode::MAILBOX: return "PresentMode::MAILBOX"; - case stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH: return "PresentMode::SHARED_CONTINUOUS_REFRESH"; - case stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH: return "PresentMode::SHARED_DEMAND_REFRESH"; + constexpr auto stormkit::core::as_string(stormkit::gpu::PresentMode value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::PresentMode::FIFO: return "PresentMode::FIFO"; + case stormkit::gpu::PresentMode::FIFO_RELAXED: return "PresentMode::FIFO_RELAXED"; + case stormkit::gpu::PresentMode::IMMEDIATE: return "PresentMode::IMMEDIATE"; + case stormkit::gpu::PresentMode::MAILBOX: return "PresentMode::MAILBOX"; + case stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH: return "PresentMode::SHARED_CONTINUOUS_REFRESH"; + case stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH: return "PresentMode::SHARED_DEMAND_REFRESH"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::PresentMode value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::PresentMode::FIFO: return "PresentMode::FIFO"; - case stormkit::gpu::PresentMode::FIFO_RELAXED: return "PresentMode::FIFO_RELAXED"; - case stormkit::gpu::PresentMode::IMMEDIATE: return "PresentMode::IMMEDIATE"; - case stormkit::gpu::PresentMode::MAILBOX: return "PresentMode::MAILBOX"; - case stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH: return "PresentMode::SHARED_CONTINUOUS_REFRESH"; - case stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH: return "PresentMode::SHARED_DEMAND_REFRESH"; + constexpr auto stormkit::core::to_string(stormkit::gpu::PresentMode value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::PresentMode::FIFO: return "PresentMode::FIFO"; + case stormkit::gpu::PresentMode::FIFO_RELAXED: return "PresentMode::FIFO_RELAXED"; + case stormkit::gpu::PresentMode::IMMEDIATE: return "PresentMode::IMMEDIATE"; + case stormkit::gpu::PresentMode::MAILBOX: return "PresentMode::MAILBOX"; + case stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH: return "PresentMode::SHARED_CONTINUOUS_REFRESH"; + case stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH: return "PresentMode::SHARED_DEMAND_REFRESH"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PrimitiveTopology) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PrimitiveTopology::LINE_LIST, stormkit::gpu::PrimitiveTopology::LINE_STRIP, - stormkit::gpu::PrimitiveTopology::POINT_LIST, stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN, - stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST, stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP, - + stormkit::gpu::PrimitiveTopology::LINE_LIST, + stormkit::gpu::PrimitiveTopology::LINE_STRIP, + stormkit::gpu::PrimitiveTopology::POINT_LIST, + stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN, + stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST, + stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PrimitiveTopology value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::PrimitiveTopology::LINE_LIST: return "PrimitiveTopology::LINE_LIST"; - case stormkit::gpu::PrimitiveTopology::LINE_STRIP: return "PrimitiveTopology::LINE_STRIP"; - case stormkit::gpu::PrimitiveTopology::POINT_LIST: return "PrimitiveTopology::POINT_LIST"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN: return "PrimitiveTopology::TRIANGLE_FAN"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST: return "PrimitiveTopology::TRIANGLE_LIST"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP: return "PrimitiveTopology::TRIANGLE_STRIP"; + constexpr auto stormkit::core::as_string(stormkit::gpu::PrimitiveTopology value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::PrimitiveTopology::LINE_LIST: return "PrimitiveTopology::LINE_LIST"; + case stormkit::gpu::PrimitiveTopology::LINE_STRIP: return "PrimitiveTopology::LINE_STRIP"; + case stormkit::gpu::PrimitiveTopology::POINT_LIST: return "PrimitiveTopology::POINT_LIST"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN: return "PrimitiveTopology::TRIANGLE_FAN"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST: return "PrimitiveTopology::TRIANGLE_LIST"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP: return "PrimitiveTopology::TRIANGLE_STRIP"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::PrimitiveTopology value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::PrimitiveTopology::LINE_LIST: return "PrimitiveTopology::LINE_LIST"; - case stormkit::gpu::PrimitiveTopology::LINE_STRIP: return "PrimitiveTopology::LINE_STRIP"; - case stormkit::gpu::PrimitiveTopology::POINT_LIST: return "PrimitiveTopology::POINT_LIST"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN: return "PrimitiveTopology::TRIANGLE_FAN"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST: return "PrimitiveTopology::TRIANGLE_LIST"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP: return "PrimitiveTopology::TRIANGLE_STRIP"; + constexpr auto stormkit::core::to_string(stormkit::gpu::PrimitiveTopology value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::PrimitiveTopology::LINE_LIST: return "PrimitiveTopology::LINE_LIST"; + case stormkit::gpu::PrimitiveTopology::LINE_STRIP: return "PrimitiveTopology::LINE_STRIP"; + case stormkit::gpu::PrimitiveTopology::POINT_LIST: return "PrimitiveTopology::POINT_LIST"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN: return "PrimitiveTopology::TRIANGLE_FAN"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST: return "PrimitiveTopology::TRIANGLE_LIST"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP: return "PrimitiveTopology::TRIANGLE_STRIP"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::QueueFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::QueueFlag::COMPUTE, stormkit::gpu::QueueFlag::GRAPHICS, stormkit::gpu::QueueFlag::NONE, - stormkit::gpu::QueueFlag::PROTECTED, stormkit::gpu::QueueFlag::SPARSE_BINDING, stormkit::gpu::QueueFlag::TRANSFER, - + stormkit::gpu::QueueFlag::COMPUTE, + stormkit::gpu::QueueFlag::GRAPHICS, + stormkit::gpu::QueueFlag::NONE, + stormkit::gpu::QueueFlag::PROTECTED, + stormkit::gpu::QueueFlag::SPARSE_BINDING, + stormkit::gpu::QueueFlag::TRANSFER, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::QueueFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; - case stormkit::gpu::QueueFlag::GRAPHICS: return "QueueFlag::GRAPHICS"; - case stormkit::gpu::QueueFlag::NONE: return "QueueFlag::NONE"; - case stormkit::gpu::QueueFlag::PROTECTED: return "QueueFlag::PROTECTED"; - case stormkit::gpu::QueueFlag::SPARSE_BINDING: return "QueueFlag::SPARSE_BINDING"; - case stormkit::gpu::QueueFlag::TRANSFER: return "QueueFlag::TRANSFER"; + constexpr auto stormkit::core::as_string(stormkit::gpu::QueueFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; + case stormkit::gpu::QueueFlag::GRAPHICS: return "QueueFlag::GRAPHICS"; + case stormkit::gpu::QueueFlag::NONE: return "QueueFlag::NONE"; + case stormkit::gpu::QueueFlag::PROTECTED: return "QueueFlag::PROTECTED"; + case stormkit::gpu::QueueFlag::SPARSE_BINDING: return "QueueFlag::SPARSE_BINDING"; + case stormkit::gpu::QueueFlag::TRANSFER: return "QueueFlag::TRANSFER"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::QueueFlag value) noexcept -> std::string { - switch (value) { - case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; - case stormkit::gpu::QueueFlag::GRAPHICS: return "QueueFlag::GRAPHICS"; - case stormkit::gpu::QueueFlag::NONE: return "QueueFlag::NONE"; - case stormkit::gpu::QueueFlag::PROTECTED: return "QueueFlag::PROTECTED"; - case stormkit::gpu::QueueFlag::SPARSE_BINDING: return "QueueFlag::SPARSE_BINDING"; - case stormkit::gpu::QueueFlag::TRANSFER: return "QueueFlag::TRANSFER"; + switch(value) { + case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; + case stormkit::gpu::QueueFlag::GRAPHICS: return "QueueFlag::GRAPHICS"; + case stormkit::gpu::QueueFlag::NONE: return "QueueFlag::NONE"; + case stormkit::gpu::QueueFlag::PROTECTED: return "QueueFlag::PROTECTED"; + case stormkit::gpu::QueueFlag::SPARSE_BINDING: return "QueueFlag::SPARSE_BINDING"; + case stormkit::gpu::QueueFlag::TRANSFER: return "QueueFlag::TRANSFER"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ResolveModeFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ResolveModeFlag::AVERAGE, stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID, - stormkit::gpu::ResolveModeFlag::MAX, stormkit::gpu::ResolveModeFlag::MIN, - stormkit::gpu::ResolveModeFlag::NONE, stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO, - + stormkit::gpu::ResolveModeFlag::AVERAGE, + stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID, + stormkit::gpu::ResolveModeFlag::MAX, + stormkit::gpu::ResolveModeFlag::MIN, + stormkit::gpu::ResolveModeFlag::NONE, + stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ResolveModeFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ResolveModeFlag::AVERAGE: return "ResolveModeFlag::AVERAGE"; - case stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID: - return "ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID"; - case stormkit::gpu::ResolveModeFlag::MAX: return "ResolveModeFlag::MAX"; - case stormkit::gpu::ResolveModeFlag::MIN: return "ResolveModeFlag::MIN"; - case stormkit::gpu::ResolveModeFlag::NONE: return "ResolveModeFlag::NONE"; - case stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO: return "ResolveModeFlag::SAMPLE_ZERO"; + constexpr auto stormkit::core::as_string(stormkit::gpu::ResolveModeFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ResolveModeFlag::AVERAGE: return "ResolveModeFlag::AVERAGE"; + case stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID: return "ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID"; + case stormkit::gpu::ResolveModeFlag::MAX: return "ResolveModeFlag::MAX"; + case stormkit::gpu::ResolveModeFlag::MIN: return "ResolveModeFlag::MIN"; + case stormkit::gpu::ResolveModeFlag::NONE: return "ResolveModeFlag::NONE"; + case stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO: return "ResolveModeFlag::SAMPLE_ZERO"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ResolveModeFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::ResolveModeFlag::AVERAGE: return "ResolveModeFlag::AVERAGE"; - case stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID: - return "ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID"; - case stormkit::gpu::ResolveModeFlag::MAX: return "ResolveModeFlag::MAX"; - case stormkit::gpu::ResolveModeFlag::MIN: return "ResolveModeFlag::MIN"; - case stormkit::gpu::ResolveModeFlag::NONE: return "ResolveModeFlag::NONE"; - case stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO: return "ResolveModeFlag::SAMPLE_ZERO"; + constexpr auto stormkit::core::to_string(stormkit::gpu::ResolveModeFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::ResolveModeFlag::AVERAGE: return "ResolveModeFlag::AVERAGE"; + case stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID: return "ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID"; + case stormkit::gpu::ResolveModeFlag::MAX: return "ResolveModeFlag::MAX"; + case stormkit::gpu::ResolveModeFlag::MIN: return "ResolveModeFlag::MIN"; + case stormkit::gpu::ResolveModeFlag::NONE: return "ResolveModeFlag::NONE"; + case stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO: return "ResolveModeFlag::SAMPLE_ZERO"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::Result) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::Result::ERROR_DEVICE_LOST, - stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT, - stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT, - stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED, - stormkit::gpu::Result::ERROR_FRAGMENTATION, - stormkit::gpu::Result::ERROR_FRAGMENTED_POOL, - stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST, - stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY, - stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER, - stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED, - stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE, - stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, - stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT, - stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED, - stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE, - stormkit::gpu::Result::ERROR_NOT_PERMITTED, - stormkit::gpu::Result::ERROR_OUT_OF_DATE, - stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY, - stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY, - stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY, - stormkit::gpu::Result::ERROR_SURFACE_LOST, - stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS, - stormkit::gpu::Result::ERROR_UNKNOWN, - stormkit::gpu::Result::ERROR_VALIDATION_FAILED, - stormkit::gpu::Result::EVENT_RESET, - stormkit::gpu::Result::EVENT_SET, - stormkit::gpu::Result::INCOMPLETE, - stormkit::gpu::Result::NOT_READY, - stormkit::gpu::Result::OPERATION_DEFERRED, - stormkit::gpu::Result::OPERATION_NOT_DEFERRED, - stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED, - stormkit::gpu::Result::SUBOPTIMAL, - stormkit::gpu::Result::SUCCESS, - stormkit::gpu::Result::THREAD_DONE, - stormkit::gpu::Result::THREAD_IDLE, - stormkit::gpu::Result::TIMEOUT, - + stormkit::gpu::Result::ERROR_DEVICE_LOST, + stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT, + stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT, + stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED, + stormkit::gpu::Result::ERROR_FRAGMENTATION, + stormkit::gpu::Result::ERROR_FRAGMENTED_POOL, + stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST, + stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY, + stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER, + stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED, + stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE, + stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, + stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT, + stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED, + stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE, + stormkit::gpu::Result::ERROR_NOT_PERMITTED, + stormkit::gpu::Result::ERROR_OUT_OF_DATE, + stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY, + stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY, + stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY, + stormkit::gpu::Result::ERROR_SURFACE_LOST, + stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS, + stormkit::gpu::Result::ERROR_UNKNOWN, + stormkit::gpu::Result::ERROR_VALIDATION_FAILED, + stormkit::gpu::Result::EVENT_RESET, + stormkit::gpu::Result::EVENT_SET, + stormkit::gpu::Result::INCOMPLETE, + stormkit::gpu::Result::NOT_READY, + stormkit::gpu::Result::OPERATION_DEFERRED, + stormkit::gpu::Result::OPERATION_NOT_DEFERRED, + stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED, + stormkit::gpu::Result::SUBOPTIMAL, + stormkit::gpu::Result::SUCCESS, + stormkit::gpu::Result::THREAD_DONE, + stormkit::gpu::Result::THREAD_IDLE, + stormkit::gpu::Result::TIMEOUT, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::Result value) noexcept -> std::string_view { - switch (value) { - case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; - case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: return "Result::ERROR_EXTENSION_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT: return "Result::ERROR_FEATURE_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED: return "Result::ERROR_FORMAT_NOT_SUPPORTED"; - case stormkit::gpu::Result::ERROR_FRAGMENTATION: return "Result::ERROR_FRAGMENTATION"; - case stormkit::gpu::Result::ERROR_FRAGMENTED_POOL: return "Result::ERROR_FRAGMENTED_POOL"; - case stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST: - return "Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST"; - case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY: return "Result::ERROR_INCOMPATIBLE_DISPLAY"; - case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER: return "Result::ERROR_INCOMPATIBLE_DRIVER"; - case stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED: return "Result::ERROR_INITIALIZATION_FAILED"; - case stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE: return "Result::ERROR_INVALID_EXTERNAL_HANDLE"; - case stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: - return "Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; - case stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT: return "Result::ERROR_LAYER_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED: return "Result::ERROR_MEMORY_MAP_FAILED"; - case stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE: return "Result::ERROR_NATIVE_WINDOW_IN_USE"; - case stormkit::gpu::Result::ERROR_NOT_PERMITTED: return "Result::ERROR_NOT_PERMITTED"; - case stormkit::gpu::Result::ERROR_OUT_OF_DATE: return "Result::ERROR_OUT_OF_DATE"; - case stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY: return "Result::ERROR_OUT_OF_DEVICE_MEMORY"; - case stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY: return "Result::ERROR_OUT_OF_HOST_MEMORY"; - case stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY: return "Result::ERROR_OUT_OF_POOL_MEMORY"; - case stormkit::gpu::Result::ERROR_SURFACE_LOST: return "Result::ERROR_SURFACE_LOST"; - case stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS: return "Result::ERROR_TOO_MANY_OBJECTS"; - case stormkit::gpu::Result::ERROR_UNKNOWN: return "Result::ERROR_UNKNOWN"; - case stormkit::gpu::Result::ERROR_VALIDATION_FAILED: return "Result::ERROR_VALIDATION_FAILED"; - case stormkit::gpu::Result::EVENT_RESET: return "Result::EVENT_RESET"; - case stormkit::gpu::Result::EVENT_SET: return "Result::EVENT_SET"; - case stormkit::gpu::Result::INCOMPLETE: return "Result::INCOMPLETE"; - case stormkit::gpu::Result::NOT_READY: return "Result::NOT_READY"; - case stormkit::gpu::Result::OPERATION_DEFERRED: return "Result::OPERATION_DEFERRED"; - case stormkit::gpu::Result::OPERATION_NOT_DEFERRED: return "Result::OPERATION_NOT_DEFERRED"; - case stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED: return "Result::PIPELINE_COMPILE_REQUIRED"; - case stormkit::gpu::Result::SUBOPTIMAL: return "Result::SUBOPTIMAL"; - case stormkit::gpu::Result::SUCCESS: return "Result::SUCCESS"; - case stormkit::gpu::Result::THREAD_DONE: return "Result::THREAD_DONE"; - case stormkit::gpu::Result::THREAD_IDLE: return "Result::THREAD_IDLE"; - case stormkit::gpu::Result::TIMEOUT: return "Result::TIMEOUT"; + switch(value) { + case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; + case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: return "Result::ERROR_EXTENSION_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT: return "Result::ERROR_FEATURE_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED: return "Result::ERROR_FORMAT_NOT_SUPPORTED"; + case stormkit::gpu::Result::ERROR_FRAGMENTATION: return "Result::ERROR_FRAGMENTATION"; + case stormkit::gpu::Result::ERROR_FRAGMENTED_POOL: return "Result::ERROR_FRAGMENTED_POOL"; + case stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST: return "Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST"; + case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY: return "Result::ERROR_INCOMPATIBLE_DISPLAY"; + case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER: return "Result::ERROR_INCOMPATIBLE_DRIVER"; + case stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED: return "Result::ERROR_INITIALIZATION_FAILED"; + case stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE: return "Result::ERROR_INVALID_EXTERNAL_HANDLE"; + case stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: return "Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; + case stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT: return "Result::ERROR_LAYER_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED: return "Result::ERROR_MEMORY_MAP_FAILED"; + case stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE: return "Result::ERROR_NATIVE_WINDOW_IN_USE"; + case stormkit::gpu::Result::ERROR_NOT_PERMITTED: return "Result::ERROR_NOT_PERMITTED"; + case stormkit::gpu::Result::ERROR_OUT_OF_DATE: return "Result::ERROR_OUT_OF_DATE"; + case stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY: return "Result::ERROR_OUT_OF_DEVICE_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY: return "Result::ERROR_OUT_OF_HOST_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY: return "Result::ERROR_OUT_OF_POOL_MEMORY"; + case stormkit::gpu::Result::ERROR_SURFACE_LOST: return "Result::ERROR_SURFACE_LOST"; + case stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS: return "Result::ERROR_TOO_MANY_OBJECTS"; + case stormkit::gpu::Result::ERROR_UNKNOWN: return "Result::ERROR_UNKNOWN"; + case stormkit::gpu::Result::ERROR_VALIDATION_FAILED: return "Result::ERROR_VALIDATION_FAILED"; + case stormkit::gpu::Result::EVENT_RESET: return "Result::EVENT_RESET"; + case stormkit::gpu::Result::EVENT_SET: return "Result::EVENT_SET"; + case stormkit::gpu::Result::INCOMPLETE: return "Result::INCOMPLETE"; + case stormkit::gpu::Result::NOT_READY: return "Result::NOT_READY"; + case stormkit::gpu::Result::OPERATION_DEFERRED: return "Result::OPERATION_DEFERRED"; + case stormkit::gpu::Result::OPERATION_NOT_DEFERRED: return "Result::OPERATION_NOT_DEFERRED"; + case stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED: return "Result::PIPELINE_COMPILE_REQUIRED"; + case stormkit::gpu::Result::SUBOPTIMAL: return "Result::SUBOPTIMAL"; + case stormkit::gpu::Result::SUCCESS: return "Result::SUCCESS"; + case stormkit::gpu::Result::THREAD_DONE: return "Result::THREAD_DONE"; + case stormkit::gpu::Result::THREAD_IDLE: return "Result::THREAD_IDLE"; + case stormkit::gpu::Result::TIMEOUT: return "Result::TIMEOUT"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::Result value) noexcept -> std::string { - switch (value) { - case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; - case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: return "Result::ERROR_EXTENSION_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT: return "Result::ERROR_FEATURE_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED: return "Result::ERROR_FORMAT_NOT_SUPPORTED"; - case stormkit::gpu::Result::ERROR_FRAGMENTATION: return "Result::ERROR_FRAGMENTATION"; - case stormkit::gpu::Result::ERROR_FRAGMENTED_POOL: return "Result::ERROR_FRAGMENTED_POOL"; - case stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST: - return "Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST"; - case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY: return "Result::ERROR_INCOMPATIBLE_DISPLAY"; - case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER: return "Result::ERROR_INCOMPATIBLE_DRIVER"; - case stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED: return "Result::ERROR_INITIALIZATION_FAILED"; - case stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE: return "Result::ERROR_INVALID_EXTERNAL_HANDLE"; - case stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: - return "Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; - case stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT: return "Result::ERROR_LAYER_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED: return "Result::ERROR_MEMORY_MAP_FAILED"; - case stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE: return "Result::ERROR_NATIVE_WINDOW_IN_USE"; - case stormkit::gpu::Result::ERROR_NOT_PERMITTED: return "Result::ERROR_NOT_PERMITTED"; - case stormkit::gpu::Result::ERROR_OUT_OF_DATE: return "Result::ERROR_OUT_OF_DATE"; - case stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY: return "Result::ERROR_OUT_OF_DEVICE_MEMORY"; - case stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY: return "Result::ERROR_OUT_OF_HOST_MEMORY"; - case stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY: return "Result::ERROR_OUT_OF_POOL_MEMORY"; - case stormkit::gpu::Result::ERROR_SURFACE_LOST: return "Result::ERROR_SURFACE_LOST"; - case stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS: return "Result::ERROR_TOO_MANY_OBJECTS"; - case stormkit::gpu::Result::ERROR_UNKNOWN: return "Result::ERROR_UNKNOWN"; - case stormkit::gpu::Result::ERROR_VALIDATION_FAILED: return "Result::ERROR_VALIDATION_FAILED"; - case stormkit::gpu::Result::EVENT_RESET: return "Result::EVENT_RESET"; - case stormkit::gpu::Result::EVENT_SET: return "Result::EVENT_SET"; - case stormkit::gpu::Result::INCOMPLETE: return "Result::INCOMPLETE"; - case stormkit::gpu::Result::NOT_READY: return "Result::NOT_READY"; - case stormkit::gpu::Result::OPERATION_DEFERRED: return "Result::OPERATION_DEFERRED"; - case stormkit::gpu::Result::OPERATION_NOT_DEFERRED: return "Result::OPERATION_NOT_DEFERRED"; - case stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED: return "Result::PIPELINE_COMPILE_REQUIRED"; - case stormkit::gpu::Result::SUBOPTIMAL: return "Result::SUBOPTIMAL"; - case stormkit::gpu::Result::SUCCESS: return "Result::SUCCESS"; - case stormkit::gpu::Result::THREAD_DONE: return "Result::THREAD_DONE"; - case stormkit::gpu::Result::THREAD_IDLE: return "Result::THREAD_IDLE"; - case stormkit::gpu::Result::TIMEOUT: return "Result::TIMEOUT"; + switch(value) { + case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; + case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: return "Result::ERROR_EXTENSION_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT: return "Result::ERROR_FEATURE_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED: return "Result::ERROR_FORMAT_NOT_SUPPORTED"; + case stormkit::gpu::Result::ERROR_FRAGMENTATION: return "Result::ERROR_FRAGMENTATION"; + case stormkit::gpu::Result::ERROR_FRAGMENTED_POOL: return "Result::ERROR_FRAGMENTED_POOL"; + case stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST: return "Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST"; + case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY: return "Result::ERROR_INCOMPATIBLE_DISPLAY"; + case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER: return "Result::ERROR_INCOMPATIBLE_DRIVER"; + case stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED: return "Result::ERROR_INITIALIZATION_FAILED"; + case stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE: return "Result::ERROR_INVALID_EXTERNAL_HANDLE"; + case stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: return "Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; + case stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT: return "Result::ERROR_LAYER_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED: return "Result::ERROR_MEMORY_MAP_FAILED"; + case stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE: return "Result::ERROR_NATIVE_WINDOW_IN_USE"; + case stormkit::gpu::Result::ERROR_NOT_PERMITTED: return "Result::ERROR_NOT_PERMITTED"; + case stormkit::gpu::Result::ERROR_OUT_OF_DATE: return "Result::ERROR_OUT_OF_DATE"; + case stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY: return "Result::ERROR_OUT_OF_DEVICE_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY: return "Result::ERROR_OUT_OF_HOST_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY: return "Result::ERROR_OUT_OF_POOL_MEMORY"; + case stormkit::gpu::Result::ERROR_SURFACE_LOST: return "Result::ERROR_SURFACE_LOST"; + case stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS: return "Result::ERROR_TOO_MANY_OBJECTS"; + case stormkit::gpu::Result::ERROR_UNKNOWN: return "Result::ERROR_UNKNOWN"; + case stormkit::gpu::Result::ERROR_VALIDATION_FAILED: return "Result::ERROR_VALIDATION_FAILED"; + case stormkit::gpu::Result::EVENT_RESET: return "Result::EVENT_RESET"; + case stormkit::gpu::Result::EVENT_SET: return "Result::EVENT_SET"; + case stormkit::gpu::Result::INCOMPLETE: return "Result::INCOMPLETE"; + case stormkit::gpu::Result::NOT_READY: return "Result::NOT_READY"; + case stormkit::gpu::Result::OPERATION_DEFERRED: return "Result::OPERATION_DEFERRED"; + case stormkit::gpu::Result::OPERATION_NOT_DEFERRED: return "Result::OPERATION_NOT_DEFERRED"; + case stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED: return "Result::PIPELINE_COMPILE_REQUIRED"; + case stormkit::gpu::Result::SUBOPTIMAL: return "Result::SUBOPTIMAL"; + case stormkit::gpu::Result::SUCCESS: return "Result::SUCCESS"; + case stormkit::gpu::Result::THREAD_DONE: return "Result::THREAD_DONE"; + case stormkit::gpu::Result::THREAD_IDLE: return "Result::THREAD_IDLE"; + case stormkit::gpu::Result::TIMEOUT: return "Result::TIMEOUT"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::SampleCountFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::SampleCountFlag::C1, stormkit::gpu::SampleCountFlag::C16, stormkit::gpu::SampleCountFlag::C2, - stormkit::gpu::SampleCountFlag::C32, stormkit::gpu::SampleCountFlag::C4, stormkit::gpu::SampleCountFlag::C64, - stormkit::gpu::SampleCountFlag::C8, - + stormkit::gpu::SampleCountFlag::C1, + stormkit::gpu::SampleCountFlag::C16, + stormkit::gpu::SampleCountFlag::C2, + stormkit::gpu::SampleCountFlag::C32, + stormkit::gpu::SampleCountFlag::C4, + stormkit::gpu::SampleCountFlag::C64, + stormkit::gpu::SampleCountFlag::C8, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::SampleCountFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::SampleCountFlag::C1: return "SampleCountFlag::C1"; - case stormkit::gpu::SampleCountFlag::C16: return "SampleCountFlag::C16"; - case stormkit::gpu::SampleCountFlag::C2: return "SampleCountFlag::C2"; - case stormkit::gpu::SampleCountFlag::C32: return "SampleCountFlag::C32"; - case stormkit::gpu::SampleCountFlag::C4: return "SampleCountFlag::C4"; - case stormkit::gpu::SampleCountFlag::C64: return "SampleCountFlag::C64"; - case stormkit::gpu::SampleCountFlag::C8: return "SampleCountFlag::C8"; + constexpr auto stormkit::core::as_string(stormkit::gpu::SampleCountFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::SampleCountFlag::C1: return "SampleCountFlag::C1"; + case stormkit::gpu::SampleCountFlag::C16: return "SampleCountFlag::C16"; + case stormkit::gpu::SampleCountFlag::C2: return "SampleCountFlag::C2"; + case stormkit::gpu::SampleCountFlag::C32: return "SampleCountFlag::C32"; + case stormkit::gpu::SampleCountFlag::C4: return "SampleCountFlag::C4"; + case stormkit::gpu::SampleCountFlag::C64: return "SampleCountFlag::C64"; + case stormkit::gpu::SampleCountFlag::C8: return "SampleCountFlag::C8"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::SampleCountFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::SampleCountFlag::C1: return "SampleCountFlag::C1"; - case stormkit::gpu::SampleCountFlag::C16: return "SampleCountFlag::C16"; - case stormkit::gpu::SampleCountFlag::C2: return "SampleCountFlag::C2"; - case stormkit::gpu::SampleCountFlag::C32: return "SampleCountFlag::C32"; - case stormkit::gpu::SampleCountFlag::C4: return "SampleCountFlag::C4"; - case stormkit::gpu::SampleCountFlag::C64: return "SampleCountFlag::C64"; - case stormkit::gpu::SampleCountFlag::C8: return "SampleCountFlag::C8"; + constexpr auto stormkit::core::to_string(stormkit::gpu::SampleCountFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::SampleCountFlag::C1: return "SampleCountFlag::C1"; + case stormkit::gpu::SampleCountFlag::C16: return "SampleCountFlag::C16"; + case stormkit::gpu::SampleCountFlag::C2: return "SampleCountFlag::C2"; + case stormkit::gpu::SampleCountFlag::C32: return "SampleCountFlag::C32"; + case stormkit::gpu::SampleCountFlag::C4: return "SampleCountFlag::C4"; + case stormkit::gpu::SampleCountFlag::C64: return "SampleCountFlag::C64"; + case stormkit::gpu::SampleCountFlag::C8: return "SampleCountFlag::C8"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::SamplerAddressMode) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER, stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE, - stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT, stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE, - stormkit::gpu::SamplerAddressMode::REPEAT, - + stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER, + stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE, + stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT, + stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE, + stormkit::gpu::SamplerAddressMode::REPEAT, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::SamplerAddressMode value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; - case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; - case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; + constexpr auto stormkit::core::as_string(stormkit::gpu::SamplerAddressMode value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; + case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; + case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerAddressMode value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; - case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; - case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; + constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerAddressMode value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; + case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; + case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::SamplerMipmapMode) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::SamplerMipmapMode::LINEAR, - stormkit::gpu::SamplerMipmapMode::NEAREST, - + stormkit::gpu::SamplerMipmapMode::LINEAR, + stormkit::gpu::SamplerMipmapMode::NEAREST, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::SamplerMipmapMode value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::SamplerMipmapMode::LINEAR: return "SamplerMipmapMode::LINEAR"; - case stormkit::gpu::SamplerMipmapMode::NEAREST: return "SamplerMipmapMode::NEAREST"; + constexpr auto stormkit::core::as_string(stormkit::gpu::SamplerMipmapMode value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::SamplerMipmapMode::LINEAR: return "SamplerMipmapMode::LINEAR"; + case stormkit::gpu::SamplerMipmapMode::NEAREST: return "SamplerMipmapMode::NEAREST"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerMipmapMode value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::SamplerMipmapMode::LINEAR: return "SamplerMipmapMode::LINEAR"; - case stormkit::gpu::SamplerMipmapMode::NEAREST: return "SamplerMipmapMode::NEAREST"; + constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerMipmapMode value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::SamplerMipmapMode::LINEAR: return "SamplerMipmapMode::LINEAR"; + case stormkit::gpu::SamplerMipmapMode::NEAREST: return "SamplerMipmapMode::NEAREST"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ShaderStageFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ShaderStageFlag::COMPUTE, stormkit::gpu::ShaderStageFlag::FRAGMENT, - stormkit::gpu::ShaderStageFlag::GEOMETRY, stormkit::gpu::ShaderStageFlag::NONE, - stormkit::gpu::ShaderStageFlag::VERTEX, - + stormkit::gpu::ShaderStageFlag::COMPUTE, + stormkit::gpu::ShaderStageFlag::FRAGMENT, + stormkit::gpu::ShaderStageFlag::GEOMETRY, + stormkit::gpu::ShaderStageFlag::NONE, + stormkit::gpu::ShaderStageFlag::VERTEX, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ShaderStageFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::ShaderStageFlag::COMPUTE: return "ShaderStageFlag::COMPUTE"; - case stormkit::gpu::ShaderStageFlag::FRAGMENT: return "ShaderStageFlag::FRAGMENT"; - case stormkit::gpu::ShaderStageFlag::GEOMETRY: return "ShaderStageFlag::GEOMETRY"; - case stormkit::gpu::ShaderStageFlag::NONE: return "ShaderStageFlag::NONE"; - case stormkit::gpu::ShaderStageFlag::VERTEX: return "ShaderStageFlag::VERTEX"; + constexpr auto stormkit::core::as_string(stormkit::gpu::ShaderStageFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::ShaderStageFlag::COMPUTE: return "ShaderStageFlag::COMPUTE"; + case stormkit::gpu::ShaderStageFlag::FRAGMENT: return "ShaderStageFlag::FRAGMENT"; + case stormkit::gpu::ShaderStageFlag::GEOMETRY: return "ShaderStageFlag::GEOMETRY"; + case stormkit::gpu::ShaderStageFlag::NONE: return "ShaderStageFlag::NONE"; + case stormkit::gpu::ShaderStageFlag::VERTEX: return "ShaderStageFlag::VERTEX"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ShaderStageFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::ShaderStageFlag::COMPUTE: return "ShaderStageFlag::COMPUTE"; - case stormkit::gpu::ShaderStageFlag::FRAGMENT: return "ShaderStageFlag::FRAGMENT"; - case stormkit::gpu::ShaderStageFlag::GEOMETRY: return "ShaderStageFlag::GEOMETRY"; - case stormkit::gpu::ShaderStageFlag::NONE: return "ShaderStageFlag::NONE"; - case stormkit::gpu::ShaderStageFlag::VERTEX: return "ShaderStageFlag::VERTEX"; + constexpr auto stormkit::core::to_string(stormkit::gpu::ShaderStageFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::ShaderStageFlag::COMPUTE: return "ShaderStageFlag::COMPUTE"; + case stormkit::gpu::ShaderStageFlag::FRAGMENT: return "ShaderStageFlag::FRAGMENT"; + case stormkit::gpu::ShaderStageFlag::GEOMETRY: return "ShaderStageFlag::GEOMETRY"; + case stormkit::gpu::ShaderStageFlag::NONE: return "ShaderStageFlag::NONE"; + case stormkit::gpu::ShaderStageFlag::VERTEX: return "ShaderStageFlag::VERTEX"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::StencilFaceFlag) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::StencilFaceFlag::BACK, - stormkit::gpu::StencilFaceFlag::FRONT, - stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK, - + stormkit::gpu::StencilFaceFlag::BACK, + stormkit::gpu::StencilFaceFlag::FRONT, + stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::StencilFaceFlag value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::StencilFaceFlag::BACK: return "StencilFaceFlag::BACK"; - case stormkit::gpu::StencilFaceFlag::FRONT: return "StencilFaceFlag::FRONT"; - case stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK: return "StencilFaceFlag::FRONT_AND_BACK"; + constexpr auto stormkit::core::as_string(stormkit::gpu::StencilFaceFlag value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::StencilFaceFlag::BACK: return "StencilFaceFlag::BACK"; + case stormkit::gpu::StencilFaceFlag::FRONT: return "StencilFaceFlag::FRONT"; + case stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK: return "StencilFaceFlag::FRONT_AND_BACK"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::StencilFaceFlag value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::StencilFaceFlag::BACK: return "StencilFaceFlag::BACK"; - case stormkit::gpu::StencilFaceFlag::FRONT: return "StencilFaceFlag::FRONT"; - case stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK: return "StencilFaceFlag::FRONT_AND_BACK"; + constexpr auto stormkit::core::to_string(stormkit::gpu::StencilFaceFlag value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::StencilFaceFlag::BACK: return "StencilFaceFlag::BACK"; + case stormkit::gpu::StencilFaceFlag::FRONT: return "StencilFaceFlag::FRONT"; + case stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK: return "StencilFaceFlag::FRONT_AND_BACK"; + } std::unreachable(); } FLAG_ENUM(stormkit::gpu::VertexInputRate) - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::VertexInputRate::INSTANCE, - stormkit::gpu::VertexInputRate::VERTEX, - + stormkit::gpu::VertexInputRate::INSTANCE, + stormkit::gpu::VertexInputRate::VERTEX, + }; } - template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::VertexInputRate value) noexcept - -> std::string_view { - switch (value) { - case stormkit::gpu::VertexInputRate::INSTANCE: return "VertexInputRate::INSTANCE"; - case stormkit::gpu::VertexInputRate::VERTEX: return "VertexInputRate::VERTEX"; + constexpr auto stormkit::core::as_string(stormkit::gpu::VertexInputRate value) noexcept -> std::string_view { + switch(value) { + case stormkit::gpu::VertexInputRate::INSTANCE: return "VertexInputRate::INSTANCE"; + case stormkit::gpu::VertexInputRate::VERTEX: return "VertexInputRate::VERTEX"; + } std::unreachable(); } - template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::VertexInputRate value) noexcept - -> std::string { - switch (value) { - case stormkit::gpu::VertexInputRate::INSTANCE: return "VertexInputRate::INSTANCE"; - case stormkit::gpu::VertexInputRate::VERTEX: return "VertexInputRate::VERTEX"; + constexpr auto stormkit::core::to_string(stormkit::gpu::VertexInputRate value) noexcept -> std::string { + switch(value) { + case stormkit::gpu::VertexInputRate::INSTANCE: return "VertexInputRate::INSTANCE"; + case stormkit::gpu::VertexInputRate::VERTEX: return "VertexInputRate::VERTEX"; + } std::unreachable(); } + } //////////////////////////////////////////////////////////////////// @@ -3401,7 +3343,8 @@ export { namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_CONST + STORMKIT_FORCE_INLINE + STORMKIT_CONST constexpr auto is_depth_only_format(PixelFormat format) noexcept -> bool { return format == PixelFormat::DEPTH16_UNORM or format == PixelFormat::DEPTH24_UNORM_PACK32 @@ -3410,7 +3353,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_CONST + STORMKIT_FORCE_INLINE + STORMKIT_CONST constexpr auto is_depth_stencil_format(PixelFormat format) noexcept -> bool { return format == PixelFormat::DEPTH16_UNORM_STENCIL8U or format == PixelFormat::DEPTH24_UNORM_STENCIL8U @@ -3419,14 +3363,16 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_CONST + STORMKIT_FORCE_INLINE + STORMKIT_CONST constexpr auto is_depth_format(PixelFormat format) noexcept -> bool { return is_depth_only_format(format) or is_depth_stencil_format(format); } ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_CONST + STORMKIT_FORCE_INLINE + STORMKIT_CONST constexpr auto get_format_channel_count(PixelFormat format) noexcept -> u8 { switch (format) { case PixelFormat::R8_SNORM: @@ -3503,7 +3449,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_CONST + STORMKIT_FORCE_INLINE + STORMKIT_CONST constexpr auto get_format_element_count(PixelFormat format) noexcept -> u8 { switch (format) { case PixelFormat::R8_SNORM: @@ -3574,7 +3521,7 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE STORMKIT_CONST STORMKIT_INTRINSIC - constexpr auto to_vk(U value) noexcept -> T { + constexpr auto to_vk(U value) noexcept -> T{ return narrow(value); } @@ -3588,295 +3535,494 @@ namespace stormkit::gpu { constexpr auto from_vk(U value) noexcept -> T { return narrow(value); } -} // namespace stormkit::gpu + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto from_image(image::Image::Format format) -> PixelFormat { + switch(format) { + case image::Image::Format::R8_SNORM : return PixelFormat::R8_SNORM ; + case image::Image::Format::RG8_SNORM : return PixelFormat::RG8_SNORM ; + case image::Image::Format::RGB8_SNORM : return PixelFormat::RGB8_SNORM ; + case image::Image::Format::RGBA8_SNORM : return PixelFormat::RGBA8_SNORM ; + case image::Image::Format::R8_UNORM : return PixelFormat::R8_UNORM ; + case image::Image::Format::RG8_UNORM : return PixelFormat::RG8_UNORM ; + case image::Image::Format::RGB8_UNORM : return PixelFormat::RGB8_UNORM ; + case image::Image::Format::RGBA8_UNORM : return PixelFormat::RGBA8_UNORM ; + case image::Image::Format::R16_SNORM : return PixelFormat::R16_SNORM ; + case image::Image::Format::RG16_SNORM : return PixelFormat::RG16_SNORM ; + case image::Image::Format::RGB16_SNORM : return PixelFormat::RGB16_SNORM ; + case image::Image::Format::RGBA16_SNORM : return PixelFormat::RGBA16_SNORM ; + case image::Image::Format::R16_UNORM : return PixelFormat::R16_UNORM ; + case image::Image::Format::RG16_UNORM : return PixelFormat::RG16_UNORM ; + case image::Image::Format::RGB16_UNORM : return PixelFormat::RGB16_UNORM ; + case image::Image::Format::RGBA16_UNORM : return PixelFormat::RGBA16_UNORM ; + case image::Image::Format::RGBA4_UNORM : return PixelFormat::RGBA4_UNORM_PACK16 ; + case image::Image::Format::BGR8_UNORM : return PixelFormat::BGR8_UNORM ; + case image::Image::Format::BGRA8_UNORM : return PixelFormat::BGRA8_UNORM ; + case image::Image::Format::R8I : return PixelFormat::R8I ; + case image::Image::Format::RG8I : return PixelFormat::RG8I ; + case image::Image::Format::RGB8I : return PixelFormat::RGB8I ; + case image::Image::Format::RGBA8I : return PixelFormat::RGBA8I ; + case image::Image::Format::R8U : return PixelFormat::R8U ; + case image::Image::Format::RG8U : return PixelFormat::RG8U ; + case image::Image::Format::RGB8U : return PixelFormat::RGB8U ; + case image::Image::Format::RGBA8U : return PixelFormat::RGBA8U ; + case image::Image::Format::R16I : return PixelFormat::R16I ; + case image::Image::Format::RG16I : return PixelFormat::RG16I ; + case image::Image::Format::RGB16I : return PixelFormat::RGB16I ; + case image::Image::Format::RGBA16I : return PixelFormat::RGBA16I ; + case image::Image::Format::R16U : return PixelFormat::R16U ; + case image::Image::Format::RG16U : return PixelFormat::RG16U ; + case image::Image::Format::RGB16U : return PixelFormat::RGB16U ; + case image::Image::Format::RGBA16U : return PixelFormat::RGBA16U ; + case image::Image::Format::R32I : return PixelFormat::R32I ; + case image::Image::Format::RG32I : return PixelFormat::RG32I ; + case image::Image::Format::RGB32I : return PixelFormat::RGB32I ; + case image::Image::Format::RGBA32I : return PixelFormat::RGBA32I ; + case image::Image::Format::R32U : return PixelFormat::R32U ; + case image::Image::Format::RG32U : return PixelFormat::RG32U ; + case image::Image::Format::RGB32U : return PixelFormat::RGB32U ; + case image::Image::Format::RGBA32U : return PixelFormat::RGBA32U ; + case image::Image::Format::R16F : return PixelFormat::R16F ; + case image::Image::Format::RG16F : return PixelFormat::RG16F ; + case image::Image::Format::RGB16F : return PixelFormat::RGB16F ; + case image::Image::Format::RGBA16F : return PixelFormat::RGBA16F ; + case image::Image::Format::R32F : return PixelFormat::R32F ; + case image::Image::Format::RG32F : return PixelFormat::RG32F ; + case image::Image::Format::RGB32F : return PixelFormat::RGB32F ; + case image::Image::Format::RGBA32F : return PixelFormat::RGBA32F ; + case image::Image::Format::SRGB8 : return PixelFormat::SRGB8 ; + case image::Image::Format::SRGBA8 : return PixelFormat::SRGBA8 ; + case image::Image::Format::SBGR8 : return PixelFormat::SBGR8 ; + case image::Image::Format::SBGRA8 : return PixelFormat::SBGRA8 ; + case image::Image::Format::UNDEFINED : return PixelFormat::UNDEFINED ; + + default: break; + } + + std::unreachable(); + } +} #ifndef STORMKIT_OS_WINDOWS #undef STORMKIT_GPU_API #define STORMKIT_GPU_API #endif -template stormkit::gpu::AccessFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::AccessFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkAccessFlagBits); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); -template VkAccessFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); - -template stormkit::gpu::AttachmentLoadOperation STORMKIT_GPU_API - stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::AttachmentLoadOperation STORMKIT_GPU_API - stormkit::gpu::from_vk(VkAttachmentLoadOp); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); -template VkAttachmentLoadOp STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); - -template stormkit::gpu::AttachmentStoreOperation STORMKIT_GPU_API - stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::AttachmentStoreOperation STORMKIT_GPU_API - stormkit::gpu::from_vk(VkAttachmentStoreOp); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); -template VkAttachmentStoreOp STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); - -template stormkit::gpu::BlendFactor STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::BlendFactor STORMKIT_GPU_API - stormkit::gpu::from_vk(VkBlendFactor); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); -template VkBlendFactor STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); - -template stormkit::gpu::BlendOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::BlendOperation STORMKIT_GPU_API - stormkit::gpu::from_vk(VkBlendOp); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); -template VkBlendOp STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); - -template stormkit::gpu::BorderColor STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::BorderColor STORMKIT_GPU_API - stormkit::gpu::from_vk(VkBorderColor); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BorderColor); -template VkBorderColor STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BorderColor); - -template stormkit::gpu::BufferUsageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::BufferUsageFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkBufferUsageFlagBits); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); -template VkBufferUsageFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); - -template stormkit::gpu::ColorComponentFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ColorComponentFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkColorComponentFlagBits); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); -template VkColorComponentFlagBits STORMKIT_GPU_API - stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); - -template stormkit::gpu::ColorSpace STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ColorSpace STORMKIT_GPU_API - stormkit::gpu::from_vk(VkColorSpaceKHR); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); -template VkColorSpaceKHR STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); - -template stormkit::gpu::CommandBufferLevel STORMKIT_GPU_API - stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::CommandBufferLevel STORMKIT_GPU_API - stormkit::gpu::from_vk(VkCommandBufferLevel); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); -template VkCommandBufferLevel STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); - -template stormkit::gpu::CompareOperation STORMKIT_GPU_API - stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::CompareOperation STORMKIT_GPU_API - stormkit::gpu::from_vk(VkCompareOp); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); -template VkCompareOp STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); - -template stormkit::gpu::CullModeFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::CullModeFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkCullModeFlagBits); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); -template VkCullModeFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); - -template stormkit::gpu::DebugObjectType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::DebugObjectType STORMKIT_GPU_API - stormkit::gpu::from_vk(VkObjectType); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); -template VkObjectType STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); - -template stormkit::gpu::DependencyFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::DependencyFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkDependencyFlagBits); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); -template VkDependencyFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); - -template stormkit::gpu::DescriptorType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::DescriptorType STORMKIT_GPU_API - stormkit::gpu::from_vk(VkDescriptorType); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); -template VkDescriptorType STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); - -template stormkit::gpu::DynamicState STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::DynamicState STORMKIT_GPU_API - stormkit::gpu::from_vk(VkDynamicState); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DynamicState); -template VkDynamicState STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DynamicState); - -template stormkit::gpu::Filter STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::Filter STORMKIT_GPU_API stormkit::gpu::from_vk(VkFilter); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::Filter); -template VkFilter STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::Filter); - -template stormkit::gpu::FormatFeatureFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::FormatFeatureFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkFormatFeatureFlagBits); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); -template VkFormatFeatureFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); - -template stormkit::gpu::FrontFace STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::FrontFace STORMKIT_GPU_API stormkit::gpu::from_vk(VkFrontFace); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::FrontFace); -template VkFrontFace STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::FrontFace); - -template stormkit::gpu::GeometryFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::GeometryFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkGeometryFlagBitsKHR); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); -template VkGeometryFlagBitsKHR STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); - -template stormkit::gpu::GeometryType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::GeometryType STORMKIT_GPU_API - stormkit::gpu::from_vk(VkGeometryTypeKHR); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::GeometryType); -template VkGeometryTypeKHR STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::GeometryType); - -template stormkit::gpu::ImageAspectFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageAspectFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkImageAspectFlagBits); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); -template VkImageAspectFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); - -template stormkit::gpu::ImageCreateFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageCreateFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkImageCreateFlagBits); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); -template VkImageCreateFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); - -template stormkit::gpu::ImageLayout STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageLayout STORMKIT_GPU_API - stormkit::gpu::from_vk(VkImageLayout); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); -template VkImageLayout STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); - -template stormkit::gpu::ImageTiling STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageTiling STORMKIT_GPU_API - stormkit::gpu::from_vk(VkImageTiling); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); -template VkImageTiling STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); - -template stormkit::gpu::ImageType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageType STORMKIT_GPU_API stormkit::gpu::from_vk(VkImageType); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageType); -template VkImageType STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageType); - -template stormkit::gpu::ImageUsageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageUsageFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkImageUsageFlagBits); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); -template VkImageUsageFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); - -template stormkit::gpu::ImageViewType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ImageViewType STORMKIT_GPU_API - stormkit::gpu::from_vk(VkImageViewType); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); -template VkImageViewType STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); - -template stormkit::gpu::LogicOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::LogicOperation STORMKIT_GPU_API - stormkit::gpu::from_vk(VkLogicOp); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); -template VkLogicOp STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); - -template stormkit::gpu::MemoryPropertyFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::MemoryPropertyFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkMemoryPropertyFlagBits); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); -template VkMemoryPropertyFlagBits STORMKIT_GPU_API - stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); - -template stormkit::gpu::PhysicalDeviceType STORMKIT_GPU_API - stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PhysicalDeviceType STORMKIT_GPU_API - stormkit::gpu::from_vk(VkPhysicalDeviceType); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); -template VkPhysicalDeviceType STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); - -template stormkit::gpu::PipelineBindPoint STORMKIT_GPU_API - stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PipelineBindPoint STORMKIT_GPU_API - stormkit::gpu::from_vk(VkPipelineBindPoint); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); -template VkPipelineBindPoint STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); - -template stormkit::gpu::PipelineStageFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PipelineStageFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkPipelineStageFlagBits); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); -template VkPipelineStageFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); - -template stormkit::gpu::PixelFormat STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PixelFormat STORMKIT_GPU_API stormkit::gpu::from_vk(VkFormat); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); -template VkFormat STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); - -template stormkit::gpu::PolygonMode STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PolygonMode STORMKIT_GPU_API - stormkit::gpu::from_vk(VkPolygonMode); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); -template VkPolygonMode STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); - -template stormkit::gpu::PresentMode STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PresentMode STORMKIT_GPU_API - stormkit::gpu::from_vk(VkPresentModeKHR); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PresentMode); -template VkPresentModeKHR STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PresentMode); - -template stormkit::gpu::PrimitiveTopology STORMKIT_GPU_API - stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::PrimitiveTopology STORMKIT_GPU_API - stormkit::gpu::from_vk(VkPrimitiveTopology); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); -template VkPrimitiveTopology STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); - -template stormkit::gpu::QueueFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::QueueFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkQueueFlagBits); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); -template VkQueueFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); - -template stormkit::gpu::ResolveModeFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ResolveModeFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkResolveModeFlagBits); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ResolveModeFlag); -template VkResolveModeFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ResolveModeFlag); - -template stormkit::gpu::Result STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::Result STORMKIT_GPU_API stormkit::gpu::from_vk(VkResult); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::Result); -template VkResult STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::Result); - -template stormkit::gpu::SampleCountFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::SampleCountFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkSampleCountFlagBits); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); -template VkSampleCountFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); - -template stormkit::gpu::SamplerAddressMode STORMKIT_GPU_API - stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::SamplerAddressMode STORMKIT_GPU_API - stormkit::gpu::from_vk(VkSamplerAddressMode); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); -template VkSamplerAddressMode STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); - -template stormkit::gpu::SamplerMipmapMode STORMKIT_GPU_API - stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::SamplerMipmapMode STORMKIT_GPU_API - stormkit::gpu::from_vk(VkSamplerMipmapMode); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); -template VkSamplerMipmapMode STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); - -template stormkit::gpu::ShaderStageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::ShaderStageFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkShaderStageFlagBits); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); -template VkShaderStageFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); - -template stormkit::gpu::StencilFaceFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::StencilFaceFlag STORMKIT_GPU_API - stormkit::gpu::from_vk(VkStencilFaceFlagBits); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); -template VkStencilFaceFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); - -template stormkit::gpu::VertexInputRate STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); -template stormkit::gpu::VertexInputRate STORMKIT_GPU_API - stormkit::gpu::from_vk(VkVertexInputRate); -template VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); -template VkVertexInputRate STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); + + template + stormkit::gpu::AccessFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::AccessFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkAccessFlagBits); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); + template + VkAccessFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); + + template + stormkit::gpu::AttachmentLoadOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::AttachmentLoadOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkAttachmentLoadOp); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); + template + VkAttachmentLoadOp STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); + + template + stormkit::gpu::AttachmentStoreOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::AttachmentStoreOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkAttachmentStoreOp); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); + template + VkAttachmentStoreOp STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); + + template + stormkit::gpu::BlendFactor STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::BlendFactor STORMKIT_GPU_API stormkit::gpu::from_vk(VkBlendFactor); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); + template + VkBlendFactor STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); + + template + stormkit::gpu::BlendOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::BlendOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkBlendOp); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); + template + VkBlendOp STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); + + template + stormkit::gpu::BorderColor STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::BorderColor STORMKIT_GPU_API stormkit::gpu::from_vk(VkBorderColor); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BorderColor); + template + VkBorderColor STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BorderColor); + + template + stormkit::gpu::BufferUsageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::BufferUsageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkBufferUsageFlagBits); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); + template + VkBufferUsageFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); + + template + stormkit::gpu::ColorComponentFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::ColorComponentFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkColorComponentFlagBits); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); + template + VkColorComponentFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); + + template + stormkit::gpu::ColorSpace STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::ColorSpace STORMKIT_GPU_API stormkit::gpu::from_vk(VkColorSpaceKHR); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); + template + VkColorSpaceKHR STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); + + template + stormkit::gpu::CommandBufferLevel STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::CommandBufferLevel STORMKIT_GPU_API stormkit::gpu::from_vk(VkCommandBufferLevel); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); + template + VkCommandBufferLevel STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); + + template + stormkit::gpu::CompareOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::CompareOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkCompareOp); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); + template + VkCompareOp STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); + + template + stormkit::gpu::CullModeFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::CullModeFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkCullModeFlagBits); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); + template + VkCullModeFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); + + template + stormkit::gpu::DebugObjectType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::DebugObjectType STORMKIT_GPU_API stormkit::gpu::from_vk(VkObjectType); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); + template + VkObjectType STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); + + template + stormkit::gpu::DependencyFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::DependencyFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkDependencyFlagBits); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); + template + VkDependencyFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); + + template + stormkit::gpu::DescriptorType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::DescriptorType STORMKIT_GPU_API stormkit::gpu::from_vk(VkDescriptorType); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); + template + VkDescriptorType STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); + + template + stormkit::gpu::DynamicState STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::DynamicState STORMKIT_GPU_API stormkit::gpu::from_vk(VkDynamicState); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DynamicState); + template + VkDynamicState STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DynamicState); + + template + stormkit::gpu::Filter STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::Filter STORMKIT_GPU_API stormkit::gpu::from_vk(VkFilter); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::Filter); + template + VkFilter STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::Filter); + + template + stormkit::gpu::FormatFeatureFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::FormatFeatureFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFormatFeatureFlagBits); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); + template + VkFormatFeatureFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); + + template + stormkit::gpu::FrontFace STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::FrontFace STORMKIT_GPU_API stormkit::gpu::from_vk(VkFrontFace); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::FrontFace); + template + VkFrontFace STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::FrontFace); + + template + stormkit::gpu::GeometryFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::GeometryFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkGeometryFlagBitsKHR); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); + template + VkGeometryFlagBitsKHR STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); + + template + stormkit::gpu::GeometryType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::GeometryType STORMKIT_GPU_API stormkit::gpu::from_vk(VkGeometryTypeKHR); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::GeometryType); + template + VkGeometryTypeKHR STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::GeometryType); + + template + stormkit::gpu::ImageAspectFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::ImageAspectFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkImageAspectFlagBits); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); + template + VkImageAspectFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); + + template + stormkit::gpu::ImageCreateFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::ImageCreateFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkImageCreateFlagBits); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); + template + VkImageCreateFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); + + template + stormkit::gpu::ImageLayout STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::ImageLayout STORMKIT_GPU_API stormkit::gpu::from_vk(VkImageLayout); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); + template + VkImageLayout STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); + + template + stormkit::gpu::ImageTiling STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::ImageTiling STORMKIT_GPU_API stormkit::gpu::from_vk(VkImageTiling); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); + template + VkImageTiling STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); + + template + stormkit::gpu::ImageType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::ImageType STORMKIT_GPU_API stormkit::gpu::from_vk(VkImageType); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageType); + template + VkImageType STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageType); + + template + stormkit::gpu::ImageUsageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::ImageUsageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkImageUsageFlagBits); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); + template + VkImageUsageFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); + + template + stormkit::gpu::ImageViewType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::ImageViewType STORMKIT_GPU_API stormkit::gpu::from_vk(VkImageViewType); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); + template + VkImageViewType STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); + + template + stormkit::gpu::LogicOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::LogicOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkLogicOp); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); + template + VkLogicOp STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); + + template + stormkit::gpu::MemoryPropertyFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::MemoryPropertyFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkMemoryPropertyFlagBits); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); + template + VkMemoryPropertyFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); + + template + stormkit::gpu::PhysicalDeviceType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::PhysicalDeviceType STORMKIT_GPU_API stormkit::gpu::from_vk(VkPhysicalDeviceType); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); + template + VkPhysicalDeviceType STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); + + template + stormkit::gpu::PipelineBindPoint STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::PipelineBindPoint STORMKIT_GPU_API stormkit::gpu::from_vk(VkPipelineBindPoint); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); + template + VkPipelineBindPoint STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); + + template + stormkit::gpu::PipelineStageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::PipelineStageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkPipelineStageFlagBits); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); + template + VkPipelineStageFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); + + template + stormkit::gpu::PixelFormat STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::PixelFormat STORMKIT_GPU_API stormkit::gpu::from_vk(VkFormat); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); + template + VkFormat STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); + + template + stormkit::gpu::PolygonMode STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::PolygonMode STORMKIT_GPU_API stormkit::gpu::from_vk(VkPolygonMode); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); + template + VkPolygonMode STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); + + template + stormkit::gpu::PresentMode STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::PresentMode STORMKIT_GPU_API stormkit::gpu::from_vk(VkPresentModeKHR); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PresentMode); + template + VkPresentModeKHR STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PresentMode); + + template + stormkit::gpu::PrimitiveTopology STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::PrimitiveTopology STORMKIT_GPU_API stormkit::gpu::from_vk(VkPrimitiveTopology); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); + template + VkPrimitiveTopology STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); + + template + stormkit::gpu::QueueFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::QueueFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkQueueFlagBits); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); + template + VkQueueFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); + + template + stormkit::gpu::ResolveModeFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::ResolveModeFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkResolveModeFlagBits); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ResolveModeFlag); + template + VkResolveModeFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ResolveModeFlag); + + template + stormkit::gpu::Result STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::Result STORMKIT_GPU_API stormkit::gpu::from_vk(VkResult); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::Result); + template + VkResult STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::Result); + + template + stormkit::gpu::SampleCountFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::SampleCountFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkSampleCountFlagBits); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); + template + VkSampleCountFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); + + template + stormkit::gpu::SamplerAddressMode STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::SamplerAddressMode STORMKIT_GPU_API stormkit::gpu::from_vk(VkSamplerAddressMode); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); + template + VkSamplerAddressMode STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); + + template + stormkit::gpu::SamplerMipmapMode STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::SamplerMipmapMode STORMKIT_GPU_API stormkit::gpu::from_vk(VkSamplerMipmapMode); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); + template + VkSamplerMipmapMode STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); + + template + stormkit::gpu::ShaderStageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::ShaderStageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkShaderStageFlagBits); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); + template + VkShaderStageFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); + + template + stormkit::gpu::StencilFaceFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::StencilFaceFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkStencilFaceFlagBits); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); + template + VkStencilFaceFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); + + template + stormkit::gpu::VertexInputRate STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + template + stormkit::gpu::VertexInputRate STORMKIT_GPU_API stormkit::gpu::from_vk(VkVertexInputRate); + template + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); + template + VkVertexInputRate STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); + diff --git a/modules/stormkit/gpu/core/vulkan/enums.mpp.tpl b/modules/stormkit/gpu/core/vulkan/enums.cppm.tpl similarity index 65% rename from modules/stormkit/gpu/core/vulkan/enums.mpp.tpl rename to modules/stormkit/gpu/core/vulkan/enums.cppm.tpl index 152e76dc4..17e01603e 100644 --- a/modules/stormkit/gpu/core/vulkan/enums.mpp.tpl +++ b/modules/stormkit/gpu/core/vulkan/enums.cppm.tpl @@ -14,6 +14,7 @@ export module stormkit.gpu.core:vulkan.enums; import std; import stormkit.core; +import stormkit.image; import :vulkan.volk; {% @@ -54,6 +55,9 @@ export { [[nodiscard]] constexpr auto from_vk(U value) noexcept -> T; + [[nodiscard]] + constexpr auto from_image(image::Image::Format format) -> PixelFormat; + [[nodiscard]] constexpr auto is_depth_only_format(PixelFormat format) noexcept -> bool; [[nodiscard]] @@ -297,6 +301,75 @@ namespace stormkit::gpu { constexpr auto from_vk(U value) noexcept -> T { return narrow(value); } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto from_image(image::Image::Format format) -> PixelFormat { + switch(format) { + case image::Image::Format::R8_SNORM : return PixelFormat::R8_SNORM ; + case image::Image::Format::RG8_SNORM : return PixelFormat::RG8_SNORM ; + case image::Image::Format::RGB8_SNORM : return PixelFormat::RGB8_SNORM ; + case image::Image::Format::RGBA8_SNORM : return PixelFormat::RGBA8_SNORM ; + case image::Image::Format::R8_UNORM : return PixelFormat::R8_UNORM ; + case image::Image::Format::RG8_UNORM : return PixelFormat::RG8_UNORM ; + case image::Image::Format::RGB8_UNORM : return PixelFormat::RGB8_UNORM ; + case image::Image::Format::RGBA8_UNORM : return PixelFormat::RGBA8_UNORM ; + case image::Image::Format::R16_SNORM : return PixelFormat::R16_SNORM ; + case image::Image::Format::RG16_SNORM : return PixelFormat::RG16_SNORM ; + case image::Image::Format::RGB16_SNORM : return PixelFormat::RGB16_SNORM ; + case image::Image::Format::RGBA16_SNORM : return PixelFormat::RGBA16_SNORM ; + case image::Image::Format::R16_UNORM : return PixelFormat::R16_UNORM ; + case image::Image::Format::RG16_UNORM : return PixelFormat::RG16_UNORM ; + case image::Image::Format::RGB16_UNORM : return PixelFormat::RGB16_UNORM ; + case image::Image::Format::RGBA16_UNORM : return PixelFormat::RGBA16_UNORM ; + case image::Image::Format::RGBA4_UNORM : return PixelFormat::RGBA4_UNORM_PACK16 ; + case image::Image::Format::BGR8_UNORM : return PixelFormat::BGR8_UNORM ; + case image::Image::Format::BGRA8_UNORM : return PixelFormat::BGRA8_UNORM ; + case image::Image::Format::R8I : return PixelFormat::R8I ; + case image::Image::Format::RG8I : return PixelFormat::RG8I ; + case image::Image::Format::RGB8I : return PixelFormat::RGB8I ; + case image::Image::Format::RGBA8I : return PixelFormat::RGBA8I ; + case image::Image::Format::R8U : return PixelFormat::R8U ; + case image::Image::Format::RG8U : return PixelFormat::RG8U ; + case image::Image::Format::RGB8U : return PixelFormat::RGB8U ; + case image::Image::Format::RGBA8U : return PixelFormat::RGBA8U ; + case image::Image::Format::R16I : return PixelFormat::R16I ; + case image::Image::Format::RG16I : return PixelFormat::RG16I ; + case image::Image::Format::RGB16I : return PixelFormat::RGB16I ; + case image::Image::Format::RGBA16I : return PixelFormat::RGBA16I ; + case image::Image::Format::R16U : return PixelFormat::R16U ; + case image::Image::Format::RG16U : return PixelFormat::RG16U ; + case image::Image::Format::RGB16U : return PixelFormat::RGB16U ; + case image::Image::Format::RGBA16U : return PixelFormat::RGBA16U ; + case image::Image::Format::R32I : return PixelFormat::R32I ; + case image::Image::Format::RG32I : return PixelFormat::RG32I ; + case image::Image::Format::RGB32I : return PixelFormat::RGB32I ; + case image::Image::Format::RGBA32I : return PixelFormat::RGBA32I ; + case image::Image::Format::R32U : return PixelFormat::R32U ; + case image::Image::Format::RG32U : return PixelFormat::RG32U ; + case image::Image::Format::RGB32U : return PixelFormat::RGB32U ; + case image::Image::Format::RGBA32U : return PixelFormat::RGBA32U ; + case image::Image::Format::R16F : return PixelFormat::R16F ; + case image::Image::Format::RG16F : return PixelFormat::RG16F ; + case image::Image::Format::RGB16F : return PixelFormat::RGB16F ; + case image::Image::Format::RGBA16F : return PixelFormat::RGBA16F ; + case image::Image::Format::R32F : return PixelFormat::R32F ; + case image::Image::Format::RG32F : return PixelFormat::RG32F ; + case image::Image::Format::RGB32F : return PixelFormat::RGB32F ; + case image::Image::Format::RGBA32F : return PixelFormat::RGBA32F ; + case image::Image::Format::SRGB8 : return PixelFormat::SRGB8 ; + case image::Image::Format::SRGBA8 : return PixelFormat::SRGBA8 ; + case image::Image::Format::SBGR8 : return PixelFormat::SBGR8 ; + case image::Image::Format::SBGRA8 : return PixelFormat::SBGRA8 ; + case image::Image::Format::UNDEFINED : return PixelFormat::UNDEFINED ; + + default: break; + } + + std::unreachable(); + } } #ifndef STORMKIT_OS_WINDOWS @@ -306,11 +379,11 @@ namespace stormkit::gpu { {% for name, enumeration in table.orderpairs(json_data) do %} template - stormkit::gpu::{% outfile:write(name) %} STORMKIT_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::{% outfile:write(name) %} STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); template - stormkit::gpu::{% outfile:write(name) %} STORMKIT_API stormkit::gpu::from_vk({% outfile:write(enumeration.vktype) %}); + stormkit::gpu::{% outfile:write(name) %} STORMKIT_GPU_API stormkit::gpu::from_vk({% outfile:write(enumeration.vktype) %}); template - VkFlags STORMKIT_API stormkit::gpu::to_vk(stormkit::gpu::{% print("lool") outfile:write(name) %}); + VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::{% outfile:write(name) %}); template - {% outfile:write(enumeration.vktype) %} STORMKIT_API stormkit::gpu::to_vk<{% print("lol") outfile:write(enumeration.vktype) %}>(stormkit::gpu::{% print("lel") outfile:write(name) %}); + {% outfile:write(enumeration.vktype) %} STORMKIT_GPU_API stormkit::gpu::to_vk<{% outfile:write(enumeration.vktype) %}>(stormkit::gpu::{% outfile:write(name) %}); {% end %} From 7b8fa6f44561c2bb60f6269771adb586ba3591b3 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 8 Feb 2026 21:29:46 +0100 Subject: [PATCH 093/194] (core) bind math::geometry to lua --- examples/wsi/framebuffer/src/main.cpp | 2 +- modules/stormkit/core/math/geometry.cppm | 116 +++++++++++++----- modules/stormkit/gpu/core/vulkan/structs.cppm | 4 +- .../gpu/execution/command_buffer.cppm | 2 +- src/lua/core/math.cpp | 73 ++++++++++- 5 files changed, 156 insertions(+), 41 deletions(-) diff --git a/examples/wsi/framebuffer/src/main.cpp b/examples/wsi/framebuffer/src/main.cpp index bd65c273d..19c4c4153 100644 --- a/examples/wsi/framebuffer/src/main.cpp +++ b/examples/wsi/framebuffer/src/main.cpp @@ -34,7 +34,7 @@ auto update_pixels(stormkit::ThreadPool& pool, std::vector& pixels, const auto x = as(x_y % extent.width); const auto y = as(x_y / extent.width); - if (math::AABB({ as(x), as(y) }, rect)) data[y, x] = colors::BLACK; + if (math::AABB(math::uvec2 { as(x), as(y) }, rect)) data[y, x] = colors::BLACK; else { const auto color_id = as(x) / as(extent.width); if (color_id >= 0.8) data[y, x] = colors::BLUE; diff --git a/modules/stormkit/core/math/geometry.cppm b/modules/stormkit/core/math/geometry.cppm index 078f64f4e..46c1db9fe 100644 --- a/modules/stormkit/core/math/geometry.cppm +++ b/modules/stormkit/core/math/geometry.cppm @@ -20,10 +20,10 @@ import :math.linear.vector; export namespace stormkit { inline namespace core { namespace math { template struct rect { - T x; - T y; - Positive width; - Positive height; + T x = T { 0 }; + T y = T { 0 }; + Positive width = T { 0 }; + Positive height = T { 0 }; constexpr auto position() const noexcept -> vec2; constexpr auto extent() const noexcept -> extent2; @@ -32,22 +32,19 @@ export namespace stormkit { inline namespace core { namespace math { constexpr auto to() const noexcept -> rect; }; - using recti = rect; - using rectu = rect; - using rectf = rect; + using irect = rect; + using urect = rect; + using frect = rect; template rect(T, T, T, T) -> rect; - template - constexpr auto format_as(const rect& point, FormatContext& ctx) -> decltype(ctx.out()); - template struct bounding_rect { - T left; - T top; - T right; - T bottom; + T left = T { 0 }; + T top = T { 0 }; + T right = T { 0 }; + T bottom = T { 0 }; constexpr auto topleft() const noexcept -> vec2; constexpr auto bottomright() const noexcept -> vec2; @@ -56,14 +53,33 @@ export namespace stormkit { inline namespace core { namespace math { constexpr auto to() const noexcept -> rect; }; - template - constexpr auto format_as(const bounding_rect& point, FormatContext& ctx) -> decltype(ctx.out()); + using ibounding_rect = bounding_rect; + using ubounding_rect = bounding_rect; + using fbounding_rect = bounding_rect; + + template + auto to_string(const rect& value) noexcept -> std::string; + + template + auto to_string(const bounding_rect& value) noexcept -> std::string; + + template + constexpr auto hasher(const rect& value) noexcept -> Ret; + + template + constexpr auto hasher(const bounding_rect& value) noexcept -> Ret; + + template + auto format_as(const rect& value, FormatContext& ctx) -> decltype(ctx.out()); + + template + auto format_as(const bounding_rect& value, FormatContext& ctx) -> decltype(ctx.out()); template - constexpr auto to_bounding_rect(const rect& _rect) noexcept -> bounding_rect; + constexpr auto to_bounding_rect(const rect& value) noexcept -> bounding_rect; template - constexpr auto to_rect(const bounding_rect& _rect) noexcept -> rect; + constexpr auto to_rect(const bounding_rect& value) noexcept -> rect; template constexpr auto AABB(const rect& rect1, const rect& rect2) noexcept -> bool; @@ -102,19 +118,6 @@ namespace stormkit { inline namespace core { namespace math { return { as(x), as(y), as(width), as(height) }; } - //////////////////////////////////////// - //////////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto format_as(const rect& point, FormatContext& ctx) -> decltype(ctx.out()) { - return std::format_to(ctx.out(), - "{{ rect: .x = {}, .y = {}, .width = {}, .height = {} }}", - point.x, - point.y, - point.width, - point.height); - } - //////////////////////////////////////// //////////////////////////////////////// template @@ -143,11 +146,56 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// //////////////////////////////////////// - template + template + STORMKIT_FORCE_INLINE + inline auto to_string(const rect& value) noexcept -> std::string { + return std::format("{}", value); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto to_string(const bounding_rect& value) noexcept -> std::string { + return std::format("{}", value); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto hasher(const rect& value) noexcept -> Ret { + return hash(value.x, value.y, value.width, value.height); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto hasher(const bounding_rect& value) noexcept -> Ret { + return hash(value.left, value.top, value.right, value.bottom); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto format_as(const rect& point, FormatContext& ctx) -> decltype(ctx.out()) { + return std::format_to(ctx.out(), + "[rect x = {}, y = {}, width = {}, height = {}]", + point.x, + point.y, + point.width, + point.height); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template STORMKIT_FORCE_INLINE - constexpr auto format_as(const bounding_rect& point, FormatContext& ctx) -> decltype(ctx.out()) { + inline auto format_as(const bounding_rect& point, FormatContext& ctx) -> decltype(ctx.out()) { return std::format_to(ctx.out(), - "{{ bounding_rect: .left = {}, .top = {}, .right = {}, .bottom = {} }}", + "[bounding_rect left = {}, top = {}, right = {}, bottom = {}]", point.left, point.top, point.right, diff --git a/modules/stormkit/gpu/core/vulkan/structs.cppm b/modules/stormkit/gpu/core/vulkan/structs.cppm index 911b22309..9d25b8775 100644 --- a/modules/stormkit/gpu/core/vulkan/structs.cppm +++ b/modules/stormkit/gpu/core/vulkan/structs.cppm @@ -49,7 +49,7 @@ export namespace stormkit::gpu { constexpr auto to_vk(const Viewport& viewport) noexcept -> VkViewport; [[nodiscard]] - constexpr auto to_vk(const math::recti& rect) noexcept -> VkRect2D; + constexpr auto to_vk(const math::irect& rect) noexcept -> VkRect2D; [[nodiscard]] constexpr auto to_vk(const Scissor& viewport) noexcept -> VkRect2D; @@ -91,7 +91,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - constexpr auto to_vk(const math::recti& rect) noexcept -> VkRect2D { + constexpr auto to_vk(const math::irect& rect) noexcept -> VkRect2D { return VkRect2D { .offset = { rect.x, rect.y }, .extent = { as(rect.width.value), as(rect.height.value) } diff --git a/modules/stormkit/gpu/execution/command_buffer.cppm b/modules/stormkit/gpu/execution/command_buffer.cppm index a94353a45..00522427c 100644 --- a/modules/stormkit/gpu/execution/command_buffer.cppm +++ b/modules/stormkit/gpu/execution/command_buffer.cppm @@ -107,7 +107,7 @@ export namespace stormkit::gpu { std::optional clear_value = std::nullopt; }; - math::recti render_area; + math::irect render_area; u32 layer_count = 1u; u32 view_mask = 0u; diff --git a/src/lua/core/math.cpp b/src/lua/core/math.cpp index eb1903b79..6e2cde3c7 100644 --- a/src/lua/core/math.cpp +++ b/src/lua/core/math.cpp @@ -14,6 +14,49 @@ import stormkit.core; namespace stormkit::lua::core { namespace { + //////////////////////////////////////// + //////////////////////////////////////// + template + auto _bind_rect(auto& parent) { + ( + [&] noexcept { + using Type = typename decltype(Rects)::Type; + using Rect = math::rect; + + parent.template new_usertype( + Rects.name, + sol::constructors {}, + "position", + &Rect::position, + "extent", + &Rect::extent, + "to_bounding_rect", + +[](const Rect* rect) noexcept -> math::bounding_rect { return to_bounding_rect(*rect); }); + }(), + ...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto _bind_bounding_rect(auto& parent) { + ( + [&] noexcept { + using Type = typename decltype(Rects)::Type; + using Rect = math::bounding_rect; + + parent.template new_usertype( + Rects.name, + sol::constructors {}, + "topleft", + &Rect::topleft, + "bottomright", + &Rect::bottomright, + "to_rect", + +[](const Rect* rect) noexcept -> math::rect { return to_rect(*rect); }); + }(), + ...); + } //////////////////////////////////////// //////////////////////////////////////// @@ -436,9 +479,33 @@ namespace stormkit::lua::core { bind_linear_matrix(parent); } + template + struct _Rect { + using Type = T; + static constexpr auto name = Name; + }; + + auto bind_geometry(sol::table& parent) noexcept -> void { + _bind_rect<_Rect {}, _Rect {}, _Rect {}>(parent); + _bind_bounding_rect<_Rect {}, + _Rect {}, + _Rect {}>(parent); + parent["AABB"] = sol::overload( + +[](const math::irect& rect1, const math::irect& rect2) static noexcept { return AABB(rect1, rect2); }, + +[](const math::ivec2& vec, const math::irect& rect) static noexcept { return AABB(vec, rect); }, + +[](const math::ivec2& vec, const math::ibounding_rect& rect) static noexcept { return AABB(vec, rect); }, + +[](const math::frect& rect1, const math::frect& rect2) static noexcept { return AABB(rect1, rect2); }, + +[](const math::fvec2& vec, const math::frect& rect) static noexcept { return AABB(vec, rect); }, + +[](const math::fvec2& vec, const math::fbounding_rect& rect) static noexcept { return AABB(vec, rect); }, + +[](const math::urect& rect1, const math::urect& rect2) static noexcept { return AABB(rect1, rect2); }, + +[](const math::uvec2& vec, const math::urect& rect) static noexcept { return AABB(vec, rect); }, + +[](const math::uvec2& vec, const math::ubounding_rect& rect) static noexcept { return AABB(vec, rect); }); + } + auto bind_math(sol::state& global_state) noexcept -> void { - auto math_metatable = global_state["math"].get_or_create(); - bind_extent(math_metatable); - bind_linear(math_metatable); + auto math_table = global_state["math"].get_or_create(); + bind_extent(math_table); + bind_linear(math_table); + bind_geometry(math_table); } } // namespace stormkit::lua::core From 1363783b43ad78477c48ebbfdf29de173dcc9d1c Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 12 Feb 2026 16:24:41 +0100 Subject: [PATCH 094/194] (core) fix operator[] for vecs and matrices types --- modules/stormkit/core/math/linear-matrix.cppm | 13 +++++----- modules/stormkit/core/math/linear-vector.cppm | 24 +++++++++---------- tests/core/math/linear-matrix.cpp | 11 +++++++++ tests/core/math/linear-vector.cpp | 11 +++++++++ 4 files changed, 41 insertions(+), 18 deletions(-) diff --git a/modules/stormkit/core/math/linear-matrix.cppm b/modules/stormkit/core/math/linear-matrix.cppm index 557d6a603..cb6a33bcf 100644 --- a/modules/stormkit/core/math/linear-matrix.cppm +++ b/modules/stormkit/core/math/linear-matrix.cppm @@ -39,12 +39,12 @@ export { template [[nodiscard]] - constexpr auto operator[](this Self&& self, size_type i) noexcept -> core::meta::ForwardLike; + constexpr auto operator[](this Self&& self, size_type i) noexcept -> core::meta::ForwardLike&; template [[nodiscard]] constexpr auto operator[](this Self&& self, size_type i, size_type j) noexcept - -> core::meta::ForwardLike; + -> core::meta::ForwardLike&; template [[nodiscard]] @@ -280,8 +280,9 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m template template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto mat::operator[](this Self&& self, size_type i) noexcept -> core::meta::ForwardLike { - return std::forward(self).values[i]; + constexpr auto mat::operator[](this Self&& self, size_type i) noexcept + -> core::meta::ForwardLike& { + return std::forward_like(self.values[i]); } //////////////////////////////////////// @@ -290,8 +291,8 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m template STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto mat::operator[](this Self&& self, size_type i, size_type j) noexcept - -> core::meta::ForwardLike { - return std::forward_like(self.operator[](j + i * M)); + -> core::meta::ForwardLike& { + return std::forward_like(self.operator[](j + i * M)); } //////////////////////////////////////// diff --git a/modules/stormkit/core/math/linear-vector.cppm b/modules/stormkit/core/math/linear-vector.cppm index 407d7bf1d..fb3ff08f0 100644 --- a/modules/stormkit/core/math/linear-vector.cppm +++ b/modules/stormkit/core/math/linear-vector.cppm @@ -36,7 +36,7 @@ export namespace stormkit { inline namespace core { namespace math { T y; template - constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst; + constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst&; template constexpr auto to() const noexcept -> vec2; @@ -59,7 +59,7 @@ export namespace stormkit { inline namespace core { namespace math { T z; template - constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst; + constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst&; template constexpr auto to() const noexcept -> vec3; @@ -83,7 +83,7 @@ export namespace stormkit { inline namespace core { namespace math { T w; template - constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst; + constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst&; template constexpr auto to() const noexcept -> vec4; @@ -212,10 +212,10 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v template template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto vec2::operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst { - static constexpr auto* members = { &vec2::x, &vec2::y }; + constexpr auto vec2::operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst& { + static constexpr auto members = std::array { &vec2::x, &vec2::y }; - return std::forward_like(self->*members[i]); + return std::forward_like(self.*members[i]); } //////////////////////////////////////// @@ -232,10 +232,10 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v template template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto vec3::operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst { - static constexpr auto* members = { &vec3::x, &vec3::y, &vec3::z }; + constexpr auto vec3::operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst& { + static constexpr auto members = std::array { &vec3::x, &vec3::y, &vec3::z }; - return std::forward_like(self->*members[i]); + return std::forward_like(self.*members[i]); } //////////////////////////////////////// @@ -252,10 +252,10 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v template template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto vec4::operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst { - static constexpr auto* members = { &vec4::x, &vec4::y, &vec4::z, &vec4::w }; + constexpr auto vec4::operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst& { + static constexpr auto members = std::array { &vec4::x, &vec4::y, &vec4::z, &vec4::w }; - return std::forward_like(self->*members[i]); + return std::forward_like(self.*members[i]); } //////////////////////////////////////// diff --git a/tests/core/math/linear-matrix.cpp b/tests/core/math/linear-matrix.cpp index 66c263931..a67885237 100644 --- a/tests/core/math/linear-matrix.cpp +++ b/tests/core/math/linear-matrix.cpp @@ -16,6 +16,17 @@ namespace { auto _ = test::TestSuite { "core.math.linear.matrix", { + { "linear.matrix.operator[]", + [] static { + auto a = math::imat4 { 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 4, 0, 0, 0 }; + EXPECTS(a[0] == 0); + EXPECTS(a[1] == 1); + EXPECTS(a[0] == 0); + + EXPECTS((a[0, 2] == 2)); + + a[0] = 5; + } }, { "linear.matrix.determinant", [] static { diff --git a/tests/core/math/linear-vector.cpp b/tests/core/math/linear-vector.cpp index 05a2182f7..2e7b1262d 100644 --- a/tests/core/math/linear-vector.cpp +++ b/tests/core/math/linear-vector.cpp @@ -16,6 +16,17 @@ namespace { auto _ = test::TestSuite { "core.math.linear.vector", { + { "linear.vector.operator[]", + [] static { + auto a = math::ivec2 { 2, 3 }; + EXPECTS(a[0] == 2); + const auto c = math::ivec3 { 1, 3, 3 }; + EXPECTS(c[1] == 3); + const auto b = math::ivec4 { 5, 3, 9, 2 }; + EXPECTS(b[2] == 9); + + a[0] = 5; + } }, { "linear.vector.add", [] static { From 9a5180192045abab69e745d2a697191357387d63 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 12 Feb 2026 16:48:13 +0100 Subject: [PATCH 095/194] (core) add as_view for vecs and matrices types --- modules/stormkit/core/math/linear-matrix.cppm | 32 ++++++++++++------- modules/stormkit/core/math/linear-vector.cppm | 24 ++++++++++++++ tests/core/math/linear-matrix.cpp | 19 +++++++++++ tests/core/math/linear-vector.cpp | 13 ++++++++ 4 files changed, 77 insertions(+), 11 deletions(-) diff --git a/modules/stormkit/core/math/linear-matrix.cppm b/modules/stormkit/core/math/linear-matrix.cppm index cb6a33bcf..69e8bd70d 100644 --- a/modules/stormkit/core/math/linear-matrix.cppm +++ b/modules/stormkit/core/math/linear-matrix.cppm @@ -216,8 +216,12 @@ export { template [[nodiscard]] - constexpr auto as_span(T& value) noexcept - -> std::span, T::EXTENTS[0] * T::EXTENTS[1]>; + constexpr auto as_view(const T& value) noexcept + -> std::span; + + template + [[nodiscard]] + constexpr auto as_view_mut(T& value) noexcept -> std::span; template [[nodiscard]] @@ -549,12 +553,18 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto as_span(T& value) noexcept - -> std::span, T::EXTENTS[0] * T::EXTENTS[1]> { - return std::span, T::EXTENTS[0] * T::EXTENTS[1]> { - stdr::data(value), - T::EXTENTS[0] * T::EXTENTS[1] - }; + constexpr auto as_view(const T& value) noexcept -> std::span { + return std::span { stdr::data(value), + T::EXTENTS[0] * T::EXTENTS[1] }; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_PURE STORMKIT_FORCE_INLINE + constexpr auto as_view_mut(T& value) noexcept -> std::span { + return std::span { stdr::data(value), + T::EXTENTS[0] * T::EXTENTS[1] }; } //////////////////////////////////////// @@ -586,7 +596,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m template STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto hasher(const T& value) noexcept -> Ret { - return hash(as_span(value)); + return hash(as_view(value)); } //////////////////////////////////////// @@ -607,7 +617,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m auto l = 0u; if constexpr (stormkit::meta::IsIntegral) { auto max_digit = 0u; - for (auto v : as_span(mat)) max_digit = std::max(max_digit, v == 0 ? 2 : narrow(std::log10(v) + 2)); + for (auto v : as_view(mat)) max_digit = std::max(max_digit, v == 0 ? 2 : narrow(std::log10(v) + 2)); for (auto&& slice : mat | stdv::chunk_by(check_by_extent)) { format_to(out, "{}|{:n:>{}}|{}", @@ -619,7 +629,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m } } else { auto max_digit = 0u; - for (auto v : as_span(mat)) max_digit = std::max(max_digit, narrow(v) == 0 ? 2 : narrow(std::log10(v) + 2)); + for (auto v : as_view(mat)) max_digit = std::max(max_digit, narrow(v) == 0 ? 2 : narrow(std::log10(v) + 2)); for (auto&& slice : mat | stdv::chunk_by(check_by_extent)) { format_to(out, "{}| {:n:>{}.5f}|{}", diff --git a/modules/stormkit/core/math/linear-vector.cppm b/modules/stormkit/core/math/linear-vector.cppm index fb3ff08f0..bcd228a53 100644 --- a/modules/stormkit/core/math/linear-vector.cppm +++ b/modules/stormkit/core/math/linear-vector.cppm @@ -141,6 +141,14 @@ export namespace stormkit { inline namespace core { namespace math { [[nodiscard]] constexpr auto normalize(const T& a) noexcept -> T; + template + [[nodiscard]] + constexpr auto as_view(const T& value) noexcept -> std::span; + + template + [[nodiscard]] + constexpr auto as_view_mut(T& value) noexcept -> std::span; + template [[nodiscard]] constexpr auto as_mdspan(const T& value) noexcept -> VectorSpan; @@ -347,6 +355,22 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v return out; } + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_PURE STORMKIT_FORCE_INLINE + constexpr auto as_view(const T& value) noexcept -> std::span { + return std::span { &value.x, T::EXTENT[0] }; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_PURE STORMKIT_FORCE_INLINE + constexpr auto as_view_mut(T& value) noexcept -> std::span { + return std::span { &value.x, T::EXTENT[0] }; + } + //////////////////////////////////////// //////////////////////////////////////// template diff --git a/tests/core/math/linear-matrix.cpp b/tests/core/math/linear-matrix.cpp index a67885237..3f5be2438 100644 --- a/tests/core/math/linear-matrix.cpp +++ b/tests/core/math/linear-matrix.cpp @@ -16,6 +16,25 @@ namespace { auto _ = test::TestSuite { "core.math.linear.matrix", { + { "linear.matrix.as_view", + [] static { + auto a = math::imat4 { 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 4, 0, 0, 0 }; + EXPECTS(a[0] == 0); + EXPECTS(a[1] == 1); + EXPECTS(a[0] == 0); + + EXPECTS((a[0, 2] == 2)); + + const auto span = math::as_view(a); + auto span2 = math::as_view_mut(a); + + EXPECTS(span[0] == 2); + EXPECTS(span[1] == 3); + + span2[0] = 1; + + EXPECTS(span[0] == 1); + } }, { "linear.matrix.operator[]", [] static { auto a = math::imat4 { 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 4, 0, 0, 0 }; diff --git a/tests/core/math/linear-vector.cpp b/tests/core/math/linear-vector.cpp index 2e7b1262d..422098840 100644 --- a/tests/core/math/linear-vector.cpp +++ b/tests/core/math/linear-vector.cpp @@ -16,6 +16,19 @@ namespace { auto _ = test::TestSuite { "core.math.linear.vector", { + { "linear.vector.as_view", + [] static { + auto a = math::ivec2 { 2, 3 }; + const auto span = math::as_view(a); + auto span2 = math::as_view_mut(a); + + EXPECTS(span[0] == 2); + EXPECTS(span[1] == 3); + + span2[0] = 1; + + EXPECTS(span[0] == 1); + } }, { "linear.vector.operator[]", [] static { auto a = math::ivec2 { 2, 3 }; From 34e96e60983be0d205b300ebe8ff7e3e5ce7e63d Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 16 Feb 2026 16:45:16 +0100 Subject: [PATCH 096/194] (core) add bytes_as_span and bytes_mut_as_span --- modules/stormkit/core/typesafe/byte.cppm | 36 +++++++++++++++++++++++ modules/stormkit/gpu/resource/shader.cppm | 7 ++--- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/modules/stormkit/core/typesafe/byte.cppm b/modules/stormkit/core/typesafe/byte.cppm index 8011b7352..978da4f23 100644 --- a/modules/stormkit/core/typesafe/byte.cppm +++ b/modules/stormkit/core/typesafe/byte.cppm @@ -89,10 +89,20 @@ export namespace stormkit { inline namespace core { [[nodiscard]] constexpr auto bytes_as(std::span bytes) noexcept -> const T&; + template + [[nodiscard]] + constexpr auto bytes_as_span(std::span bytes) noexcept + -> std::span; + template [[nodiscard]] constexpr auto bytes_mut_as(std::span bytes) noexcept -> T&; + template + [[nodiscard]] + constexpr auto bytes_mut_as_span(std::span bytes) noexcept + -> std::span; + template [[nodiscard]] constexpr auto into_bytes(const T (&bytes)[N]) noexcept -> ByteArray; @@ -234,6 +244,19 @@ namespace stormkit { inline namespace core { return *std::bit_cast(stdr::data(bytes)); } + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto bytes_as_span(std::span bytes) noexcept + -> std::span { + if constexpr (EXTENT != std::dynamic_extent) + return std::span { std::bit_cast(stdr::data(bytes)), + EXTENT / sizeof(T) }; + else + return std::span { std::bit_cast(stdr::data(bytes)), stdr::size(bytes) / sizeof(T) }; + } + ///////////////////////////////////// ///////////////////////////////////// template @@ -244,6 +267,19 @@ namespace stormkit { inline namespace core { return *std::bit_cast(stdr::data(bytes)); } + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto bytes_mut_as_span(std::span bytes) noexcept + -> std::span { + if constexpr (EXTENT != std::dynamic_extent) + return std::span { std::bit_cast(stdr::data(bytes)), + EXTENT / sizeof(T) }; + else + return std::span { std::bit_cast(stdr::data(bytes)), stdr::size(bytes) / sizeof(T) }; + } + ///////////////////////////////////// ///////////////////////////////////// template diff --git a/modules/stormkit/gpu/resource/shader.cppm b/modules/stormkit/gpu/resource/shader.cppm index 6e8f58016..870f46df7 100644 --- a/modules/stormkit/gpu/resource/shader.cppm +++ b/modules/stormkit/gpu/resource/shader.cppm @@ -170,10 +170,7 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto Shader::load_from_bytes(const Device& device, std::span data, ShaderStageFlag type) noexcept -> Expected { - auto shader = Shader { device, - bytes_as>(data) | stdr::to(), - type, - PrivateFuncTag {} }; + auto shader = Shader { device, bytes_as_span(data) | stdr::to(), type, PrivateFuncTag {} }; return shader.do_init().transform(core::monadic::consume(shader)); } @@ -217,7 +214,7 @@ namespace stormkit::gpu { std::span data, ShaderStageFlag type) noexcept -> Expected> { auto shader = std::make_unique(device, - bytes_as>(data) | stdr::to(), + bytes_as_span(data) | stdr::to(), type, PrivateFuncTag {}); return shader->do_init().transform(core::monadic::consume(shader)); From 284ced735f91a259503d9f84af8b5d97335d2610 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 16 Feb 2026 18:00:01 +0100 Subject: [PATCH 097/194] (log) add maybe_unused attribute to NAMED_LOGGER --- include/stormkit/log/log_macro.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/stormkit/log/log_macro.hpp b/include/stormkit/log/log_macro.hpp index 779efd554..0c2ebb460 100644 --- a/include/stormkit/log/log_macro.hpp +++ b/include/stormkit/log/log_macro.hpp @@ -9,6 +9,7 @@ #define NAMED_LOGGER(NAME, module_chars) \ namespace { \ + [[maybe_unused]] \ constexpr auto NAME = stormkit::log::Module { module_chars }; \ } @@ -35,7 +36,9 @@ LOG_MODULE.flog(std::forward(args)...); \ } -#define IN_MODULE_NAMED_LOGGER(NAME, module_chars) inline constexpr auto NAME = stormkit::log::Module { module_chars }; +#define IN_MODULE_NAMED_LOGGER(NAME, module_chars) \ + [[maybe_unused]] \ + inline constexpr auto NAME = stormkit::log::Module { module_chars }; #define IN_MODULE_LOGGER(module) \ IN_MODULE_NAMED_LOGGER(LOG_MODULE, module) \ From 034cd70541f61440e16f2b3446cf966ddf341bf4 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 16 Feb 2026 18:30:01 +0100 Subject: [PATCH 098/194] (xmake) update rules --- xmake/rules/stormkit_application.xmake.lua | 32 ++++++++++++++++++-- xmake/rules/stormkit_library.xmake.lua | 34 +++++++++++++++++++--- 2 files changed, 59 insertions(+), 7 deletions(-) diff --git a/xmake/rules/stormkit_application.xmake.lua b/xmake/rules/stormkit_application.xmake.lua index 259c1de01..0e9d4605b 100644 --- a/xmake/rules/stormkit_application.xmake.lua +++ b/xmake/rules/stormkit_application.xmake.lua @@ -1,11 +1,37 @@ namespace("stormkit", function() rule("application", function() - add_deps("flags") + add_deps("@stormkit::flags") on_config(function(target) + import("core.base.hashset") + local stormkit_components = target:values("stormkit.components") or {} - target:set("kind", "binary") - target:set("languages", "cxxlatest", "clatest") + local stormkit_components_set = hashset.from(stormkit_components) + + -- core -- + target:add("packages", "frozen", "unordered_dense", "tl_function_ref") + + if stormkit_components_set:has("image") then target:add("packages", "libktx", "libpng", "libjpeg-turbo") end + if stormkit_components_set:has("wsi") then + if target:is_plat("linux") then + target:add( + "packages", + "libxcb", + "xcb-util-keysyms", + "xcb-util", + "xcb-util-image", + "xcb-util-wm", + "xcb-util-errors", + "wayland", + "wayland-protocols", + "libxkbcommon" + ) + end + end + if stormkit_components_set:has("gpu") then + target:add("packages", "volk", "vulkan-headers", "vulkan-memory-allocator") + end + target:add("packages", "stormkit", { components = table.join("core", "main", stormkit_components) }) end) end) diff --git a/xmake/rules/stormkit_library.xmake.lua b/xmake/rules/stormkit_library.xmake.lua index d4c1f431b..fa37232fb 100644 --- a/xmake/rules/stormkit_library.xmake.lua +++ b/xmake/rules/stormkit_library.xmake.lua @@ -1,12 +1,38 @@ namespace("stormkit", function() rule("library", function() - add_deps("flags") + add_deps("@stormkit::flags") on_config(function(target) + import("core.base.hashset") + local stormkit_components = target:values("stormkit.components") or {} - if not target:kind() then target:set("kind", "$(kind)") end - target:set("languages", "cxxlatest", "clatest") - target:add("packages", "stormkit", { components = table.join("core", "main", stormkit_components) }) + local stormkit_components_set = hashset.from(stormkit_components) + + -- core -- + target:add("packages", "frozen", "unordered_dense", "tl_function_ref") + + if stormkit_components_set:has("image") then target:add("packages", "libktx", "libpng", "libjpeg-turbo") end + if stormkit_components_set:has("wsi") then + if target:is_plat("linux") then + target:add( + "packages", + "libxcb", + "xcb-util-keysyms", + "xcb-util", + "xcb-util-image", + "xcb-util-wm", + "xcb-util-errors", + "wayland", + "wayland-protocols", + "libxkbcommon" + ) + end + end + if stormkit_components_set:has("gpu") then + target:add("packages", "volk", "vulkan-headers", "vulkan-memory-allocator") + end + + target:add("packages", "stormkit", { components = table.join("core", stormkit_components) }) end) end) end) From 6fab2b5602f212a0361954a9332b2adca1731903 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 17 Feb 2026 19:04:57 +0100 Subject: [PATCH 099/194] (core) fix reverse DAG --- modules/stormkit/core/containers/dag.cppm | 104 ++++++++++------------ tests/core/containers/dag.cpp | 38 ++++++-- 2 files changed, 78 insertions(+), 64 deletions(-) diff --git a/modules/stormkit/core/containers/dag.cppm b/modules/stormkit/core/containers/dag.cppm index 6a5899916..6a5f65b42 100644 --- a/modules/stormkit/core/containers/dag.cppm +++ b/modules/stormkit/core/containers/dag.cppm @@ -28,9 +28,6 @@ namespace stdfs = std::filesystem; export namespace stormkit { inline namespace core { namespace dag { - inline constexpr struct { - } DIRECTED = {}; - using VertexID = u32; struct Edge { @@ -62,10 +59,7 @@ export namespace stormkit { inline namespace core { }(); }; - struct Directed {}; - - constexpr explicit DAG(std::optional = std::nullopt, - std::optional reserve = std::nullopt) noexcept; + constexpr explicit DAG(std::optional reserve = std::nullopt) noexcept; constexpr ~DAG() noexcept; constexpr DAG(DAG&&) noexcept; @@ -108,13 +102,18 @@ export namespace stormkit { inline namespace core { constexpr auto topological_sort() const noexcept -> std::expected, std::vector>; constexpr auto find_cycle() const noexcept -> std::optional>; - constexpr auto reverse() const noexcept -> DAG>; + constexpr auto reverse_view() const noexcept -> DAG>; constexpr auto reverse_clone() const noexcept -> DAG; constexpr auto dump(Closures closures = {}) const noexcept -> std::string; + // FIXME find a way to make it not accessible to user + template + static constexpr auto reverse_from(dag::VertexID, + const std::vector&, + const std::vector&) noexcept -> DAG; + private: - bool m_directed; dag::VertexID m_next_id = 0; std::vector m_vertices; @@ -146,8 +145,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - constexpr DAG::DAG(std::optional directed, std::optional reserve) noexcept - : m_directed { directed } { + constexpr DAG::DAG(std::optional reserve) noexcept { if (reserve) m_vertices.reserve(*reserve); } @@ -166,13 +164,6 @@ namespace stormkit { inline namespace core { template constexpr auto DAG::operator=(DAG&&) noexcept -> DAG& = default; - //////////////////////////////////////// - //////////////////////////////////////// - template - constexpr auto DAG::directed() const noexcept -> bool { - return m_directed; - } - //////////////////////////////////////// //////////////////////////////////////// template @@ -324,12 +315,7 @@ namespace stormkit { inline namespace core { const auto& edge = m_edges.emplace_back(from, to); - if (m_directed) { - m_adjacent_edges[from].emplace_back(edge); - } else { - m_adjacent_edges[from].emplace_back(edge); - m_adjacent_edges[to].emplace_back(edge); - } + m_adjacent_edges[from].emplace_back(edge); } //////////////////////////////////////// @@ -339,9 +325,7 @@ namespace stormkit { inline namespace core { if (not has_vertex(from) or not has_vertex(to)) return false; return stdr::any_of(m_edges, [from, to](auto&& edge) noexcept { return edge.from == from and edge.to == to; }) - and (m_directed ? true : stdr::any_of(m_edges, [from, to](auto&& edge) noexcept { - return edge.from == to and edge.to == from; - })); + and stdr::any_of(m_edges, [from, to](auto&& edge) noexcept { return edge.from == to and edge.to == from; }); } //////////////////////////////////////// @@ -358,13 +342,6 @@ namespace stormkit { inline namespace core { }); m_edges.erase(it); } - if (not m_directed) { - const auto it = stdr::find_if(m_edges, [from, to](auto&& edge) noexcept { - return edge.from == to and edge.to == from; - }); - m_edges.erase(it); - } - for (auto&& [_, edges] : m_adjacent_edges) { { const auto it = stdr::find_if(edges, [from, to](auto&& edge) noexcept { @@ -372,12 +349,6 @@ namespace stormkit { inline namespace core { }); if (it != stdr::cend(edges)) edges.erase(it); } - if (not m_directed) { - const auto it = stdr::find_if(edges, [from, to](auto&& edge) noexcept { - return edge.from == to and edge.to == from; - }); - if (it != stdr::cend(edges)) edges.erase(it); - } } } @@ -427,8 +398,6 @@ namespace stormkit { inline namespace core { template constexpr auto DAG::topological_sort() const noexcept -> std::expected, std::vector> { - expects(m_directed, "Can't do topological sort on a non-directed graph"); - if (auto result = find_cycle(); result.has_value()) return std::unexpected { std::move(*result) }; struct Degree { @@ -536,27 +505,15 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - constexpr auto DAG::reverse() const noexcept -> DAG> { - auto out = DAG>(dag::DIRECTED, stdr::size(m_vertices)); - - for (auto&& [_, vertice] : m_vertices) out.add_vertex(as_ref(vertice)); - - for (auto&& [from, to] : m_edges) out.add_edge(to, from); - - return out; + constexpr auto DAG::reverse_view() const noexcept -> DAG> { + return DAG>::template reverse_from, true>(m_next_id, m_vertices, m_edges); } //////////////////////////////////////// //////////////////////////////////////// template constexpr auto DAG::reverse_clone() const noexcept -> DAG { - auto out = DAG>(dag::DIRECTED, stdr::size(m_vertices)); - - for (auto&& [_, vertice] : m_vertices) out.add_vertex(vertice); - - for (auto&& [from, to] : m_edges) out.add_edge(to, from); - - return out; + return reverse_from, false>(m_next_id, m_vertices, m_edges); } //////////////////////////////////////// @@ -591,6 +548,39 @@ namespace stormkit { inline namespace core { return out; } + //////////////////////////////////////// + //////////////////////////////////////// + template + template + constexpr auto DAG::reverse_from(dag::VertexID next_id, + const std::vector& vertices, + const std::vector& edges) noexcept -> DAG { + auto out = DAG {}; + out.m_next_id = next_id; + + out.m_adjacent_edges.reserve(stdr::size(vertices)); + if constexpr (AS_REF) { + for (const auto& [id, vertice] : vertices) { + out.m_vertices.emplace_back(id, as_ref(vertice)); + out.m_adjacent_edges[id] = {}; + } + } else { + for (const auto& [id, vertice] : vertices) { + out.m_vertices.emplace_back(id, auto(vertice)); + out.m_adjacent_edges[id] = {}; + } + } + + out.m_edges.reserve(stdr::size(edges)); + for (auto&& [from, to] : edges) { + const auto& edge = out.m_edges.emplace_back(to, from); + + out.m_adjacent_edges[to].emplace_back(edge); + } + + return out; + } + namespace dag { ///////////////////////////////////// ///////////////////////////////////// diff --git a/tests/core/containers/dag.cpp b/tests/core/containers/dag.cpp index 496e92728..d42ffc0a1 100644 --- a/tests/core/containers/dag.cpp +++ b/tests/core/containers/dag.cpp @@ -33,7 +33,7 @@ namespace { Edge { 3, 2 }, Edge { 1, 4 }); - auto dag = DAG { dag::DIRECTED }; + auto dag = DAG {}; for (auto i : range(7)) dag.add_vertex(i); for (auto&& [from, to] : edges) dag.add_edge(from, to); @@ -56,7 +56,7 @@ namespace { } }, { "remove_edge_and_vertex", [] { - auto dag = DAG { dag::DIRECTED }; + auto dag = DAG {}; dag.emplace_vertex("a"); dag.emplace_vertex("b"); dag.emplace_vertex("c"); @@ -99,7 +99,7 @@ namespace { } }, { "find_cycle", [] { - auto dag = DAG { dag::DIRECTED }; + auto dag = DAG {}; dag.add_vertex(0); dag.add_vertex(1); dag.add_vertex(4); @@ -130,9 +130,9 @@ namespace { EXPECTS(not result.has_value()); } } }, - { "reverse", + { "reverse_view", [] { - auto dag = DAG { dag::DIRECTED }; + auto dag = DAG {}; dag.emplace_vertex("a"); dag.emplace_vertex("b"); dag.emplace_vertex("c"); @@ -143,7 +143,31 @@ namespace { dag.add_edge(2, 3); dag.add_edge(0, 3); - auto reversed = dag.reverse(); + auto reversed = dag.reverse_view(); + + const auto& edges = dag.edges(); + const auto& redges = reversed.edges(); + + for (auto i : range(4u)) { + const auto [from, to] = edges[i]; + const auto [rfrom, rto] = redges[i]; + EXPECTS(from == rto and rfrom == to); + } + } }, + { "reverse_clone", + [] { + auto dag = DAG {}; + dag.emplace_vertex("a"); + dag.emplace_vertex("b"); + dag.emplace_vertex("c"); + dag.emplace_vertex("d"); + + dag.add_edge(0, 1); + dag.add_edge(1, 2); + dag.add_edge(2, 3); + dag.add_edge(0, 3); + + auto reversed = dag.reverse_clone(); const auto& edges = dag.edges(); const auto& redges = reversed.edges(); @@ -156,7 +180,7 @@ namespace { } }, { "dump", [] { - auto dag = DAG { dag::DIRECTED }; + auto dag = DAG {}; dag.emplace_vertex("a"); dag.emplace_vertex("b"); dag.emplace_vertex("c"); From ddf4efad28e4fb52025f3079ceacb7447943c1a7 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 17 Feb 2026 19:05:14 +0100 Subject: [PATCH 100/194] (lua) fix lua binding of Rect types --- modules/stormkit/core/typesafe/safecasts.cppm | 4 ++-- src/lua/core/math.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/stormkit/core/typesafe/safecasts.cppm b/modules/stormkit/core/typesafe/safecasts.cppm index 66c2d7ed3..c2d86f0d7 100644 --- a/modules/stormkit/core/typesafe/safecasts.cppm +++ b/modules/stormkit/core/typesafe/safecasts.cppm @@ -68,8 +68,8 @@ export { }; template - concept HasIsTypeQueryier = requires(U&& value) { - { is_impl(std::forward(value)) } -> IsBooleanTestable; + concept HasIsTypeQueryier = requires(const U& value) { + { is_impl(value) } -> IsBooleanTestable; }; template diff --git a/src/lua/core/math.cpp b/src/lua/core/math.cpp index 6e2cde3c7..dd60943fa 100644 --- a/src/lua/core/math.cpp +++ b/src/lua/core/math.cpp @@ -24,7 +24,7 @@ namespace stormkit::lua::core { using Rect = math::rect; parent.template new_usertype( - Rects.name, + std::string { Rects.name }, sol::constructors {}, "position", &Rect::position, @@ -46,7 +46,7 @@ namespace stormkit::lua::core { using Rect = math::bounding_rect; parent.template new_usertype( - Rects.name, + std::string { Rects.name }, sol::constructors {}, "topleft", &Rect::topleft, From 13adbe53b059ac09d7b9800a2ea4490bff406196 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 17 Feb 2026 20:25:13 +0100 Subject: [PATCH 101/194] (core) fix writing file on windows --- modules/stormkit/core/utils/filesystem.cppm | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/stormkit/core/utils/filesystem.cppm b/modules/stormkit/core/utils/filesystem.cppm index 48186300c..aea442acf 100644 --- a/modules/stormkit/core/utils/filesystem.cppm +++ b/modules/stormkit/core/utils/filesystem.cppm @@ -143,14 +143,15 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// template inline auto Descriptor::open(const stdfs::path& path, Access access) noexcept -> Expected> { - if (not stdfs::exists(path)) return std::unexpected { SystemError { .code = std::errc::no_such_file_or_directory } }; + if (access == Access::READ and not stdfs::exists(path)) + return std::unexpected { SystemError { .code = std::errc::no_such_file_or_directory } }; if (stdfs::is_directory(path)) return std::unexpected { SystemError { .code = std::errc::is_a_directory } }; const auto posix_access = [&access]() noexcept { #ifdef STORMKIT_OS_WINDOWS if (access == Access::READ) return _O_RDONLY; else if (access == Access::WRITE) - return _O_WRONLY; + return (_O_WRONLY | _O_CREAT); else return _O_RDWR; #else @@ -168,8 +169,8 @@ namespace stormkit { inline namespace core { namespace io { switch (mode) { #ifdef STORMKIT_OS_WINDOWS case Mode::BINARY: return _O_BINARY; - case Mode::AINSI: return _O_TEXT; - case Mode::UTF8: return _O_U8TEXT; + case Mode::AINSI: [[fallthrough]]; + case Mode::UTF8: return _O_TEXT; case Mode::WIDE: return _O_WTEXT; default: break; #else @@ -182,8 +183,7 @@ namespace stormkit { inline namespace core { namespace io { auto ret = 0; auto str = path.string(); const auto // - err = _sopen_s(&ret, str.c_str(), posix_access | text_mode, _SH_DENYWR, 0); - // err = _sopen_s(&ret, stdr::data(p), posix_access | text_mode, _SH_SECURE, 0); + err = _sopen_s(&ret, str.c_str(), posix_access | text_mode, _SH_DENYNO, _S_IREAD); if (err != 0) return std::unexpected { SystemError::from_errno() }; #else const auto ret = ::open(path.c_str(), posix_access); From 6f9f49bdeb0d06c2403cfa83f3650763e3acdc98 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 17 Feb 2026 20:25:27 +0100 Subject: [PATCH 102/194] (gpu) add hasher for Buffer::CreateInfo and Image::CreateInfo --- modules/stormkit/gpu/resource/buffer.cppm | 10 ++++++++++ modules/stormkit/gpu/resource/image.cppm | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/modules/stormkit/gpu/resource/buffer.cppm b/modules/stormkit/gpu/resource/buffer.cppm index 67c0d95ad..edc0eb319 100644 --- a/modules/stormkit/gpu/resource/buffer.cppm +++ b/modules/stormkit/gpu/resource/buffer.cppm @@ -120,6 +120,9 @@ export namespace stormkit::gpu { usize size; u64 offset = 0; }; + + template + constexpr auto hasher(const Buffer::CreateInfo& create_info) noexcept -> Ret; } // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// @@ -328,4 +331,11 @@ namespace stormkit::gpu { EXPECTS(m_vk_handle); return m_vk_handle; } + + ///////////////////////////////////// + ///////////////////////////////////// + template + constexpr auto hasher(const Buffer::CreateInfo& create_info) noexcept -> Ret { + return hash(create_info.usages, create_info.size, create_info.property); + } } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/resource/image.cppm b/modules/stormkit/gpu/resource/image.cppm index 5e71b597a..ad36186a0 100644 --- a/modules/stormkit/gpu/resource/image.cppm +++ b/modules/stormkit/gpu/resource/image.cppm @@ -211,6 +211,9 @@ export namespace stormkit::gpu { const Image& image; ImageSubresourceRange range; }; + + template + constexpr auto hasher(const Image::CreateInfo& value) noexcept -> Ret; } // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// @@ -562,4 +565,20 @@ namespace stormkit::gpu { return do_init(create_info, info.property); } + + ///////////////////////////////////// + ///////////////////////////////////// + template + constexpr auto hasher(const Image::CreateInfo& create_info) noexcept -> Ret { + return hash(create_info.extent, + create_info.format, + create_info.layers, + create_info.mip_levels, + create_info.type, + create_info.flags, + create_info.samples, + create_info.usages, + create_info.tiling, + create_info.property); + } } // namespace stormkit::gpu From eb86794b2a3063d4cb8f8229be715e40bc1143cb Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 23 Feb 2026 16:36:42 +0100 Subject: [PATCH 103/194] (entities, core) remove component_hash and implement generic string hash --- .../entities/gameoflife/src/Components.cppm | 2 +- modules/stormkit/core/hash/base.cppm | 37 +++++++++++++ modules/stormkit/core/hash/string.cppm | 48 ++++++++++++----- modules/stormkit/entities.cppm | 53 +++---------------- src/lua/entities.cpp | 5 +- 5 files changed, 82 insertions(+), 63 deletions(-) diff --git a/examples/entities/gameoflife/src/Components.cppm b/examples/entities/gameoflife/src/Components.cppm index 89d08f7b5..cfd9c7265 100644 --- a/examples/entities/gameoflife/src/Components.cppm +++ b/examples/entities/gameoflife/src/Components.cppm @@ -20,7 +20,7 @@ export { stormkit::u32 x; stormkit::u32 y; - static constexpr Type TYPE = stormkit::entities::component_hash("PositionComponent"); + static constexpr Type TYPE = stormkit::hash("PositionComponent"); }; #ifdef STORMKIT_BUILD_MODULES diff --git a/modules/stormkit/core/hash/base.cppm b/modules/stormkit/core/hash/base.cppm index 6d5574366..e443756ec 100644 --- a/modules/stormkit/core/hash/base.cppm +++ b/modules/stormkit/core/hash/base.cppm @@ -52,6 +52,13 @@ export namespace stormkit { inline namespace core { template requires(sizeof...(Args) >= 2) constexpr auto hash_combine(Ret& hash, Args&&... args) noexcept -> void; + + namespace literals { + constexpr auto operator""_hash32(unsigned long long int) -> hash32; + constexpr auto operator""_hash32(long double) -> hash32; + constexpr auto operator""_hash64(unsigned long long int) -> hash64; + constexpr auto operator""_hash64(long double) -> hash64; + } // namespace literals }} // namespace stormkit::core //////////////////////////////////////////////////////////////////// @@ -125,4 +132,34 @@ namespace stormkit { inline namespace core { (stormkit::hash_combine(out, std::forward(args)), ...); #endif } + + namespace literals { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto operator""_hash32(unsigned long long int value) -> hash32 { + return hash(value); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto operator""_hash32(long double value) -> hash32 { + return hash(value); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto operator""_hash64(unsigned long long int value) -> hash64 { + return hash(value); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto operator""_hash64(long double value) -> hash64 { + return hash(value); + } + } // namespace literals }} // namespace stormkit::core diff --git a/modules/stormkit/core/hash/string.cppm b/modules/stormkit/core/hash/string.cppm index ae26de816..bbcfc2bd4 100644 --- a/modules/stormkit/core/hash/string.cppm +++ b/modules/stormkit/core/hash/string.cppm @@ -8,6 +8,8 @@ module; export module stormkit.core:hash.string; +import :hash.base; + import :string.czstring; import :typesafe.integer; import :typesafe.safecasts; @@ -21,13 +23,8 @@ export namespace stormkit { inline namespace core { using is_transparent = void; using is_avalanching = void; -#ifdef STORMKIT_COMPILER_MSVC - [[nodiscard]] - auto operator()(std::string_view value, u64 seed = 0) const noexcept -> u64; -#else [[nodiscard]] - static auto operator()(std::string_view value, u64 seed = 0) noexcept -> u64; -#endif + static constexpr auto operator()(std::string_view value, u64 seed = 0) noexcept -> u64; }; template @@ -43,6 +40,14 @@ export namespace stormkit { inline namespace core { template using FrozenStringHashSet = frozen::unordered_set, Size, StringHash, std::equal_to<>>; + + template + constexpr auto hasher(std::string_view value) noexcept -> Ret; + + namespace literals { + constexpr auto operator""_hash32(CZString str, usize size) -> hash32; + constexpr auto operator""_hash64(CZString str, usize size) -> hash64; + } // namespace literals }} // namespace stormkit::core //////////////////////////////////////////////////////////////////// @@ -177,15 +182,34 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE -#ifdef STORMKIT_COMPILER_MSVC - inline auto StringHash::operator()(std::string_view value, u64 seed) const noexcept -#else - inline auto StringHash::operator()(std::string_view value, u64 seed) noexcept -#endif - -> u64 { + constexpr auto StringHash::operator()(std::string_view value, u64 seed) noexcept -> u64 { auto mask = u8 { 0b01111 }; auto hasher = Lehmer128Hasher { seed }; hash_selected_characters(mask, hasher, std::data(value), std::size(value)); return hasher.hash(); } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto hasher(std::string_view value) noexcept -> Ret { + return StringHash::operator()(value); + } + + namespace literals { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto operator""_hash32(CZString str, usize size) -> hash32 { + return hash(std::string_view { str, size }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + constexpr auto operator""_hash64(CZString str, usize size) -> hash64 { + return hash(std::string_view { str, size }); + } + } // namespace literals }} // namespace stormkit::core diff --git a/modules/stormkit/entities.cppm b/modules/stormkit/entities.cppm index 69ed70c8e..30cc7f454 100644 --- a/modules/stormkit/entities.cppm +++ b/modules/stormkit/entities.cppm @@ -34,7 +34,7 @@ export namespace stormkit::entities { #endif }; - using ComponentType = u64; + using ComponentType = u32; namespace meta { template @@ -43,17 +43,6 @@ export namespace stormkit::entities { }; } // namespace meta - template - constexpr auto component_hash(std::string_view str) noexcept -> Result; - - constexpr auto component_hash(CZString str, usize size) noexcept -> ComponentType; - - constexpr auto component_hash(std::string_view str) noexcept -> ComponentType; - - namespace literals { - constexpr auto operator""_component_type(CZString str, usize size) -> ComponentType; - } // namespace literals - struct Message { u32 id; std::vector entities; @@ -248,36 +237,6 @@ namespace stormkit::entities { return as(k); } - ///////////////////////////////////// - ///////////////////////////////////// - template - constexpr auto component_hash(std::string_view str) noexcept -> Result { - return std::empty(str) - ? 0xcbf29ce484222325UL - : (as(str[0]) ^ component_hash(str.substr(1, std::size(str) - 1))) * 0x100000001b3UL; - } - - ///////////////////////////////////// - ///////////////////////////////////// - constexpr auto component_hash(CZString str, usize size) noexcept -> ComponentType { - return size == 0 ? 0xcbf29ce484222325UL - : (as(str[0]) ^ component_hash(std::string_view { str + 1, size - 1 })) * 0x100000001b3UL; - } - - ///////////////////////////////////// - ///////////////////////////////////// - constexpr auto component_hash(std::string_view str) noexcept -> ComponentType { - return component_hash(std::data(str), std::size(str)); - } - - namespace literals { - ///////////////////////////////////// - ///////////////////////////////////// - constexpr auto operator""_component_type(CZString str, usize size) -> ComponentType { - return stormkit::entities::component_hash(str, size); - } - } // namespace literals - ///////////////////////////////////// ///////////////////////////////////// inline auto MessageBus::empty() const noexcept -> bool { @@ -331,13 +290,13 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// inline auto EntityManager::destroy_component(Entity entity, std::string_view name) noexcept -> void { - destroy_component(entity, component_hash(name)); + destroy_component(entity, hash(name)); } ///////////////////////////////////// ///////////////////////////////////// inline auto EntityManager::has_component(Entity entity, std::string_view name) const noexcept -> bool { - return has_component(entity, component_hash(name)); + return has_component(entity, hash(name)); } ///////////////////////////////////// @@ -359,7 +318,7 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// inline auto EntityManager::entities_with_component(std::string_view name) const noexcept -> std::vector { - return entities_with_component(component_hash(name)); + return entities_with_component(hash(name)); } ///////////////////////////////////// @@ -395,7 +354,7 @@ namespace stormkit::entities { template auto EntityManager::get_component(this Self& self, Entity entity, std::string_view name) noexcept -> core::meta::ForwardConst { - return self.template get_component(entity, component_hash(name)); + return self.template get_component(entity, hash(name)); } ///////////////////////////////////// @@ -418,7 +377,7 @@ namespace stormkit::entities { template auto EntityManager::components_of_type(this Self& self, std::string_view name) noexcept -> std::vector>> { - return self.template components_of_type(component_hash(name)); + return self.template components_of_type(hash(name)); } ///////////////////////////////////// diff --git a/src/lua/entities.cpp b/src/lua/entities.cpp index bd7e956f8..8c676f012 100644 --- a/src/lua/entities.cpp +++ b/src/lua/entities.cpp @@ -17,7 +17,6 @@ namespace stdr = std::ranges; namespace stdv = std::views; namespace stormkit::lua::entities { - using stormkit::entities::component_hash; using stormkit::entities::ComponentType; using stormkit::entities::Entity; using stormkit::entities::EntityManager; @@ -54,7 +53,7 @@ namespace stormkit::lua::entities { const auto value = sol::object { result }; ensures(value.is(), "Component type() must return a string or a component type"); - const auto _type = component_hash(value.as()); + const auto _type = hash(value.as()); manager->add_component(entity, LuaComponent { .data = std::move(component), ._type = _type }); }; manager["get_component"] = +[](EntityManager* manager, Entity entity, std::string_view name) static noexcept { @@ -93,7 +92,7 @@ namespace stormkit::lua::entities { manager->add_system(std::move(name), types | stdv::transform([](const auto& type) static noexcept { - return component_hash(type); + return hash(type); }) | stdr::to(), std::move(_closures)); }; From 2b2c6d651848130a6f194be15763de1cf1771ee9 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 24 Feb 2026 15:21:30 +0100 Subject: [PATCH 104/194] (core) make get_vertex_value return vertex value instead of vertex for dag class --- modules/stormkit/core/containers/dag.cppm | 12 +++++++----- tests/core/containers/dag.cpp | 8 ++++---- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/modules/stormkit/core/containers/dag.cppm b/modules/stormkit/core/containers/dag.cppm index 6a5f65b42..f04e85b49 100644 --- a/modules/stormkit/core/containers/dag.cppm +++ b/modules/stormkit/core/containers/dag.cppm @@ -80,7 +80,8 @@ export namespace stormkit { inline namespace core { template constexpr auto emplace_vertex(Args&&... vertex) noexcept -> dag::VertexID requires(meta::IsConstructible); - constexpr auto get_vertex_value(this auto&& self, dag::VertexID id) noexcept -> decltype(auto); + template + constexpr auto get_vertex_value(this Self&& self, dag::VertexID id) noexcept -> meta::ForwardLike; constexpr auto has_vertex(const VertexValue& vertex) const noexcept -> bool requires(meta::HasEqualityOperator); constexpr auto has_vertex(dag::VertexID vertex) const noexcept -> bool; @@ -240,12 +241,13 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - constexpr auto DAG::get_vertex_value(this auto&& self, dag::VertexID id) noexcept -> decltype(auto) { + template + constexpr auto DAG::get_vertex_value(this Self&& self, dag::VertexID id) noexcept + -> meta::ForwardLike { expects(self.has_vertex(id), std::format("Unknown DAG vertex id: {}!", id)); - return std::forward_like(*stdr::find_if(self.m_vertices, [id](const auto& other) noexcept { - return other.id == id; - })); + return std::forward_like(stdr::find_if(self.m_vertices, [id](const auto& other) noexcept { return other.id == id; }) + ->value); } //////////////////////////////////////// diff --git a/tests/core/containers/dag.cpp b/tests/core/containers/dag.cpp index d42ffc0a1..88a57bd06 100644 --- a/tests/core/containers/dag.cpp +++ b/tests/core/containers/dag.cpp @@ -119,10 +119,10 @@ namespace { auto&& cycle = std::move(*result); EXPECTS(stdr::size(cycle) == 4); - EXPECTS(dag.get_vertex_value(cycle[0]).value == 0); - EXPECTS(dag.get_vertex_value(cycle[1]).value == 1); - EXPECTS(dag.get_vertex_value(cycle[2]).value == 6); - EXPECTS(dag.get_vertex_value(cycle[3]).value == 0); + EXPECTS(dag.get_vertex_value(cycle[0]) == 0); + EXPECTS(dag.get_vertex_value(cycle[1]) == 1); + EXPECTS(dag.get_vertex_value(cycle[2]) == 6); + EXPECTS(dag.get_vertex_value(cycle[3]) == 0); } { From fec7d005a813ac8accaa287482e275b6554d1076 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 24 Feb 2026 20:47:10 +0100 Subject: [PATCH 105/194] (core, lua) fix compilation on linux --- include/stormkit/lua/lua.hpp | 2 ++ modules/stormkit/core/utils/filesystem.cppm | 2 +- xmake/targets/lua.xmake.lua | 4 ++-- xmake/targets/wsi.xmake.lua | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/stormkit/lua/lua.hpp b/include/stormkit/lua/lua.hpp index ae80422e0..7228ee045 100644 --- a/include/stormkit/lua/lua.hpp +++ b/include/stormkit/lua/lua.hpp @@ -19,6 +19,8 @@ extern "C" { } // #pragma clang diagnostic ignored "-Wdeprecated-declarations" +#define SOL_USING_CXX_LUA 0 +#define SOL_NO_LUA_HPP 1 #define SOL_USE_LUAU 1 #define SOL_SAFE_STACK_CHECK 1 #define SOL_LUA_BIT32_LIB 1 diff --git a/modules/stormkit/core/utils/filesystem.cppm b/modules/stormkit/core/utils/filesystem.cppm index aea442acf..9a363b34c 100644 --- a/modules/stormkit/core/utils/filesystem.cppm +++ b/modules/stormkit/core/utils/filesystem.cppm @@ -326,7 +326,7 @@ namespace stormkit { inline namespace core { namespace io { #ifdef STORMKIT_OS_WINDOWS FlushFileBuffers(reinterpret_cast(m_descriptor)); #else - #if STORMKIT_OS_LINUX + #ifdef STORMKIT_OS_LINUX fdatasync #else fsync diff --git a/xmake/targets/lua.xmake.lua b/xmake/targets/lua.xmake.lua index a1beb9f39..f112871c7 100644 --- a/xmake/targets/lua.xmake.lua +++ b/xmake/targets/lua.xmake.lua @@ -7,7 +7,7 @@ add_requires("luau", { build_cli = false, }, }) -add_requires("sol2", { +add_requires("sol2_luau", { system = false, version = "develop", }) @@ -58,7 +58,7 @@ target("lua", function() if get_config("wsi") then add_deps("wsi") end if get_config("gpu") then add_deps("gpu") end - add_packages("luau", "sol2", { public = true }) + add_packages("luau", "sol2_luau", { public = true }) add_options("sanitizers") diff --git a/xmake/targets/wsi.xmake.lua b/xmake/targets/wsi.xmake.lua index 629f2f04f..5ddfc867c 100644 --- a/xmake/targets/wsi.xmake.lua +++ b/xmake/targets/wsi.xmake.lua @@ -31,7 +31,7 @@ target("wsi", function() add_files(path.join(src_wsi_dir, "*.cpp"), path.join(src_wsi_dir, "common/*.cppm")) if is_plat("linux") then - add_files(path.join(src_wsi_dir, "linux/**.cpp")) + add_files(path.join(src_wsi_dir, "linux/**.cpp"), path.join(src_wsi_dir, "linux/**.cppm")) add_rules("wayland.protocols") From 5edf94b3284d351e945b0cbf64a2e025bfd30e67 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 25 Feb 2026 16:00:59 +0100 Subject: [PATCH 106/194] (examples) replace defines with static constexpr for examples constants --- examples/gpu/textured_cube/src/main.cpp | 10 +++++----- examples/gpu/triangle/src/main.cpp | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/gpu/textured_cube/src/main.cpp b/examples/gpu/textured_cube/src/main.cpp index 77db8fcf6..e40321b56 100644 --- a/examples/gpu/textured_cube/src/main.cpp +++ b/examples/gpu/textured_cube/src/main.cpp @@ -15,16 +15,16 @@ import gpu_app; #include #ifndef SHADER_DIR - #define SHADER_DIR "../share/stormkit/shaders/" +static constexpr auto SHADER_DIR "../share/stormkit/shaders/" #endif #ifndef RESOURCE_DIR - #define RESOURCE_DIR "../share/stormkit/" + static constexpr auto RESOURCE_DIR "../share/stormkit/" #endif -namespace stdc = std::chrono; -namespace stdr = std::ranges; -namespace stdfs = std::filesystem; + namespace stdc = std::chrono; +namespace stdr = std::ranges; +namespace stdfs = std::filesystem; using clock = stdc::high_resolution_clock; diff --git a/examples/gpu/triangle/src/main.cpp b/examples/gpu/triangle/src/main.cpp index 55e6d8981..ffd181637 100644 --- a/examples/gpu/triangle/src/main.cpp +++ b/examples/gpu/triangle/src/main.cpp @@ -13,11 +13,11 @@ import gpu_app; #include #ifndef SHADER_DIR - #define SHADER_DIR "../share/stormkit/shaders/" +static constexpr auto SHADER_DIR "../share/stormkit/shaders/" #endif -namespace stdr = std::ranges; -namespace stdfs = std::filesystem; + namespace stdr = std::ranges; +namespace stdfs = std::filesystem; using namespace std::literals; using namespace stormkit; From 2c457b93c6776473cf7f723ffddb9716956df5e1 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 25 Feb 2026 16:01:13 +0100 Subject: [PATCH 107/194] (lua) fix luau using libstdc++ on clang --- xmake/targets/lua.xmake.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xmake/targets/lua.xmake.lua b/xmake/targets/lua.xmake.lua index f112871c7..f78acaf04 100644 --- a/xmake/targets/lua.xmake.lua +++ b/xmake/targets/lua.xmake.lua @@ -5,6 +5,9 @@ add_requires("luau", { shared = false, extern_c = true, build_cli = false, + cxxflags = is_plat("linux") and { "-stdlib=libc++" } or nil, + shflags = is_plat("linux") and { "-stdlib=libc++" } or nil, + arflags = is_plat("linux") and { "-stdlib=libc++" } or nil, }, }) add_requires("sol2_luau", { From ebec00c7799cf2ce2495788cb403c0498e89fec0 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 25 Feb 2026 16:01:48 +0100 Subject: [PATCH 108/194] (examples) fix shader directory --- examples/gpu/textured_cube/xmake.lua | 2 +- examples/gpu/triangle/xmake.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/gpu/textured_cube/xmake.lua b/examples/gpu/textured_cube/xmake.lua index e30c23e7a..a3b279187 100644 --- a/examples/gpu/textured_cube/xmake.lua +++ b/examples/gpu/textured_cube/xmake.lua @@ -14,7 +14,7 @@ target("textured_cube", function() if get_config("devmode") then add_defines(format('RESOURCE_DIR="%s"', path.unix(path.join(os.projectdir(), "gpu/textured_cube")))) - add_defines(format('SHADER_DIR="%s"', path.unix("$(builddir)/shader"))) + add_defines(format('SHADER_DIR="%s"', path.unix("$(builddir)/shaders"))) end add_embeddirs("$(builddir)/shaders") diff --git a/examples/gpu/triangle/xmake.lua b/examples/gpu/triangle/xmake.lua index 25681d8db..7ddb137e9 100644 --- a/examples/gpu/triangle/xmake.lua +++ b/examples/gpu/triangle/xmake.lua @@ -14,7 +14,7 @@ target("triangle", function() if get_config("devmode") then add_defines(format('RESOURCE_DIR="%s"', path.unix(path.join(os.projectdir(), "gpu/triangle")))) - add_defines(format('SHADER_DIR="%s"', path.unix("$(builddir)/shader"))) + add_defines(format('SHADER_DIR="%s"', path.unix("$(builddir)/shaders"))) end add_embeddirs("$(builddir)/shaders") From d22d5bbfc97873fffbad0cd5a20f453c00355846 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 25 Feb 2026 16:13:16 +0100 Subject: [PATCH 109/194] (lua) fix luau package --- xmake/targets/lua.xmake.lua | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/xmake/targets/lua.xmake.lua b/xmake/targets/lua.xmake.lua index f78acaf04..db77e2e86 100644 --- a/xmake/targets/lua.xmake.lua +++ b/xmake/targets/lua.xmake.lua @@ -1,3 +1,8 @@ +local is_libcpp = false +if is_plat("linux") then + if has_config("runtimes") then is_libcpp = get_config("runtimes"):startswith("c++") end +end + add_requires("luau", { system = false, version = "upstream", @@ -5,9 +10,9 @@ add_requires("luau", { shared = false, extern_c = true, build_cli = false, - cxxflags = is_plat("linux") and { "-stdlib=libc++" } or nil, - shflags = is_plat("linux") and { "-stdlib=libc++" } or nil, - arflags = is_plat("linux") and { "-stdlib=libc++" } or nil, + cxxflags = is_libcpp and { "-stdlib=libc++" } or nil, + shflags = is_libcpp and { "-stdlib=libc++" } or nil, + arflags = is_libcpp and { "-stdlib=libc++" } or nil, }, }) add_requires("sol2_luau", { From 6e9055633cd8c35a4ddff587c2b6c144e38899d5 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 27 Feb 2026 16:43:22 +0100 Subject: [PATCH 110/194] (xmake) try to fix missing dso on linux --- xmake.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xmake.lua b/xmake.lua index d7162b9e0..c7a89ecc6 100644 --- a/xmake.lua +++ b/xmake.lua @@ -81,7 +81,7 @@ namespace("stormkit", function() if get_config("tools") then includes("xmake/targets/tools.xmake.lua") end target("stormkit", function() - set_kind("moduleonly") + set_kind("static") set_languages("cxxlatest", "clatest") From 3c59eb3504ba2bc9e245e5cf2cc80685196b8129 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 2 Mar 2026 14:17:35 +0100 Subject: [PATCH 111/194] (xmake) fix stormkit library --- modules/stormkit.cppm | 12 ++++++------ xmake.lua | 7 +++++-- xmake/targets/core.xmake.lua | 2 ++ xmake/targets/entities.xmake.lua | 2 ++ xmake/targets/gpu.xmake.lua | 2 ++ xmake/targets/image.xmake.lua | 2 ++ xmake/targets/log.xmake.lua | 2 ++ xmake/targets/lua.xmake.lua | 2 ++ xmake/targets/main.xmake.lua | 2 ++ xmake/targets/test.xmake.lua | 2 ++ xmake/targets/wsi.xmake.lua | 2 ++ 11 files changed, 29 insertions(+), 8 deletions(-) diff --git a/modules/stormkit.cppm b/modules/stormkit.cppm index 469b22768..717b4c732 100644 --- a/modules/stormkit.cppm +++ b/modules/stormkit.cppm @@ -13,21 +13,21 @@ export module stormkit; export import stormkit.core; -#if STORMKIT_LIB_LOG_ENABLED +#if STORMKIT_LIB_LOG_ENABLED and defined(STORMKIT_IMPORT_LOG) export import stormkit.log; #endif -#if STORMKIT_LIB_ENTITIES_ENABLED +#if STORMKIT_LIB_ENTITIES_ENABLED and defined(STORMKIT_IMPORT_ENTITIES) export import stormkit.entities; #endif -#if STORMKIT_LIB_IMAGE_ENABLED +#if STORMKIT_LIB_IMAGE_ENABLED and defined(STORMKIT_IMPORT_IMAGE) export import stormkit.image; #endif -#if STORMKIT_LIB_WSI_ENABLED +#if STORMKIT_LIB_WSI_ENABLED and defined(STORMKIT_IMPORT_WSI) export import stormkit.wsi; #endif -#if STORMKIT_LIB_GPU_ENABLED +#if STORMKIT_LIB_GPU_ENABLED and defined(STORMKIT_IMPORT_GPU) export import stormkit.gpu; #endif -#if STORMKIT_LIB_LUA_ENABLED +#if STORMKIT_LIB_LUA_ENABLED and defined(STORMKIT_IMPORT_LUA) export import stormkit.lua; #endif diff --git a/xmake.lua b/xmake.lua index c7a89ecc6..3158979f1 100644 --- a/xmake.lua +++ b/xmake.lua @@ -87,11 +87,14 @@ namespace("stormkit", function() add_rules("stormkit::flags") - add_files("modules/stormkit.cppm") + add_files("modules/stormkit.cppm", { public = true }) add_deps("stormkit::core") for _, name in ipairs({ "log", "entities", "gpu", "image", "wsi", "lua" }) do - if get_config(name) then add_deps("stormkit::" .. name) end + if get_config(name) then + add_deps("stormkit::" .. name) + add_defines("STORMKIT_IMPORT_" .. string.upper(name), { public = true }) + end end set_group("libraries") diff --git a/xmake/targets/core.xmake.lua b/xmake/targets/core.xmake.lua index 50c5ab8d8..c0f5a09bf 100644 --- a/xmake/targets/core.xmake.lua +++ b/xmake/targets/core.xmake.lua @@ -11,6 +11,8 @@ target("core", function() set_languages("cxxlatest", "clatest") + set_prefixname("libstormkit-") + add_defines("ANKERL_UNORDERED_DENSE_STD_MODULE=1", "FROZEN_STD_MODULE=1", { public = true }) add_defines("STORMKIT_CORE_BUILD", { public = false }) if is_mode("debug") then add_defines("STORMKIT_BUILD_DEBUG", { public = true }) end diff --git a/xmake/targets/entities.xmake.lua b/xmake/targets/entities.xmake.lua index ea609e23f..617b01b29 100644 --- a/xmake/targets/entities.xmake.lua +++ b/xmake/targets/entities.xmake.lua @@ -6,6 +6,8 @@ target("entities", function() set_languages("cxxlatest", "clatest") + set_prefixname("libstormkit-") + add_defines("STORMKIT_ENTITIES_BUILD", { public = false }) add_files(path.join(module_dir, "entities.cppm"), { public = true }) diff --git a/xmake/targets/gpu.xmake.lua b/xmake/targets/gpu.xmake.lua index fed88445f..3237188eb 100644 --- a/xmake/targets/gpu.xmake.lua +++ b/xmake/targets/gpu.xmake.lua @@ -22,6 +22,8 @@ target("gpu", function() set_kind("$(kind)") add_rules("flags") + set_prefixname("libstormkit-") + set_languages("cxxlatest", "clatest") add_defines("STORMKIT_GPU_BUILD", { public = false }) diff --git a/xmake/targets/image.xmake.lua b/xmake/targets/image.xmake.lua index 78b5e71b1..41055b926 100644 --- a/xmake/targets/image.xmake.lua +++ b/xmake/targets/image.xmake.lua @@ -16,6 +16,8 @@ target("image", function() set_languages("cxxlatest", "clatest") + set_prefixname("libstormkit-") + add_defines("STORMKIT_IMAGE_BUILD", { public = false }) add_files(path.join(module_dir, "image.cppm"), { public = true }) diff --git a/xmake/targets/log.xmake.lua b/xmake/targets/log.xmake.lua index bb42a8bf9..42523d3d2 100644 --- a/xmake/targets/log.xmake.lua +++ b/xmake/targets/log.xmake.lua @@ -6,6 +6,8 @@ target("log", function() set_languages("cxxlatest", "clatest") + set_prefixname("libstormkit-") + add_defines("STORMKIT_LOG_BUILD", { public = false }) add_files(path.join(module_dir, "log.cppm"), { public = true }) diff --git a/xmake/targets/lua.xmake.lua b/xmake/targets/lua.xmake.lua index db77e2e86..75a798360 100644 --- a/xmake/targets/lua.xmake.lua +++ b/xmake/targets/lua.xmake.lua @@ -29,6 +29,8 @@ target("lua", function() set_languages("cxxlatest", "clatest") + set_prefixname("libstormkit-") + add_defines("STORMKIT_LUA_BUILD", { public = false }) add_files(path.join(module_dir, "lua.cppm"), { public = true }) diff --git a/xmake/targets/main.xmake.lua b/xmake/targets/main.xmake.lua index 111694709..bb78ce703 100644 --- a/xmake/targets/main.xmake.lua +++ b/xmake/targets/main.xmake.lua @@ -6,6 +6,8 @@ target("main", function() set_languages("cxxlatest", "clatest") + set_prefixname("libstormkit-") + add_defines("STORMKIT_MAIN_BUILD", { public = false }) add_files(path.join(module_dir, "main.cppm"), { public = true }) diff --git a/xmake/targets/test.xmake.lua b/xmake/targets/test.xmake.lua index 3b205e949..4fd9db4d6 100644 --- a/xmake/targets/test.xmake.lua +++ b/xmake/targets/test.xmake.lua @@ -6,6 +6,8 @@ target("test", function() set_languages("cxxlatest", "clatest") + set_prefixname("libstormkit-") + add_files(path.join(module_dir, "test.cppm"), { public = true }) add_files(path.join(src_test_dir, "*.cpp")) diff --git a/xmake/targets/wsi.xmake.lua b/xmake/targets/wsi.xmake.lua index 5ddfc867c..c53d4daa5 100644 --- a/xmake/targets/wsi.xmake.lua +++ b/xmake/targets/wsi.xmake.lua @@ -25,6 +25,8 @@ target("wsi", function() set_languages("cxxlatest", "clatest") + set_prefixname("libstormkit-") + add_defines("STORMKIT_WSI_BUILD", { public = false }) add_files(path.join(module_dir, "wsi.cppm"), path.join(module_wsi_dir, "**.cppm"), { public = true }) From 8f7e06c9e50e7bc8ad9eb398e5fae9cde998b256 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 2 Mar 2026 14:43:02 +0100 Subject: [PATCH 112/194] (xmake) fix libraries names --- xmake/targets/core.xmake.lua | 2 +- xmake/targets/entities.xmake.lua | 2 +- xmake/targets/gpu.xmake.lua | 2 +- xmake/targets/image.xmake.lua | 2 +- xmake/targets/log.xmake.lua | 2 +- xmake/targets/lua.xmake.lua | 2 +- xmake/targets/main.xmake.lua | 2 +- xmake/targets/test.xmake.lua | 2 +- xmake/targets/wsi.xmake.lua | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/xmake/targets/core.xmake.lua b/xmake/targets/core.xmake.lua index c0f5a09bf..062101467 100644 --- a/xmake/targets/core.xmake.lua +++ b/xmake/targets/core.xmake.lua @@ -11,7 +11,7 @@ target("core", function() set_languages("cxxlatest", "clatest") - set_prefixname("libstormkit-") + set_basename("stormkit-core") add_defines("ANKERL_UNORDERED_DENSE_STD_MODULE=1", "FROZEN_STD_MODULE=1", { public = true }) add_defines("STORMKIT_CORE_BUILD", { public = false }) diff --git a/xmake/targets/entities.xmake.lua b/xmake/targets/entities.xmake.lua index 617b01b29..64018b35d 100644 --- a/xmake/targets/entities.xmake.lua +++ b/xmake/targets/entities.xmake.lua @@ -6,7 +6,7 @@ target("entities", function() set_languages("cxxlatest", "clatest") - set_prefixname("libstormkit-") + set_basename("stormkit-entities") add_defines("STORMKIT_ENTITIES_BUILD", { public = false }) diff --git a/xmake/targets/gpu.xmake.lua b/xmake/targets/gpu.xmake.lua index 3237188eb..a02cebfbe 100644 --- a/xmake/targets/gpu.xmake.lua +++ b/xmake/targets/gpu.xmake.lua @@ -22,7 +22,7 @@ target("gpu", function() set_kind("$(kind)") add_rules("flags") - set_prefixname("libstormkit-") + set_basename("stormkit-gpu") set_languages("cxxlatest", "clatest") diff --git a/xmake/targets/image.xmake.lua b/xmake/targets/image.xmake.lua index 41055b926..3499cd233 100644 --- a/xmake/targets/image.xmake.lua +++ b/xmake/targets/image.xmake.lua @@ -16,7 +16,7 @@ target("image", function() set_languages("cxxlatest", "clatest") - set_prefixname("libstormkit-") + set_basename("stormkit-image") add_defines("STORMKIT_IMAGE_BUILD", { public = false }) diff --git a/xmake/targets/log.xmake.lua b/xmake/targets/log.xmake.lua index 42523d3d2..ba7f0425d 100644 --- a/xmake/targets/log.xmake.lua +++ b/xmake/targets/log.xmake.lua @@ -6,7 +6,7 @@ target("log", function() set_languages("cxxlatest", "clatest") - set_prefixname("libstormkit-") + set_basename("stormkit-log") add_defines("STORMKIT_LOG_BUILD", { public = false }) diff --git a/xmake/targets/lua.xmake.lua b/xmake/targets/lua.xmake.lua index 75a798360..ee4dd28b1 100644 --- a/xmake/targets/lua.xmake.lua +++ b/xmake/targets/lua.xmake.lua @@ -29,7 +29,7 @@ target("lua", function() set_languages("cxxlatest", "clatest") - set_prefixname("libstormkit-") + set_basename("stormkit-lua") add_defines("STORMKIT_LUA_BUILD", { public = false }) diff --git a/xmake/targets/main.xmake.lua b/xmake/targets/main.xmake.lua index bb78ce703..82a7b2909 100644 --- a/xmake/targets/main.xmake.lua +++ b/xmake/targets/main.xmake.lua @@ -6,7 +6,7 @@ target("main", function() set_languages("cxxlatest", "clatest") - set_prefixname("libstormkit-") + set_basename("stormkit-main") add_defines("STORMKIT_MAIN_BUILD", { public = false }) diff --git a/xmake/targets/test.xmake.lua b/xmake/targets/test.xmake.lua index 4fd9db4d6..e0f9a9496 100644 --- a/xmake/targets/test.xmake.lua +++ b/xmake/targets/test.xmake.lua @@ -6,7 +6,7 @@ target("test", function() set_languages("cxxlatest", "clatest") - set_prefixname("libstormkit-") + set_basename("stormkit-test") add_files(path.join(module_dir, "test.cppm"), { public = true }) add_files(path.join(src_test_dir, "*.cpp")) diff --git a/xmake/targets/wsi.xmake.lua b/xmake/targets/wsi.xmake.lua index c53d4daa5..add7c89f9 100644 --- a/xmake/targets/wsi.xmake.lua +++ b/xmake/targets/wsi.xmake.lua @@ -25,7 +25,7 @@ target("wsi", function() set_languages("cxxlatest", "clatest") - set_prefixname("libstormkit-") + set_basename("stormkit-wsi") add_defines("STORMKIT_WSI_BUILD", { public = false }) From 8ce70cfc1ada50f7cb41309176c0412ef54097f4 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 2 Mar 2026 17:56:35 +0100 Subject: [PATCH 113/194] (xmake) improve rules --- xmake/rules/{nzsl2spv.xmake.lua => nzsl.xmake.lua} | 2 ++ .../rules/{resource2cpp.xmake.lua => resources.xmake.lua} | 7 ++----- xmake/rules/wayland-protocols.xmake.lua | 2 ++ 3 files changed, 6 insertions(+), 5 deletions(-) rename xmake/rules/{nzsl2spv.xmake.lua => nzsl.xmake.lua} (97%) rename xmake/rules/{resource2cpp.xmake.lua => resources.xmake.lua} (91%) diff --git a/xmake/rules/nzsl2spv.xmake.lua b/xmake/rules/nzsl.xmake.lua similarity index 97% rename from xmake/rules/nzsl2spv.xmake.lua rename to xmake/rules/nzsl.xmake.lua index c4263094e..cf91ddd58 100644 --- a/xmake/rules/nzsl2spv.xmake.lua +++ b/xmake/rules/nzsl.xmake.lua @@ -87,6 +87,7 @@ rule("compile.shaders", function() before_buildcmd_file(function(target, batchcmds, shaderfile, opt) import("lib.detect.find_tool") + import("utils.progress") local outputdir = path.join(import("core.project.config").builddir(), "shaders") local nzslc = target:data("nzslc") @@ -96,6 +97,7 @@ rule("compile.shaders", function() local outputfile = path.join(outputdir or path.directory(shaderfile), path.basename(shaderfile) .. ".spv") -- add commands + if progress.apply_target then opt.progress = progress.apply_target(target, opt.progress) end batchcmds:show_progress(opt.progress, "${color.build.object}compiling.shader %s", shaderfile) local argv = { "--compile=spv", "--optimize", "--spv-version=130", "--gl-flipy" } if outputdir then diff --git a/xmake/rules/resource2cpp.xmake.lua b/xmake/rules/resources.xmake.lua similarity index 91% rename from xmake/rules/resource2cpp.xmake.lua rename to xmake/rules/resources.xmake.lua index 8fc1922fb..016def4aa 100644 --- a/xmake/rules/resource2cpp.xmake.lua +++ b/xmake/rules/resources.xmake.lua @@ -2,15 +2,12 @@ rule("stormkit.utils.resource2cpp", function() before_build(function(target, opt) import("core.base.option") - if xmake.version():ge("2.5.9") then - import("utils.progress") - elseif not import("utils.progress", { try = true }) then - import("private.utils.progress") - end + import("utils.progress") local function GenerateEmbedHeader(filepath, targetpath) local bufferSize = 1024 * 1024 + if progress.apply_target then opt.progress = progress.apply_target(target, opt.progress) end progress.show(opt.progress, "${color.build.object}embedding %s", filepath) local resource = assert(io.open(filepath, "rb")) diff --git a/xmake/rules/wayland-protocols.xmake.lua b/xmake/rules/wayland-protocols.xmake.lua index 96778e3f7..7687e1c9d 100644 --- a/xmake/rules/wayland-protocols.xmake.lua +++ b/xmake/rules/wayland-protocols.xmake.lua @@ -51,6 +51,7 @@ rule("wayland.protocols", function() before_buildcmd_file(function(target, batchcmds, sourcefile, opt) import("lib.detect.find_tool") + import("utils.progress") local outputdir = target:extraconf("rules", "wayland.protocols", "outputdir") or path.join(target:autogendir(), "rules", "wayland.protocols") @@ -67,6 +68,7 @@ rule("wayland.protocols", function() local client_flags = { client_flag, sourcefile, clientfile } local private_flags = { private_flag, sourcefile, privatefile } + if progress.apply_target then opt.progress = progress.apply_target(target, opt.progress) end batchcmds:show_progress( opt.progress, "${color.build.object}generating.wayland.protocol.client %s", From 8e4766f1b106e274eaecc7afc6b0dc6a777175d4 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 2 Mar 2026 18:32:25 +0100 Subject: [PATCH 114/194] (xmake) fix stormkit library --- examples/gpu/textured_cube/xmake.lua | 18 ++++++++++-------- examples/gpu/triangle/xmake.lua | 18 ++++++++++-------- xmake.lua | 2 ++ 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/examples/gpu/textured_cube/xmake.lua b/examples/gpu/textured_cube/xmake.lua index a3b279187..d1a6b5154 100644 --- a/examples/gpu/textured_cube/xmake.lua +++ b/examples/gpu/textured_cube/xmake.lua @@ -1,11 +1,13 @@ -add_requires("nzsl", { - configs = { - fs_watcher = false, - kind = "binary", - toolchain = is_plat("windows") and "cl" or nil, - runtimes = is_plat("windows") and "MD" or nil, - }, -}) +local runtimes +local toolchain +if is_plat("windows") then + runtimes = "MD" + toolchain = "msvc" +elseif is_plat("linux") then + runtimes = "stdc++_shared" + toolchain = "gcc" +end +add_requires("nzsl", { configs = { fs_watcher = false, kind = "binary", toolchains = toolchain, runtimes = runtimes } }) target("textured_cube", function() add_rules("stormkit::example", "compile.shaders") diff --git a/examples/gpu/triangle/xmake.lua b/examples/gpu/triangle/xmake.lua index 7ddb137e9..762d686d0 100644 --- a/examples/gpu/triangle/xmake.lua +++ b/examples/gpu/triangle/xmake.lua @@ -1,11 +1,13 @@ -add_requires("nzsl", { - configs = { - fs_watcher = false, - kind = "binary", - toolchain = is_plat("windows") and "cl" or nil, - runtimes = is_plat("windows") and "MD" or nil, - }, -}) +local runtimes +local toolchain +if is_plat("windows") then + runtimes = "MD" + toolchain = "msvc" +elseif is_plat("linux") then + runtimes = "stdc++_shared" + toolchain = "gcc" +end +add_requires("nzsl", { configs = { fs_watcher = false, kind = "binary", toolchains = toolchain, runtimes = runtimes } }) target("triangle", function() add_rules("stormkit::example", "compile.shaders") diff --git a/xmake.lua b/xmake.lua index 3158979f1..804f82d8a 100644 --- a/xmake.lua +++ b/xmake.lua @@ -85,6 +85,8 @@ namespace("stormkit", function() set_languages("cxxlatest", "clatest") + set_suffixname("") + add_rules("stormkit::flags") add_files("modules/stormkit.cppm", { public = true }) From 733d3c3a6e8898cf1369de14779ffa90f3115a8d Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Mar 2026 16:55:55 +0100 Subject: [PATCH 115/194] (core) fix open on linux / macOS --- modules/stormkit/core/utils/filesystem.cppm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stormkit/core/utils/filesystem.cppm b/modules/stormkit/core/utils/filesystem.cppm index 9a363b34c..0c2414bff 100644 --- a/modules/stormkit/core/utils/filesystem.cppm +++ b/modules/stormkit/core/utils/filesystem.cppm @@ -157,7 +157,7 @@ namespace stormkit { inline namespace core { namespace io { #else if (access == Access::READ) return O_RDONLY; else if (access == Access::WRITE) - return O_WRONLY; + return O_WRONLY | O_CREAT; else return O_RDWR; #endif From d44538ba0107f026116f706301758df683423165 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Mar 2026 17:38:30 +0100 Subject: [PATCH 116/194] (core) remove operator== check for add_vertex --- modules/stormkit/core/containers/dag.cppm | 38 +++++------------------ 1 file changed, 8 insertions(+), 30 deletions(-) diff --git a/modules/stormkit/core/containers/dag.cppm b/modules/stormkit/core/containers/dag.cppm index f04e85b49..26fdb5097 100644 --- a/modules/stormkit/core/containers/dag.cppm +++ b/modules/stormkit/core/containers/dag.cppm @@ -188,21 +188,10 @@ namespace stormkit { inline namespace core { constexpr auto DAG::add_vertex(const VertexValue& vertex) noexcept -> dag::VertexID requires(meta::IsCopyConstructible) { - if constexpr (meta::HasEqualityOperator) { - if (not has_vertex(vertex)) { - const auto id = m_next_id++; - m_vertices.emplace_back(id, vertex); - m_adjacent_edges[id] = {}; - return id; - } - - return stdr::find_if(m_vertices, [&vertex](const auto& other) noexcept { return vertex == other.value; })->id; - } else { - const auto id = m_next_id++; - m_vertices.emplace_back(id, vertex); - m_adjacent_edges[id] = {}; - return id; - } + const auto id = m_next_id++; + m_vertices.emplace_back(id, vertex); + m_adjacent_edges[id] = {}; + return id; } //////////////////////////////////////// @@ -211,21 +200,10 @@ namespace stormkit { inline namespace core { constexpr auto DAG::add_vertex(VertexValue&& vertex) noexcept -> dag::VertexID requires(meta::IsMoveConstructible) { - if constexpr (meta::HasEqualityOperator) { - if (not has_vertex(vertex)) { - const auto id = m_next_id++; - m_vertices.emplace_back(id, std::move(vertex)); - m_adjacent_edges[id] = {}; - return id; - } - - return stdr::find_if(m_vertices, [&vertex](const auto& other) noexcept { return vertex == other.value; })->id; - } else { - const auto id = m_next_id++; - m_vertices.emplace_back(id, std::move(vertex)); - m_adjacent_edges[id] = {}; - return id; - } + const auto id = m_next_id++; + m_vertices.emplace_back(id, std::move(vertex)); + m_adjacent_edges[id] = {}; + return id; } //////////////////////////////////////// From 9fc528e7be11fc7bde77cdd32b6190ce35974cc6 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Mar 2026 18:19:15 +0100 Subject: [PATCH 117/194] (gpu) add support for sub command buffer using Vk rendering extension --- .../gpu/execution/command_buffer.cppm | 14 ++++- src/gpu/execution/command_buffer.cpp | 56 ++++++++++++++----- 2 files changed, 54 insertions(+), 16 deletions(-) diff --git a/modules/stormkit/gpu/execution/command_buffer.cppm b/modules/stormkit/gpu/execution/command_buffer.cppm index 00522427c..106e94a8e 100644 --- a/modules/stormkit/gpu/execution/command_buffer.cppm +++ b/modules/stormkit/gpu/execution/command_buffer.cppm @@ -82,12 +82,22 @@ export namespace stormkit::gpu { class CommandPool; - struct InheritanceInfo { + struct RenderPassInheritanceInfo { OptionalRef render_pass = std::nullopt; u32 subpass = 0; OptionalRef framebuffer = std::nullopt; }; + struct RenderingInheritanceInfo { + u32 view_mask = 0; + std::vector color_attachments = {}; + std::optional depth_attachment = std::nullopt; + std::optional stencil_attachment = std::nullopt; + SampleCountFlag rasterization_samples = SampleCountFlag::C1; + }; + + using InheritanceInfo = std::variant; + struct RenderingInfo { struct Attachment { struct Resolve { @@ -149,7 +159,7 @@ export namespace stormkit::gpu { [[nodiscard]] auto level() const noexcept -> CommandBufferLevel; - auto begin(bool one_time_submit = false, std::optional inheritance_info = std::nullopt) noexcept + auto begin(bool one_time_submit = false, InheritanceInfo inheritance_info = std::monostate {}) noexcept -> Expected>; auto end() noexcept -> Expected>; diff --git a/src/gpu/execution/command_buffer.cpp b/src/gpu/execution/command_buffer.cpp index 07932be2b..bbbc7d2ff 100644 --- a/src/gpu/execution/command_buffer.cpp +++ b/src/gpu/execution/command_buffer.cpp @@ -71,22 +71,50 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::begin(bool one_time_submit, std::optional inheritance_info) noexcept + auto CommandBuffer::begin(bool one_time_submit, InheritanceInfo inheritance_info_variant) noexcept -> Expected> { EXPECTS(m_state == State::INITIAL); - const auto vk_inheritance_info = [&inheritance_info] { - auto info = zeroed(); - info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; - if (inheritance_info) { - info.renderPass = to_vk(*inheritance_info->render_pass); - info.subpass = inheritance_info->subpass; - info.framebuffer = to_vk(*inheritance_info->framebuffer); - } - return info; - }(); - - const auto flags = [this, one_time_submit]() -> VkCommandBufferUsageFlags { + auto rendering_color_attachments = std::vector {}; + auto vk_rendering_inheritance_info = zeroed(); + vk_rendering_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO; + + const auto vk_inheritance_info = + [&inheritance_info_variant, &rendering_color_attachments, &vk_rendering_inheritance_info] noexcept { + auto info = zeroed(); + info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; + + if (is(inheritance_info_variant)) { + const auto& inheritance_info = as(inheritance_info_variant); + info.renderPass = to_vk(*inheritance_info.render_pass); + info.subpass = inheritance_info.subpass; + info.framebuffer = to_vk(*inheritance_info.framebuffer); + } else if (is(inheritance_info_variant)) { + info.pNext = &vk_rendering_inheritance_info; + + const auto& inheritance_info = as(inheritance_info_variant); + + rendering_color_attachments = inheritance_info.color_attachments + | stdv::transform(gpu::monadic::to_vk()) + | stdr::to(); + vk_rendering_inheritance_info.viewMask = inheritance_info.view_mask; + vk_rendering_inheritance_info.colorAttachmentCount = as(stdr::size(inheritance_info.color_attachments)); + vk_rendering_inheritance_info.pColorAttachmentFormats = stdr::data(rendering_color_attachments); + + if (inheritance_info.depth_attachment) + vk_rendering_inheritance_info + .depthAttachmentFormat = gpu::to_vk(*inheritance_info.depth_attachment); + if (inheritance_info.stencil_attachment) + vk_rendering_inheritance_info + .stencilAttachmentFormat = gpu::to_vk(*inheritance_info.stencil_attachment); + + vk_rendering_inheritance_info + .rasterizationSamples = gpu::to_vk(inheritance_info.rasterization_samples); + } + return info; + }(); + + const auto flags = [this, one_time_submit] noexcept -> VkCommandBufferUsageFlags { auto flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; if (!one_time_submit) flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; @@ -407,7 +435,7 @@ namespace stormkit::gpu { ImageLayout dst_layout, const ImageSubresourceLayers& src_subresource_layers, const ImageSubresourceLayers& dst_subresource_layers, - const math::uextent3& extent) noexcept -> CommandBuffer& { + const math::uextent3& extent) noexcept -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); const auto vk_src_subresource_layers = VkImageSubresourceLayers { From 45d5e06ad9589ddaedf755ff6b1829c5fa7bcbba Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Mar 2026 18:44:51 +0100 Subject: [PATCH 118/194] (gpu) add stencil only format --- modules/stormkit/gpu/core/vulkan/enums.cppm | 112 +++++++++++------- .../stormkit/gpu/core/vulkan/enums.cppm.tpl | 20 ++++ modules/stormkit/gpu/core/vulkan/mapping.json | 3 +- 3 files changed, 90 insertions(+), 45 deletions(-) diff --git a/modules/stormkit/gpu/core/vulkan/enums.cppm b/modules/stormkit/gpu/core/vulkan/enums.cppm index 0dcab474c..eab76d793 100644 --- a/modules/stormkit/gpu/core/vulkan/enums.cppm +++ b/modules/stormkit/gpu/core/vulkan/enums.cppm @@ -476,8 +476,8 @@ export { EQUIVALENT = VK_LOGIC_OP_EQUIVALENT, INVERT = VK_LOGIC_OP_INVERT, NAND = VK_LOGIC_OP_NAND, - NOR = VK_LOGIC_OP_NOR, NO_OP = VK_LOGIC_OP_NO_OP, + NOR = VK_LOGIC_OP_NOR, OR = VK_LOGIC_OP_OR, OR_INVERTED = VK_LOGIC_OP_OR_INVERTED, OR_REVERSE = VK_LOGIC_OP_OR_REVERSE, @@ -548,9 +548,9 @@ export { enum class PixelFormat : u32 { A1_RGB5_UNORM_PACK16 = VK_FORMAT_A1R5G5B5_UNORM_PACK16, A2_RGB10I_PACK32 = VK_FORMAT_A2R10G10B10_SINT_PACK32, - A2_RGB10U_PACK32 = VK_FORMAT_A2R10G10B10_UINT_PACK32, A2_RGB10_SNORM_PACK32 = VK_FORMAT_A2R10G10B10_SNORM_PACK32, A2_RGB10_UNORM_PACK32 = VK_FORMAT_A2R10G10B10_UNORM_PACK32, + A2_RGB10U_PACK32 = VK_FORMAT_A2R10G10B10_UINT_PACK32, B10_GR11UF_PACK32 = VK_FORMAT_B10G11R11_UFLOAT_PACK32, BGR8_UNORM = VK_FORMAT_B8G8R8_UNORM, BGRA8_UNORM = VK_FORMAT_B8G8R8A8_UNORM, @@ -562,54 +562,55 @@ export { DEPTH32F_STENCIL8U = VK_FORMAT_D32_SFLOAT_S8_UINT, R16F = VK_FORMAT_R16_SFLOAT, R16I = VK_FORMAT_R16_SINT, - R16U = VK_FORMAT_R16_UINT, R16_SNORM = VK_FORMAT_R16_SNORM, + R16U = VK_FORMAT_R16_UINT, R16_UNORM = VK_FORMAT_R16_UNORM, R32F = VK_FORMAT_R32_SFLOAT, R32I = VK_FORMAT_R32_SINT, R32U = VK_FORMAT_R32_UINT, R5_G6_B5_UNORM_PACK16 = VK_FORMAT_R5G6B5_UNORM_PACK16, R8I = VK_FORMAT_R8_SINT, - R8U = VK_FORMAT_R8_UINT, R8_SNORM = VK_FORMAT_R8_SNORM, + R8U = VK_FORMAT_R8_UINT, R8_UNORM = VK_FORMAT_R8_UNORM, RG16F = VK_FORMAT_R16G16_SFLOAT, RG16I = VK_FORMAT_R16G16_SINT, - RG16U = VK_FORMAT_R16G16_UINT, RG16_SNORM = VK_FORMAT_R16G16_SNORM, + RG16U = VK_FORMAT_R16G16_UINT, RG16_UNORM = VK_FORMAT_R16G16_UNORM, RG32F = VK_FORMAT_R32G32_SFLOAT, RG32I = VK_FORMAT_R32G32_SINT, RG32U = VK_FORMAT_R32G32_UINT, RG8I = VK_FORMAT_R8G8_SINT, - RG8U = VK_FORMAT_R8G8_UINT, RG8_SNORM = VK_FORMAT_R8G8_SNORM, + RG8U = VK_FORMAT_R8G8_UINT, RG8_UNORM = VK_FORMAT_R8G8_UNORM, RGB16F = VK_FORMAT_R16G16B16_SFLOAT, RGB16I = VK_FORMAT_R16G16B16_SINT, - RGB16U = VK_FORMAT_R16G16B16_UINT, RGB16_SNORM = VK_FORMAT_R16G16B16_SNORM, + RGB16U = VK_FORMAT_R16G16B16_UINT, RGB16_UNORM = VK_FORMAT_R16G16B16_UNORM, RGB32F = VK_FORMAT_R32G32B32_SFLOAT, RGB32I = VK_FORMAT_R32G32B32_SINT, RGB32U = VK_FORMAT_R32G32B32_UINT, RGB8I = VK_FORMAT_R8G8B8_SINT, - RGB8U = VK_FORMAT_R8G8B8_UINT, RGB8_SNORM = VK_FORMAT_R8G8B8_SNORM, + RGB8U = VK_FORMAT_R8G8B8_UINT, RGB8_UNORM = VK_FORMAT_R8G8B8_UNORM, RGBA16F = VK_FORMAT_R16G16B16A16_SFLOAT, RGBA16I = VK_FORMAT_R16G16B16A16_SINT, - RGBA16U = VK_FORMAT_R16G16B16A16_UINT, RGBA16_SNORM = VK_FORMAT_R16G16B16A16_SNORM, + RGBA16U = VK_FORMAT_R16G16B16A16_UINT, RGBA16_UNORM = VK_FORMAT_R16G16B16A16_UNORM, RGBA32F = VK_FORMAT_R32G32B32A32_SFLOAT, RGBA32I = VK_FORMAT_R32G32B32A32_SINT, RGBA32U = VK_FORMAT_R32G32B32A32_UINT, RGBA4_UNORM_PACK16 = VK_FORMAT_R4G4B4A4_UNORM_PACK16, RGBA8I = VK_FORMAT_R8G8B8A8_SINT, - RGBA8U = VK_FORMAT_R8G8B8A8_UINT, RGBA8_SNORM = VK_FORMAT_R8G8B8A8_SNORM, + RGBA8U = VK_FORMAT_R8G8B8A8_UINT, RGBA8_UNORM = VK_FORMAT_R8G8B8A8_UNORM, + S8U = VK_FORMAT_S8_UINT, SBGR8 = VK_FORMAT_B8G8R8_SRGB, SBGRA8 = VK_FORMAT_B8G8R8A8_SRGB, SR8 = VK_FORMAT_R8_SRGB, @@ -745,8 +746,8 @@ export { enum class SamplerAddressMode : u8 { CLAMP_TO_BORDER = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, - MIRRORED_REPEAT = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, MIRROR_CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, + MIRRORED_REPEAT = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, REPEAT = VK_SAMPLER_ADDRESS_MODE_REPEAT, }; @@ -811,9 +812,13 @@ export { [[nodiscard]] constexpr auto is_depth_only_format(PixelFormat format) noexcept -> bool; [[nodiscard]] + constexpr auto is_stencil_only_format(PixelFormat format) noexcept -> bool; + [[nodiscard]] constexpr auto is_depth_stencil_format(PixelFormat format) noexcept -> bool; [[nodiscard]] constexpr auto is_depth_format(PixelFormat format) noexcept -> bool; + [[nodiscard]] + constexpr auto is_stencil_format(PixelFormat format) noexcept -> bool; [[nodiscard]] constexpr auto get_format_channel_count(PixelFormat format) noexcept -> u8; @@ -2274,8 +2279,8 @@ export { stormkit::gpu::LogicOperation::EQUIVALENT, stormkit::gpu::LogicOperation::INVERT, stormkit::gpu::LogicOperation::NAND, - stormkit::gpu::LogicOperation::NOR, stormkit::gpu::LogicOperation::NO_OP, + stormkit::gpu::LogicOperation::NOR, stormkit::gpu::LogicOperation::OR, stormkit::gpu::LogicOperation::OR_INVERTED, stormkit::gpu::LogicOperation::OR_REVERSE, @@ -2298,8 +2303,8 @@ export { case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; - case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; + case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; case stormkit::gpu::LogicOperation::OR: return "LogicOperation::OR"; case stormkit::gpu::LogicOperation::OR_INVERTED: return "LogicOperation::OR_INVERTED"; case stormkit::gpu::LogicOperation::OR_REVERSE: return "LogicOperation::OR_REVERSE"; @@ -2322,8 +2327,8 @@ export { case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; - case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; + case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; case stormkit::gpu::LogicOperation::OR: return "LogicOperation::OR"; case stormkit::gpu::LogicOperation::OR_INVERTED: return "LogicOperation::OR_INVERTED"; case stormkit::gpu::LogicOperation::OR_REVERSE: return "LogicOperation::OR_REVERSE"; @@ -2529,9 +2534,9 @@ export { return std::array { stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16, stormkit::gpu::PixelFormat::A2_RGB10I_PACK32, - stormkit::gpu::PixelFormat::A2_RGB10U_PACK32, stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32, stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32, + stormkit::gpu::PixelFormat::A2_RGB10U_PACK32, stormkit::gpu::PixelFormat::B10_GR11UF_PACK32, stormkit::gpu::PixelFormat::BGR8_UNORM, stormkit::gpu::PixelFormat::BGRA8_UNORM, @@ -2543,54 +2548,55 @@ export { stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U, stormkit::gpu::PixelFormat::R16F, stormkit::gpu::PixelFormat::R16I, - stormkit::gpu::PixelFormat::R16U, stormkit::gpu::PixelFormat::R16_SNORM, + stormkit::gpu::PixelFormat::R16U, stormkit::gpu::PixelFormat::R16_UNORM, stormkit::gpu::PixelFormat::R32F, stormkit::gpu::PixelFormat::R32I, stormkit::gpu::PixelFormat::R32U, stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16, stormkit::gpu::PixelFormat::R8I, - stormkit::gpu::PixelFormat::R8U, stormkit::gpu::PixelFormat::R8_SNORM, + stormkit::gpu::PixelFormat::R8U, stormkit::gpu::PixelFormat::R8_UNORM, stormkit::gpu::PixelFormat::RG16F, stormkit::gpu::PixelFormat::RG16I, - stormkit::gpu::PixelFormat::RG16U, stormkit::gpu::PixelFormat::RG16_SNORM, + stormkit::gpu::PixelFormat::RG16U, stormkit::gpu::PixelFormat::RG16_UNORM, stormkit::gpu::PixelFormat::RG32F, stormkit::gpu::PixelFormat::RG32I, stormkit::gpu::PixelFormat::RG32U, stormkit::gpu::PixelFormat::RG8I, - stormkit::gpu::PixelFormat::RG8U, stormkit::gpu::PixelFormat::RG8_SNORM, + stormkit::gpu::PixelFormat::RG8U, stormkit::gpu::PixelFormat::RG8_UNORM, stormkit::gpu::PixelFormat::RGB16F, stormkit::gpu::PixelFormat::RGB16I, - stormkit::gpu::PixelFormat::RGB16U, stormkit::gpu::PixelFormat::RGB16_SNORM, + stormkit::gpu::PixelFormat::RGB16U, stormkit::gpu::PixelFormat::RGB16_UNORM, stormkit::gpu::PixelFormat::RGB32F, stormkit::gpu::PixelFormat::RGB32I, stormkit::gpu::PixelFormat::RGB32U, stormkit::gpu::PixelFormat::RGB8I, - stormkit::gpu::PixelFormat::RGB8U, stormkit::gpu::PixelFormat::RGB8_SNORM, + stormkit::gpu::PixelFormat::RGB8U, stormkit::gpu::PixelFormat::RGB8_UNORM, stormkit::gpu::PixelFormat::RGBA16F, stormkit::gpu::PixelFormat::RGBA16I, - stormkit::gpu::PixelFormat::RGBA16U, stormkit::gpu::PixelFormat::RGBA16_SNORM, + stormkit::gpu::PixelFormat::RGBA16U, stormkit::gpu::PixelFormat::RGBA16_UNORM, stormkit::gpu::PixelFormat::RGBA32F, stormkit::gpu::PixelFormat::RGBA32I, stormkit::gpu::PixelFormat::RGBA32U, stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16, stormkit::gpu::PixelFormat::RGBA8I, - stormkit::gpu::PixelFormat::RGBA8U, stormkit::gpu::PixelFormat::RGBA8_SNORM, + stormkit::gpu::PixelFormat::RGBA8U, stormkit::gpu::PixelFormat::RGBA8_UNORM, + stormkit::gpu::PixelFormat::S8U, stormkit::gpu::PixelFormat::SBGR8, stormkit::gpu::PixelFormat::SBGRA8, stormkit::gpu::PixelFormat::SR8, @@ -2608,9 +2614,9 @@ export { switch(value) { case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; @@ -2622,54 +2628,55 @@ export { case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; - case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; + case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; case stormkit::gpu::PixelFormat::R16_UNORM: return "PixelFormat::R16_UNORM"; case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; - case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; + case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; case stormkit::gpu::PixelFormat::R8_UNORM: return "PixelFormat::R8_UNORM"; case stormkit::gpu::PixelFormat::RG16F: return "PixelFormat::RG16F"; case stormkit::gpu::PixelFormat::RG16I: return "PixelFormat::RG16I"; - case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; + case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; case stormkit::gpu::PixelFormat::RG16_UNORM: return "PixelFormat::RG16_UNORM"; case stormkit::gpu::PixelFormat::RG32F: return "PixelFormat::RG32F"; case stormkit::gpu::PixelFormat::RG32I: return "PixelFormat::RG32I"; case stormkit::gpu::PixelFormat::RG32U: return "PixelFormat::RG32U"; case stormkit::gpu::PixelFormat::RG8I: return "PixelFormat::RG8I"; - case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; + case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; case stormkit::gpu::PixelFormat::RG8_UNORM: return "PixelFormat::RG8_UNORM"; case stormkit::gpu::PixelFormat::RGB16F: return "PixelFormat::RGB16F"; case stormkit::gpu::PixelFormat::RGB16I: return "PixelFormat::RGB16I"; - case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; + case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; case stormkit::gpu::PixelFormat::RGB16_UNORM: return "PixelFormat::RGB16_UNORM"; case stormkit::gpu::PixelFormat::RGB32F: return "PixelFormat::RGB32F"; case stormkit::gpu::PixelFormat::RGB32I: return "PixelFormat::RGB32I"; case stormkit::gpu::PixelFormat::RGB32U: return "PixelFormat::RGB32U"; case stormkit::gpu::PixelFormat::RGB8I: return "PixelFormat::RGB8I"; - case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; + case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; case stormkit::gpu::PixelFormat::RGB8_UNORM: return "PixelFormat::RGB8_UNORM"; case stormkit::gpu::PixelFormat::RGBA16F: return "PixelFormat::RGBA16F"; case stormkit::gpu::PixelFormat::RGBA16I: return "PixelFormat::RGBA16I"; - case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; + case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; case stormkit::gpu::PixelFormat::RGBA16_UNORM: return "PixelFormat::RGBA16_UNORM"; case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; - case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; + case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; case stormkit::gpu::PixelFormat::RGBA8_UNORM: return "PixelFormat::RGBA8_UNORM"; + case stormkit::gpu::PixelFormat::S8U: return "PixelFormat::S8U"; case stormkit::gpu::PixelFormat::SBGR8: return "PixelFormat::SBGR8"; case stormkit::gpu::PixelFormat::SBGRA8: return "PixelFormat::SBGRA8"; case stormkit::gpu::PixelFormat::SR8: return "PixelFormat::SR8"; @@ -2687,9 +2694,9 @@ export { switch(value) { case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; @@ -2701,54 +2708,55 @@ export { case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; - case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; + case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; case stormkit::gpu::PixelFormat::R16_UNORM: return "PixelFormat::R16_UNORM"; case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; - case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; + case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; case stormkit::gpu::PixelFormat::R8_UNORM: return "PixelFormat::R8_UNORM"; case stormkit::gpu::PixelFormat::RG16F: return "PixelFormat::RG16F"; case stormkit::gpu::PixelFormat::RG16I: return "PixelFormat::RG16I"; - case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; + case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; case stormkit::gpu::PixelFormat::RG16_UNORM: return "PixelFormat::RG16_UNORM"; case stormkit::gpu::PixelFormat::RG32F: return "PixelFormat::RG32F"; case stormkit::gpu::PixelFormat::RG32I: return "PixelFormat::RG32I"; case stormkit::gpu::PixelFormat::RG32U: return "PixelFormat::RG32U"; case stormkit::gpu::PixelFormat::RG8I: return "PixelFormat::RG8I"; - case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; + case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; case stormkit::gpu::PixelFormat::RG8_UNORM: return "PixelFormat::RG8_UNORM"; case stormkit::gpu::PixelFormat::RGB16F: return "PixelFormat::RGB16F"; case stormkit::gpu::PixelFormat::RGB16I: return "PixelFormat::RGB16I"; - case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; + case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; case stormkit::gpu::PixelFormat::RGB16_UNORM: return "PixelFormat::RGB16_UNORM"; case stormkit::gpu::PixelFormat::RGB32F: return "PixelFormat::RGB32F"; case stormkit::gpu::PixelFormat::RGB32I: return "PixelFormat::RGB32I"; case stormkit::gpu::PixelFormat::RGB32U: return "PixelFormat::RGB32U"; case stormkit::gpu::PixelFormat::RGB8I: return "PixelFormat::RGB8I"; - case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; + case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; case stormkit::gpu::PixelFormat::RGB8_UNORM: return "PixelFormat::RGB8_UNORM"; case stormkit::gpu::PixelFormat::RGBA16F: return "PixelFormat::RGBA16F"; case stormkit::gpu::PixelFormat::RGBA16I: return "PixelFormat::RGBA16I"; - case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; + case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; case stormkit::gpu::PixelFormat::RGBA16_UNORM: return "PixelFormat::RGBA16_UNORM"; case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; - case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; + case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; case stormkit::gpu::PixelFormat::RGBA8_UNORM: return "PixelFormat::RGBA8_UNORM"; + case stormkit::gpu::PixelFormat::S8U: return "PixelFormat::S8U"; case stormkit::gpu::PixelFormat::SBGR8: return "PixelFormat::SBGR8"; case stormkit::gpu::PixelFormat::SBGRA8: return "PixelFormat::SBGRA8"; case stormkit::gpu::PixelFormat::SR8: return "PixelFormat::SR8"; @@ -3160,8 +3168,8 @@ export { return std::array { stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER, stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE, - stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT, stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE, + stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT, stormkit::gpu::SamplerAddressMode::REPEAT, }; @@ -3173,8 +3181,8 @@ export { switch(value) { case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; } @@ -3186,8 +3194,8 @@ export { switch(value) { case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; } @@ -3351,6 +3359,14 @@ namespace stormkit::gpu { or format == PixelFormat::DEPTH32F; } + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto is_stencil_only_format(PixelFormat format) noexcept -> bool { + return format == PixelFormat::S8U; + } + ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE @@ -3369,6 +3385,14 @@ namespace stormkit::gpu { return is_depth_only_format(format) or is_depth_stencil_format(format); } + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto is_stencil_format(PixelFormat format) noexcept -> bool { + return is_stencil_only_format(format) or is_depth_stencil_format(format); + } + ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE diff --git a/modules/stormkit/gpu/core/vulkan/enums.cppm.tpl b/modules/stormkit/gpu/core/vulkan/enums.cppm.tpl index 17e01603e..97941c6d6 100644 --- a/modules/stormkit/gpu/core/vulkan/enums.cppm.tpl +++ b/modules/stormkit/gpu/core/vulkan/enums.cppm.tpl @@ -61,9 +61,13 @@ export { [[nodiscard]] constexpr auto is_depth_only_format(PixelFormat format) noexcept -> bool; [[nodiscard]] + constexpr auto is_stencil_only_format(PixelFormat format) noexcept -> bool; + [[nodiscard]] constexpr auto is_depth_stencil_format(PixelFormat format) noexcept -> bool; [[nodiscard]] constexpr auto is_depth_format(PixelFormat format) noexcept -> bool; + [[nodiscard]] + constexpr auto is_stencil_format(PixelFormat format) noexcept -> bool; [[nodiscard]] constexpr auto get_format_channel_count(PixelFormat format) noexcept -> u8; @@ -117,6 +121,14 @@ namespace stormkit::gpu { or format == PixelFormat::DEPTH32F; } + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto is_stencil_only_format(PixelFormat format) noexcept -> bool { + return format == PixelFormat::S8U; + } + ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE @@ -135,6 +147,14 @@ namespace stormkit::gpu { return is_depth_only_format(format) or is_depth_stencil_format(format); } + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto is_stencil_format(PixelFormat format) noexcept -> bool { + return is_stencil_only_format(format) or is_depth_stencil_format(format); + } + ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE diff --git a/modules/stormkit/gpu/core/vulkan/mapping.json b/modules/stormkit/gpu/core/vulkan/mapping.json index 5f4407b2b..33d262724 100644 --- a/modules/stormkit/gpu/core/vulkan/mapping.json +++ b/modules/stormkit/gpu/core/vulkan/mapping.json @@ -244,7 +244,8 @@ "DEPTH32F": { "vulkan": "VK_FORMAT_D32_SFLOAT", "webgpu": "" }, "DEPTH16_UNORM_STENCIL8U": { "vulkan": "VK_FORMAT_D16_UNORM_S8_UINT", "webgpu": "" }, "DEPTH24_UNORM_STENCIL8U": { "vulkan": "VK_FORMAT_D24_UNORM_S8_UINT", "webgpu": "" }, - "DEPTH32F_STENCIL8U": { "vulkan": "VK_FORMAT_D32_SFLOAT_S8_UINT", "webgpu": "" } + "DEPTH32F_STENCIL8U": { "vulkan": "VK_FORMAT_D32_SFLOAT_S8_UINT", "webgpu": "" }, + "S8U": { "vulkan": "VK_FORMAT_S8_UINT", "webgpu": "" } } }, "AttachmentLoadOperation": { From 9c45abbed484d5b8fd3ecff7200a27869e28728e Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 3 Mar 2026 19:26:18 +0100 Subject: [PATCH 119/194] (gpu) fix secondary command buffer begin --- modules/stormkit/gpu/execution/command_buffer.cppm | 2 +- src/gpu/execution/command_buffer.cpp | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/modules/stormkit/gpu/execution/command_buffer.cppm b/modules/stormkit/gpu/execution/command_buffer.cppm index 106e94a8e..787416ac4 100644 --- a/modules/stormkit/gpu/execution/command_buffer.cppm +++ b/modules/stormkit/gpu/execution/command_buffer.cppm @@ -167,7 +167,7 @@ export namespace stormkit::gpu { auto insert_debug_label(std::string_view name, const fcolor_rgb& color = colors::WHITE) noexcept -> CommandBuffer&; auto end_debug_region() noexcept -> CommandBuffer&; - auto begin_rendering(const RenderingInfo& info) noexcept -> CommandBuffer&; + auto begin_rendering(const RenderingInfo& info, bool secondary_commandbuffers = false) noexcept -> CommandBuffer&; auto begin_render_pass(const RenderPass& render_pass, const FrameBuffer& framebuffer, std::span clear_values = std::array { ClearValue { diff --git a/src/gpu/execution/command_buffer.cpp b/src/gpu/execution/command_buffer.cpp index bbbc7d2ff..2b2041a0f 100644 --- a/src/gpu/execution/command_buffer.cpp +++ b/src/gpu/execution/command_buffer.cpp @@ -114,11 +114,15 @@ namespace stormkit::gpu { return info; }(); - const auto flags = [this, one_time_submit] noexcept -> VkCommandBufferUsageFlags { + const auto flags = [this, one_time_submit, &inheritance_info_variant] noexcept -> VkCommandBufferUsageFlags { auto flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; if (!one_time_submit) flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; - if (m_level == CommandBufferLevel::SECONDARY) flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; + if (m_level == CommandBufferLevel::SECONDARY) { + if (is(inheritance_info_variant) + or is(inheritance_info_variant)) + flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; + } return flags; }(); @@ -140,7 +144,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::begin_rendering(const RenderingInfo& info) noexcept -> CommandBuffer& { + auto CommandBuffer::begin_rendering(const RenderingInfo& info, bool secondary) noexcept -> CommandBuffer& { EXPECTS(m_state == State::RECORDING); auto to_vk_attachment = [](const auto& attachment) static noexcept { @@ -198,7 +202,7 @@ namespace stormkit::gpu { const auto rendering_info = VkRenderingInfo { .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, .pNext = nullptr, - .flags = 0, + .flags = as((secondary) ? VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT : 0), .renderArea = to_vk(info.render_area), .layerCount = info.layer_count, .viewMask = info.view_mask, From 164c00bf73560335366cc7cf1f611edfb23407ca Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 4 Mar 2026 14:40:26 +0100 Subject: [PATCH 120/194] (core) try to fix locked class --- modules/stormkit/core/parallelism/locked.cppm | 27 +++++++------------ 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/modules/stormkit/core/parallelism/locked.cppm b/modules/stormkit/core/parallelism/locked.cppm index c3dd0ee3d..558f439f7 100644 --- a/modules/stormkit/core/parallelism/locked.cppm +++ b/modules/stormkit/core/parallelism/locked.cppm @@ -87,7 +87,7 @@ export namespace stormkit { inline namespace core { LockArgs&&... lock_args) noexcept(noexcept(std::is_nothrow_assignable_v)) -> void; template - auto unsafe(this Self& self) noexcept -> meta::ForwardConst; + auto unsafe(this Self& self) noexcept -> meta::ForwardConst&; auto mutex() const noexcept -> const MutexType&; @@ -97,8 +97,6 @@ export namespace stormkit { inline namespace core { public: using AccessValueType = std::conditional_t; using RefContainerType = std::conditional_t, Ref>; - using ReferenceType = ValueType&; - using PointerType = ValueType*; template Access(ReferenceType value, MutexType& mutex, LockArgs&&... args) noexcept; @@ -109,11 +107,8 @@ export namespace stormkit { inline namespace core { template explicit Access(Locked& locked, LockArgs&&... args) noexcept; - template - auto operator->(this Self&& self) noexcept -> meta::ForwardConst; - - template - auto operator*(this Self&& self) noexcept -> meta::ForwardConst; + auto operator->() const noexcept -> AccessValueType*; + auto operator*() const noexcept -> AccessValueType&; mutable Lock lock; @@ -158,7 +153,7 @@ namespace stormkit { inline namespace core { static_assert(not(Mode == LockAccessMode::Read_Only and not std::is_const_v>), "can't get read access on const Locked"); using AccessType = Access; - return AccessType { self, std::forward(lock_args)... }; + return AccessType { std::forward(self), std::forward(lock_args)... }; } //////////////////////////////////////// @@ -217,8 +212,8 @@ namespace stormkit { inline namespace core { template template STORMKIT_FORCE_INLINE - auto Locked::unsafe(this Self& self) noexcept -> meta::ForwardConst { - return self.m_value; + auto Locked::unsafe(this Self& self) noexcept -> meta::ForwardConst& { + return std::forward_like(self.m_value); } //////////////////////////////////////// @@ -263,19 +258,17 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template template class Lock, LockAccessMode Mode> - template STORMKIT_FORCE_INLINE - auto Locked::Access::operator->(this Self&& self) noexcept -> meta::ForwardConst { - return self.m_value.get(); + auto Locked::Access::operator->() const noexcept -> AccessValueType* { + return m_value.get(); } //////////////////////////////////////// //////////////////////////////////////// template template class Lock, LockAccessMode Mode> - template STORMKIT_FORCE_INLINE - auto Locked::Access::operator*(this Self&& self) noexcept -> meta::ForwardConst { - return *self.m_value; + auto Locked::Access::operator*() const noexcept -> AccessValueType& { + return *m_value; } }} // namespace stormkit::core From 7fb3f27c6f1ca4ddffe7bb7748346d8772ddc8fb Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 4 Mar 2026 14:40:37 +0100 Subject: [PATCH 121/194] (entities) format --- modules/stormkit/entities.cppm | 37 +++++++++++++++++----------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/modules/stormkit/entities.cppm b/modules/stormkit/entities.cppm index 30cc7f454..f8e1c1b87 100644 --- a/modules/stormkit/entities.cppm +++ b/modules/stormkit/entities.cppm @@ -20,7 +20,9 @@ namespace stdr = std::ranges; namespace stdv = std::views; export namespace stormkit::entities { - using Entity = u32; + using Entity = u32; + using Entities = std::vector; + inline constexpr auto INVALID_ENTITY = Entity { 0 }; class System; @@ -44,8 +46,8 @@ export namespace stormkit::entities { } // namespace meta struct Message { - u32 id; - std::vector entities; + u32 id; + Entities entities; }; class STORMKIT_ENTITIES_API MessageBus { @@ -76,7 +78,6 @@ export namespace stormkit::entities { class STORMKIT_ENTITIES_API System { public: using ComponentTypes = std::vector; - using Entities = std::vector; using PreUpdateClosure = std::function; using UpdateClosure = std::function; @@ -156,15 +157,15 @@ export namespace stormkit::entities { auto has_component(Entity entity, std::string_view name) const noexcept -> bool; auto has_component(Entity entity, ComponentType type) const noexcept -> bool; - auto entities() const noexcept -> const std::vector&; + auto entities() const noexcept -> const Entities&; - auto entities_with_component(ComponentType type) const noexcept -> std::vector; - auto entities_with_component(std::string_view name) const noexcept -> std::vector; + auto entities_with_component(ComponentType type) const noexcept -> Entities; + auto entities_with_component(std::string_view name) const noexcept -> Entities; template - auto get_component(this Self& self, Entity entity, ComponentType type) noexcept -> core::meta::ForwardConst; + auto get_component(this Self& self, Entity entity, ComponentType type) noexcept -> core::meta::ForwardConst&; template - auto get_component(this Self& self, Entity entity, std::string_view name) noexcept -> core::meta::ForwardConst; + auto get_component(this Self& self, Entity entity, std::string_view name) noexcept -> core::meta::ForwardConst&; template auto components_of_type(this Self& self, ComponentType type) noexcept @@ -197,7 +198,7 @@ export namespace stormkit::entities { struct Store { ComponentType type; usize size; - std::vector entities; + Entities entities; std::vector data; std::function delete_func; }; @@ -210,9 +211,9 @@ export namespace stormkit::entities { Entity m_next_valid_entity = 1; - std::vector m_entities; + Entities m_entities; - std::vector m_free_entities; + Entities m_free_entities; HashSet m_added_entities; HashSet m_updated_entities; @@ -301,13 +302,13 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - inline auto EntityManager::entities() const noexcept -> const std::vector& { + inline auto EntityManager::entities() const noexcept -> const Entities& { return m_entities; } ///////////////////////////////////// ///////////////////////////////////// - inline auto EntityManager::entities_with_component(ComponentType type) const noexcept -> std::vector { + inline auto EntityManager::entities_with_component(ComponentType type) const noexcept -> Entities { // clang-format off return entities() | stdv::filter([this, type](auto entity) noexcept { return has_component(entity, type); }) @@ -317,7 +318,7 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - inline auto EntityManager::entities_with_component(std::string_view name) const noexcept -> std::vector { + inline auto EntityManager::entities_with_component(std::string_view name) const noexcept -> Entities { return entities_with_component(hash(name)); } @@ -325,7 +326,7 @@ namespace stormkit::entities { ///////////////////////////////////// template auto EntityManager::get_component(this Self& self, Entity entity, ComponentType type) noexcept - -> core::meta::ForwardConst { + -> core::meta::ForwardConst& { EXPECTS(self.has_entity(entity)); EXPECTS(self.has_component(entity, type)); @@ -346,14 +347,14 @@ namespace stormkit::entities { break; } - return std::forward_like(*std::bit_cast(component_it)); + return std::forward_like(*std::bit_cast*>(component_it)); } ///////////////////////////////////// ///////////////////////////////////// template auto EntityManager::get_component(this Self& self, Entity entity, std::string_view name) noexcept - -> core::meta::ForwardConst { + -> core::meta::ForwardConst& { return self.template get_component(entity, hash(name)); } From e10c6f1acf5765be31b5dd7769d7a5862c7cb055 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 4 Mar 2026 15:17:24 +0100 Subject: [PATCH 122/194] (core) fix locked class --- modules/stormkit/core/parallelism/locked.cppm | 40 +++++++++++++------ 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/modules/stormkit/core/parallelism/locked.cppm b/modules/stormkit/core/parallelism/locked.cppm index 558f439f7..1a7051e96 100644 --- a/modules/stormkit/core/parallelism/locked.cppm +++ b/modules/stormkit/core/parallelism/locked.cppm @@ -25,8 +25,8 @@ namespace stormkit { inline namespace core { namespace details { export namespace stormkit { inline namespace core { enum class LockAccessMode : core::u8 { - Read_Only, - Read_Write, + READ_ONLY, + READ_WRITE, }; template @@ -50,14 +50,15 @@ export namespace stormkit { inline namespace core { public: template class Lock> - using ReadAccess = Access; + using ReadAccess = Access; template class Lock> - using WriteAccess = Access; + using WriteAccess = Access; Locked() noexcept(noexcept(std::is_nothrow_default_constructible_v)); template - explicit Locked(Args&&... args) noexcept(noexcept(std::is_nothrow_constructible_v)); + explicit(sizeof...(Args) == 1) + Locked(Args&&... args) noexcept(noexcept(std::is_nothrow_constructible_v)); Locked(const Locked&) = delete; auto operator=(const Locked&) -> Locked& = delete; @@ -95,17 +96,20 @@ export namespace stormkit { inline namespace core { template class Lock, LockAccessMode Mode> class Access { public: - using AccessValueType = std::conditional_t; - using RefContainerType = std::conditional_t, Ref>; + using AccessValueType = std::conditional_t; + using RefContainerType = std::conditional_t, Ref>; template Access(ReferenceType value, MutexType& mutex, LockArgs&&... args) noexcept; template - explicit Access(const Locked& locked, LockArgs&&... args) noexcept; + Access(ConstReferenceType value, MutexType& mutex, LockArgs&&... args) noexcept; template - explicit Access(Locked& locked, LockArgs&&... args) noexcept; + explicit(sizeof...(LockArgs) == 0) Access(const Locked& locked, LockArgs&&... args) noexcept; + + template + explicit(sizeof...(LockArgs) == 0) Access(Locked& locked, LockArgs&&... args) noexcept; auto operator->() const noexcept -> AccessValueType*; auto operator*() const noexcept -> AccessValueType&; @@ -150,7 +154,7 @@ namespace stormkit { inline namespace core { template class Lock, typename... LockArgs, class Self> STORMKIT_FORCE_INLINE auto Locked::access(this Self& self, LockArgs&&... lock_args) noexcept -> Access { - static_assert(not(Mode == LockAccessMode::Read_Only and not std::is_const_v>), + static_assert(not(Mode == LockAccessMode::READ_ONLY and not std::is_const_v>), "can't get read access on const Locked"); using AccessType = Access; return AccessType { std::forward(self), std::forward(lock_args)... }; @@ -162,7 +166,7 @@ namespace stormkit { inline namespace core { template class Lock, typename... LockArgs> STORMKIT_FORCE_INLINE auto Locked::read(LockArgs&&... lock_args) const noexcept -> ReadAccess { - return access(std::forward(lock_args)...); + return access(std::forward(lock_args)...); } //////////////////////////////////////// @@ -171,7 +175,7 @@ namespace stormkit { inline namespace core { template class Lock, typename... LockArgs> STORMKIT_FORCE_INLINE auto Locked::write(LockArgs&&... lock_args) noexcept -> WriteAccess { - return access(std::forward(lock_args)...); + return access(std::forward(lock_args)...); } //////////////////////////////////////// @@ -231,7 +235,17 @@ namespace stormkit { inline namespace core { template STORMKIT_FORCE_INLINE Locked::Access::Access(ReferenceType value, MutexType& mutex, LockArgs&&... lock_args) noexcept - : lock { mutex, std::forward(lock_args)... }, m_value { as_ref_like(value) } { + : lock { mutex, std::forward(lock_args)... }, m_value { as_ref_mut(value) } { + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + template class Lock, LockAccessMode Mode> + template + STORMKIT_FORCE_INLINE + Locked::Access::Access(ConstReferenceType value, MutexType& mutex, LockArgs&&... lock_args) noexcept + : lock { mutex, std::forward(lock_args)... }, m_value { as_ref(value) } { } //////////////////////////////////////// From a8b177db49091cbe660dc74bc596f602ec6c4432 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 4 Mar 2026 15:33:47 +0100 Subject: [PATCH 123/194] (core) add move operation for locked --- modules/stormkit/core/parallelism/locked.cppm | 45 ++++++++++++++++--- tests/core/parallelism/locked.cpp | 6 +++ 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/modules/stormkit/core/parallelism/locked.cppm b/modules/stormkit/core/parallelism/locked.cppm index 1a7051e96..38c26021b 100644 --- a/modules/stormkit/core/parallelism/locked.cppm +++ b/modules/stormkit/core/parallelism/locked.cppm @@ -63,8 +63,10 @@ export namespace stormkit { inline namespace core { Locked(const Locked&) = delete; auto operator=(const Locked&) -> Locked& = delete; - Locked(Locked&&) noexcept = delete; - auto operator=(Locked&&) noexcept -> Locked& = delete; + Locked(Locked&&) noexcept; + auto operator=(Locked&&) noexcept -> Locked&; + + ~Locked() noexcept; template class Lock, typename... LockArgs, class Self> auto access(this Self& self, LockArgs&&... lock_args) noexcept -> Access; @@ -106,7 +108,8 @@ export namespace stormkit { inline namespace core { Access(ConstReferenceType value, MutexType& mutex, LockArgs&&... args) noexcept; template - explicit(sizeof...(LockArgs) == 0) Access(const Locked& locked, LockArgs&&... args) noexcept; + explicit(sizeof...(LockArgs) == 0) Access(const Locked& locked, LockArgs&&... args) noexcept + requires(Mode == LockAccessMode::READ_ONLY); template explicit(sizeof...(LockArgs) == 0) Access(Locked& locked, LockArgs&&... args) noexcept; @@ -120,8 +123,8 @@ export namespace stormkit { inline namespace core { RefContainerType m_value; }; - Mutex m_mutex; - ValueType m_value; + mutable Mutex m_mutex; + ValueType m_value; }; template @@ -148,6 +151,35 @@ namespace stormkit { inline namespace core { : m_value { std::forward(args)... } { } + //////////////////////////////////////// + //////////////////////////////////////// + template + Locked::Locked(Locked&& other) noexcept { + auto from = other.write(); + + m_value = std::move(*from); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + auto Locked::operator=(Locked&& other) noexcept -> Locked& { + if (&other == this) [[unlikely]] + return *this; + + auto from = other.write(); + auto to = write(); + + *to = std::move(*from); + + return *this; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + Locked::~Locked() noexcept = default; + //////////////////////////////////////// //////////////////////////////////////// template @@ -157,7 +189,7 @@ namespace stormkit { inline namespace core { static_assert(not(Mode == LockAccessMode::READ_ONLY and not std::is_const_v>), "can't get read access on const Locked"); using AccessType = Access; - return AccessType { std::forward(self), std::forward(lock_args)... }; + return AccessType { std::forward(self), std::forward(lock_args)... }; } //////////////////////////////////////// @@ -255,6 +287,7 @@ namespace stormkit { inline namespace core { template STORMKIT_FORCE_INLINE Locked::Access::Access(const Locked& locked, LockArgs&&... lock_args) noexcept + requires(Mode == LockAccessMode::READ_ONLY) : Access { locked.m_value, locked.m_mutex, std::forward(lock_args)... } { } diff --git a/tests/core/parallelism/locked.cpp b/tests/core/parallelism/locked.cpp index 8f1926011..8240724be 100644 --- a/tests/core/parallelism/locked.cpp +++ b/tests/core/parallelism/locked.cpp @@ -34,6 +34,12 @@ namespace { EXPECTS(locked_int.unsafe() == (ITERATIONS * 2)); } }, + { "Locked.move", + [] static noexcept { + auto locked_int = Locked { 0 }; + + auto locked_int2 = std::move(locked_int); + } }, } }; } // namespace From bc751aada2b4ab80a78bf2d6199d426b8d7b78fb Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 4 Mar 2026 19:57:45 +0100 Subject: [PATCH 124/194] (gpu) fix warning --- modules/stormkit/gpu/execution/command_buffer.cppm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stormkit/gpu/execution/command_buffer.cppm b/modules/stormkit/gpu/execution/command_buffer.cppm index 787416ac4..3c67d9956 100644 --- a/modules/stormkit/gpu/execution/command_buffer.cppm +++ b/modules/stormkit/gpu/execution/command_buffer.cppm @@ -121,7 +121,7 @@ export namespace stormkit::gpu { u32 layer_count = 1u; u32 view_mask = 0u; - std::vector color_attachments; + std::vector color_attachments = {}; std::optional depth_attachment = std::nullopt; std::optional stencil_attachment = std::nullopt; }; From 297174e4dd8d74312f8016db5f1314cd1ce899b5 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 5 Mar 2026 17:03:48 +0100 Subject: [PATCH 125/194] (core) fix linear matrix print --- modules/stormkit/core/math/linear-matrix.cppm | 64 +++++++++---------- modules/stormkit/core/math/linear.cppm | 25 ++++---- tests/core/math/linear-matrix.cpp | 18 +++++- 3 files changed, 60 insertions(+), 47 deletions(-) diff --git a/modules/stormkit/core/math/linear-matrix.cppm b/modules/stormkit/core/math/linear-matrix.cppm index 69e8bd70d..a468710c1 100644 --- a/modules/stormkit/core/math/linear-matrix.cppm +++ b/modules/stormkit/core/math/linear-matrix.cppm @@ -23,9 +23,13 @@ import :hash.base; import :string.format; +import :utils.numeric_range; + export { namespace stormkit { inline namespace core { namespace math { inline namespace matrix { + // M => rows + // N => columns template struct alignas(std::array) mat { using value_type = T; @@ -296,7 +300,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto mat::operator[](this Self&& self, size_type i, size_type j) noexcept -> core::meta::ForwardLike& { - return std::forward_like(self.operator[](j + i * M)); + return std::forward_like(self.operator[](((i * EXTENTS[0]) + j))); } //////////////////////////////////////// @@ -506,7 +510,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m template STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto orthographique(T left, T right, T bottom, T top, T near, T far) noexcept -> mat4x4 { - auto out = mat4x4 {}; + auto out = mat4x4::identity(); math::orthographique(left, right, bottom, top, near, far, as_mdspan_mut(out)); @@ -518,7 +522,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m template STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto orthographique(T left, T right, T bottom, T top) noexcept -> mat4x4 { - auto out = mat4x4 {}; + auto out = mat4x4::identity(); math::orthographique(left, right, bottom, top, as_mdspan_mut(out)); @@ -605,39 +609,31 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m inline auto format_as(const T& mat, FormatContext& ctx) noexcept -> decltype(ctx.out()) { auto out = ctx.out(); - auto i = 0; - auto check_by_extent = [&i](auto, auto) mutable { - const auto insert = i++ < (T::EXTENTS[0] - 1); - if (not insert) i = 0; - - return insert; - }; + auto max_digit = 0u; + for (auto v : as_view(mat)) max_digit = std::max(max_digit, narrow(v) == 0 ? 2 : narrow(std::log10(v) + 2)); format_to(out, "[mat "); - auto l = 0u; - if constexpr (stormkit::meta::IsIntegral) { - auto max_digit = 0u; - for (auto v : as_view(mat)) max_digit = std::max(max_digit, v == 0 ? 2 : narrow(std::log10(v) + 2)); - for (auto&& slice : mat | stdv::chunk_by(check_by_extent)) { - format_to(out, - "{}|{:n:>{}}|{}", - (l > 0) ? " "sv : " "sv, - slice, - max_digit, - (l != (T::EXTENTS[0] - 1)) ? "\n"sv : "}"sv); - ++l; - } - } else { - auto max_digit = 0u; - for (auto v : as_view(mat)) max_digit = std::max(max_digit, narrow(v) == 0 ? 2 : narrow(std::log10(v) + 2)); - for (auto&& slice : mat | stdv::chunk_by(check_by_extent)) { - format_to(out, - "{}| {:n:>{}.5f}|{}", - (l > 0) ? " "sv : " "sv, - slice, - max_digit, - (l != (T::EXTENTS[0] - 1)) ? "\n"sv : "]"sv); - ++l; + + for (auto i : range(T::EXTENTS[0] * T::EXTENTS[1])) { + const auto row = i / T::EXTENTS[1]; + const auto col = i % T::EXTENTS[1]; + + if (row != 0 && col == 0) format_to(out, " "); + + if constexpr (stormkit::meta::IsIntegral) { + if (col < T::EXTENTS[1] - 1) format_to(out, "{:>{}}, ", mat[i], max_digit); + else { + if (row < T::EXTENTS[0] - 1) format_to(out, "{:>{}}\n", mat[i], max_digit); + else + format_to(out, "{:>{}}]", mat[i], max_digit); + } + } else { + if (col < T::EXTENTS[1] - 1) format_to(out, "{:>{}.5f}, ", mat[i], max_digit + 5); + else { + if (row < T::EXTENTS[0] - 1) format_to(out, "{:>{}.5f}\n", mat[i], max_digit + 5); + else + format_to(out, "{:>{}.5f}]", mat[i], max_digit + 5); + } } } diff --git a/modules/stormkit/core/math/linear.cppm b/modules/stormkit/core/math/linear.cppm index 1179e33b5..269495b1e 100644 --- a/modules/stormkit/core/math/linear.cppm +++ b/modules/stormkit/core/math/linear.cppm @@ -659,13 +659,12 @@ namespace stormkit { inline namespace core { namespace math { requires(std::is_signed_v and not core::meta::IsConst) STORMKIT_FORCE_INLINE constexpr auto orthographique(T left, T right, T bottom, T top, T near, T far, SquareMatrixSpan out) noexcept -> void { - (void)left; - (void)right; - (void)bottom; - (void)top; - (void)near; - (void)far; - (void)out; + out[0, 0] = T { 2 } / (right - left); + out[1, 1] = T { 2 } / (top - bottom); + out[2, 2] = -T { 2 } / (far - near); + out[3, 0] = -((right + left) / (right - left)); + out[3, 1] = -((top + bottom) / (top - bottom)); + out[3, 2] = -((far + near) / (far - near)); } //////////////////////////////////////// @@ -674,11 +673,13 @@ namespace stormkit { inline namespace core { namespace math { requires(std::is_signed_v and not core::meta::IsConst) STORMKIT_FORCE_INLINE constexpr auto orthographique(T left, T right, T bottom, T top, SquareMatrixSpan out) noexcept -> void { - (void)left; - (void)right; - (void)bottom; - (void)top; - (void)out; + out[0, 0] = T { 2 } / (right - left); + out[1, 1] = T { 2 } / (top - bottom); + out[2, 2] = -T { 2 }; + + out[0, 3] = -((right + left) / (right - left)); + out[1, 3] = -((top + bottom) / (top - bottom)); + out[2, 3] = -T { 1 }; } //////////////////////////////////////// diff --git a/tests/core/math/linear-matrix.cpp b/tests/core/math/linear-matrix.cpp index 3f5be2438..d833cac0d 100644 --- a/tests/core/math/linear-matrix.cpp +++ b/tests/core/math/linear-matrix.cpp @@ -173,6 +173,22 @@ namespace { EXPECTS((result[2, 2] == 3)); EXPECTS((result[3, 3] == 1)); }, - }, }, + }, { "linear.matrix.to_string", + [] static { + auto a = math::imat4x3 { + { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 } + }; + + const auto as_string = math::to_string(a); + EXPECTS((as_string == + // clang-format off +R"([mat 1, 2, 3 + 4, 5, 6 + 7, 8, 9 + 10, 11, 12])")); + // clang-format on + } }, + + }, }; } // namespace From 2ee0e4cb65f6da92c72a08a4c43ffaccc8828ae9 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 5 Mar 2026 17:52:32 +0100 Subject: [PATCH 126/194] (core) fix dag remove_vertex / remove_edge --- modules/stormkit/core/containers/dag.cppm | 67 ++++++++++++----------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/modules/stormkit/core/containers/dag.cppm b/modules/stormkit/core/containers/dag.cppm index 26fdb5097..3a2576425 100644 --- a/modules/stormkit/core/containers/dag.cppm +++ b/modules/stormkit/core/containers/dag.cppm @@ -117,9 +117,9 @@ export namespace stormkit { inline namespace core { private: dag::VertexID m_next_id = 0; - std::vector m_vertices; - std::vector m_edges; - HashMap> m_adjacent_edges; + std::vector m_vertices; + std::vector m_edges; + std::vector>> m_adjacent_edges; }; namespace dag { @@ -190,7 +190,7 @@ namespace stormkit { inline namespace core { { const auto id = m_next_id++; m_vertices.emplace_back(id, vertex); - m_adjacent_edges[id] = {}; + m_adjacent_edges.emplace_back(id, std::vector {}); return id; } @@ -202,7 +202,7 @@ namespace stormkit { inline namespace core { { const auto id = m_next_id++; m_vertices.emplace_back(id, std::move(vertex)); - m_adjacent_edges[id] = {}; + m_adjacent_edges.emplace_back(id, std::vector {}); return id; } @@ -243,7 +243,7 @@ namespace stormkit { inline namespace core { template STORMKIT_FORCE_INLINE constexpr auto DAG::has_vertex(dag::VertexID id) const noexcept -> bool { - return m_adjacent_edges.find(id) != stdr::cend(m_adjacent_edges); + return stdr::any_of(m_vertices, [&id](const auto& vertex) noexcept { return vertex.id == id; }); } //////////////////////////////////////// @@ -257,14 +257,9 @@ namespace stormkit { inline namespace core { expects(has_vertex(vertex), "Unknown DAG vertex value!"); auto it = stdr::find_if(m_vertices, [&value = vertex](const auto& vertex) noexcept { return vertex.value == value; }); - auto&& [remove_begin, remove_end] = stdr::remove_if(m_edges, [&it](auto&& edge) noexcept { - return edge.from == it->id or edge.to == it->id; - }); - const auto id = it->id; - m_adjacent_edges.erase(it->id); - m_edges.erase(remove_begin, remove_end); - m_vertices.erase(it); + + remove_vertex(id); } //////////////////////////////////////// @@ -273,16 +268,17 @@ namespace stormkit { inline namespace core { constexpr auto DAG::remove_vertex(dag::VertexID id) noexcept -> void { expects(has_vertex(id), std::format("Unknown DAG vertex id: {}!", id)); - auto it = stdr::find_if(m_vertices, [id](const auto& vertex) noexcept { return vertex.id == id; }); - auto touching = std::vector {}; for (auto&& edge : m_edges) if (edge.from == id or edge.to == id) touching.emplace_back(edge); for (auto&& [from, to] : touching) remove_edge(from, to); - m_adjacent_edges.erase(id); - m_vertices.erase(it); + auto&& [begin, end] = stdr::remove_if(m_vertices, [id](const auto& vertex) noexcept { return vertex.id == id; }); + auto&& [begin2, end2] = stdr::remove_if(m_adjacent_edges, [id](const auto& pair) noexcept { return pair.first == id; }); + + m_adjacent_edges.erase(begin2, end2); + m_vertices.erase(begin, end); } //////////////////////////////////////// @@ -295,7 +291,10 @@ namespace stormkit { inline namespace core { const auto& edge = m_edges.emplace_back(from, to); - m_adjacent_edges[from].emplace_back(edge); + auto& adjacent_edges = stdr::find_if(m_adjacent_edges, [id = from](const auto& pair) noexcept { + return pair.first == id; + })->second; + adjacent_edges.emplace_back(edge); } //////////////////////////////////////// @@ -304,8 +303,7 @@ namespace stormkit { inline namespace core { constexpr auto DAG::has_edge(dag::VertexID from, dag::VertexID to) const noexcept -> bool { if (not has_vertex(from) or not has_vertex(to)) return false; - return stdr::any_of(m_edges, [from, to](auto&& edge) noexcept { return edge.from == from and edge.to == to; }) - and stdr::any_of(m_edges, [from, to](auto&& edge) noexcept { return edge.from == to and edge.to == from; }); + return stdr::any_of(m_edges, [from, to](auto&& edge) noexcept { return edge.from == from and edge.to == to; }); } //////////////////////////////////////// @@ -314,21 +312,21 @@ namespace stormkit { inline namespace core { constexpr auto DAG::remove_edge(dag::VertexID from, dag::VertexID to) noexcept -> void { expects(has_vertex(from), std::format("Unknown DAG vertex from: {}", from)); expects(has_vertex(to), std::format("Unknown DAG vertex to: {}", to)); + if (not has_edge(from, to)) return; { - const auto it = stdr::find_if(m_edges, [from, to](auto&& edge) noexcept { + auto&& [begin, end] = stdr::remove_if(m_edges, [from, to](auto&& edge) noexcept { return edge.from == from and edge.to == to; }); - m_edges.erase(it); + + m_edges.erase(begin, end); } for (auto&& [_, edges] : m_adjacent_edges) { - { - const auto it = stdr::find_if(edges, [from, to](auto&& edge) noexcept { - return edge.from == from and edge.to == to; - }); - if (it != stdr::cend(edges)) edges.erase(it); - } + auto&& [begin, end] = stdr::remove_if(edges, [from, to](auto&& edge) noexcept { + return edge.from == from and edge.to == to; + }); + edges.erase(begin, end); } } @@ -338,7 +336,9 @@ namespace stormkit { inline namespace core { constexpr auto DAG::adjacent_edges(dag::VertexID id) const noexcept -> const std::vector& { expects(has_vertex(id), std::format("Unknown DAG vertex id: {}!", id)); - return m_adjacent_edges.at(id); + const auto& adjacent_edges = stdr::find_if(m_adjacent_edges, [id](const auto& pair) noexcept { return pair.first == id; }) + ->second; + return adjacent_edges; } //////////////////////////////////////// @@ -542,12 +542,12 @@ namespace stormkit { inline namespace core { if constexpr (AS_REF) { for (const auto& [id, vertice] : vertices) { out.m_vertices.emplace_back(id, as_ref(vertice)); - out.m_adjacent_edges[id] = {}; + out.m_adjacent_edges.emplace_back(id, std::vector {}); } } else { for (const auto& [id, vertice] : vertices) { out.m_vertices.emplace_back(id, auto(vertice)); - out.m_adjacent_edges[id] = {}; + out.m_adjacent_edges.emplace_back(id, std::vector {}); } } @@ -555,7 +555,10 @@ namespace stormkit { inline namespace core { for (auto&& [from, to] : edges) { const auto& edge = out.m_edges.emplace_back(to, from); - out.m_adjacent_edges[to].emplace_back(edge); + auto& adjacent_edges = stdr::find_if(out.m_adjacent_edges, [id = to](const auto& pair) noexcept { + return pair.first == id; + })->second; + adjacent_edges.emplace_back(edge); } return out; From 3f11e6ba17baf32d4b57b98abf6629e1b54220b4 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 5 Mar 2026 17:55:15 +0100 Subject: [PATCH 127/194] (core) fix matrix tests --- tests/core/math/linear-matrix.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/core/math/linear-matrix.cpp b/tests/core/math/linear-matrix.cpp index d833cac0d..c003a5b0d 100644 --- a/tests/core/math/linear-matrix.cpp +++ b/tests/core/math/linear-matrix.cpp @@ -21,15 +21,13 @@ namespace { auto a = math::imat4 { 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 3, 4, 0, 0, 0 }; EXPECTS(a[0] == 0); EXPECTS(a[1] == 1); - EXPECTS(a[0] == 0); - - EXPECTS((a[0, 2] == 2)); + EXPECTS((a[1, 2] == 2)); const auto span = math::as_view(a); auto span2 = math::as_view_mut(a); - EXPECTS(span[0] == 2); - EXPECTS(span[1] == 3); + EXPECTS(span[0] == 0); + EXPECTS(span[1] == 1); span2[0] = 1; @@ -42,7 +40,7 @@ namespace { EXPECTS(a[1] == 1); EXPECTS(a[0] == 0); - EXPECTS((a[0, 2] == 2)); + EXPECTS((a[1, 2] == 2)); a[0] = 5; } }, From 42b0466e9dbe36f893dc7456c7dd3ecfbdc7720d Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 5 Mar 2026 21:17:01 +0100 Subject: [PATCH 128/194] (core) fix orthographique projection --- modules/stormkit/core/math/linear-matrix.cppm | 26 ++++++++++++------- modules/stormkit/core/math/linear.cppm | 21 ++++++++------- tests/core/math/linear-matrix.cpp | 1 - 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/modules/stormkit/core/math/linear-matrix.cppm b/modules/stormkit/core/math/linear-matrix.cppm index a468710c1..6cd3dc90f 100644 --- a/modules/stormkit/core/math/linear-matrix.cppm +++ b/modules/stormkit/core/math/linear-matrix.cppm @@ -204,11 +204,11 @@ export { template [[nodiscard]] - constexpr auto orthographique(T left, T right, T bottom, T top, T near, T far) noexcept -> mat4x4; + constexpr auto orthographique(T left, T right, T top, T bottom, T near, T far) noexcept -> mat4x4; template [[nodiscard]] - constexpr auto orthographique(T left, T right, T bottom, T top) noexcept -> mat4x4; + constexpr auto orthographique(T left, T right, T top, T bottom) noexcept -> mat4x4; template [[nodiscard]] @@ -509,10 +509,10 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto orthographique(T left, T right, T bottom, T top, T near, T far) noexcept -> mat4x4 { + constexpr auto orthographique(T left, T right, T top, T bottom, T near, T far) noexcept -> mat4x4 { auto out = mat4x4::identity(); - math::orthographique(left, right, bottom, top, near, far, as_mdspan_mut(out)); + math::orthographique(left, right, top, bottom, near, far, as_mdspan_mut(out)); return out; } @@ -521,10 +521,10 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto orthographique(T left, T right, T bottom, T top) noexcept -> mat4x4 { + constexpr auto orthographique(T left, T right, T top, T bottom) noexcept -> mat4x4 { auto out = mat4x4::identity(); - math::orthographique(left, right, bottom, top, as_mdspan_mut(out)); + math::orthographique(left, right, top, bottom, as_mdspan_mut(out)); return out; } @@ -610,7 +610,13 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m auto out = ctx.out(); auto max_digit = 0u; - for (auto v : as_view(mat)) max_digit = std::max(max_digit, narrow(v) == 0 ? 2 : narrow(std::log10(v) + 2)); + if constexpr (stormkit::meta::IsSigned) + for (auto v : as_view(mat)) { + max_digit = std::max(max_digit, narrow(v) == 0 ? 2 : narrow(std::log10(v) + 2)); + if (v < 0) max_digit = max_digit + 1; + } + else + for (auto v : as_view(mat)) max_digit = std::max(max_digit, narrow(v) == 0 ? 2 : narrow(std::log10(v) + 2)); format_to(out, "[mat "); @@ -628,11 +634,11 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m format_to(out, "{:>{}}]", mat[i], max_digit); } } else { - if (col < T::EXTENTS[1] - 1) format_to(out, "{:>{}.5f}, ", mat[i], max_digit + 5); + if (col < T::EXTENTS[1] - 1) format_to(out, "{:>{}.5f}, ", mat[i], max_digit); else { - if (row < T::EXTENTS[0] - 1) format_to(out, "{:>{}.5f}\n", mat[i], max_digit + 5); + if (row < T::EXTENTS[0] - 1) format_to(out, "{:>{}.5f}\n", mat[i], max_digit); else - format_to(out, "{:>{}.5f}]", mat[i], max_digit + 5); + format_to(out, "{:>{}.5f}]", mat[i], max_digit); } } } diff --git a/modules/stormkit/core/math/linear.cppm b/modules/stormkit/core/math/linear.cppm index 269495b1e..a00d30cd6 100644 --- a/modules/stormkit/core/math/linear.cppm +++ b/modules/stormkit/core/math/linear.cppm @@ -173,11 +173,11 @@ export namespace stormkit { inline namespace core { namespace math { /* graphics */ template requires(std::is_signed_v and not core::meta::IsConst) - constexpr auto orthographique(T left, T right, T bottom, T top, T near, T far, SquareMatrixSpan out) noexcept -> void; + constexpr auto orthographique(T left, T right, T top, T bottom, T near, T far, SquareMatrixSpan out) noexcept -> void; template requires(std::is_signed_v and not core::meta::IsConst) - constexpr auto orthographique(T left, T right, T bottom, T top, SquareMatrixSpan out) noexcept -> void; + constexpr auto orthographique(T left, T right, T top, T bottom, SquareMatrixSpan out) noexcept -> void; template requires(std::is_signed_v and not core::meta::IsConst) @@ -658,13 +658,14 @@ namespace stormkit { inline namespace core { namespace math { template requires(std::is_signed_v and not core::meta::IsConst) STORMKIT_FORCE_INLINE - constexpr auto orthographique(T left, T right, T bottom, T top, T near, T far, SquareMatrixSpan out) noexcept -> void { + constexpr auto orthographique(T left, T right, T top, T bottom, T near, T far, SquareMatrixSpan out) noexcept -> void { out[0, 0] = T { 2 } / (right - left); out[1, 1] = T { 2 } / (top - bottom); out[2, 2] = -T { 2 } / (far - near); - out[3, 0] = -((right + left) / (right - left)); - out[3, 1] = -((top + bottom) / (top - bottom)); - out[3, 2] = -((far + near) / (far - near)); + + out[0, 3] = -((right + left) / (right - left)); + out[1, 3] = -((top + bottom) / (top - bottom)); + out[2, 3] = -((far + near) / (far - near)); } //////////////////////////////////////// @@ -672,14 +673,14 @@ namespace stormkit { inline namespace core { namespace math { template requires(std::is_signed_v and not core::meta::IsConst) STORMKIT_FORCE_INLINE - constexpr auto orthographique(T left, T right, T bottom, T top, SquareMatrixSpan out) noexcept -> void { + constexpr auto orthographique(T left, T right, T top, T bottom, SquareMatrixSpan out) noexcept -> void { out[0, 0] = T { 2 } / (right - left); out[1, 1] = T { 2 } / (top - bottom); out[2, 2] = -T { 2 }; - out[0, 3] = -((right + left) / (right - left)); - out[1, 3] = -((top + bottom) / (top - bottom)); - out[2, 3] = -T { 1 }; + out[3, 0] = -((right + left) / (right - left)); + out[3, 1] = -((top + bottom) / (top - bottom)); + out[3, 2] = -T { 1 }; } //////////////////////////////////////// diff --git a/tests/core/math/linear-matrix.cpp b/tests/core/math/linear-matrix.cpp index c003a5b0d..b325e2679 100644 --- a/tests/core/math/linear-matrix.cpp +++ b/tests/core/math/linear-matrix.cpp @@ -186,7 +186,6 @@ R"([mat 1, 2, 3 10, 11, 12])")); // clang-format on } }, - }, }; } // namespace From 117c2733118bf74aae588a977bee222d41405561 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 5 Mar 2026 21:17:44 +0100 Subject: [PATCH 129/194] (gpu) change entry point name of shaders --- .../gpu/textured_cube/shaders/textured_cube.nzsl | 4 ++-- examples/gpu/triangle/shaders/triangle.nzsl | 4 ++-- src/gpu/execution/pipeline.cpp | 13 +++++++++++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/examples/gpu/textured_cube/shaders/textured_cube.nzsl b/examples/gpu/textured_cube/shaders/textured_cube.nzsl index 8580764db..0c3dd2ac1 100644 --- a/examples/gpu/textured_cube/shaders/textured_cube.nzsl +++ b/examples/gpu/textured_cube/shaders/textured_cube.nzsl @@ -29,7 +29,7 @@ external { } [entry(vert)] -fn main(input: VertIn) -> VertOut { +fn vert_main(input: VertIn) -> VertOut { let output: VertOut; output.position = viewer.proj * viewer.view * viewer.model * vec4[f32](input.position, 1.); @@ -49,7 +49,7 @@ external { } [entry(frag)] -fn main(input: VertOut) -> FragOut { +fn frag_main(input: VertOut) -> FragOut { let output: FragOut; output.color = texture.Sample(input.uv); diff --git a/examples/gpu/triangle/shaders/triangle.nzsl b/examples/gpu/triangle/shaders/triangle.nzsl index 5f88feefe..e6b6d6b57 100644 --- a/examples/gpu/triangle/shaders/triangle.nzsl +++ b/examples/gpu/triangle/shaders/triangle.nzsl @@ -15,7 +15,7 @@ struct VertOut { } [entry(vert)] -fn main(input: VertIn) -> VertOut { +fn vert_main(input: VertIn) -> VertOut { let output: VertOut; let position: vec2[f32]; @@ -44,7 +44,7 @@ struct FragOut { } [entry(frag)] -fn main(input: VertOut) -> FragOut { +fn frag_main(input: VertOut) -> FragOut { let output: FragOut; output.color = vec4[f32](input.color, 1.); diff --git a/src/gpu/execution/pipeline.cpp b/src/gpu/execution/pipeline.cpp index 723680df8..ceb22aa07 100644 --- a/src/gpu/execution/pipeline.cpp +++ b/src/gpu/execution/pipeline.cpp @@ -17,6 +17,8 @@ import stormkit.gpu.core; namespace stdr = std::ranges; namespace stdv = std::views; +using namespace std::literals; + namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// @@ -154,14 +156,21 @@ namespace stormkit::gpu { const auto shaders = state.shader_state | stdv::transform(core::monadic::unref()) | stdv::transform([](auto&& shader) static noexcept { - static constexpr auto NAME = "main"; + const auto name = [](const auto& shader) static noexcept { + if (shader.type() == ShaderStageFlag::VERTEX) return "vert_main"sv; + else if (shader.type() == ShaderStageFlag::FRAGMENT) + return "frag_main"sv; + else + return "main"sv; + }(shader); + return VkPipelineShaderStageCreateInfo { .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, .pNext = nullptr, .flags = 0, .stage = to_vk(shader.type()), .module = to_vk(shader), - .pName = NAME, + .pName = stdr::data(name), .pSpecializationInfo = nullptr, }; }) From a6e88aca2c7eaa0036ff6a0cdbdceb11920bfff4 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 6 Mar 2026 16:43:53 +0100 Subject: [PATCH 130/194] (core) fix warning --- modules/stormkit/core/math/linear-matrix.cppm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stormkit/core/math/linear-matrix.cppm b/modules/stormkit/core/math/linear-matrix.cppm index 6cd3dc90f..cd53c99cd 100644 --- a/modules/stormkit/core/math/linear-matrix.cppm +++ b/modules/stormkit/core/math/linear-matrix.cppm @@ -620,7 +620,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m format_to(out, "[mat "); - for (auto i : range(T::EXTENTS[0] * T::EXTENTS[1])) { + for (auto i : range(T::EXTENTS[0] * T::EXTENTS[1])) { const auto row = i / T::EXTENTS[1]; const auto col = i % T::EXTENTS[1]; From b7de04fb2a0a8ce4f8c27619c6f803a91de63d95 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 6 Mar 2026 16:44:02 +0100 Subject: [PATCH 131/194] (core) fix orthographique projection --- modules/stormkit/core/math/linear.cppm | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/modules/stormkit/core/math/linear.cppm b/modules/stormkit/core/math/linear.cppm index a00d30cd6..98cbf96a7 100644 --- a/modules/stormkit/core/math/linear.cppm +++ b/modules/stormkit/core/math/linear.cppm @@ -661,11 +661,11 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto orthographique(T left, T right, T top, T bottom, T near, T far, SquareMatrixSpan out) noexcept -> void { out[0, 0] = T { 2 } / (right - left); out[1, 1] = T { 2 } / (top - bottom); - out[2, 2] = -T { 2 } / (far - near); + out[2, 2] = T { 1 } / (far - near); - out[0, 3] = -((right + left) / (right - left)); - out[1, 3] = -((top + bottom) / (top - bottom)); - out[2, 3] = -((far + near) / (far - near)); + out[0, 3] = -(right + left) / (right - left); + out[1, 3] = -(top + bottom) / (top - bottom); + out[2, 3] = -near / (far - near); } //////////////////////////////////////// @@ -674,13 +674,10 @@ namespace stormkit { inline namespace core { namespace math { requires(std::is_signed_v and not core::meta::IsConst) STORMKIT_FORCE_INLINE constexpr auto orthographique(T left, T right, T top, T bottom, SquareMatrixSpan out) noexcept -> void { - out[0, 0] = T { 2 } / (right - left); - out[1, 1] = T { 2 } / (top - bottom); - out[2, 2] = -T { 2 }; + constexpr auto far = T { 100 }; + constexpr auto near = T { 0.1 }; - out[3, 0] = -((right + left) / (right - left)); - out[3, 1] = -((top + bottom) / (top - bottom)); - out[3, 2] = -T { 1 }; + return orthographique(left, right, top, bottom, near, far); } //////////////////////////////////////// From ea569c1c2205eb84b04cfdd1f59f295488b44c38 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 8 Mar 2026 17:51:20 +0100 Subject: [PATCH 132/194] (gpu, examples) fix RESOURCE_DIR for textured_cube example --- examples/gpu/textured_cube/xmake.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/gpu/textured_cube/xmake.lua b/examples/gpu/textured_cube/xmake.lua index d1a6b5154..748a76f2e 100644 --- a/examples/gpu/textured_cube/xmake.lua +++ b/examples/gpu/textured_cube/xmake.lua @@ -15,7 +15,7 @@ target("textured_cube", function() add_files("src/*.cpp", "src/*.cppm", "../common/app.cppm", "shaders/*.nzsl") if get_config("devmode") then - add_defines(format('RESOURCE_DIR="%s"', path.unix(path.join(os.projectdir(), "gpu/textured_cube")))) + add_defines(format('RESOURCE_DIR="%s"', path.unix(path.join(os.projectdir(), "examples/gpu/textured_cube")))) add_defines(format('SHADER_DIR="%s"', path.unix("$(builddir)/shaders"))) end add_embeddirs("$(builddir)/shaders") From 3ddac38f5498eace4b9f1db95ab727c2b69df655 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 8 Mar 2026 17:51:36 +0100 Subject: [PATCH 133/194] (gpu) fix descriptor sets support of dynamic buffers --- .../stormkit/gpu/execution/descriptors.cppm | 33 ++++++++----------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/modules/stormkit/gpu/execution/descriptors.cppm b/modules/stormkit/gpu/execution/descriptors.cppm index c71a4c3f5..4113b2a6d 100644 --- a/modules/stormkit/gpu/execution/descriptors.cppm +++ b/modules/stormkit/gpu/execution/descriptors.cppm @@ -23,11 +23,11 @@ namespace stdv = std::views; export namespace stormkit::gpu { struct BufferDescriptor { - DescriptorType type = DescriptorType::UNIFORM_BUFFER; - u32 binding; - Ref buffer; - u32 range; - u32 offset = 0; + DescriptorType type = DescriptorType::UNIFORM_BUFFER; + u32 binding; + Ref buffer; + std::optional range = std::nullopt; + u32 offset = 0; }; struct ImageDescriptor { @@ -247,17 +247,14 @@ namespace stormkit::gpu { images.reserve(std::size(descriptors)); writes.reserve(std::size(descriptors)); - auto dst = 0u; std::ranges::for_each(descriptors, core::monadic::either( - [vk_handle = m_vk_handle, - &buffers, - &writes, - &dst](const BufferDescriptor& descriptor) mutable noexcept -> decltype(auto) { + [vk_handle = m_vk_handle, &buffers, &writes](const BufferDescriptor& descriptor) noexcept + -> decltype(auto) { buffers.push_back(VkDescriptorBufferInfo { .buffer = to_vk(descriptor.buffer), .offset = descriptor.offset, - .range = descriptor.range, + .range = descriptor.range.value_or(VK_WHOLE_SIZE), }); const auto& buffer_descriptor = buffers.back(); @@ -265,19 +262,17 @@ namespace stormkit::gpu { .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, .pNext = nullptr, .dstSet = vk_handle, - .dstBinding = dst++, + .dstBinding = descriptor.binding, .dstArrayElement = 0, .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + .descriptorType = to_vk(descriptor.type), .pImageInfo = nullptr, .pBufferInfo = &buffer_descriptor, .pTexelBufferView = nullptr, }); }, - [vk_handle = m_vk_handle, - &images, - &writes, - &dst](const ImageDescriptor& descriptor) mutable noexcept -> decltype(auto) { + [vk_handle = m_vk_handle, &images, &writes](const ImageDescriptor& descriptor) noexcept + -> decltype(auto) { images.push_back(VkDescriptorImageInfo { .sampler = to_vk(descriptor.sampler), .imageView = to_vk(descriptor.image_view), @@ -289,10 +284,10 @@ namespace stormkit::gpu { .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, .pNext = nullptr, .dstSet = vk_handle, - .dstBinding = dst++, + .dstBinding = descriptor.binding, .dstArrayElement = 0, .descriptorCount = 1, - .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + .descriptorType = to_vk(descriptor.type), .pImageInfo = &image_descriptor, .pBufferInfo = nullptr, .pTexelBufferView = nullptr, From 05f491ce79e3f268b9ef96feb9e1f28baad0aa6d Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 8 Mar 2026 17:51:46 +0100 Subject: [PATCH 134/194] (core) fix orthographique projection --- modules/stormkit/core/math/linear-matrix.cppm | 10 +++++----- modules/stormkit/core/math/linear.cppm | 20 +++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/modules/stormkit/core/math/linear-matrix.cppm b/modules/stormkit/core/math/linear-matrix.cppm index cd53c99cd..f874c157d 100644 --- a/modules/stormkit/core/math/linear-matrix.cppm +++ b/modules/stormkit/core/math/linear-matrix.cppm @@ -204,11 +204,11 @@ export { template [[nodiscard]] - constexpr auto orthographique(T left, T right, T top, T bottom, T near, T far) noexcept -> mat4x4; + constexpr auto orthographique(T left, T right, T bottom, T top, T near, T far) noexcept -> mat4x4; template [[nodiscard]] - constexpr auto orthographique(T left, T right, T top, T bottom) noexcept -> mat4x4; + constexpr auto orthographique(T left, T right, T bottom, T top) noexcept -> mat4x4; template [[nodiscard]] @@ -509,7 +509,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto orthographique(T left, T right, T top, T bottom, T near, T far) noexcept -> mat4x4 { + constexpr auto orthographique(T left, T right, T bottom, T top, T near, T far) noexcept -> mat4x4 { auto out = mat4x4::identity(); math::orthographique(left, right, top, bottom, near, far, as_mdspan_mut(out)); @@ -521,10 +521,10 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto orthographique(T left, T right, T top, T bottom) noexcept -> mat4x4 { + constexpr auto orthographique(T left, T right, T bottom, T top) noexcept -> mat4x4 { auto out = mat4x4::identity(); - math::orthographique(left, right, top, bottom, as_mdspan_mut(out)); + math::orthographique(left, right, bottom, top, as_mdspan_mut(out)); return out; } diff --git a/modules/stormkit/core/math/linear.cppm b/modules/stormkit/core/math/linear.cppm index 98cbf96a7..b2c61bec4 100644 --- a/modules/stormkit/core/math/linear.cppm +++ b/modules/stormkit/core/math/linear.cppm @@ -173,11 +173,11 @@ export namespace stormkit { inline namespace core { namespace math { /* graphics */ template requires(std::is_signed_v and not core::meta::IsConst) - constexpr auto orthographique(T left, T right, T top, T bottom, T near, T far, SquareMatrixSpan out) noexcept -> void; + constexpr auto orthographique(T left, T right, T bottom, T top, T near, T far, SquareMatrixSpan out) noexcept -> void; template requires(std::is_signed_v and not core::meta::IsConst) - constexpr auto orthographique(T left, T right, T top, T bottom, SquareMatrixSpan out) noexcept -> void; + constexpr auto orthographique(T left, T right, T bottom, T top, SquareMatrixSpan out) noexcept -> void; template requires(std::is_signed_v and not core::meta::IsConst) @@ -658,10 +658,10 @@ namespace stormkit { inline namespace core { namespace math { template requires(std::is_signed_v and not core::meta::IsConst) STORMKIT_FORCE_INLINE - constexpr auto orthographique(T left, T right, T top, T bottom, T near, T far, SquareMatrixSpan out) noexcept -> void { - out[0, 0] = T { 2 } / (right - left); - out[1, 1] = T { 2 } / (top - bottom); - out[2, 2] = T { 1 } / (far - near); + constexpr auto orthographique(T left, T right, T bottom, T top, T near, T far, SquareMatrixSpan out) noexcept -> void { + out[0, 0] = core::as(2) / (right - left); + out[1, 1] = core::as(2) / (top - bottom); + out[2, 2] = core::as(1) / (far - near); out[0, 3] = -(right + left) / (right - left); out[1, 3] = -(top + bottom) / (top - bottom); @@ -673,11 +673,11 @@ namespace stormkit { inline namespace core { namespace math { template requires(std::is_signed_v and not core::meta::IsConst) STORMKIT_FORCE_INLINE - constexpr auto orthographique(T left, T right, T top, T bottom, SquareMatrixSpan out) noexcept -> void { - constexpr auto far = T { 100 }; - constexpr auto near = T { 0.1 }; + constexpr auto orthographique(T left, T right, T bottom, T top, SquareMatrixSpan out) noexcept -> void { + constexpr auto far = core::as(100); + constexpr auto near = core::narrow(0.1); - return orthographique(left, right, top, bottom, near, far); + return orthographique(left, right, bottom, top, near, far, out); } //////////////////////////////////////// From 7c3d1aad9d1d2ef99510699dc521e19c04d9decb Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 8 Mar 2026 21:00:51 +0100 Subject: [PATCH 135/194] (log) add macro to define log functions with a custom module --- include/stormkit/log/log_macro.hpp | 32 ++++++++---------------------- 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/include/stormkit/log/log_macro.hpp b/include/stormkit/log/log_macro.hpp index 0c2ebb460..52b68cec9 100644 --- a/include/stormkit/log/log_macro.hpp +++ b/include/stormkit/log/log_macro.hpp @@ -13,8 +13,7 @@ constexpr auto NAME = stormkit::log::Module { module_chars }; \ } -#define LOGGER(module) \ - NAMED_LOGGER(LOG_MODULE, module) \ +#define LOGGER_FUNC(LOG_MODULE) \ template \ STORMKIT_FORCE_INLINE inline auto dlog(Args&&... args) noexcept -> void { \ LOG_MODULE.dlog(std::forward(args)...); \ @@ -36,31 +35,16 @@ LOG_MODULE.flog(std::forward(args)...); \ } +#define LOGGER(module) \ + NAMED_LOGGER(LOG_MODULE, module) \ + LOGGER_FUNC(LOG_MODULE) + #define IN_MODULE_NAMED_LOGGER(NAME, module_chars) \ [[maybe_unused]] \ inline constexpr auto NAME = stormkit::log::Module { module_chars }; -#define IN_MODULE_LOGGER(module) \ - IN_MODULE_NAMED_LOGGER(LOG_MODULE, module) \ - template \ - STORMKIT_FORCE_INLINE inline auto dlog(Args&&... args) noexcept -> void { \ - LOG_MODULE.dlog(std::forward(args)...); \ - } \ - template \ - STORMKIT_FORCE_INLINE inline auto ilog(Args&&... args) noexcept -> void { \ - LOG_MODULE.ilog(std::forward(args)...); \ - } \ - template \ - STORMKIT_FORCE_INLINE inline auto wlog(Args&&... args) noexcept -> void { \ - LOG_MODULE.wlog(std::forward(args)...); \ - } \ - template \ - STORMKIT_FORCE_INLINE inline auto elog(Args&&... args) noexcept -> void { \ - LOG_MODULE.elog(std::forward(args)...); \ - } \ - template \ - STORMKIT_FORCE_INLINE inline auto flog(Args&&... args) noexcept -> void { \ - LOG_MODULE.flog(std::forward(args)...); \ - } +#define IN_MODULE_LOGGER(module) \ + IN_MODULE_NAMED_LOGGER(LOG_MODULE, module) \ + LOGGER_FUNC(LOG_MODULE) #endif From cee1ea6df129b64c36699acce3923a0c10e93dc0 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 8 Mar 2026 21:01:03 +0100 Subject: [PATCH 136/194] (core) add wait_idle() on ThreadPool --- .../stormkit/core/parallelism/threadpool.cppm | 12 ++++-- src/core/threadpool.cpp | 43 +++++++++++++++++-- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/modules/stormkit/core/parallelism/threadpool.cppm b/modules/stormkit/core/parallelism/threadpool.cppm index 5230ef604..0b5f8bdea 100644 --- a/modules/stormkit/core/parallelism/threadpool.cppm +++ b/modules/stormkit/core/parallelism/threadpool.cppm @@ -49,6 +49,8 @@ export namespace stormkit { inline namespace core { auto join_all() noexcept -> void; + auto wait_idle(bool cancel_tasks = false) noexcept -> void; + auto set_name(std::string_view name) noexcept -> void; private: @@ -81,9 +83,10 @@ export namespace stormkit { inline namespace core { std::vector m_workers; - mutable std::mutex m_mutex; - std::condition_variable m_work_signal; - std::queue m_tasks; + mutable std::mutex m_mutex; + std::condition_variable m_work_signal; + std::counting_semaphore<64> m_running_task_counter; + std::queue m_tasks; }; template&> F> @@ -105,7 +108,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// STORMKIT_FORCE_INLINE inline ThreadPool::ThreadPool(u32 worker_count) - : m_worker_count { worker_count } { + : m_worker_count { worker_count }, m_running_task_counter { worker_count } { m_workers.reserve(m_worker_count); for (auto i : range(m_worker_count)) { @@ -118,6 +121,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// STORMKIT_FORCE_INLINE inline ThreadPool::~ThreadPool() { + wait_idle(); join_all(); } diff --git a/src/core/threadpool.cpp b/src/core/threadpool.cpp index 2e7bbc525..4e5fb7ea8 100644 --- a/src/core/threadpool.cpp +++ b/src/core/threadpool.cpp @@ -11,11 +11,14 @@ namespace stdr = std::ranges; namespace stormkit { ///////////////////////////////////// ///////////////////////////////////// - ThreadPool::ThreadPool(ThreadPool&& other) noexcept { + ThreadPool::ThreadPool(ThreadPool&& other) noexcept + : m_worker_count { other.m_worker_count }, m_running_task_counter { m_worker_count } { + wait_idle(); + other.wait_idle(); + auto lock = std::scoped_lock { other.m_mutex }; - m_worker_count = other.m_worker_count; - m_tasks = std::move(other.m_tasks); + m_tasks = std::move(other.m_tasks); m_workers.reserve(m_worker_count); for (const auto i : range(m_worker_count)) { @@ -30,6 +33,9 @@ namespace stormkit { if (&other == this) [[unlikely]] return *this; + wait_idle(); + other.wait_idle(); + auto lock1 = std::unique_lock { m_mutex, std::defer_lock }; auto lock2 = std::unique_lock { other.m_mutex, std::defer_lock }; std::lock(lock1, lock2); @@ -53,9 +59,36 @@ namespace stormkit { auto ThreadPool::join_all() noexcept -> void { for (const auto _ : range(m_worker_count)) post_task(Task::Type::Terminate, [] {}, ThreadPool::NO_FUTURE); - for (auto& thread : m_workers) { + for (auto& thread : m_workers) if (thread.joinable()) thread.join(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto ThreadPool::wait_idle(bool cancel_tasks) noexcept -> void { + if (cancel_tasks) { + auto _ = std::unique_lock { m_mutex }; + while (not stdr::empty(m_tasks)) m_tasks.pop(); } + + for (;;) { + { + auto _ = std::unique_lock { m_mutex }; + if (stdr::empty(m_tasks)) break; + } + std::this_thread::yield(); + } + + auto count = worker_count(); + for (;;) { + while (m_running_task_counter.try_acquire()) --count; + + if (count == 0) break; + + std::this_thread::yield(); + } + + for (auto _ : range(worker_count())) m_running_task_counter.release(); } ///////////////////////////////////// @@ -72,7 +105,9 @@ namespace stormkit { m_tasks.pop(); } + m_running_task_counter.acquire(); task.work(); + m_running_task_counter.release(); if (task.type == Task::Type::Terminate) return; } From dec4695c5d98d6d36c39c86c887041b40184f4f9 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 8 Mar 2026 21:01:17 +0100 Subject: [PATCH 137/194] (core) fix bytes_mut_as --- modules/stormkit/core/typesafe/byte.cppm | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/modules/stormkit/core/typesafe/byte.cppm b/modules/stormkit/core/typesafe/byte.cppm index 978da4f23..0ecf4ca90 100644 --- a/modules/stormkit/core/typesafe/byte.cppm +++ b/modules/stormkit/core/typesafe/byte.cppm @@ -96,11 +96,11 @@ export namespace stormkit { inline namespace core { template [[nodiscard]] - constexpr auto bytes_mut_as(std::span bytes) noexcept -> T&; + constexpr auto bytes_mut_as(std::span bytes) noexcept -> T&; template [[nodiscard]] - constexpr auto bytes_mut_as_span(std::span bytes) noexcept + constexpr auto bytes_mut_as_span(std::span bytes) noexcept -> std::span; template @@ -261,7 +261,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto bytes_mut_as(std::span bytes) noexcept -> T& { + constexpr auto bytes_mut_as(std::span bytes) noexcept -> T& { if constexpr (EXTENT != std::dynamic_extent) EXPECTS(EXTENT == sizeof(T)); EXPECTS(stdr::size(bytes) == sizeof(T)); return *std::bit_cast(stdr::data(bytes)); @@ -271,13 +271,12 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto bytes_mut_as_span(std::span bytes) noexcept + constexpr auto bytes_mut_as_span(std::span bytes) noexcept -> std::span { if constexpr (EXTENT != std::dynamic_extent) - return std::span { std::bit_cast(stdr::data(bytes)), - EXTENT / sizeof(T) }; + return std::span { std::bit_cast(stdr::data(bytes)), EXTENT / sizeof(T) }; else - return std::span { std::bit_cast(stdr::data(bytes)), stdr::size(bytes) / sizeof(T) }; + return std::span { std::bit_cast(stdr::data(bytes)), stdr::size(bytes) / sizeof(T) }; } ///////////////////////////////////// From b3f4337618831eb2aecc3d1c3a2cf7dd50badfc1 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 8 Mar 2026 21:02:13 +0100 Subject: [PATCH 138/194] (entities) add xxx_component template variant for component with a static type --- modules/stormkit/entities.cppm | 137 ++++++++++++++++++++++----------- 1 file changed, 93 insertions(+), 44 deletions(-) diff --git a/modules/stormkit/entities.cppm b/modules/stormkit/entities.cppm index f8e1c1b87..cb4fe5f67 100644 --- a/modules/stormkit/entities.cppm +++ b/modules/stormkit/entities.cppm @@ -19,6 +19,8 @@ import stormkit.core; namespace stdr = std::ranges; namespace stdv = std::views; +namespace cmeta = stormkit::core::meta; + export namespace stormkit::entities { using Entity = u32; using Entities = std::vector; @@ -41,8 +43,14 @@ export namespace stormkit::entities { namespace meta { template concept IsComponentType = requires(T&& component) { - { component.type() } -> core::meta::Is; + { component.type() } -> cmeta::Is; }; + + template + concept ComponentWithStaticType = IsComponentType and requires(T) { + { T::type() } -> cmeta::SameAs; + }; + } // namespace meta struct Message { @@ -154,6 +162,8 @@ export namespace stormkit::entities { auto destroy_component(Entity entity, std::string_view name) noexcept -> void; auto destroy_component(Entity entity, ComponentType type) noexcept -> void; + template + auto has_component(Entity entity) const noexcept -> bool; auto has_component(Entity entity, std::string_view name) const noexcept -> bool; auto has_component(Entity entity, ComponentType type) const noexcept -> bool; @@ -162,17 +172,20 @@ export namespace stormkit::entities { auto entities_with_component(ComponentType type) const noexcept -> Entities; auto entities_with_component(std::string_view name) const noexcept -> Entities; + template + auto get_component(this Self& self, Entity entity) noexcept -> cmeta::ForwardConst&; template - auto get_component(this Self& self, Entity entity, ComponentType type) noexcept -> core::meta::ForwardConst&; + auto get_component(this Self& self, Entity entity, ComponentType) noexcept -> cmeta::ForwardConst&; template - auto get_component(this Self& self, Entity entity, std::string_view name) noexcept -> core::meta::ForwardConst&; + auto get_component(this Self& self, Entity entity, std::string_view) noexcept -> cmeta::ForwardConst&; + template + auto components_of_type(this Self& self) noexcept -> std::vector>>; template - auto components_of_type(this Self& self, ComponentType type) noexcept - -> std::vector>>; + auto components_of_type(this Self& self, ComponentType type) noexcept -> std::vector>>; template auto components_of_type(this Self& self, std::string_view name) noexcept - -> std::vector>>; + -> std::vector>>; auto components_types_of(Entity entity) const noexcept -> std::vector; @@ -181,10 +194,10 @@ export namespace stormkit::entities { auto remove_system(std::string_view name) noexcept -> void; template - auto systems(this Self& self) noexcept -> std::vector>>; + auto systems(this Self& self) noexcept -> std::vector>>; template - auto get_system(this Self& self, std::string_view name) noexcept -> core::meta::ForwardConst; + auto get_system(this Self& self, std::string_view name) noexcept -> cmeta::ForwardConst; auto step(fsecond delta) noexcept -> void; @@ -193,14 +206,18 @@ export namespace stormkit::entities { // void commit(Entity e); private: + template + auto get_component(this Self& self, Entity entity, ComponentType type) noexcept + -> std::span>; + using ComponentKey = u64; struct Store { - ComponentType type; - usize size; - Entities entities; - std::vector data; - std::function delete_func; + ComponentType type; + usize size; + Entities entities; + std::vector data; + std::function delete_func; }; using ComponentStore = std::vector; @@ -260,7 +277,7 @@ namespace stormkit::entities { ///////////////////////////////////// template auto EntityManager::add_component(Entity entity, T&& component) noexcept -> T& { - using PureT = core::meta::ToPlainType; + using PureT = cmeta::ToPlainType; EXPECTS(has_entity(entity)); EXPECTS(not has_component(entity, component.type())); @@ -294,6 +311,13 @@ namespace stormkit::entities { destroy_component(entity, hash(name)); } + ///////////////////////////////////// + ///////////////////////////////////// + template + inline auto EntityManager::has_component(Entity entity) const noexcept -> bool { + return has_component(entity, T::type()); + } + ///////////////////////////////////// ///////////////////////////////////// inline auto EntityManager::has_component(Entity entity, std::string_view name) const noexcept -> bool { @@ -322,52 +346,48 @@ namespace stormkit::entities { return entities_with_component(hash(name)); } + ///////////////////////////////////// + ///////////////////////////////////// + template + auto EntityManager::get_component(this Self& self, Entity entity) noexcept -> cmeta::ForwardConst& { + return self.template get_component(entity, T::type()); + } + ///////////////////////////////////// ///////////////////////////////////// template auto EntityManager::get_component(this Self& self, Entity entity, ComponentType type) noexcept - -> core::meta::ForwardConst& { - EXPECTS(self.has_entity(entity)); - EXPECTS(self.has_component(entity, type)); - - auto it = stdr::find_if(self.m_components, [&type](const auto& pair) noexcept { return pair.type == type; }); - ENSURES(it != stdr::cend(self.m_components)); - - auto& [_, size, _, components, _] = *it; - - auto component_it = stdr::data(components); - for (;;) { - auto e = *std::bit_cast(component_it); - if (e != entity) { - component_it += sizeof(Entity) + size; - continue; - } - - component_it += sizeof(Entity); - - break; - } - return std::forward_like(*std::bit_cast*>(component_it)); + -> cmeta::ForwardConst& { + if constexpr (cmeta::IsConst) return bytes_as(self.get_component(entity, type)); + else + return bytes_mut_as(self.get_component(entity, type)); } ///////////////////////////////////// ///////////////////////////////////// template auto EntityManager::get_component(this Self& self, Entity entity, std::string_view name) noexcept - -> core::meta::ForwardConst& { + -> cmeta::ForwardConst& { return self.template get_component(entity, hash(name)); } + ///////////////////////////////////// + ///////////////////////////////////// + template + auto EntityManager::components_of_type(this Self& self) noexcept -> std::vector>> { + return self.template components_of_type(T::type()); + } + ///////////////////////////////////// ///////////////////////////////////// template auto EntityManager::components_of_type(this Self& self, ComponentType type) noexcept - -> std::vector>> { + -> std::vector>> { // clang-format off return self.m_entities | stdv::filter([&self, type](auto entity) noexcept { return self.has_component(entity, type); }) | stdv::transform([&self, type](auto entity) noexcept { return self.template get_component(entity, type); }) - | stdv::transform(monadic::forward_like()) + // | stdv::transform(monadic::forward_like()) | stdv::transform(monadic::as_ref()) | stdr::to(); // clang-format on @@ -377,7 +397,7 @@ namespace stormkit::entities { ///////////////////////////////////// template auto EntityManager::components_of_type(this Self& self, std::string_view name) noexcept - -> std::vector>> { + -> std::vector>> { return self.template components_of_type(hash(name)); } @@ -424,9 +444,9 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// template - auto EntityManager::systems(this Self& self) noexcept -> std::vector>> { + auto EntityManager::systems(this Self& self) noexcept -> std::vector>> { constexpr auto as_refer = [] { - if constexpr (core::meta::IsConst) return monadic::as_ref(); + if constexpr (cmeta::IsConst) return monadic::as_ref(); else return monadic::as_ref_mut(); }(); @@ -437,10 +457,10 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// template - auto EntityManager::get_system(this Self& self, std::string_view name) noexcept -> core::meta::ForwardConst { + auto EntityManager::get_system(this Self& self, std::string_view name) noexcept -> cmeta::ForwardConst { EXPECTS(self.has_system(name)); - auto it = stdr::find_if(self.m_systems, [name](const auto& system) noexcept { return system.name() == name; }); + const auto it = stdr::find_if(self.m_systems, [name](const auto& system) noexcept { return system.name() == name; }); return std::forward_like(*it->get()); } @@ -449,4 +469,33 @@ namespace stormkit::entities { inline auto EntityManager::entity_count() const noexcept -> usize { return std::size(m_entities); } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto EntityManager::get_component(this Self& self, Entity entity, ComponentType type) noexcept + -> std::span> { + EXPECTS(self.has_entity(entity)); + EXPECTS(self.has_component(entity, type)); + + auto it = stdr::find_if(self.m_components, [&type](const auto& pair) noexcept { return pair.type == type; }); + ENSURES(it != stdr::cend(self.m_components)); + + auto& [_, size, _, components, _] = *it; + + auto component_it = stdr::data(components); + for (;;) { + auto e = *std::bit_cast(component_it); + if (e != entity) { + component_it += sizeof(Entity) + size; + continue; + } + + component_it += sizeof(Entity); + + break; + } + + return { component_it, size }; + } } // namespace stormkit::entities From b27e7f3bf34457cc8190350c675fbe05564baa61 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 8 Mar 2026 21:03:45 +0100 Subject: [PATCH 139/194] (entities) remove redondant and incorrect assertion in destroy_component() --- src/entities/entity_manager.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/entities/entity_manager.cpp b/src/entities/entity_manager.cpp index 92f27a8e3..19d1540fa 100644 --- a/src/entities/entity_manager.cpp +++ b/src/entities/entity_manager.cpp @@ -86,7 +86,6 @@ namespace stormkit::entities { EXPECTS(has_component(entity, type)); auto it = stdr::find_if(m_components, [type](const auto& pair) noexcept { return pair.type == type; }); - ENSURES(it == stdr::cend(m_components)); auto& [_, size, entities, components, delete_func] = *it; auto component_it = stdr::begin(components); From 670309cdb080bc148ef34ca46caf705b546c7157 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 9 Mar 2026 19:06:24 +0100 Subject: [PATCH 140/194] (entities) fix lua binding --- modules/stormkit/entities.cppm | 119 +++++++++++++++++++++---------- src/entities/entity_manager.cpp | 55 +++++++++----- src/lua/entities.cpp | 7 +- xmake/targets/entities.xmake.lua | 2 + 4 files changed, 122 insertions(+), 61 deletions(-) diff --git a/modules/stormkit/entities.cppm b/modules/stormkit/entities.cppm index cb4fe5f67..7b421b6d3 100644 --- a/modules/stormkit/entities.cppm +++ b/modules/stormkit/entities.cppm @@ -10,6 +10,13 @@ module; #include +#include + +#include +#ifdef STORMKIT_LIB_LUA_ENABLED + #include +#endif + export module stormkit.entities; import std; @@ -22,6 +29,22 @@ namespace stdv = std::views; namespace cmeta = stormkit::core::meta; export namespace stormkit::entities { + using ComponentType = u32; + +#ifdef STORMKIT_LIB_LUA_ENABLED + namespace lua { + struct LuaComponent { + sol::table data; + ComponentType _type; + + STORMKIT_FORCE_INLINE + inline auto type() const noexcept -> ComponentType { + return _type; + } + }; + } // namespace lua +#endif + using Entity = u32; using Entities = std::vector; @@ -38,8 +61,6 @@ export namespace stormkit::entities { #endif }; - using ComponentType = u32; - namespace meta { template concept IsComponentType = requires(T&& component) { @@ -139,6 +160,7 @@ export namespace stormkit::entities { class STORMKIT_ENTITIES_API EntityManager { public: + using DeleteFunc = std::function; static constexpr auto ADDED_ENTITY_MESSAGE_ID = 1; static constexpr auto REMOVED_ENTITY_MESSAGE_ID = 2; @@ -157,7 +179,7 @@ export namespace stormkit::entities { auto has_entity(Entity entity) const noexcept -> bool; template - auto add_component(Entity entity, T&& component) noexcept -> T&; + auto add_component(Entity entity, T&& component) noexcept -> cmeta::ToPlainType&; auto destroy_component(Entity entity, std::string_view name) noexcept -> void; auto destroy_component(Entity entity, ComponentType type) noexcept -> void; @@ -199,25 +221,29 @@ export namespace stormkit::entities { template auto get_system(this Self& self, std::string_view name) noexcept -> cmeta::ForwardConst; + auto flush() noexcept -> void; auto step(fsecond delta) noexcept -> void; auto entity_count() const noexcept -> usize; - // void commit(Entity e); + auto add_raw_component(Entity entity, + ComponentType type, + std::span component, + DeleteFunc delete_func) noexcept -> std::span; - private: template - auto get_component(this Self& self, Entity entity, ComponentType type) noexcept + auto get_raw_component(this Self& self, Entity entity, ComponentType type) noexcept -> std::span>; + private: using ComponentKey = u64; struct Store { - ComponentType type; - usize size; - Entities entities; - std::vector data; - std::function delete_func; + ComponentType type; + usize size; + Entities entities; + std::vector data; + DeleteFunc delete_func; }; using ComponentStore = std::vector; @@ -276,33 +302,15 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// template - auto EntityManager::add_component(Entity entity, T&& component) noexcept -> T& { + auto EntityManager::add_component(Entity entity, T&& component) noexcept -> cmeta::ToPlainType& { using PureT = cmeta::ToPlainType; - EXPECTS(has_entity(entity)); - EXPECTS(not has_component(entity, component.type())); - - auto it = stdr::find_if(m_components, [type = component.type()](const auto& pair) noexcept { return pair.type == type; }); - if (it == stdr::cend(m_components)) - it = m_components.emplace(stdr::cend(m_components), - Store { component.type(), sizeof(PureT), {}, {}, [](auto ptr) static noexcept { - std::bit_cast(ptr)->~PureT(); - } }); - ENSURES(it != stdr::cend(m_components)); - - auto& [_, size, entities, components, _] = *it; - ENSURES(size == sizeof(PureT)); - - const auto old_size = stdr::size(components); - components.resize(old_size + sizeof(Entity) + size); - new (stdr::data(components) + old_size) Entity { entity }; - auto* _component = new (stdr::data(components) + sizeof(Entity) + old_size) PureT { std::forward(component) }; - - entities.emplace_back(entity); + auto _component = add_raw_component(entity, + component.type(), + as_bytes(std::forward(component)), + [](auto ptr) static noexcept { std::bit_cast(ptr)->~PureT(); }); - m_updated_entities.emplace(entity); - - return *_component; + return bytes_mut_as(_component); } ///////////////////////////////////// @@ -358,9 +366,9 @@ namespace stormkit::entities { template auto EntityManager::get_component(this Self& self, Entity entity, ComponentType type) noexcept -> cmeta::ForwardConst& { - if constexpr (cmeta::IsConst) return bytes_as(self.get_component(entity, type)); + if constexpr (cmeta::IsConst) return bytes_as(self.get_raw_component(entity, type)); else - return bytes_mut_as(self.get_component(entity, type)); + return bytes_mut_as(self.get_raw_component(entity, type)); } ///////////////////////////////////// @@ -470,10 +478,45 @@ namespace stormkit::entities { return std::size(m_entities); } + ///////////////////////////////////// + ///////////////////////////////////// + auto EntityManager::add_raw_component(Entity entity, + ComponentType type, + std::span component, + DeleteFunc delete_func) noexcept -> std::span { + EXPECTS(has_entity(entity)); + EXPECTS(not has_component(entity, type)); + + const auto _size = stdr::size(component); + + auto it = stdr::find_if(m_components, [type = type](const auto& pair) noexcept { return pair.type == type; }); + if (it == stdr::cend(m_components)) + it = m_components + .emplace(stdr::cend(m_components), Store { type, stdr::size(component), {}, {}, std::move(delete_func) }); + + ENSURES(it != stdr::cend(m_components)); + + auto& [_, size, entities, components, _] = *it; + ENSURES(size == _size); + + const auto old_size = stdr::size(components); + components.resize(old_size + sizeof(Entity) + size); + + new (stdr::data(components) + old_size) Entity { entity }; + auto _component = std::span { stdr::data(components) + old_size + sizeof(Entity), _size }; + stdr::copy(component, stdr::begin(_component)); + + entities.emplace_back(entity); + + m_updated_entities.emplace(entity); + + return _component; + } + ///////////////////////////////////// ///////////////////////////////////// template - auto EntityManager::get_component(this Self& self, Entity entity, ComponentType type) noexcept + auto EntityManager::get_raw_component(this Self& self, Entity entity, ComponentType type) noexcept -> std::span> { EXPECTS(self.has_entity(entity)); EXPECTS(self.has_component(entity, type)); diff --git a/src/entities/entity_manager.cpp b/src/entities/entity_manager.cpp index 19d1540fa..8471befb8 100644 --- a/src/entities/entity_manager.cpp +++ b/src/entities/entity_manager.cpp @@ -89,20 +89,18 @@ namespace stormkit::entities { auto& [_, size, entities, components, delete_func] = *it; auto component_it = stdr::begin(components); + for (;;) { auto e = *std::bit_cast(&*component_it); - if (e != entity) { - component_it += as(sizeof(Entity) + size); - continue; - } - component_it += sizeof(Entity); + if (e == entity) break; - break; + component_it += as(sizeof(Entity) + size); } - delete_func(&*component_it); - components.erase(component_it - as(sizeof(Entity)), component_it + as(size)); + delete_func(&*component_it + sizeof(Entity)); + + components.erase(component_it, component_it + as(size)); auto&& [begin, end] = stdr::remove(entities, entity); entities.erase(begin, end); @@ -125,20 +123,37 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - auto EntityManager::step(fsecond delta) noexcept -> void { - for (auto entity : m_removed_entities) { - const auto components_types = components_types_of(entity); + auto EntityManager::flush() noexcept -> void { + if (not stdr::empty(m_removed_entities)) { + if (stdr::size(m_entities) == stdr::size(m_removed_entities)) { + for (auto& [_, size, entities, data, delete_func] : m_components) { + for (auto component_it = stdr::data(data); component_it != stdr::data(data) + stdr::size(data); + component_it += as(sizeof(Entity) + size)) + delete_func(component_it + sizeof(Entity)); + + entities.clear(); + data.clear(); + } + + merge(m_free_entities, m_entities); + m_entities.clear(); + m_removed_entities.clear(); + } else { + for (auto entity : m_removed_entities) { + const auto components_types = components_types_of(entity); - for (auto t : components_types) destroy_component(entity, t); + for (auto t : components_types) destroy_component(entity, t); - auto&& [begin, end] = stdr::remove(m_entities, entity); - m_entities.erase(begin, end); + auto&& [begin, end] = stdr::remove(m_entities, entity); + m_entities.erase(begin, end); - remove_from_systems(entity); + remove_from_systems(entity); - if (not stdr::any_of(m_added_entities, monadic::is_equal(entity))) m_free_entities.emplace_back(entity); + if (not stdr::any_of(m_added_entities, monadic::is_equal(entity))) m_free_entities.emplace_back(entity); + } + m_removed_entities.clear(); + } } - m_removed_entities.clear(); stdr::for_each(m_added_entities, [this](auto&& entity) noexcept { m_entities.emplace_back(entity); }); m_added_entities.clear(); @@ -150,7 +165,12 @@ namespace stormkit::entities { for (auto& system : m_systems) system.on_message_received(*this, m_message_bus.top()); m_message_bus.pop(); } + } + ///////////////////////////////////// + ///////////////////////////////////// + auto EntityManager::step(fsecond delta) noexcept -> void { + flush(); for (auto& system : m_systems) system.pre_update(*this); for (auto& system : m_systems) system.update(*this, delta); for (auto& system : m_systems) system.post_update(*this); @@ -191,4 +211,5 @@ namespace stormkit::entities { stdr::for_each(entities() | stdv::filter(reliable_entity_filter), [&system](auto&& e) noexcept { system.add_entity(e); }); } + } // namespace stormkit::entities diff --git a/src/lua/entities.cpp b/src/lua/entities.cpp index 8c676f012..d1a8e6337 100644 --- a/src/lua/entities.cpp +++ b/src/lua/entities.cpp @@ -22,12 +22,7 @@ namespace stormkit::lua::entities { using stormkit::entities::EntityManager; using stormkit::entities::System; - struct LuaComponent { - sol::table data; - ComponentType _type; - - auto type() const noexcept -> ComponentType { return _type; } - }; + using stormkit::entities::lua::LuaComponent; //////////////////////////////////////// //////////////////////////////////////// diff --git a/xmake/targets/entities.xmake.lua b/xmake/targets/entities.xmake.lua index 64018b35d..badfc1aff 100644 --- a/xmake/targets/entities.xmake.lua +++ b/xmake/targets/entities.xmake.lua @@ -10,6 +10,8 @@ target("entities", function() add_defines("STORMKIT_ENTITIES_BUILD", { public = false }) + if get_config("lua") then add_packages("luau", "sol2_luau", { public = true }) end + add_files(path.join(module_dir, "entities.cppm"), { public = true }) add_files(path.join(src_entities_dir, "*.cpp")) From 68a8703a97355d89c975cca57e0bdb7c40d87492 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 9 Mar 2026 19:06:46 +0100 Subject: [PATCH 141/194] (gpu) implement Device::wait_idle() --- modules/stormkit/gpu/core/device.cppm | 32 +++------------------------ src/gpu/core/device.cpp | 6 +++++ 2 files changed, 9 insertions(+), 29 deletions(-) diff --git a/modules/stormkit/gpu/core/device.cppm b/modules/stormkit/gpu/core/device.cppm index b8b3b567c..9ff191961 100644 --- a/modules/stormkit/gpu/core/device.cppm +++ b/modules/stormkit/gpu/core/device.cppm @@ -6,6 +6,7 @@ module; #include #include +#include #include #include @@ -59,7 +60,7 @@ export { Device(Device&&) noexcept; auto operator=(Device&&) noexcept -> Device&; - auto wait_idle() const noexcept -> void; + auto wait_idle() const noexcept -> Expected; auto wait_for_fences(std::span> fences, bool wait_all = true, @@ -141,21 +142,16 @@ export { namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - inline Device::Device(const PhysicalDevice& physical_device, PrivateFuncTag) noexcept : m_physical_device { as_ref(physical_device) } { } ///////////////////////////////////// ///////////////////////////////////// - - inline Device::~Device() noexcept { - if (m_vk_handle) wait_idle(); - } + inline Device::~Device() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::create(const PhysicalDevice& physical_device, const Instance& instance, const Info& info) noexcept -> Expected { auto device = Device { physical_device, PrivateFuncTag {} }; @@ -164,7 +160,6 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::allocate(const PhysicalDevice& physical_device, const Instance& instance, const Info& info) noexcept -> Expected> { auto device = core::allocate_unsafe(physical_device, PrivateFuncTag {}); @@ -173,24 +168,14 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - inline Device::Device(Device&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::operator=(Device&&) noexcept -> Device& = default; ///////////////////////////////////// ///////////////////////////////////// - - inline auto Device::wait_idle() const noexcept -> void { - // native_handle().wait_idle(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Device::wait_for_fence(const Fence& fence, const std::chrono::milliseconds& timeout) const noexcept -> Expected { return wait_for_fences(as_refs(fence), true, timeout); @@ -198,21 +183,18 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::reset_fence(const Fence& fence) const noexcept -> Expected { return reset_fences(as_refs(fence)); } ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::raster_queue_entry() const noexcept -> const QueueEntry& { return m_raster_queue; } ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::async_transfer_queue_entry() const noexcept -> const QueueEntry& { EXPECTS(m_async_transfert_queue != std::nullopt); @@ -221,7 +203,6 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::async_compute_queue_entry() const noexcept -> const QueueEntry& { EXPECTS(m_async_compute_queue != std::nullopt); @@ -230,21 +211,18 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::has_async_transfer_queue() const noexcept -> bool { return m_async_transfert_queue != std::nullopt; } ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::has_async_compute_queue() const noexcept -> bool { return m_async_compute_queue != std::nullopt; } ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::physical_device() const noexcept -> const PhysicalDevice& { return m_physical_device; } @@ -252,7 +230,6 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - inline auto Device::set_object_name(const T& object, std::string_view name) const -> Expected { if (not vkSetDebugUtilsObjectNameEXT) return {}; @@ -262,7 +239,6 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::native_handle() const noexcept -> VkDevice { EXPECTS(m_vk_handle.value() != nullptr); return m_vk_handle.value(); @@ -270,14 +246,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::device_table() const noexcept -> const VolkDeviceTable& { return m_vk_device_table; } ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::allocator() const noexcept -> VmaAllocator { return m_vma_allocator; } diff --git a/src/gpu/core/device.cpp b/src/gpu/core/device.cpp index bbd97f04f..782dbac9c 100644 --- a/src/gpu/core/device.cpp +++ b/src/gpu/core/device.cpp @@ -202,6 +202,12 @@ namespace stormkit::gpu { }; } + ///////////////////////////////////// + ///////////////////////////////////// + auto Device::wait_idle() const noexcept -> Expected { + return vk_call(m_vk_device_table.vkDeviceWaitIdle, m_vk_handle).transform_error(core::monadic::narrow()); + } + ///////////////////////////////////// ///////////////////////////////////// auto Device::do_init(const Instance& instance, const Info& info) noexcept -> Expected { From 30edf1fccbeb2dc56ec71b16d97aacab5cdae291 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 9 Mar 2026 19:07:04 +0100 Subject: [PATCH 142/194] (core) use unique_lock instead of lock_guard by default in Locked --- modules/stormkit/core/parallelism/locked.cppm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/stormkit/core/parallelism/locked.cppm b/modules/stormkit/core/parallelism/locked.cppm index 38c26021b..a564d341a 100644 --- a/modules/stormkit/core/parallelism/locked.cppm +++ b/modules/stormkit/core/parallelism/locked.cppm @@ -18,9 +18,9 @@ import :typesafe.ref; namespace stormkit { inline namespace core { namespace details { using DefaultMutex = std::mutex; template - using DefaultReadOnlyLock = std::lock_guard; + using DefaultReadOnlyLock = std::unique_lock; template - using DefaultReadWriteLock = std::lock_guard; + using DefaultReadWriteLock = std::unique_lock; }}} // namespace stormkit::core::details export namespace stormkit { inline namespace core { From 954328bfd563bd9b47b51b652f1fc80b335e6efc Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 10 Mar 2026 21:14:56 +0100 Subject: [PATCH 143/194] (core) annotate locked mutex --- include/stormkit/core/platform_macro.hpp | 6 ++++++ modules/stormkit/core/parallelism/locked.cppm | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/stormkit/core/platform_macro.hpp b/include/stormkit/core/platform_macro.hpp index 356616710..846d9b0fc 100644 --- a/include/stormkit/core/platform_macro.hpp +++ b/include/stormkit/core/platform_macro.hpp @@ -97,6 +97,12 @@ #define STORMKIT_LIFETIMEBOUND #endif +#if __has_cpp_attribute(clang::guarded_by) + #define STORMKIT_GUARDED_BY(x) [[clang::guarded_by(x)]] +#else + #define STORMKIT_GUARDED_BY(_) +#endif + #if __has_cpp_attribute(gnu::pure) #define STORMKIT_PURE [[gnu::pure]] #else diff --git a/modules/stormkit/core/parallelism/locked.cppm b/modules/stormkit/core/parallelism/locked.cppm index a564d341a..f8ce56343 100644 --- a/modules/stormkit/core/parallelism/locked.cppm +++ b/modules/stormkit/core/parallelism/locked.cppm @@ -123,8 +123,8 @@ export namespace stormkit { inline namespace core { RefContainerType m_value; }; - mutable Mutex m_mutex; - ValueType m_value; + mutable Mutex m_mutex; + ValueType m_value STORMKIT_GUARDED_BY(m_mutex); }; template From 26ce79c7d99d3a2aa24ae920e90084f4458f462c Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 10 Mar 2026 21:16:08 +0100 Subject: [PATCH 144/194] (entities) enable add_system to work with class / struct --- modules/stormkit/entities.cppm | 39 ++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/modules/stormkit/entities.cppm b/modules/stormkit/entities.cppm index 7b421b6d3..09c9dd065 100644 --- a/modules/stormkit/entities.cppm +++ b/modules/stormkit/entities.cppm @@ -156,6 +156,13 @@ export namespace stormkit::entities { friend class EntityManager; }; + namespace meta { + template + concept IsUsableAsSystem = requires(T& value) { + value.update(std::declval(), std::declval(), std::declval()); + }; + } // namespace meta + struct ComponentStore {}; class STORMKIT_ENTITIES_API EntityManager { @@ -211,6 +218,8 @@ export namespace stormkit::entities { auto components_types_of(Entity entity) const noexcept -> std::vector; + template + auto add_system(std::string name, System::ComponentTypes types, T& system) noexcept -> System&; auto add_system(std::string name, System::ComponentTypes types, System::Closures&& closures) noexcept -> System&; auto has_system(std::string_view name) const noexcept -> bool; auto remove_system(std::string_view name) noexcept -> void; @@ -425,6 +434,36 @@ namespace stormkit::entities { return out; } + namespace meta { + template + concept HasPreUpdate = requires(T& value) { value.pre_update(std::declval()); }; + + template + concept HasPostUpdate = requires(T& value) { value.post_update(std::declval()); }; + + template + concept HasOnMessageReceived = requires(T& value) { + value.on_message_received(std::declval(), + std::declval(), + std::declval()); + }; + } // namespace meta + + ///////////////////////////////////// + ///////////////////////////////////// + template + inline auto EntityManager::add_system(std::string name, System::ComponentTypes types, T& system) noexcept -> System& { + auto closures = System::Closures { + .update = bind_front(&T::update, &system), + }; + + if constexpr (meta::HasPreUpdate) closures.pre_update = bind_front(&T::pre_update, &system); + if constexpr (meta::HasPostUpdate) closures.post_update = bind_front(&T::post_update, &system); + if constexpr (meta::HasOnMessageReceived) closures.on_message_received = bind_front(&T::on_message_received, &system); + + return add_system(std::move(name), std::move(types), std::move(closures)); + } + ///////////////////////////////////// ///////////////////////////////////// inline auto EntityManager::add_system(std::string name, System::ComponentTypes types, System::Closures&& closures) noexcept From cc9c2dcff631e8eb88b448954f8ce9cb4cca0dde Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 10 Mar 2026 21:16:19 +0100 Subject: [PATCH 145/194] (lua) improve lua::Engine --- modules/stormkit/lua.cppm | 43 ++++++++++++++++++++++++++++----------- src/lua/lua.cpp | 38 +++++++++++++++++++++------------- 2 files changed, 55 insertions(+), 26 deletions(-) diff --git a/modules/stormkit/lua.cppm b/modules/stormkit/lua.cppm index 3d6da2cf2..8f498c7c4 100644 --- a/modules/stormkit/lua.cppm +++ b/modules/stormkit/lua.cppm @@ -30,7 +30,8 @@ export namespace stormkit::lua { class STORMKIT_LUA_API Engine { public: - using InitUserLibrariesClosure = FunctionRef; + using InitUserLibrariesClosure = std::function; + ~Engine() noexcept; Engine(const Engine&) = delete; @@ -39,16 +40,26 @@ export namespace stormkit::lua { Engine(Engine&& other) noexcept; auto operator=(Engine&& other) noexcept -> Engine&; + static auto load_from_file(stdfs::path path, + Modules modules = {}, + InitUserLibrariesClosure init_user_libraries = monadic::noop()) noexcept -> Engine; + auto run() noexcept -> sol::state; + static auto run(stdfs::path file, Modules modules = {}, - InitUserLibrariesClosure init_user_libraries = monadic::noop()) noexcept -> Engine; + InitUserLibrariesClosure init_user_libraries = monadic::noop()) noexcept -> void; private: - Engine() noexcept; + Engine(Modules&&, InitUserLibrariesClosure&&) noexcept; + + auto load(stdfs::path&&) noexcept -> void; + + auto init_libraries(sol::state&) noexcept -> void; - auto load(stdfs::path&&, Modules&&, InitUserLibrariesClosure&&) noexcept -> void; + Modules m_modules; + InitUserLibrariesClosure m_init_user_libraries; - auto init_libraries(Modules&&, sol::state&) noexcept -> void; + std::vector m_script; }; template @@ -62,28 +73,36 @@ export namespace stormkit::lua { namespace stormkit::lua { //////////////////////////////////////// //////////////////////////////////////// - inline Engine::Engine() noexcept = default; - - //////////////////////////////////////// - //////////////////////////////////////// + STORMKIT_FORCE_INLINE inline Engine::Engine(Engine&& other) noexcept = default; //////////////////////////////////////// //////////////////////////////////////// + STORMKIT_FORCE_INLINE inline auto Engine::operator=(Engine&& other) noexcept -> Engine& = default; //////////////////////////////////////// //////////////////////////////////////// + STORMKIT_FORCE_INLINE inline Engine::~Engine() noexcept = default; //////////////////////////////////////// //////////////////////////////////////// - inline auto Engine::run(stdfs::path file, Modules modules, InitUserLibrariesClosure init_user_libraries) noexcept -> Engine { - auto engine = Engine {}; - engine.load(std::move(file), std::move(modules), std::move(init_user_libraries)); + STORMKIT_FORCE_INLINE + inline auto Engine::load_from_file(stdfs::path file, Modules modules, InitUserLibrariesClosure init_user_libraries) noexcept + -> Engine { + auto engine = Engine { std::move(modules), std::move(init_user_libraries) }; + engine.load(std::move(file)); return engine; } + //////////////////////////////////////// + //////////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Engine::run(stdfs::path file, Modules modules, InitUserLibrariesClosure init_user_libraries) noexcept -> void { + Engine::load_from_file(std::move(file), std::move(modules), std::move(init_user_libraries)).run(); + } + //////////////////////////////////////// //////////////////////////////////////// template diff --git a/src/lua/lua.cpp b/src/lua/lua.cpp index 299b67645..ea1386df6 100644 --- a/src/lua/lua.cpp +++ b/src/lua/lua.cpp @@ -48,22 +48,32 @@ LOGGER("stormkit.lua") namespace stormkit::lua { //////////////////////////////////////// //////////////////////////////////////// - auto Engine::load(stdfs::path&& file, Modules&& modules, InitUserLibrariesClosure&& init_user_libraries) noexcept -> void { - auto global_state = sol::state {}; + Engine::Engine(Modules&& modules, InitUserLibrariesClosure&& closure) noexcept + : m_modules { std::move(modules) }, m_init_user_libraries { std::move(closure) } { + } + + //////////////////////////////////////// + //////////////////////////////////////// + auto Engine::load(stdfs::path&& file) noexcept -> void { + m_script = TryAssert(io::read_text(file), std::format("Failed to load {}", file.string())); + } + + //////////////////////////////////////// + //////////////////////////////////////// + auto Engine::run() noexcept -> sol::state { + auto state = sol::state {}; - init_libraries(std::move(modules), global_state); - init_user_libraries(global_state); + init_libraries(state); + m_init_user_libraries(state); - const auto code = TryAssert(io::read_text(file), std::format("Failed to load {}", file.string())); - const auto script = global_state.load(std::string_view { stdr::data(code), stdr::size(code) }); - const auto function = sol::protected_function { script }; + state.do_string(std::string_view { stdr::data(m_script), stdr::size(m_script) }); - luacall(function); + return state; } //////////////////////////////////////// //////////////////////////////////////// - auto Engine::init_libraries(Modules&& modules, sol::state& global_state) noexcept -> void { + auto Engine::init_libraries(sol::state& global_state) noexcept -> void { for (auto lib : { sol::lib::base, sol::lib::bit32, @@ -128,7 +138,7 @@ namespace stormkit::lua { }; core::init_lua(global_state); - if (modules.log) { + if (m_modules.log) { #if STORMKIT_LIB_LOG_ENABLED dlog("Log module enabled"); log::init_lua(global_state); @@ -136,7 +146,7 @@ namespace stormkit::lua { elog("Trying to bind log module while disabled in this stormkit distribution!"); #endif } - if (modules.entities) { + if (m_modules.entities) { #if STORMKIT_LIB_ENTITIES_ENABLED dlog("Entities module enabled"); entities::init_lua(global_state); @@ -144,7 +154,7 @@ namespace stormkit::lua { elog("Trying to bind entities module while disabled in this stormkit distribution!"); #endif } - if (modules.image) { + if (m_modules.image) { #if STORMKIT_LIB_IMAGE_ENABLED dlog("Image module enabled"); image::init_lua(global_state); @@ -152,7 +162,7 @@ namespace stormkit::lua { elog("Trying to bind image module while disabled in this stormkit distribution!"); #endif } - if (modules.wsi) { + if (m_modules.wsi) { #if STORMKIT_LIB_WSI_ENABLED dlog("Wsi module enabled"); wsi::init_lua(global_state); @@ -160,7 +170,7 @@ namespace stormkit::lua { elog("Trying to bind wsi module while disabled in this stormkit distribution!"); #endif } - if (modules.gpu) { + if (m_modules.gpu) { #if STORMKIT_LIB_GPU_ENABLED dlog("Gpu module enabled"); gpu::init_lua(global_state); From 5a02ae842342af4ae8ac0293f3096392b42295ca Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 10 Mar 2026 21:28:05 +0100 Subject: [PATCH 146/194] (core) add a way to disable fancy support in as_ref_* --- modules/stormkit/core/typesafe/ref.cppm | 156 ++++++++++++------------ 1 file changed, 76 insertions(+), 80 deletions(-) diff --git a/modules/stormkit/core/typesafe/ref.cppm b/modules/stormkit/core/typesafe/ref.cppm index 7d1129286..d35f03adf 100644 --- a/modules/stormkit/core/typesafe/ref.cppm +++ b/modules/stormkit/core/typesafe/ref.cppm @@ -145,49 +145,49 @@ export { PointerType m_value; - template - friend constexpr auto as_ref(U&& value) noexcept -> decltype(auto); + template + friend constexpr auto as_ref(U&&) noexcept -> decltype(auto); - template - friend constexpr auto as_ref_mut(U&& value) noexcept -> decltype(auto); + template + friend constexpr auto as_ref_mut(U&&) noexcept -> decltype(auto); - template - friend constexpr auto as_ref_like(U&& value) noexcept -> decltype(auto); + template + friend constexpr auto as_ref_like(U&&) noexcept -> decltype(auto); - template - friend constexpr auto as_opt_ref(U&& value) noexcept -> decltype(auto); + template + friend constexpr auto as_opt_ref(U&&) noexcept -> decltype(auto); - template - friend constexpr auto as_opt_ref_mut(U&& value) noexcept -> decltype(auto); + template + friend constexpr auto as_opt_ref_mut(U&&) noexcept -> decltype(auto); - template - friend constexpr auto as_opt_ref_like(U&& value) noexcept -> decltype(auto); + template + friend constexpr auto as_opt_ref_like(U&&) noexcept -> decltype(auto); }; template using OptionalRef = Ref; - template + template [[nodiscard]] constexpr auto as_ref(T&& value STORMKIT_LIFETIMEBOUND) noexcept -> decltype(auto); - template + template [[nodiscard]] constexpr auto as_ref_mut(T&& value STORMKIT_LIFETIMEBOUND) noexcept -> decltype(auto); - template + template [[nodiscard]] constexpr auto as_ref_like(T&& value STORMKIT_LIFETIMEBOUND) noexcept -> decltype(auto); - template + template [[nodiscard]] constexpr auto as_opt_ref(T&& value STORMKIT_LIFETIMEBOUND) noexcept -> decltype(auto); - template + template [[nodiscard]] constexpr auto as_opt_ref_mut(T&& value STORMKIT_LIFETIMEBOUND) noexcept -> decltype(auto); - template + template [[nodiscard]] constexpr auto as_opt_ref_like(T&& value STORMKIT_LIFETIMEBOUND) noexcept -> decltype(auto); @@ -199,62 +199,62 @@ export { [[nodiscard]] constexpr auto unref_mut(const Ref& value STORMKIT_LIFETIMEBOUND) noexcept -> T&; - template typename Out = std::array, typename... Args> + template typename Out = std::array, bool RAW = false, typename... Args> requires(not std::ranges::range and ...) [[nodiscard]] constexpr auto as_refs(Args&&... args) noexcept -> decltype(auto); - template typename Out = std::vector, typename... Args> + template typename Out = std::vector, bool RAW = false, typename... Args> requires(not std::ranges::range and ...) [[nodiscard]] constexpr auto to_refs(Args&&... args) noexcept -> decltype(auto); - template typename Out = std::array, typename... Args> + template typename Out = std::array, bool RAW = false, typename... Args> requires(not std::ranges::range and ...) [[nodiscard]] constexpr auto as_ref_muts(Args&&... args) noexcept -> decltype(auto); - template typename Out = std::vector, typename... Args> + template typename Out = std::vector, bool RAW = false, typename... Args> requires(not std::ranges::range and ...) [[nodiscard]] constexpr auto to_ref_muts(Args&&... args) noexcept -> decltype(auto); - template class Out = std::vector, std::ranges::range T> + template class Out = std::vector, bool RAW = false, std::ranges::range T> requires(std::ranges::range>) [[nodiscard]] constexpr auto to_refs(const T& range) noexcept -> decltype(auto); - template class Out = std::vector, std::ranges::range T> + template class Out = std::vector, bool RAW = false, std::ranges::range T> requires(std::ranges::range>) [[nodiscard]] constexpr auto to_mut_refs(T& range) noexcept -> decltype(auto); - template typename Out = std::array, typename... Args> - requires(not std::ranges::range and ...) + template typename Out = std::array, bool RAW = false, typename... Args> + requires(not std::ranges::range and ...) [[nodiscard]] constexpr auto as_opt_refs(Args&&... args) noexcept -> decltype(auto); - template typename Out = std::vector, typename... Args> + template typename Out = std::vector, bool RAW = false, typename... Args> requires(not std::ranges::range and ...) [[nodiscard]] constexpr auto to_opt_refs(Args&&... args) noexcept -> decltype(auto); - template typename Out = std::array, typename... Args> + template typename Out = std::array, bool RAW = false, typename... Args> requires(not std::ranges::range and ...) [[nodiscard]] constexpr auto as_opt_ref_muts(Args&&... args) noexcept -> decltype(auto); - template typename Out = std::vector, typename... Args> + template typename Out = std::vector, bool RAW = false, typename... Args> requires(not std::ranges::range and ...) [[nodiscard]] constexpr auto to_opt_ref_muts(Args&&... args) noexcept -> decltype(auto); - template class Out = std::vector, std::ranges::range T> + template class Out = std::vector, bool RAW = false, std::ranges::range T> requires(std::ranges::range>) [[nodiscard]] constexpr auto to_opt_refs(const T& range) noexcept -> decltype(auto); - template class Out = std::vector, std::ranges::range T> + template class Out = std::vector, bool RAW = false, std::ranges::range T> requires(std::ranges::range>) [[nodiscard]] constexpr auto to_mut_opt_refs(T& range) noexcept -> decltype(auto); @@ -605,14 +605,14 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE constexpr auto as_ref(T&& value) noexcept -> decltype(auto) { using TValue = meta::CanonicalType; - if constexpr (meta::IsPointer) { + if constexpr (not RAW and meta::IsPointer) { EXPECTS(value != nullptr); return Ref> { std::to_address(value) }; - } else if constexpr (meta::IsContainedSemantics) { + } else if constexpr (not RAW and meta::IsContainedSemantics) { EXPECTS(value.operator bool()); return Ref> { &(value.operator*()) }; } else { @@ -622,18 +622,17 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - // template - template + template STORMKIT_FORCE_INLINE constexpr auto as_ref_mut(T&& value) noexcept -> decltype(auto) { - using TValue = std::remove_reference_t; + using TValue = meta::CanonicalType; static constexpr auto error_msg = "as_ref_mut can't take a reference of a const object"sv; - if constexpr (meta::IsPointer) { + if constexpr (not RAW and meta::IsPointer) { using PointedType = meta::ElementType; static_assert(meta::IsNotConst, error_msg); EXPECTS(value != nullptr); return Ref> { std::to_address(value) }; - } else if constexpr (meta::IsContainedSemantics) { + } else if constexpr (not RAW and meta::IsContainedSemantics) { using UnderlyingType = meta::UnderlyingType; static_assert(meta::IsNotConst, error_msg); EXPECTS(value.operator bool()); @@ -646,15 +645,14 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - // template - template + template STORMKIT_FORCE_INLINE constexpr auto as_ref_like(T&& value) noexcept -> decltype(auto) { using TValue = meta::CanonicalType; - if constexpr (meta::IsPointer) { + if constexpr (not RAW and meta::IsPointer) { EXPECTS(value != nullptr); return Ref> { std::to_address(value) }; - } else if constexpr (meta::IsContainedSemantics) { + } else if constexpr (not RAW and meta::IsContainedSemantics) { EXPECTS(value.operator bool()); return Ref> { &(value.operator*()) }; } else { @@ -664,14 +662,13 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - // template - template + template STORMKIT_FORCE_INLINE constexpr auto as_opt_ref(T&& value) noexcept -> decltype(auto) { using TValue = meta::CanonicalType; - if constexpr (meta::IsPointer) { + if constexpr (not RAW and meta::IsPointer) { return OptionalRef> { std::to_address(value) }; - } else if constexpr (meta::IsContainedSemantics) { + } else if constexpr (not RAW and meta::IsContainedSemantics) { return OptionalRef> { &(value.operator*()) }; } else { return OptionalRef { &value }; @@ -680,17 +677,16 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - // template - template + template STORMKIT_FORCE_INLINE constexpr auto as_opt_ref_mut(T&& value) noexcept -> decltype(auto) { - using TValue = std::remove_reference_t; + using TValue = meta::CanonicalType; static constexpr auto error_msg = "as_ref_mut can't take a reference of a const object"sv; - if constexpr (meta::IsPointer) { + if constexpr (not RAW and meta::IsPointer) { using PointedType = meta::ElementType; static_assert(meta::IsNotConst, error_msg); return OptionalRef> { std::to_address(value) }; - } else if constexpr (meta::IsContainedSemantics) { + } else if constexpr (not RAW and meta::IsContainedSemantics) { using UnderlyingType = meta::UnderlyingType; static_assert(meta::IsNotConst, error_msg); return OptionalRef { &(value.operator*()) }; @@ -702,14 +698,14 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - // template - template + // template + template STORMKIT_FORCE_INLINE constexpr auto as_opt_ref_like(T&& value) noexcept -> decltype(auto) { using TValue = meta::CanonicalType; - if constexpr (meta::IsPointer) { + if constexpr (not RAW and meta::IsPointer) { return OptionalRef> { std::to_address(value) }; - } else if constexpr (meta::IsContainedSemantics) { + } else if constexpr (not RAW and meta::IsContainedSemantics) { return OptionalRef> { &(value.get()) }; } else { return OptionalRef { &value }; @@ -734,124 +730,124 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template typename Out, typename... Args> + template typename Out, bool RAW, typename... Args> requires(not std::ranges::range and ...) STORMKIT_FORCE_INLINE constexpr auto as_refs(Args&&... args) noexcept -> decltype(auto) { - return Out { as_ref(std::forward(args))... }; + return Out { as_ref(std::forward(args))... }; } ///////////////////////////////////// ///////////////////////////////////// - template typename Out, typename... Args> + template typename Out, bool RAW, typename... Args> requires(not std::ranges::range and ...) STORMKIT_FORCE_INLINE constexpr auto to_refs(Args&&... args) noexcept -> decltype(auto) { - return Out { { as_ref(std::forward(args))... } }; + return Out { { as_ref(std::forward(args))... } }; } ///////////////////////////////////// ///////////////////////////////////// - template typename Out, typename... Args> + template typename Out, bool RAW, typename... Args> requires(not std::ranges::range and ...) STORMKIT_FORCE_INLINE constexpr auto as_ref_muts(Args&&... args) noexcept -> decltype(auto) { - return Out { { as_ref_mut(std::forward(args))... } }; + return Out { { as_ref_mut(std::forward(args))... } }; } ///////////////////////////////////// ///////////////////////////////////// - template typename Out, typename... Args> + template typename Out, bool RAW, typename... Args> requires(not std::ranges::range and ...) STORMKIT_FORCE_INLINE constexpr auto to_ref_muts(Args&&... args) noexcept -> decltype(auto) { - return Out { { as_ref_mut(std::forward(args))... } }; + return Out { { as_ref_mut(std::forward(args))... } }; } ///////////////////////////////////// ///////////////////////////////////// - template class Out, std::ranges::range T> + template class Out, bool RAW, std::ranges::range T> requires(std::ranges::range>) STORMKIT_FORCE_INLINE constexpr auto to_refs(const T& range) noexcept -> decltype(auto) { return range | std::views::transform([](U&& val) static noexcept -> decltype(auto) { - return as_ref(std::forward(val)); + return as_ref(std::forward(val)); }) | std::ranges::to(); } ///////////////////////////////////// ///////////////////////////////////// - template class Out, std::ranges::range T> + template class Out, bool RAW, std::ranges::range T> requires(std::ranges::range>) STORMKIT_FORCE_INLINE constexpr auto to_mut_refs(T& range) noexcept -> decltype(auto) { return range | std::views::transform([](U&& val) static noexcept -> decltype(auto) { - return as_ref_mut(std::forward(val)); + return as_ref_mut(std::forward(val)); }) | std::ranges::to(); } ///////////////////////////////////// ///////////////////////////////////// - template typename Out, typename... Args> + template typename Out, bool RAW, typename... Args> requires(not std::ranges::range and ...) STORMKIT_FORCE_INLINE constexpr auto as_opt_refs(Args&&... args) noexcept -> decltype(auto) { - return Out { as_opt_ref(std::forward(args))... }; + return Out { as_opt_ref(std::forward(args))... }; } ///////////////////////////////////// ///////////////////////////////////// - template typename Out, typename... Args> + template typename Out, bool RAW, typename... Args> requires(not std::ranges::range and ...) STORMKIT_FORCE_INLINE constexpr auto to_opt_refs(Args&&... args) noexcept -> decltype(auto) { - return Out { { as_opt_ref(std::forward(args))... } }; + return Out { { as_opt_ref(std::forward(args))... } }; } ///////////////////////////////////// ///////////////////////////////////// - template typename Out, typename... Args> + template typename Out, bool RAW, typename... Args> requires(not std::ranges::range and ...) STORMKIT_FORCE_INLINE constexpr auto as_opt_ref_muts(Args&&... args) noexcept -> decltype(auto) { - return Out { { as_opt_ref_mut(std::forward(args))... } }; + return Out { { as_opt_ref_mut(std::forward(args))... } }; } ///////////////////////////////////// ///////////////////////////////////// - template typename Out, typename... Args> + template typename Out, bool RAW, typename... Args> requires(not std::ranges::range and ...) STORMKIT_FORCE_INLINE constexpr auto to_opt_ref_muts(Args&&... args) noexcept -> decltype(auto) { - return Out { { as_opt_ref_mut(std::forward(args))... } }; + return Out { { as_opt_ref_mut(std::forward(args))... } }; } ///////////////////////////////////// ///////////////////////////////////// - template class Out, std::ranges::range T> + template class Out, bool RAW, std::ranges::range T> requires(std::ranges::range>) STORMKIT_FORCE_INLINE constexpr auto to_opt_refs(const T& range) noexcept -> decltype(auto) { return range | std::views::transform([](U&& val) static noexcept -> decltype(auto) { - return as_opt_ref(std::forward(val)); + return as_opt_ref(std::forward(val)); }) | std::ranges::to(); } ///////////////////////////////////// ///////////////////////////////////// - template class Out, std::ranges::range T> + template class Out, bool RAW, std::ranges::range T> requires(std::ranges::range>) STORMKIT_FORCE_INLINE constexpr auto to_mut_opt_refs(T& range) noexcept -> decltype(auto) { return range | std::views::transform([](U&& val) static noexcept -> decltype(auto) { - return as_opt_ref_mut(std::forward(val)); + return as_opt_ref_mut(std::forward(val)); }) | std::ranges::to(); } From b9c3f946601bcd6b0cf2b7a8025643bf121648c6 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 10 Mar 2026 22:12:54 +0100 Subject: [PATCH 147/194] (core) rename IsOneOf / SameAsOneOf to IsAnyOf / SameAsAnyOf --- .../core/containers/multi_buffer.cppm | 4 +-- modules/stormkit/core/hash/base.cppm | 2 +- modules/stormkit/core/meta/concepts.cppm | 29 +++++++++---------- .../stormkit/core/typesafe/strong_type.cppm | 4 +-- modules/stormkit/core/utils/contract.cppm | 2 +- modules/stormkit/gpu/core/vulkan/utils.cppm | 2 +- 6 files changed, 20 insertions(+), 23 deletions(-) diff --git a/modules/stormkit/core/containers/multi_buffer.cppm b/modules/stormkit/core/containers/multi_buffer.cppm index e624b2140..e294bdcc6 100644 --- a/modules/stormkit/core/containers/multi_buffer.cppm +++ b/modules/stormkit/core/containers/multi_buffer.cppm @@ -128,7 +128,7 @@ namespace stormkit { inline namespace core { template template constexpr auto MultiBuffer::init_range(V&& init_data) noexcept -> std::span { - static_assert(meta::IsOneOf, "U should be a type contained by MultiBuffer"); + static_assert(meta::IsAnyOf, "U should be a type contained by MultiBuffer"); static_assert(meta::Is>, "range V should be of type U"); static constexpr auto TYPE_INDEX = meta::find_type_index_of(); return init_range(std::forward(init_data)); @@ -156,7 +156,7 @@ namespace stormkit { inline namespace core { template template constexpr auto MultiBuffer::range(this Self& self) noexcept -> std::span> { - static_assert(meta::IsOneOf, "U should be a type contained by MultiBuffer"); + static_assert(meta::IsAnyOf, "U should be a type contained by MultiBuffer"); static constexpr auto TYPE_INDEX = meta::find_type_index_of(); return self.template range(); } diff --git a/modules/stormkit/core/hash/base.cppm b/modules/stormkit/core/hash/base.cppm index e443756ec..8c6626ec7 100644 --- a/modules/stormkit/core/hash/base.cppm +++ b/modules/stormkit/core/hash/base.cppm @@ -18,7 +18,7 @@ export namespace stormkit { inline namespace core { namespace meta { template - concept HashType = meta::IsOneOf; + concept HashType = meta::IsAnyOf; } template diff --git a/modules/stormkit/core/meta/concepts.cppm b/modules/stormkit/core/meta/concepts.cppm index 163a5fb91..e1417e0a2 100644 --- a/modules/stormkit/core/meta/concepts.cppm +++ b/modules/stormkit/core/meta/concepts.cppm @@ -55,14 +55,14 @@ export namespace stormkit { inline namespace core { namespace meta { template concept IsNot = not Is; - // template concept C> - // concept Not = not C; + template concept C> + concept Not = not C; - // template concept... C> - // concept AllOf = (C and ...); + template concept... C> + concept AllOf = (C and ...); - // template concept... C> - // concept AnyOf = (C or ...); + template concept... C> + concept AnyOf = (C or ...); template concept ConvertibleTo = std::convertible_to; @@ -86,13 +86,10 @@ export namespace stormkit { inline namespace core { namespace meta { concept Are = (Is and ...); template - concept AnyOf = (Is or ...); + concept IsAnyOf = (Is or ...); template - concept IsOneOf = (Is or ...); - - template - concept SameAsOneOf = (SameAs or ...); + concept SameAsAnyOf = (SameAs or ...); template concept IsByte = IsStrict; @@ -286,13 +283,13 @@ export namespace stormkit { inline namespace core { namespace meta { // val); }; template - concept IsCharacter = IsOneOf; + concept IsCharacter = IsAnyOf; template - concept IsCharType = IsOneOf; + concept IsCharType = IsAnyOf; template - concept IsColorComponent = IsOneOf; template - concept IsVolatile = std::is_volatile_v; + concept IsNotConst = not IsConst; template - concept IsNotConst = not IsConst; + concept IsVolatile = std::is_volatile_v; template concept IsBraceInitializableTo = requires(From&& from) { To { std::forward(from) }; }; diff --git a/modules/stormkit/core/typesafe/strong_type.cppm b/modules/stormkit/core/typesafe/strong_type.cppm index fdef23356..b6d2af019 100644 --- a/modules/stormkit/core/typesafe/strong_type.cppm +++ b/modules/stormkit/core/typesafe/strong_type.cppm @@ -82,10 +82,10 @@ export { concept HasCapability = DerivedFrom; template - concept HasArithmeticCapability = AnyOf; + concept HasArithmeticCapability = IsAnyOf; template - concept HasImplicitConvertionCapability = AnyOf; + concept HasImplicitConvertionCapability = IsAnyOf; } // namespace meta template diff --git a/modules/stormkit/core/utils/contract.cppm b/modules/stormkit/core/utils/contract.cppm index c60a7ca48..84c7790ad 100644 --- a/modules/stormkit/core/utils/contract.cppm +++ b/modules/stormkit/core/utils/contract.cppm @@ -59,7 +59,7 @@ export namespace stormkit { inline namespace core { constexpr auto ensures(bool cond, const std::source_location& location = std::source_location::current()) noexcept -> void; namespace casts::core { - template To> + template To> [[nodiscard]] constexpr auto as(AssertType t) noexcept -> To; } diff --git a/modules/stormkit/gpu/core/vulkan/utils.cppm b/modules/stormkit/gpu/core/vulkan/utils.cppm index b7f579ed6..b30569be9 100644 --- a/modules/stormkit/gpu/core/vulkan/utils.cppm +++ b/modules/stormkit/gpu/core/vulkan/utils.cppm @@ -221,7 +221,7 @@ namespace stormkit::gpu { auto out = Out { std::in_place }; const auto result = [&] noexcept { - if constexpr (core::meta::IsOneOf) return std::invoke(func, std::forward(args)...); + if constexpr (core::meta::IsAnyOf) return std::invoke(func, std::forward(args)...); else if constexpr (core::meta::Is) { const auto _result = std::invoke(func, std::forward(args)...); out = _result; From 4f39affa5e188831655f700d64c1bfdc0d64dd3c Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 10 Mar 2026 22:13:16 +0100 Subject: [PATCH 148/194] (core) add AddConstIf type modifier --- modules/stormkit/core/meta/type_manipulation.cppm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/stormkit/core/meta/type_manipulation.cppm b/modules/stormkit/core/meta/type_manipulation.cppm index d5e0f0247..df561b105 100644 --- a/modules/stormkit/core/meta/type_manipulation.cppm +++ b/modules/stormkit/core/meta/type_manipulation.cppm @@ -32,6 +32,9 @@ namespace stormkit { inline namespace core { namespace meta { template using AddConst = std::add_const_t; + template + using AddConstIf = If, T>; + template using AddVolatile = std::add_volatile_t; From 2d8d733b562a5417ad6b4d3767b8ce84b804b82e Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 10 Mar 2026 22:13:29 +0100 Subject: [PATCH 149/194] (core) missing IsOneOf => IsAnyOf --- modules/stormkit/core/meta.cppm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stormkit/core/meta.cppm b/modules/stormkit/core/meta.cppm index 4693e4746..25353daf5 100644 --- a/modules/stormkit/core/meta.cppm +++ b/modules/stormkit/core/meta.cppm @@ -23,7 +23,7 @@ export namespace stormkit { inline namespace core { namespace meta { template consteval auto find_type_index_of() noexcept -> std::size_t { - static_assert(IsOneOf); + static_assert(IsAnyOf); auto i = 0u; ((not Is and ++i) and ...); return i; From 9bf3f690eec39880c7f90546cfed87c60413d1a3 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 10 Mar 2026 22:13:42 +0100 Subject: [PATCH 150/194] (core) add PointedType type query --- modules/stormkit/core/meta/type_query.cppm | 26 +++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/modules/stormkit/core/meta/type_query.cppm b/modules/stormkit/core/meta/type_query.cppm index e88fc0078..6cf8d8288 100644 --- a/modules/stormkit/core/meta/type_query.cppm +++ b/modules/stormkit/core/meta/type_query.cppm @@ -47,15 +47,38 @@ namespace stormkit { inline namespace core { namespace meta { struct UnderlyingType { using Type = std::underlying_type_t; }; + + template + struct PointedType { + using Type = RemoveReferencesType; + }; + + template + struct PointedType { + using Type = UnderlyingType::Type; + }; + + template + struct PointedType { + using Type = typename std::pointer_traits::element_type; + }; } // namespace details export { + template + using UnderlyingType = details::UnderlyingType::Type; + template using ElementType = typename std::pointer_traits::element_type; template using PointerType = typename std::pointer_traits::pointer; + // clang-format off + template + using PointedType = details::PointedType::Type; + // clang-format on + template using IteratorType = stdr::iterator_t; @@ -74,9 +97,6 @@ namespace stormkit { inline namespace core { namespace meta { template using SafeNarrowHelperOtherType = Select(), V, T>; - template - using UnderlyingType = details::UnderlyingType::Type; - template using ArithmeticOrderingType = Select, std::strong_ordering, std::partial_ordering>; From 6302c8b390e3b8a864904375a9948890103b66ba Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 10 Mar 2026 22:13:58 +0100 Subject: [PATCH 151/194] (core) simplify as_**_ref_** implementation --- modules/stormkit/core/typesafe/ref.cppm | 173 +++++++++++++----------- 1 file changed, 91 insertions(+), 82 deletions(-) diff --git a/modules/stormkit/core/typesafe/ref.cppm b/modules/stormkit/core/typesafe/ref.cppm index d35f03adf..0818d723f 100644 --- a/modules/stormkit/core/typesafe/ref.cppm +++ b/modules/stormkit/core/typesafe/ref.cppm @@ -25,6 +25,14 @@ export { namespace stormkit { inline namespace core { template using ptr = T*; + template + using owned_ptr = T*; + + template + class Ref; + + template + using OptionalRef = Ref; template class Ref { @@ -145,51 +153,51 @@ export { PointerType m_value; - template - friend constexpr auto as_ref(U&&) noexcept -> decltype(auto); + template + friend constexpr auto as_ref(const U&) noexcept -> Ref>; - template - friend constexpr auto as_ref_mut(U&&) noexcept -> decltype(auto); + template + friend constexpr auto as_ref_mut(U&) noexcept -> Ref>; - template - friend constexpr auto as_ref_like(U&&) noexcept -> decltype(auto); + template + friend constexpr auto as_ref_like(U&) noexcept -> Ref, meta::PointedType>>; - template - friend constexpr auto as_opt_ref(U&&) noexcept -> decltype(auto); + template + friend constexpr auto as_opt_ref(const U&) noexcept -> OptionalRef>; - template - friend constexpr auto as_opt_ref_mut(U&&) noexcept -> decltype(auto); + template + friend constexpr auto as_opt_ref_mut(U&) noexcept -> OptionalRef>; - template - friend constexpr auto as_opt_ref_like(U&&) noexcept -> decltype(auto); + template + friend constexpr auto as_opt_ref_like(U&) noexcept + -> OptionalRef, meta::PointedType>>; }; - template - using OptionalRef = Ref; - - template + template [[nodiscard]] - constexpr auto as_ref(T&& value STORMKIT_LIFETIMEBOUND) noexcept -> decltype(auto); + constexpr auto as_ref(const T& value STORMKIT_LIFETIMEBOUND) noexcept -> Ref>; - template + template [[nodiscard]] - constexpr auto as_ref_mut(T&& value STORMKIT_LIFETIMEBOUND) noexcept -> decltype(auto); + constexpr auto as_ref_mut(T& value STORMKIT_LIFETIMEBOUND) noexcept -> Ref>; - template + template [[nodiscard]] - constexpr auto as_ref_like(T&& value STORMKIT_LIFETIMEBOUND) noexcept -> decltype(auto); + constexpr auto as_ref_like(T& value STORMKIT_LIFETIMEBOUND) noexcept + -> Ref, meta::PointedType>>; - template + template [[nodiscard]] - constexpr auto as_opt_ref(T&& value STORMKIT_LIFETIMEBOUND) noexcept -> decltype(auto); + constexpr auto as_opt_ref(const T& value STORMKIT_LIFETIMEBOUND) noexcept -> OptionalRef>; - template + template [[nodiscard]] - constexpr auto as_opt_ref_mut(T&& value STORMKIT_LIFETIMEBOUND) noexcept -> decltype(auto); + constexpr auto as_opt_ref_mut(T& value STORMKIT_LIFETIMEBOUND) noexcept -> OptionalRef>; - template + template [[nodiscard]] - constexpr auto as_opt_ref_like(T&& value STORMKIT_LIFETIMEBOUND) noexcept -> decltype(auto); + constexpr auto as_opt_ref_like(T& value STORMKIT_LIFETIMEBOUND) noexcept + -> OptionalRef, meta::PointedType>>; template [[nodiscard]] @@ -355,7 +363,7 @@ namespace stormkit { inline namespace core { template U, bool OptionalU> requires(not(meta::IsConst and not meta::IsConst)) constexpr auto Ref::operator=(Ref&& other) noexcept -> decltype(auto) { - if constexpr (meta::IsStrict) + if constexpr (meta::IsStrict and Optional == OptionalU) if (&other == this) return *this; m_value = std::exchange(other.m_value, nullptr); @@ -605,103 +613,104 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr auto as_ref(T&& value) noexcept -> decltype(auto) { - using TValue = meta::CanonicalType; - if constexpr (not RAW and meta::IsPointer) { + constexpr auto as_ref(const T& value) noexcept -> Ref> { + using OutRef = Ref>; + + if constexpr (not RAW and meta::IsPointer) { EXPECTS(value != nullptr); - return Ref> { std::to_address(value) }; - } else if constexpr (not RAW and meta::IsContainedSemantics) { + return OutRef { unref(value) }; + } else if constexpr (not RAW and meta::IsContainedSemantics) { EXPECTS(value.operator bool()); - return Ref> { &(value.operator*()) }; + return OutRef { &(value.operator*()) }; } else { - return Ref { &value }; + return OutRef { std::addressof(value) }; } } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr auto as_ref_mut(T&& value) noexcept -> decltype(auto) { - using TValue = meta::CanonicalType; - static constexpr auto error_msg = "as_ref_mut can't take a reference of a const object"sv; - if constexpr (not RAW and meta::IsPointer) { - using PointedType = meta::ElementType; - static_assert(meta::IsNotConst, error_msg); + constexpr auto as_ref_mut(T& value) noexcept -> Ref> { + using OutRef = Ref>; + + if constexpr (not RAW and meta::IsPointer) { EXPECTS(value != nullptr); - return Ref> { std::to_address(value) }; - } else if constexpr (not RAW and meta::IsContainedSemantics) { - using UnderlyingType = meta::UnderlyingType; - static_assert(meta::IsNotConst, error_msg); + return OutRef { unref(value) }; + } else if constexpr (not RAW and meta::IsContainedSemantics) { EXPECTS(value.operator bool()); - return Ref { &(value.operator*()) }; + return OutRef { &(value.operator*()) }; } else { - static_assert(meta::IsNotConst, error_msg); - return Ref { &value }; + return OutRef { std::addressof(value) }; } } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr auto as_ref_like(T&& value) noexcept -> decltype(auto) { - using TValue = meta::CanonicalType; - if constexpr (not RAW and meta::IsPointer) { + constexpr auto as_ref_like(T& value) noexcept -> Ref, meta::PointedType>> { + using OutRef = Ref, meta::PointedType>>; + + if constexpr (not RAW and meta::IsPointer) { EXPECTS(value != nullptr); - return Ref> { std::to_address(value) }; + return OutRef { unref(value) }; } else if constexpr (not RAW and meta::IsContainedSemantics) { EXPECTS(value.operator bool()); - return Ref> { &(value.operator*()) }; + return OutRef { &(value.operator*()) }; } else { - return Ref { &value }; + return OutRef { std::addressof(value) }; } } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr auto as_opt_ref(T&& value) noexcept -> decltype(auto) { - using TValue = meta::CanonicalType; - if constexpr (not RAW and meta::IsPointer) { - return OptionalRef> { std::to_address(value) }; - } else if constexpr (not RAW and meta::IsContainedSemantics) { - return OptionalRef> { &(value.operator*()) }; + constexpr auto as_opt_ref(const T& value) noexcept -> OptionalRef> { + using OutRef = OptionalRef>; + + if constexpr (not RAW and meta::IsPointer) { + return OutRef { unref(value) }; + } else if constexpr (not RAW and meta::IsContainedSemantics) { + return OutRef { &(value.operator*()) }; } else { - return OptionalRef { &value }; + return OutRef { std::addressof(value) }; } } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr auto as_opt_ref_mut(T&& value) noexcept -> decltype(auto) { - using TValue = meta::CanonicalType; - static constexpr auto error_msg = "as_ref_mut can't take a reference of a const object"sv; - if constexpr (not RAW and meta::IsPointer) { - using PointedType = meta::ElementType; - static_assert(meta::IsNotConst, error_msg); - return OptionalRef> { std::to_address(value) }; - } else if constexpr (not RAW and meta::IsContainedSemantics) { - using UnderlyingType = meta::UnderlyingType; - static_assert(meta::IsNotConst, error_msg); - return OptionalRef { &(value.operator*()) }; + constexpr auto as_opt_ref_mut(T& value) noexcept -> OptionalRef> { + using OutRef = OptionalRef>; + + if constexpr (not RAW and meta::IsPointer) { + return OutRef { unref(value) }; + } else if constexpr (not RAW and meta::IsContainedSemantics) { + return OutRef { &(value.operator*()) }; } else { - static_assert(meta::IsNotConst, error_msg); - return OptionalRef { &value }; + return OutRef { std::addressof(value) }; } } ///////////////////////////////////// ///////////////////////////////////// - // template - template + template STORMKIT_FORCE_INLINE - constexpr auto as_opt_ref_like(T&& value) noexcept -> decltype(auto) { + constexpr auto as_opt_ref_like(T& value) noexcept -> OptionalRef, meta::PointedType>> { + using OutRef = OptionalRef, meta::PointedType>>; + if constexpr (not RAW and meta::IsPointer) { + return OutRef { unref(value) }; + } else if constexpr (not RAW and meta::IsContainedSemantics) { + return OutRef { &(value.operator*()) }; + } else { + return OutRef { std::addressof(value) }; + } + using TValue = meta::CanonicalType; if constexpr (not RAW and meta::IsPointer) { return OptionalRef> { std::to_address(value) }; From bc831dbcc761c339f764c88b91307c4a4cc2971f Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 11 Mar 2026 15:20:50 +0100 Subject: [PATCH 152/194] (core) improve Ref --- modules/stormkit/core/typesafe/ref.cppm | 39 ++++++++++++------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/modules/stormkit/core/typesafe/ref.cppm b/modules/stormkit/core/typesafe/ref.cppm index 0818d723f..3fc34dc03 100644 --- a/modules/stormkit/core/typesafe/ref.cppm +++ b/modules/stormkit/core/typesafe/ref.cppm @@ -156,7 +156,8 @@ export { template friend constexpr auto as_ref(const U&) noexcept -> Ref>; - template + template + requires meta::IsNotConst> friend constexpr auto as_ref_mut(U&) noexcept -> Ref>; template @@ -165,7 +166,8 @@ export { template friend constexpr auto as_opt_ref(const U&) noexcept -> OptionalRef>; - template + template + requires meta::IsNotConst> friend constexpr auto as_opt_ref_mut(U&) noexcept -> OptionalRef>; template @@ -177,7 +179,8 @@ export { [[nodiscard]] constexpr auto as_ref(const T& value STORMKIT_LIFETIMEBOUND) noexcept -> Ref>; - template + template + requires meta::IsNotConst> [[nodiscard]] constexpr auto as_ref_mut(T& value STORMKIT_LIFETIMEBOUND) noexcept -> Ref>; @@ -190,7 +193,8 @@ export { [[nodiscard]] constexpr auto as_opt_ref(const T& value STORMKIT_LIFETIMEBOUND) noexcept -> OptionalRef>; - template + template + requires meta::IsNotConst> [[nodiscard]] constexpr auto as_opt_ref_mut(T& value STORMKIT_LIFETIMEBOUND) noexcept -> OptionalRef>; @@ -620,7 +624,7 @@ namespace stormkit { inline namespace core { if constexpr (not RAW and meta::IsPointer) { EXPECTS(value != nullptr); - return OutRef { unref(value) }; + return OutRef { std::addressof(*value) }; } else if constexpr (not RAW and meta::IsContainedSemantics) { EXPECTS(value.operator bool()); return OutRef { &(value.operator*()) }; @@ -631,14 +635,15 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template + template + requires meta::IsNotConst> STORMKIT_FORCE_INLINE constexpr auto as_ref_mut(T& value) noexcept -> Ref> { using OutRef = Ref>; if constexpr (not RAW and meta::IsPointer) { EXPECTS(value != nullptr); - return OutRef { unref(value) }; + return OutRef { std::addressof(*value) }; } else if constexpr (not RAW and meta::IsContainedSemantics) { EXPECTS(value.operator bool()); return OutRef { &(value.operator*()) }; @@ -656,7 +661,7 @@ namespace stormkit { inline namespace core { if constexpr (not RAW and meta::IsPointer) { EXPECTS(value != nullptr); - return OutRef { unref(value) }; + return OutRef { std::addressof(*value) }; } else if constexpr (not RAW and meta::IsContainedSemantics) { EXPECTS(value.operator bool()); return OutRef { &(value.operator*()) }; @@ -673,7 +678,7 @@ namespace stormkit { inline namespace core { using OutRef = OptionalRef>; if constexpr (not RAW and meta::IsPointer) { - return OutRef { unref(value) }; + return OutRef { std::addressof(*value) }; } else if constexpr (not RAW and meta::IsContainedSemantics) { return OutRef { &(value.operator*()) }; } else { @@ -683,13 +688,14 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template + template + requires meta::IsNotConst> STORMKIT_FORCE_INLINE constexpr auto as_opt_ref_mut(T& value) noexcept -> OptionalRef> { using OutRef = OptionalRef>; if constexpr (not RAW and meta::IsPointer) { - return OutRef { unref(value) }; + return OutRef { std::addressof(*value) }; } else if constexpr (not RAW and meta::IsContainedSemantics) { return OutRef { &(value.operator*()) }; } else { @@ -704,21 +710,12 @@ namespace stormkit { inline namespace core { constexpr auto as_opt_ref_like(T& value) noexcept -> OptionalRef, meta::PointedType>> { using OutRef = OptionalRef, meta::PointedType>>; if constexpr (not RAW and meta::IsPointer) { - return OutRef { unref(value) }; + return OutRef { std::addressof(*value) }; } else if constexpr (not RAW and meta::IsContainedSemantics) { return OutRef { &(value.operator*()) }; } else { return OutRef { std::addressof(value) }; } - - using TValue = meta::CanonicalType; - if constexpr (not RAW and meta::IsPointer) { - return OptionalRef> { std::to_address(value) }; - } else if constexpr (not RAW and meta::IsContainedSemantics) { - return OptionalRef> { &(value.get()) }; - } else { - return OptionalRef { &value }; - } } ///////////////////////////////////// From 2adb5af225a5f730c310f7c213200b03fca2c999 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 11 Mar 2026 15:21:12 +0100 Subject: [PATCH 153/194] (entities) format --- modules/stormkit/entities.cppm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/stormkit/entities.cppm b/modules/stormkit/entities.cppm index 09c9dd065..fd5e71a54 100644 --- a/modules/stormkit/entities.cppm +++ b/modules/stormkit/entities.cppm @@ -109,7 +109,7 @@ export namespace stormkit::entities { using ComponentTypes = std::vector; using PreUpdateClosure = std::function; - using UpdateClosure = std::function; + using UpdateClosure = std::function; using PostUpdateClosure = std::function; using OnMessageReceived = std::function; From 0aa1db391184d3d0074eff5c8b423b49e46053d8 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 11 Mar 2026 15:21:33 +0100 Subject: [PATCH 154/194] (core) fix locked unsafe() when using a ContainerSemantics type --- modules/stormkit/core/parallelism/locked.cppm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/stormkit/core/parallelism/locked.cppm b/modules/stormkit/core/parallelism/locked.cppm index f8ce56343..5cc419859 100644 --- a/modules/stormkit/core/parallelism/locked.cppm +++ b/modules/stormkit/core/parallelism/locked.cppm @@ -32,7 +32,7 @@ export namespace stormkit { inline namespace core { template class STORMKIT_CORE_API Locked { public: - using ValueType = T; + using ValueType = meta::PointedType; using ReferenceType = ValueType&; using ConstReferenceType = const ValueType&; using PointerType = ValueType*; @@ -90,7 +90,7 @@ export namespace stormkit { inline namespace core { LockArgs&&... lock_args) noexcept(noexcept(std::is_nothrow_assignable_v)) -> void; template - auto unsafe(this Self& self) noexcept -> meta::ForwardConst&; + auto unsafe(this Self& self) noexcept -> meta::ForwardConst&; auto mutex() const noexcept -> const MutexType&; @@ -123,8 +123,8 @@ export namespace stormkit { inline namespace core { RefContainerType m_value; }; - mutable Mutex m_mutex; - ValueType m_value STORMKIT_GUARDED_BY(m_mutex); + mutable Mutex m_mutex; + T m_value STORMKIT_GUARDED_BY(m_mutex); }; template @@ -248,7 +248,7 @@ namespace stormkit { inline namespace core { template template STORMKIT_FORCE_INLINE - auto Locked::unsafe(this Self& self) noexcept -> meta::ForwardConst& { + auto Locked::unsafe(this Self& self) noexcept -> meta::ForwardConst& { return std::forward_like(self.m_value); } From 21c2f7d7d0b8aedaa0bd3100cdae429671203743 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 11 Mar 2026 18:28:34 +0100 Subject: [PATCH 155/194] (lua) handle lua errors --- src/lua/lua.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/lua/lua.cpp b/src/lua/lua.cpp index ea1386df6..142b11628 100644 --- a/src/lua/lua.cpp +++ b/src/lua/lua.cpp @@ -66,7 +66,8 @@ namespace stormkit::lua { init_libraries(state); m_init_user_libraries(state); - state.do_string(std::string_view { stdr::data(m_script), stdr::size(m_script) }); + auto result = state.do_string(std::string_view { stdr::data(m_script), stdr::size(m_script) }); + if (not result.valid()) elog("lua error!\n{}", sol::error { result }.what()); return state; } @@ -140,7 +141,7 @@ namespace stormkit::lua { core::init_lua(global_state); if (m_modules.log) { #if STORMKIT_LIB_LOG_ENABLED - dlog("Log module enabled"); + dlog("Log module enabled."); log::init_lua(global_state); #else elog("Trying to bind log module while disabled in this stormkit distribution!"); @@ -148,7 +149,7 @@ namespace stormkit::lua { } if (m_modules.entities) { #if STORMKIT_LIB_ENTITIES_ENABLED - dlog("Entities module enabled"); + dlog("Entities module enabled."); entities::init_lua(global_state); #else elog("Trying to bind entities module while disabled in this stormkit distribution!"); @@ -156,7 +157,7 @@ namespace stormkit::lua { } if (m_modules.image) { #if STORMKIT_LIB_IMAGE_ENABLED - dlog("Image module enabled"); + dlog("Image module enabled."); image::init_lua(global_state); #else elog("Trying to bind image module while disabled in this stormkit distribution!"); @@ -164,7 +165,7 @@ namespace stormkit::lua { } if (m_modules.wsi) { #if STORMKIT_LIB_WSI_ENABLED - dlog("Wsi module enabled"); + dlog("Wsi module enabled."); wsi::init_lua(global_state); #else elog("Trying to bind wsi module while disabled in this stormkit distribution!"); @@ -172,7 +173,7 @@ namespace stormkit::lua { } if (m_modules.gpu) { #if STORMKIT_LIB_GPU_ENABLED - dlog("Gpu module enabled"); + dlog("Gpu module enabled."); gpu::init_lua(global_state); #else elog("Trying to bind gpu module while disabled in this stormkit distribution!"); From 6196e3760a70fbd8fed9e8d3ecde5f7579ea5988 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 15 Mar 2026 15:53:32 +0100 Subject: [PATCH 156/194] (core) improve try_expected --- include/stormkit/core/try_expected.hpp | 30 ++++++++++++++++++++------ 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/include/stormkit/core/try_expected.hpp b/include/stormkit/core/try_expected.hpp index 7d82b0159..2d75b9f23 100644 --- a/include/stormkit/core/try_expected.hpp +++ b/include/stormkit/core/try_expected.hpp @@ -20,27 +20,43 @@ t(std::move(res).error()); \ std::move(res).value(); \ }) + #define TryTransformError(m, t) \ + ({ \ + auto res = (m); \ + if (not res.has_value()) [[unlikely]] \ + return std::unexpected { t(std::move(res).error()) }; \ + std::move(res).value(); \ + }) + #define TryDiscard(m) \ ({ \ auto res = (m).transform(stormkit::core::monadic::discard()); \ if (not res.has_value()) [[unlikely]] \ return std::unexpected { std::move(res).error() }; \ }) - #define TryOrDiscard(m, t) \ + #define TryDiscardOr(m, t) \ ({ \ auto res = (m).transform(stormkit::core::monadic::discard()); \ if (not res.has_value()) [[unlikely]] \ t(std::move(res).error()); \ }) + #define TryDiscardTransformError(m, t) \ + ({ \ + auto res = (m).transform(stormkit::core::monadic::discard()); \ + if (not res.has_value()) [[unlikely]] \ + return std::unexpected { t(std::move(res).error()) }; \ + }) #define Return return #else - #define Try(m) co_await m - #define TryOr(m, t) co_await t(co_await m) - #define TryDiscard(m) co_await m.transform(stormkit::core::monadic::discard()) - #define TryOrDiscard(m, t) co_await m.transform(stormkit::core::monadic::discard()) - #define Return co_return + #define Try(m) co_await m + #define TryOr(m, t) co_await m.transform_error(t) + #define TryTransformError(m, t) TryOr(m, t) + #define TryDiscard(m) co_await m.transform(stormkit::core::monadic::discard()) + #define TryDiscardOr(m, t) co_await m.transform(stormkit::core::monadic::discard()).transform_error(t) + #define TryDiscardTransformError(m, t) TryDiscardOr(m, t) + #define Return co_return #endif #define TryAssert(m, msg) TryOr(m, stormkit::core::monadic::assert(msg)) -#define TryAssertDiscard(m, msg) TryOrDiscard(m, stormkit::core::monadic::assert(msg)) +#define TryDiscardAssert(m, msg) TryDiscardOr(m, stormkit::core::monadic::assert(msg)) #endif From 329bd9791f76eadb22bc295d46dfa4173fde304a Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 15 Mar 2026 15:53:59 +0100 Subject: [PATCH 157/194] (core) move signal_handlers in a TU --- .../stormkit/core/utils/signal_handler.cppm | 29 ---------------- src/core/signal_handler.cpp | 34 +++++++++++++++++++ 2 files changed, 34 insertions(+), 29 deletions(-) create mode 100644 src/core/signal_handler.cpp diff --git a/modules/stormkit/core/utils/signal_handler.cppm b/modules/stormkit/core/utils/signal_handler.cppm index 1b310b09f..46701b71c 100644 --- a/modules/stormkit/core/utils/signal_handler.cppm +++ b/modules/stormkit/core/utils/signal_handler.cppm @@ -1,39 +1,10 @@ module; #include -#include - -#include export module stormkit.core:utils.signal_handler; -import std; -import :utils.stracktrace; - export namespace stormkit { inline namespace core { STORMKIT_CORE_API auto setup_signal_handler() noexcept -> void; }} // namespace stormkit::core - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit { inline namespace core { - extern "C" auto terminate_handler() noexcept -> void { - print_stacktrace(3); - } - - extern "C" auto signalHandler(int signum) noexcept -> void { - std::signal(signum, SIG_DFL); - print_stacktrace(3); - std::raise(SIGABRT); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto setup_signal_handler() noexcept -> void { - std::set_terminate(&terminate_handler); - std::signal(SIGSEGV, &signalHandler); - } -}} // namespace stormkit::core diff --git a/src/core/signal_handler.cpp b/src/core/signal_handler.cpp new file mode 100644 index 000000000..edb8efe36 --- /dev/null +++ b/src/core/signal_handler.cpp @@ -0,0 +1,34 @@ +module; + +#include +#include + +#include + +module stormkit.core; + +import std; +import :utils.stracktrace; + +namespace stormkit { inline namespace core { + ///////////////////////////////////// + ///////////////////////////////////// + extern "C" auto terminate_handler() noexcept -> void { + print_stacktrace(3); + } + + ///////////////////////////////////// + ///////////////////////////////////// + extern "C" auto signal_handler(int signum) noexcept -> void { + std::signal(signum, SIG_DFL); + print_stacktrace(3); + std::raise(SIGABRT); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto setup_signal_handler() noexcept -> void { + std::set_terminate(&terminate_handler); + std::signal(SIGSEGV, &signal_handler); + } +}} // namespace stormkit::core From 434ea20cd8df9786fc295f68474e927fa17747c4 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 15 Mar 2026 15:54:20 +0100 Subject: [PATCH 158/194] (core) containers algorithms --- modules/stormkit/core/utils/algorithms.cppm | 84 +++++++++------------ 1 file changed, 34 insertions(+), 50 deletions(-) diff --git a/modules/stormkit/core/utils/algorithms.cppm b/modules/stormkit/core/utils/algorithms.cppm index 4f6276093..17bb0e4a3 100644 --- a/modules/stormkit/core/utils/algorithms.cppm +++ b/modules/stormkit/core/utils/algorithms.cppm @@ -8,25 +8,28 @@ import std; import :meta; +namespace stdr = std::ranges; +namespace stdv = std::views; + export namespace stormkit { inline namespace core { - template::value_type> Predicate> + template::value_type> Predicate> [[nodiscard]] - constexpr auto copy_if(Range&& input, Predicate&& predicate) noexcept; + constexpr auto copy_if(Range&& input, Predicate&& predicate) noexcept -> decltype(auto); - template::value_type&> Lambda> + template::value_type&> Lambda> [[nodiscard]] - constexpr auto transform(Range&& input, Lambda&& lambda) noexcept; + constexpr auto transform(Range&& input, Lambda&& lambda) noexcept -> decltype(auto); - template::value_type> Predicate, - std::invocable::value_type&> Lambda> + template::value_type> Predicate, + std::invocable::value_type&> Lambda> [[nodiscard]] - constexpr auto transform_if(Range&& input, Predicate&& predicate, Lambda&& lambda) noexcept; + constexpr auto transform_if(Range&& input, Predicate&& predicate, Lambda&& lambda) noexcept -> decltype(auto); - template::value_type> Predicate, - std::invocable::value_type&> Lambda, - std::output_iterator::value_type&>> Iterator> + template::value_type> Predicate, + std::invocable::value_type&> Lambda, + std::output_iterator::value_type&>> Iterator> constexpr auto transform_if(Range&& input, Iterator&& it, Predicate&& predicate, Lambda&& lambda) noexcept -> void; }} // namespace stormkit::core @@ -37,57 +40,38 @@ export namespace stormkit { inline namespace core { namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template::value_type> Predicate> - constexpr auto copy_if(Range&& input, Predicate&& predicate) noexcept { - auto output = std::vector::value_type> {}; - - output.reserve(std::size(input)); - - std::ranges::copy_if(input, std::back_inserter(output), std::forward(predicate)); - - return output; - + template::value_type> Predicate> + constexpr auto copy_if(Range&& input, Predicate&& predicate) noexcept -> decltype(auto) { + return std::forward(input) | stdv::filter(std::forward(predicate)) | stdr::to(); } ///////////////////////////////////// ///////////////////////////////////// - template::value_type&> Lambda> - constexpr auto transform(Range&& input, Lambda&& lambda) noexcept { - auto output = std::vector< - std::invoke_result_t, const typename std::remove_cvref_t::value_type&>> {}; - output.reserve(std::size(input)); - - std::ranges::transform(input, std::back_inserter(output), lambda); - - return output; + template::value_type&> Lambda> + constexpr auto transform(Range&& input, Lambda&& lambda) noexcept -> decltype(auto) { + return std::forward(input) | stdv::transform(lambda) | stdr::to(); } ///////////////////////////////////// ///////////////////////////////////// - template::value_type> Predicate, - std::invocable::value_type&> Lambda> - constexpr auto transform_if(Range&& input, Predicate&& predicate, Lambda&& lambda) noexcept { - auto output = std::vector< - std::invoke_result_t, const typename std::remove_cvref_t::value_type&>> {}; - output.reserve(std::size(input)); - - std::ranges::for_each(input, [&](auto& elem) { - if (predicate(elem)) output.emplace_back(lambda(elem)); - }); - - return output; - + template::value_type> Predicate, + std::invocable::value_type&> Lambda> + constexpr auto transform_if(Range&& input, Predicate&& predicate, Lambda&& lambda) noexcept -> decltype(auto) { + return std::forward(input) + | stdv::filter(std::forward(predicate)) + | stdv::transform(std::forward(lambda)) + | stdr::to(); } ///////////////////////////////////// ///////////////////////////////////// - template::value_type> Predicate, - std::invocable::value_type&> Lambda, - std::output_iterator::value_type&>> Iterator> + template::value_type> Predicate, + std::invocable::value_type&> Lambda, + std::output_iterator::value_type&>> Iterator> constexpr auto transform_if(Range&& input, Iterator&& it, Predicate&& predicate, Lambda&& lambda) noexcept -> void { - std::ranges::for_each(input, [&](auto& elem) { + stdr::for_each(std::forward(input), [&it, &predicate, &lambda](auto&& elem) { if (predicate(elem)) *it++ = lambda(elem); }); } From 48fcd2488de4b9556dff0bd2157ae8faed304dc4 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 15 Mar 2026 15:54:34 +0100 Subject: [PATCH 159/194] (core) improve to/from bytes --- modules/stormkit/core/typesafe/byte.cppm | 40 ++++++++++++++++++++---- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/modules/stormkit/core/typesafe/byte.cppm b/modules/stormkit/core/typesafe/byte.cppm index 0ecf4ca90..ad7fb4d94 100644 --- a/modules/stormkit/core/typesafe/byte.cppm +++ b/modules/stormkit/core/typesafe/byte.cppm @@ -56,7 +56,7 @@ export namespace stormkit { inline namespace core { [[nodiscard]] constexpr auto as_bytes(const T* const ptr, usize size = 1) noexcept -> std::span; - template + template [[nodiscard]] constexpr auto as_bytes(const Range& range) noexcept -> std::span; @@ -73,7 +73,7 @@ export namespace stormkit { inline namespace core { constexpr auto as_bytes_mut(std::span container) noexcept -> std::span()>; - template + template [[nodiscard]] constexpr auto as_bytes_mut(Range& range) noexcept -> std::span; @@ -85,11 +85,16 @@ export namespace stormkit { inline namespace core { [[nodiscard]] constexpr auto as_bytes_mut(T& value) noexcept -> std::span; - template + template [[nodiscard]] constexpr auto bytes_as(std::span bytes) noexcept -> const T&; - template + template + requires(meta::SameAs>, byte>) + [[nodiscard]] + constexpr auto bytes_as_span(const Range& bytes) noexcept -> std::span; + + template [[nodiscard]] constexpr auto bytes_as_span(std::span bytes) noexcept -> std::span; @@ -98,6 +103,11 @@ export namespace stormkit { inline namespace core { [[nodiscard]] constexpr auto bytes_mut_as(std::span bytes) noexcept -> T&; + template + requires(meta::SameAs, byte> and not meta::IsConst) + [[nodiscard]] + constexpr auto bytes_mut_as_span(Range& range) noexcept -> std::span; + template [[nodiscard]] constexpr auto bytes_mut_as_span(std::span bytes) noexcept @@ -181,7 +191,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE constexpr auto as_bytes(const Range& range) noexcept -> std::span { return as_bytes(std::span { range }); @@ -212,7 +222,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE constexpr auto as_bytes_mut(Range& range) noexcept -> std::span { return as_bytes_mut(std::span { range }); @@ -244,6 +254,15 @@ namespace stormkit { inline namespace core { return *std::bit_cast(stdr::data(bytes)); } + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(meta::SameAs>, byte>) + STORMKIT_FORCE_INLINE + constexpr auto bytes_as_span(const Range& bytes) noexcept -> std::span { + return std::span { std::bit_cast(stdr::data(bytes)), stdr::size(bytes) / sizeof(T) }; + } + ///////////////////////////////////// ///////////////////////////////////// template @@ -267,6 +286,15 @@ namespace stormkit { inline namespace core { return *std::bit_cast(stdr::data(bytes)); } + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(meta::SameAs, byte> and not meta::IsConst) + STORMKIT_FORCE_INLINE + constexpr auto bytes_mut_as_span(Range& bytes) noexcept -> std::span { + return std::span { std::bit_cast(stdr::data(bytes)), stdr::size(bytes) / sizeof(T) }; + } + ///////////////////////////////////// ///////////////////////////////////// template From 37365c05ff2a3d63a72ecfca190e3897b56970f8 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 15 Mar 2026 15:54:45 +0100 Subject: [PATCH 160/194] (core) constrain more IsContainedSemantics --- modules/stormkit/core/meta/concepts.cppm | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/stormkit/core/meta/concepts.cppm b/modules/stormkit/core/meta/concepts.cppm index e1417e0a2..8f6a8ecf5 100644 --- a/modules/stormkit/core/meta/concepts.cppm +++ b/modules/stormkit/core/meta/concepts.cppm @@ -223,6 +223,7 @@ export namespace stormkit { inline namespace core { namespace meta { concept IsContainedSemantics = requires(T& val) { typename T::value_type; { val.operator*() } -> IsReferenceTo; + { val.operator->() } -> IsReferenceTo; }; template class T> From 75adc2b569cf452f5abb4bdae698cc3d2bd8214d Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 15 Mar 2026 15:54:58 +0100 Subject: [PATCH 161/194] (core) improve monadic::assert --- modules/stormkit/core/functional/error_handling.cppm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/stormkit/core/functional/error_handling.cppm b/modules/stormkit/core/functional/error_handling.cppm index 5b81d8963..44e1a82f7 100644 --- a/modules/stormkit/core/functional/error_handling.cppm +++ b/modules/stormkit/core/functional/error_handling.cppm @@ -48,8 +48,8 @@ namespace stormkit { inline namespace core { namespace monadic { template STORMKIT_FORCE_INLINE constexpr auto assert(std::optional message, std::source_location location) noexcept -> decltype(auto) { - return [message = std::move(message), location = std::move(location)] NORETURN_LAMBDA() -> T { - if (message.has_value()) core::assert(false, *message, std::move(location)); + return [message = std::move(message), location = std::move(location)] NORETURN_LAMBDA(const E& error) -> T { + if (message.has_value()) core::assert(false, std::format("{} ({})", *message, error), std::move(location)); else core::assert(false, std::move(location)); From 90b8f92b4e226eabcb4b1daad82a02b2c573f5ab Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 15 Mar 2026 15:55:11 +0100 Subject: [PATCH 162/194] (core) improve into_array_of --- modules/stormkit/core/containers/utils.cppm | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/modules/stormkit/core/containers/utils.cppm b/modules/stormkit/core/containers/utils.cppm index 1ab6b2c3e..78f881b11 100644 --- a/modules/stormkit/core/containers/utils.cppm +++ b/modules/stormkit/core/containers/utils.cppm @@ -170,10 +170,7 @@ namespace stormkit { inline namespace core { STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto into_array_of(Args&&... args) noexcept -> std::array { - static_assert((not meta::IsLValueReference and ...), - "lvalue reference can't be passed to into_ functions as it take " - "ownership"); - return std::array { std::move(args)... }; + return std::array { T { std::move(args) }... }; } ///////////////////////////////////// @@ -194,10 +191,7 @@ namespace stormkit { inline namespace core { requires(sizeof...(Args) > 0) STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto into_dyn_array_of(Args&&... args) noexcept -> std::vector { - static_assert((not meta::IsLValueReference and ...), - "lvalue reference can't be passed to into_ functions as it take " - "ownership"); - return std::vector { std::move(args)... }; + return std::vector { T { std::move(args) }... }; } ///////////////////////////////////// From 25e188feda7dcbfbb7106dbc9de7dde7db01994d Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Sun, 15 Mar 2026 15:55:19 +0100 Subject: [PATCH 163/194] (core) add COntainedOrPointerOf concept --- modules/stormkit/core/typesafe/ref.cppm | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/stormkit/core/typesafe/ref.cppm b/modules/stormkit/core/typesafe/ref.cppm index 3fc34dc03..406ecd5a5 100644 --- a/modules/stormkit/core/typesafe/ref.cppm +++ b/modules/stormkit/core/typesafe/ref.cppm @@ -23,6 +23,11 @@ import :hash; export { namespace stormkit { inline namespace core { + namespace meta { + template + concept ContainedOrPointerOf = (IsContainedSemantics or IsPointer) and SameAs>; + } + template using ptr = T*; template From a9b3370164e753542f86e22cdb8826cd78bd6533 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 16 Mar 2026 14:43:53 +0100 Subject: [PATCH 164/194] (core) proper use of ValueType --- examples/entities/gameoflife/src/Renderer.cpp | 83 +- examples/gpu/common/app.cppm | 61 +- examples/gpu/imgui/src/main.cpp | 20 +- examples/gpu/textured_cube/src/main.cpp | 74 +- examples/gpu/triangle/src/main.cpp | 22 +- modules/stormkit/core/containers/dag.cppm | 2 + .../core/containers/raii_capsule.cppm | 41 +- .../stormkit/core/containers/shmbuffer.cppm | 4 +- modules/stormkit/core/math/extent.cppm | 56 +- modules/stormkit/core/math/geometry.cppm | 28 +- modules/stormkit/core/math/linear-matrix.cppm | 97 +- modules/stormkit/core/math/linear-vector.cppm | 96 +- modules/stormkit/core/utils/deferinit.cppm | 43 +- modules/stormkit/gpu/core.cppm | 6 +- modules/stormkit/gpu/core/base.cppm | 403 +++ modules/stormkit/gpu/core/debug_callback.cppm | 92 + modules/stormkit/gpu/core/device.cppm | 508 ++-- modules/stormkit/gpu/core/instance.cppm | 417 ++-- .../stormkit/gpu/core/physical_device.cppm | 408 +++ modules/stormkit/gpu/core/surface.cppm | 135 + modules/stormkit/gpu/core/sync.cppm | 262 +- modules/stormkit/gpu/core/vulkan/enums.cppm | 430 ++-- .../stormkit/gpu/core/vulkan/enums.cppm.tpl | 68 +- modules/stormkit/gpu/core/vulkan/mapping.json | 3 +- modules/stormkit/gpu/core/vulkan/structs.cppm | 10 +- modules/stormkit/gpu/core/vulkan/utils.cppm | 564 +++-- .../gpu/execution/command_buffer.cppm | 1248 ++++++---- .../stormkit/gpu/execution/descriptors.cppm | 112 +- modules/stormkit/gpu/execution/pipeline.cppm | 170 +- .../stormkit/gpu/execution/render_pass.cppm | 406 +-- modules/stormkit/gpu/execution/swapchain.cppm | 186 +- modules/stormkit/gpu/resource/buffer.cppm | 409 ++- modules/stormkit/gpu/resource/image.cppm | 707 ++++-- modules/stormkit/gpu/resource/shader.cppm | 251 +- src/gpu/core/debug_callback.cpp | 49 + src/gpu/core/device.cpp | 602 ++--- src/gpu/core/fence.cpp | 122 + src/gpu/core/instance.cpp | 276 +- src/gpu/core/loader.cpp | 2 +- src/gpu/core/physical_device.cpp | 710 ++++-- src/gpu/core/semaphore.cpp | 37 + src/gpu/core/surface.cpp | 43 +- src/gpu/execution/command_buffer.cpp | 2215 +++++++++++++---- src/gpu/execution/command_pool.cpp | 152 +- src/gpu/execution/frame_buffer.cpp | 50 + src/gpu/execution/pipeline.cpp | 71 +- src/gpu/execution/pipeline_cache.cpp | 34 +- src/gpu/execution/queue.cpp | 342 ++- src/gpu/execution/render_pass.cpp | 54 +- src/gpu/execution/swapchain.cpp | 275 +- src/gpu/resource/buffer.cpp | 193 +- src/gpu/resource/image.cpp | 88 +- src/gpu/resource/image_view.cpp | 57 + src/gpu/resource/sampler.cpp | 50 + src/gpu/resource/shader.cpp | 24 + src/wsi/linux/wayland/window.cpp | 6 +- 56 files changed, 8400 insertions(+), 4474 deletions(-) create mode 100644 modules/stormkit/gpu/core/base.cppm create mode 100644 modules/stormkit/gpu/core/debug_callback.cppm create mode 100644 modules/stormkit/gpu/core/physical_device.cppm create mode 100644 modules/stormkit/gpu/core/surface.cppm create mode 100644 src/gpu/core/debug_callback.cpp create mode 100644 src/gpu/core/fence.cpp create mode 100644 src/gpu/core/semaphore.cpp create mode 100644 src/gpu/execution/frame_buffer.cpp create mode 100644 src/gpu/resource/image_view.cpp create mode 100644 src/gpu/resource/sampler.cpp diff --git a/examples/entities/gameoflife/src/Renderer.cpp b/examples/entities/gameoflife/src/Renderer.cpp index c2f88aa74..6aa4e4520 100644 --- a/examples/entities/gameoflife/src/Renderer.cpp +++ b/examples/entities/gameoflife/src/Renderer.cpp @@ -38,8 +38,8 @@ auto Renderer::renderFrame() -> void { const auto viewports = [&] { auto v = std::vector {}; v.emplace_back(gpu::Viewport { - .extent = surface_extentf, - .depth = { 0, 1 } + .extent = surface_extentf, + .depth = { 0, 1 } }); return v; @@ -88,14 +88,12 @@ auto Renderer::updateBoard(const stormkit::image::Image& board) -> void { if (m_current_fence) m_current_fence->wait(); - const auto descriptors = into_array(gpu::Descriptor { - gpu::ImageDescriptor { .type = gpu::DescriptorType::Combined_Image_Sampler, - .binding = 0, - .layout = gpu::ImageLayout::Shader_Read_Only_Optimal, - .image_view - = makeConstObserver(m_board.image_views[m_board.current_image]), - .sampler = makeConstObserver(m_board.sampler) } - }); + const auto descriptors = into_array_of(gpu::ImageDescriptor { + .type = gpu::DescriptorType::Combined_Image_Sampler, + .binding = 0, + .layout = gpu::ImageLayout::Shader_Read_Only_Optimal, + .image_view = makeConstObserver(m_board.image_views[m_board.current_image]), + .sampler = makeConstObserver(m_board.sampler) }); m_board.descriptor_set->update(descriptors); } @@ -122,9 +120,7 @@ auto Renderer::do_initBaseRenderObjects() -> void { const auto& physical_device_info = physical_device.info(); - ilog("Using physical device {} ({:#06x})", - physical_device_info.device_name, - physical_device_info.device_id); + ilog("Using physical device {} ({:#06x})", physical_device_info.device_name, physical_device_info.device_id); m_device = physical_device.allocateLogicalDevice(); @@ -141,44 +137,41 @@ auto Renderer::do_initMeshRenderObjects() -> void { m_board.vertex_shader = m_device->allocateShader(SHADER_DATA, gpu::ShaderStageFlag::Vertex); m_board.fragment_shader = m_device->allocateShader(SHADER_DATA, gpu::ShaderStageFlag::Fragment); - const auto description - = gpu::RenderPassDescription { .attachments = { { .format = m_surface->pixelFormat() } }, - .subpasses - = { { .bind_point = gpu::PipelineBindPoint::Graphics, - .attachment_refs = { { .attachment_id = 0u } } } } }; + const auto description = gpu::RenderPassDescription { + .attachments = { { .format = m_surface->pixelFormat() } }, + .subpasses = { { .bind_point = gpu::PipelineBindPoint::Graphics, .attachment_refs = { { .attachment_id = 0u } } } } + }; m_descriptor_set_layout = m_device->allocateDescriptorSetLayout(); - m_descriptor_set_layout->addBinding({ .binding = 0, - .type = gpu::DescriptorType::Combined_Image_Sampler, - .stages = gpu::ShaderStageFlag::Fragment, - .descriptor_count = 1 }); + m_descriptor_set_layout + ->addBinding({ .binding = 0, + .type = gpu::DescriptorType::Combined_Image_Sampler, + .stages = gpu::ShaderStageFlag::Fragment, + .descriptor_count = 1 }); m_descriptor_set_layout->bake(); m_descriptor_pool = m_device->allocateDescriptorPool( - std::array { - gpu::DescriptorPool::Size { gpu::DescriptorType::Combined_Image_Sampler, 1 } + std::array { + gpu::DescriptorPool::Size { gpu::DescriptorType::Combined_Image_Sampler, 1 } }, - 1); + 1); m_render_pass = m_device->allocateRenderPass(description); m_board.pipeline = m_device->allocateRasterPipeline(); const auto state = gpu::RasterPipelineState { .input_assembly_state = { .topology = gpu::PrimitiveTopology::Triangle_Strip }, - .viewport_state - = { .viewports = { gpu::Viewport { .position = { 0.f, 0.f }, - .extent = surface_extentf, - .depth = { 0.f, 1.f } } }, + .viewport_state = { .viewports = { gpu::Viewport { .position = { 0.f, 0.f }, + .extent = surface_extentf, + .depth = { 0.f, 1.f } } }, .scissors = { gpu::Scissor { .offset = { 0, 0 }, .extent = surface_extent } } }, - .color_blend_state - = { .attachments = { { .blend_enable = true, - .src_color_blend_factor = gpu::BlendFactor::Src_Alpha, - .dst_color_blend_factor = gpu::BlendFactor::One_Minus_Src_Alpha, - .src_alpha_blend_factor = gpu::BlendFactor::Src_Alpha, - .dst_alpha_blend_factor = gpu::BlendFactor::One_Minus_Src_Alpha, - .alpha_blend_operation = gpu::BlendOperation::Add } } }, - .dynamic_state = { { gpu::DynamicState::Viewport, gpu::DynamicState::Scissor } }, - .shader_state - = { .shaders = makeConstObserverArray(m_board.vertex_shader, m_board.fragment_shader) }, + .color_blend_state = { .attachments = { { .blend_enable = true, + .src_color_blend_factor = gpu::BlendFactor::Src_Alpha, + .dst_color_blend_factor = gpu::BlendFactor::One_Minus_Src_Alpha, + .src_alpha_blend_factor = gpu::BlendFactor::Src_Alpha, + .dst_alpha_blend_factor = gpu::BlendFactor::One_Minus_Src_Alpha, + .alpha_blend_operation = gpu::BlendOperation::Add } } }, + .dynamic_state = { { gpu::DynamicState::Viewport, gpu::DynamicState::Scissor } }, + .shader_state = { .shaders = makeConstObserverArray(m_board.vertex_shader, m_board.fragment_shader) }, /*.vertex_input_state = { .binding_descriptions = to_dyn_array(MESH_VERTEX_BINDING_DESCRIPTIONS), .input_attribute_descriptions = @@ -193,17 +186,17 @@ auto Renderer::do_initMeshRenderObjects() -> void { for (auto i : range(BOARD_BUFFERING_COUNT)) { auto& img = m_board.images.emplace_back(*m_device, gpu::Image::CreateInfo { - .extent = { BOARD_SIZE, BOARD_SIZE } + .extent = { BOARD_SIZE, BOARD_SIZE } }); m_board.image_views.emplace_back(img.createView()); } - m_board.sampler = m_device->allocateSampler( - gpu::Sampler::Settings { .mag_filter = gpu::Filter::Nearest, - .min_filter = gpu::Filter::Nearest, - .address_mode_u = gpu::SamplerAddressMode::Clamp_To_Edge, - .address_mode_v = gpu::SamplerAddressMode::Clamp_To_Edge }); + m_board.sampler = m_device->allocateSampler(gpu::Sampler::Settings { + .mag_filter = gpu::Filter::Nearest, + .min_filter = gpu::Filter::Nearest, + .address_mode_u = gpu::SamplerAddressMode::Clamp_To_Edge, + .address_mode_v = gpu::SamplerAddressMode::Clamp_To_Edge }); m_board.descriptor_set = m_descriptor_pool->allocateDescriptorSet(*m_descriptor_set_layout); diff --git a/examples/gpu/common/app.cppm b/examples/gpu/common/app.cppm index d15edbf5e..4b9c46894 100644 --- a/examples/gpu/common/app.cppm +++ b/examples/gpu/common/app.cppm @@ -4,8 +4,13 @@ module; +#include #include +#include + +#include + export module gpu_app; import std; @@ -18,6 +23,26 @@ using namespace stormkit; namespace stdr = std::ranges; namespace stdv = std::views; +NAMED_LOGGER(vulkan_logger, "vulkan") + +extern "C" auto debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, + VkDebugUtilsMessageTypeFlagsEXT, + const VkDebugUtilsMessengerCallbackDataEXT* callback_data, + void*) noexcept -> u32 { + EXPECTS(callback_data); + auto message = std::format("{}", callback_data->pMessage); + + if (check_flag_bit(severity, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT)) vulkan_logger.ilog("{}", message); + else if (check_flag_bit(severity, VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT)) + vulkan_logger.dlog("{}", message); + else if (check_flag_bit(severity, VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)) + vulkan_logger.elog("{}", message); + else if (check_flag_bit(severity, VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)) + vulkan_logger.wlog("{}", message); + + return 0; +} + export namespace base { class Application { public: @@ -36,21 +61,22 @@ export namespace base { self.m_window->event_loop([&self] noexcept { self.run_example(); }); - TryAssertDiscard(self.m_raster_queue->wait_idle(), "Failed to wait for raster queue"); + TryDiscardAssert(self.m_raster_queue->wait_idle(), "Failed to wait for raster queue"); self.m_device->wait_idle(); if constexpr (requires { self.deinit(); }) self.deinit(); } protected: - DeferInit m_window; - DeferInit m_instance; - DeferInit m_surface; - OptionalRef m_physical_device; - DeferInit m_device; - DeferInit m_swapchain; - DeferInit m_raster_queue; - DeferInit m_command_pool; + DeferInit m_window; + DeferInit m_instance; + DeferInit m_debug_callback; + DeferInit m_surface; + DeferInit m_physical_device; + DeferInit m_device; + DeferInit m_swapchain; + DeferInit m_raster_queue; + DeferInit m_command_pool; private: auto init_window(std::string_view example_name) noexcept -> void { @@ -64,12 +90,15 @@ export namespace base { auto init_gpu(std::string_view example_name) noexcept -> void { // initialize gpu backend (vulkan or webgpu depending the platform) - TryAssertDiscard(gpu::initialize_backend(), "Failed to initialize gpu backend"); + TryDiscardAssert(gpu::initialize_backend(), "Failed to initialize gpu backend"); // create gpu instance and attach surface to window m_instance = TryAssert(gpu::Instance::create(std::string { example_name }, true), "Failed to initialize gpu instance"); + m_debug_callback = TryAssert(gpu::DebugCallback::create(m_instance, debug_callback), + "Failed to initialize gpu instance"); + m_surface = TryAssert(gpu::Surface::create_from_window(m_instance, m_window), "Failed to initialize window gpu surface"); @@ -81,13 +110,13 @@ export namespace base { } ilog("Physical devices: {}", physical_devices); - m_physical_device = as_opt_ref(physical_devices.front()); + m_physical_device = physical_devices.front(); auto score = gpu::score_physical_device(*m_physical_device); for (auto i : range(1_u32, stdr::size(physical_devices))) { const auto& d = physical_devices[i]; const auto d_score = gpu::score_physical_device(d); if (d_score > score) { - m_physical_device = as_opt_ref(d); + m_physical_device = d; score = d_score; } } @@ -95,13 +124,17 @@ export namespace base { ilog("Picked gpu: {}", *m_physical_device); // create gpu device - m_device = TryAssert(gpu::Device::create(*m_physical_device, m_instance), "Failed to initialize gpu device"); + m_device = TryAssert(gpu::Device::create(m_physical_device), "Failed to initialize gpu device"); // create swapchain const auto window_extent = m_window->extent(); m_swapchain = TryAssert(gpu::SwapChain::create(m_device, m_surface, window_extent), "Failed to create swapchain"); - m_raster_queue = gpu::Queue::create(m_device, m_device->raster_queue_entry()); + const auto queue_entries = m_device->queue_entries(); + const auto it = stdr::find_if(queue_entries, gpu::monadic::find_queue()); + ensures(it != stdr::cend(queue_entries), "No raster queue found!"); + + m_raster_queue = gpu::Queue::create(m_device, *it); m_command_pool = TryAssert(gpu::CommandPool::create(m_device), "Failed to create raster queue " diff --git a/examples/gpu/imgui/src/main.cpp b/examples/gpu/imgui/src/main.cpp index 4adbb8b57..cb012c652 100644 --- a/examples/gpu/imgui/src/main.cpp +++ b/examples/gpu/imgui/src/main.cpp @@ -92,13 +92,13 @@ class Application: public base::Application { "signal semaphore") }); auto& transition_cmb = transition_cmbs[image_index]; - TryAssertDiscard(transition_cmb.begin(true), "Failed to begin texture transition command buffer"); + TryDiscardAssert(transition_cmb.begin(true), "Failed to begin texture transition command buffer"); transition_cmb.begin_debug_region(std::format("transition image {}", image_index)) .transition_image_layout(swap_image, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::PRESENT_SRC) .end_debug_region(); - TryAssertDiscard(transition_cmb.end(), + TryDiscardAssert(transition_cmb.end(), "Failed to begin texture transition command " "buffer"); @@ -123,7 +123,7 @@ class Application: public base::Application { io.DisplaySize.x = m_window->extent().to().width; io.DisplaySize.y = m_window->extent().to().height; - const auto format = to_vk(m_swapchain->pixel_format()); + const auto format = gpu::vk::to_vk(m_swapchain->pixel_format()); /*const*/ auto init_info = ImGui_ImplVulkan_InitInfo { .ApiVersion = VK_API_VERSION_1_3, .Instance = m_instance->native_handle(), @@ -155,13 +155,13 @@ class Application: public base::Application { .Allocator = nullptr, .CheckVkResultFn = [](auto result) static noexcept { - if (result != VK_SUCCESS) elog("{}", gpu::from_vk(result)); + if (result != VK_SUCCESS) elog("{}", gpu::vk::from_vk(result)); }, .MinAllocationSize = 1024 * 1024, .CustomShaderVertCreateInfo = {}, .CustomShaderFragCreateInfo = {}, }; - ImGui_ImplVulkan_LoadFunctions(VK_API_VERSION_1_1, gpu::imgui_vk_loader, &*m_device); + ImGui_ImplVulkan_LoadFunctions(VK_API_VERSION_1_1, gpu::vk::imgui_vk_loader, &*m_device); ImGui_ImplVulkan_Init(&init_info); m_window @@ -234,8 +234,8 @@ class Application: public base::Application { // render in it auto& render_cmb = submission_resource.render_cmb; - TryAssertDiscard(render_cmb.reset(), "Failed to reset render command buffer"); - TryAssertDiscard(render_cmb.begin(), "Failed to begin render command buffer"); + TryDiscardAssert(render_cmb.reset(), "Failed to reset render command buffer"); + TryDiscardAssert(render_cmb.begin(), "Failed to begin render command buffer"); render_cmb .transition_image_layout(swapchain_image_resource.image, @@ -252,12 +252,12 @@ class Application: public base::Application { gpu::ImageLayout::ATTACHMENT_OPTIMAL, gpu::ImageLayout::PRESENT_SRC); - TryAssertDiscard(render_cmb.end(), "Failed to end render command buffer"); - TryAssertDiscard(render_cmb.submit(m_raster_queue, as_refs(wait), PIPELINE_FLAGS, as_refs(signal), as_ref(in_flight)), + TryDiscardAssert(render_cmb.end(), "Failed to end render command buffer"); + TryDiscardAssert(render_cmb.submit(m_raster_queue, as_refs(wait), PIPELINE_FLAGS, as_refs(signal), as_ref(in_flight)), "Failed to submit render command buffer"); // present it - TryAssertDiscard(m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)), + TryDiscardAssert(m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)), "Failed to present swapchain image"); if (++m_current_frame >= BUFFERING_COUNT) m_current_frame = 0; diff --git a/examples/gpu/textured_cube/src/main.cpp b/examples/gpu/textured_cube/src/main.cpp index e40321b56..f75fc2a05 100644 --- a/examples/gpu/textured_cube/src/main.cpp +++ b/examples/gpu/textured_cube/src/main.cpp @@ -246,21 +246,23 @@ class Application: public base::Application { TryAssert(image.load_from_file(TEXTURE), std::format("Failed to load texture file {}", TEXTURE.string())); m_texture = TryAssert(gpu::Image::create(m_device, - { .extent = image.extent(), - .format = gpu::PixelFormat::RGBA8_UNORM, - .usages = gpu::ImageUsageFlag::SAMPLED | gpu::ImageUsageFlag::TRANSFER_DST, - .property = gpu::MemoryPropertyFlag::DEVICE_LOCAL }), + gpu::Image::CreateInfo { + .extent = image.extent(), + .format = gpu::PixelFormat::RGBA8_UNORM, + .usages = gpu::ImageUsageFlag::SAMPLED | gpu::ImageUsageFlag::TRANSFER_DST, + .properties = gpu::MemoryPropertyFlag::DEVICE_LOCAL }), "Failed to allocate texture"); { auto cpy_fence = TryAssert(gpu::Fence::create(m_device), "Failed to create copy texture buffer fence"); auto staging_buffer = TryAssert(gpu::Buffer::create(m_device, - { .usages = gpu::BufferUsageFlag::TRANSFER_SRC, + gpu::Buffer::CreateInfo { + .usages = gpu::BufferUsageFlag::TRANSFER_SRC, .size = image.size() }), "Failed to allocate gpu texture staging buffer"); TryAssert(staging_buffer.upload(image.data()), "Failed to upload texture data to staging buffer"); - const auto copy = { + const auto copy = std::array { gpu::BufferImageCopy { .buffer_offset = 0, .buffer_row_length = 0, @@ -281,15 +283,15 @@ class Application: public base::Application { gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL) .end_debug_region(); - TryAssertDiscard(copy_cmb.end(), "Failed to end texture upload command buffer"); - TryAssertDiscard(copy_cmb.submit(m_raster_queue, {}, {}, {}, as_ref(cpy_fence)), + TryDiscardAssert(copy_cmb.end(), "Failed to end texture upload command buffer"); + TryDiscardAssert(copy_cmb.submit(m_raster_queue, {}, {}, {}, as_ref(cpy_fence)), "Failed to submit texture upload command buffer"); - TryAssertDiscard(cpy_fence.wait(), "Failed to create texture view"); + TryDiscardAssert(cpy_fence.wait(), "Failed to create texture view"); } m_texture_view = TryAssert(gpu::ImageView::create(m_device, m_texture), "Failed to create texture view"); - m_sampler = TryAssert(gpu::Sampler::create(m_device, {}), "Failed to create sampler"); + m_sampler = TryAssert(gpu::Sampler::create(m_device, gpu::Sampler::Settings {}), "Failed to create sampler"); m_submission_resources = std::vector {}; m_submission_resources.reserve(BUFFERING_COUNT); @@ -299,11 +301,11 @@ class Application: public base::Application { .image_available = TryAssert(gpu::Semaphore::create(m_device), "Failed to create present image"), .render_cmb = TryAssert(m_command_pool->create_command_buffer(), "Failed to create buffers"), .viewer_buffer = TryAssert(gpu::Buffer::create(m_device, - { - .usages = gpu::BufferUsageFlag::UNIFORM, - .size = sizeof(ViewerData), - }, - true), + gpu::Buffer::CreateInfo { + .usages = gpu::BufferUsageFlag::UNIFORM, + .size = sizeof(ViewerData), + .persistently_mapped = true, + }), "Failed to allocate gpu viewer buffer"), .descriptor_set = TryAssert(m_descriptor_pool->create_descriptor_set(m_descriptor_set_layout), "Failed to create descriptor set") }); @@ -311,7 +313,7 @@ class Application: public base::Application { const auto sets = std::array { gpu::BufferDescriptor { .binding = 0, - .buffer = as_ref(res.viewer_buffer), + .buffer = res.viewer_buffer, .range = sizeof(ViewerData), .offset = 0, }, @@ -339,16 +341,16 @@ class Application: public base::Application { auto view = TryAssert(gpu::ImageView::create(m_device, swap_image), "Failed to create swapchain image view"); auto depth_image = TryAssert(gpu::Image::create(m_device, gpu::Image::CreateInfo { - .extent = swap_image.extent(), - .format = depth_format, - .usages = gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT, - .property = gpu::MemoryPropertyFlag::DEVICE_LOCAL }), + .extent = swap_image.extent(), + .format = depth_format, + .usages = gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT, + .properties = gpu::MemoryPropertyFlag::DEVICE_LOCAL }), "Failed to create depth image"); auto depth_view = TryAssert(gpu::ImageView::create(m_device, depth_image, gpu::ImageViewType::T2D, - { .aspect_mask = depth_aspect_flag }), + gpu::ImageSubresourceRange { .aspect_mask = depth_aspect_flag }), "Failed to create depth image view"); m_image_resources @@ -361,7 +363,7 @@ class Application: public base::Application { const auto& resources = m_image_resources.back(); auto& transition_cmb = transition_cmbs[image_index]; - TryAssertDiscard(transition_cmb.begin(true), "Failed to begin texture transition command buffer"); + TryDiscardAssert(transition_cmb.begin(true), "Failed to begin texture transition command buffer"); transition_cmb.begin_debug_region(std::format("transition image {}", image_index)) .transition_image_layout(swap_image, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::PRESENT_SRC) @@ -371,7 +373,7 @@ class Application: public base::Application { { .aspect_mask = depth_aspect_flag }) .end_debug_region(); - TryAssertDiscard(transition_cmb.end(), "Failed to begin texture transition command buffer"); + TryDiscardAssert(transition_cmb.end(), "Failed to begin texture transition command buffer"); ++image_index; } @@ -379,20 +381,22 @@ class Application: public base::Application { const auto fence = TryAssert(gpu::Fence::create(m_device), "Failed to create transition fence"); const auto cmbs = to_refs(transition_cmbs); - TryAssertDiscard(m_raster_queue->submit({ .command_buffers = cmbs }, as_ref(fence)), + TryDiscardAssert(m_raster_queue->submit({ .command_buffers = cmbs }, as_ref(fence)), "Failed to submit texture transition command buffers"); // setup vertex buffer m_vertex_buffer = TryAssert(gpu::Buffer::create(m_device, - { .usages = gpu::BufferUsageFlag::VERTEX - | gpu::BufferUsageFlag::TRANSFER_DST, - .size = VERTICES_SIZE, - .property = gpu::MemoryPropertyFlag::DEVICE_LOCAL }), + gpu::Buffer::CreateInfo { + .usages = gpu::BufferUsageFlag::VERTEX + | gpu::BufferUsageFlag::TRANSFER_DST, + .size = VERTICES_SIZE, + .properties = gpu::MemoryPropertyFlag::DEVICE_LOCAL }), "Failed to allocate gpu vertex buffer"); { auto staging_buffer = TryAssert(gpu::Buffer::create(m_device, - { .usages = gpu::BufferUsageFlag::TRANSFER_SRC, + gpu::Buffer::CreateInfo { + .usages = gpu::BufferUsageFlag::TRANSFER_SRC, .size = VERTICES_SIZE }), "Failed to allocate gpu vertex staging buffer"); @@ -407,8 +411,8 @@ class Application: public base::Application { .copy_buffer(staging_buffer, m_vertex_buffer, VERTICES_SIZE) .end_debug_region(); - TryAssertDiscard(copy_cmb.end(), "Failed to begin vertices upload command buffer"); - TryAssertDiscard(copy_cmb.submit(m_raster_queue, {}, {}, {}, as_ref(cpy_fence)), + TryDiscardAssert(copy_cmb.end(), "Failed to begin vertices upload command buffer"); + TryDiscardAssert(copy_cmb.submit(m_raster_queue, {}, {}, {}, as_ref(cpy_fence)), "Failed to submit vertices upload command buffer"); TryAssert(cpy_fence.wait(), "Failed to acquire next swapchain image"); } @@ -469,8 +473,8 @@ class Application: public base::Application { auto& render_cmb = submission_resource.render_cmb; const auto& descriptor_set = submission_resource.descriptor_set; - TryAssertDiscard(render_cmb.reset(), "Failed to reset render command buffer"); - TryAssertDiscard(render_cmb.begin(), "Failed to begin render command buffer"); + TryDiscardAssert(render_cmb.reset(), "Failed to reset render command buffer"); + TryDiscardAssert(render_cmb.begin(), "Failed to begin render command buffer"); render_cmb .transition_image_layout(swapchain_image_resource.image, @@ -488,8 +492,8 @@ class Application: public base::Application { gpu::ImageLayout::ATTACHMENT_OPTIMAL, gpu::ImageLayout::PRESENT_SRC); - TryAssertDiscard(render_cmb.end(), "Failed to end render command buffer"); - TryAssertDiscard(render_cmb.submit(m_raster_queue, as_refs(wait), PIPELINE_FLAGS, as_refs(signal), as_ref(in_flight)), + TryDiscardAssert(render_cmb.end(), "Failed to end render command buffer"); + TryDiscardAssert(render_cmb.submit(m_raster_queue, as_refs(wait), PIPELINE_FLAGS, as_refs(signal), as_ref(in_flight)), "Failed to submit render command buffer"); // present it diff --git a/examples/gpu/triangle/src/main.cpp b/examples/gpu/triangle/src/main.cpp index ffd181637..3dd2bb2b2 100644 --- a/examples/gpu/triangle/src/main.cpp +++ b/examples/gpu/triangle/src/main.cpp @@ -29,9 +29,9 @@ struct SubmissionResource { }; struct SwapchainImageResource { - Ref image; - gpu::ImageView view; - gpu::Semaphore render_finished; + gpu::view::Image image; + gpu::ImageView view; + gpu::Semaphore render_finished; }; namespace { @@ -116,20 +116,20 @@ class Application: public base::Application { auto view = TryAssert(gpu::ImageView::create(m_device, swap_image), "Failed to create swapchain image view"); m_image_resources - .push_back({ .image = as_ref(swap_image), + .push_back({ .image = swap_image, .view = std::move(view), .render_finished = TryAssert(gpu::Semaphore::create(m_device), "Failed to create render " "signal semaphore") }); auto& transition_cmb = transition_cmbs[image_index]; - TryAssertDiscard(transition_cmb.begin(true), "Failed to begin texture transition command buffer"); + TryDiscardAssert(transition_cmb.begin(true), "Failed to begin texture transition command buffer"); transition_cmb.begin_debug_region(std::format("transition image {}", image_index)) .transition_image_layout(swap_image, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::PRESENT_SRC) .end_debug_region(); - TryAssertDiscard(transition_cmb.end(), + TryDiscardAssert(transition_cmb.end(), "Failed to begin texture transition command " "buffer"); @@ -177,8 +177,8 @@ class Application: public base::Application { // render in it auto& render_cmb = submission_resource.render_cmb; - TryAssertDiscard(render_cmb.reset(), "Failed to reset render command buffer"); - TryAssertDiscard(render_cmb.begin(), "Failed to begin render command buffer"); + TryDiscardAssert(render_cmb.reset(), "Failed to reset render command buffer"); + TryDiscardAssert(render_cmb.begin(), "Failed to begin render command buffer"); render_cmb .transition_image_layout(swapchain_image_resource.image, @@ -194,12 +194,12 @@ class Application: public base::Application { gpu::ImageLayout::ATTACHMENT_OPTIMAL, gpu::ImageLayout::PRESENT_SRC); - TryAssertDiscard(render_cmb.end(), "Failed to end render command buffer"); - TryAssertDiscard(render_cmb.submit(m_raster_queue, as_refs(wait), PIPELINE_FLAGS, as_refs(signal), as_ref(in_flight)), + TryDiscardAssert(render_cmb.end(), "Failed to end render command buffer"); + TryDiscardAssert(render_cmb.submit(m_raster_queue, as_refs(wait), PIPELINE_FLAGS, as_refs(signal), as_ref(in_flight)), "Failed to submit render command buffer"); // present it - TryAssertDiscard(m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)), + TryDiscardAssert(m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)), "Failed to present swapchain image"); if (++m_current_frame >= BUFFERING_COUNT) m_current_frame = 0; diff --git a/modules/stormkit/core/containers/dag.cppm b/modules/stormkit/core/containers/dag.cppm index 3a2576425..0018153ec 100644 --- a/modules/stormkit/core/containers/dag.cppm +++ b/modules/stormkit/core/containers/dag.cppm @@ -49,6 +49,8 @@ export namespace stormkit { inline namespace core { using ColorizeClosure = FunctionRef; using FormatValueClosure = FunctionRef; + using ValueType = Vertex; + struct Closures { std::optional colorize = std::nullopt; std::optional format_value = []() static noexcept -> std::optional { diff --git a/modules/stormkit/core/containers/raii_capsule.cppm b/modules/stormkit/core/containers/raii_capsule.cppm index f018d4434..5f4bcd816 100644 --- a/modules/stormkit/core/containers/raii_capsule.cppm +++ b/modules/stormkit/core/containers/raii_capsule.cppm @@ -19,16 +19,20 @@ export namespace stormkit { inline namespace core { template class RAIICapsule { public: - using value_type = T; + using ValueType = T; + using ReferenceType = ValueType&; + + using value_type = ValueType; + using reference = ReferenceType; template static constexpr auto create(Args&&... args) noexcept -> RAIICapsule - requires meta::Is, T>; + requires meta::Is, ValueType>; template static constexpr auto create(Args&&... args) noexcept -> decltype(auto) requires meta::IsSpecializationOf, std::expected>; - static constexpr auto take(T&& value) noexcept -> RAIICapsule; + static constexpr auto take(ValueType&& value) noexcept -> RAIICapsule; static constexpr auto empty() noexcept -> RAIICapsule; constexpr ~RAIICapsule() noexcept; @@ -39,19 +43,19 @@ export namespace stormkit { inline namespace core { constexpr RAIICapsule(RAIICapsule&& other) noexcept; constexpr auto operator=(RAIICapsule&& other) noexcept -> RAIICapsule&; - constexpr operator T() const noexcept; - constexpr auto handle() noexcept -> T&; - constexpr auto handle() const noexcept -> T; - constexpr auto release() noexcept -> T; + constexpr operator ValueType() const noexcept; + constexpr auto handle() noexcept -> ReferenceType; + constexpr auto handle() const noexcept -> ValueType; + constexpr auto release() noexcept -> ValueType; constexpr auto reset(T handle = RELEASE_VALUE) noexcept -> void; private: constexpr RAIICapsule() noexcept; - constexpr RAIICapsule(T handle) noexcept; + constexpr RAIICapsule(ValueType handle) noexcept; constexpr auto destroy() noexcept -> void; - T m_handle = RELEASE_VALUE; + ValueType m_handle = RELEASE_VALUE; }; }} // namespace stormkit::core @@ -65,7 +69,7 @@ namespace stormkit { inline namespace core { template template constexpr auto RAIICapsule::create(Args&&... args) noexcept -> RAIICapsule - requires meta::Is, T> + requires meta::Is, ValueType> { return RAIICapsule { Constructor(std::forward(args)...) }; } @@ -84,7 +88,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto RAIICapsule::take(T&& value) noexcept -> RAIICapsule { + constexpr auto RAIICapsule::take(ValueType&& value) noexcept -> RAIICapsule { return RAIICapsule { std::move(value) }; } @@ -126,7 +130,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr RAIICapsule::operator T() const noexcept { + constexpr RAIICapsule::operator ValueType() const noexcept { return m_handle; } @@ -134,7 +138,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto RAIICapsule::handle() noexcept -> T& { + constexpr auto RAIICapsule::handle() noexcept -> ReferenceType { return m_handle; } @@ -142,7 +146,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto RAIICapsule::handle() const noexcept -> T { + constexpr auto RAIICapsule::handle() const noexcept -> ValueType { return m_handle; } @@ -150,7 +154,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto RAIICapsule::release() noexcept -> T { + constexpr auto RAIICapsule::release() noexcept -> ValueType { auto tmp = std::exchange(m_handle, RELEASE_VALUE); return tmp; } @@ -159,7 +163,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto RAIICapsule::reset(T handle) noexcept -> void { + constexpr auto RAIICapsule::reset(ValueType handle) noexcept -> void { destroy(); m_handle = handle; } @@ -176,7 +180,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr RAIICapsule::RAIICapsule(T handle) noexcept { + constexpr RAIICapsule::RAIICapsule(ValueType handle) noexcept { m_handle = handle; } @@ -184,6 +188,5 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr RAIICapsule::RAIICapsule() noexcept - = default; + constexpr RAIICapsule::RAIICapsule() noexcept = default; }} // namespace stormkit::core diff --git a/modules/stormkit/core/containers/shmbuffer.cppm b/modules/stormkit/core/containers/shmbuffer.cppm index dd79ad43e..3c974ff5d 100644 --- a/modules/stormkit/core/containers/shmbuffer.cppm +++ b/modules/stormkit/core/containers/shmbuffer.cppm @@ -24,7 +24,9 @@ export namespace stormkit { inline namespace core { struct PrivateFuncTag {}; public: - using value_type = Byte; + using ValueType = byte; + + using value_type = ValueType; enum class Access : u8 { READ = 1, diff --git a/modules/stormkit/core/math/extent.cppm b/modules/stormkit/core/math/extent.cppm index 8640f9092..1b27b3204 100644 --- a/modules/stormkit/core/math/extent.cppm +++ b/modules/stormkit/core/math/extent.cppm @@ -28,7 +28,7 @@ export { template struct alignas(std::array) extent { static constexpr auto RANK = 2uz; - using ElementType = T; + using ValueType = T; using OrderingType = meta::ArithmeticOrderingType; template @@ -41,10 +41,10 @@ export { constexpr auto to() const noexcept -> extent; /// @brief The extent width - ElementType width = 0; + ValueType width = 0; /// @brief The extent height - ElementType height = 0; + ValueType height = 0; }; template @@ -57,7 +57,7 @@ export { template struct alignas(std::array) extent { static constexpr auto RANK = 3uz; - using ElementType = T; + using ValueType = T; using OrderingType = meta::ArithmeticOrderingType; template @@ -70,13 +70,13 @@ export { constexpr auto to() const noexcept -> extent; /// @brief The extent width - ElementType width = 0; + ValueType width = 0; /// @brief The extent height - ElementType height = 0; + ValueType height = 0; /// @brief The extent depth - ElementType depth = 1; + ValueType depth = 1; }; template @@ -95,7 +95,7 @@ export { namespace meta { template concept IsExtent = requires(T&&) { - typename T::ElementType; + typename T::ValueType; typename T::OrderingType; { T::RANK } -> core::meta::Is; }; @@ -124,7 +124,7 @@ export { constexpr auto operator==(const Extent& first, const Extent& second) noexcept -> bool; /// @brief Multiply an extent with a factor. - /// @param factor ElementType factor to multiply + /// @param factor ValueType factor to multiply /// @returns A newly constructed extent equal to this extent multiplied with /// `factor` template @@ -133,7 +133,7 @@ export { -> core::meta::CanonicalType; /// @brief Divide an extent with a factor. - /// @param factor ElementType factor to divide + /// @param factor ValueType factor to divide /// @returns A newly constructed extent equal to this extent Divided with `factor` template [[nodiscard]] @@ -141,18 +141,18 @@ export { -> core::meta::CanonicalType; /// @brief Multiply this extent with a factor. - /// @param factor ElementType factor to multiply + /// @param factor ValueType factor to multiply /// @returns A reference to this after the multiplication with `factor` template [[nodiscard]] - constexpr auto operator*=(Extent& extent, typename Extent::ElementType factor) noexcept -> Extent&; + constexpr auto operator*=(Extent& extent, typename Extent::ValueType factor) noexcept -> Extent&; /// @brief Divide this extent with a factor. - /// @param factor ElementType factor to divide + /// @param factor ValueType factor to divide /// @returns A reference to this after the division with `factor` template [[nodiscard]] - constexpr auto operator/=(Extent& extent, typename Extent::ElementType factor) noexcept -> Extent&; + constexpr auto operator/=(Extent& extent, typename Extent::ValueType factor) noexcept -> Extent&; template auto to_string(const Extent& extent) noexcept -> std::string; @@ -203,9 +203,9 @@ namespace stormkit { inline namespace core { namespace math { template STORMKIT_PURE constexpr auto extent::to() const noexcept -> extent { - using Out = extent; - using Array = std::array; - using OtherArray = std::array; + using Out = extent; + using Array = std::array; + using OtherArray = std::array; auto out = Out {}; @@ -244,9 +244,9 @@ namespace stormkit { inline namespace core { namespace math { template STORMKIT_PURE constexpr auto extent::to() const noexcept -> extent { - using Out = extent; - using Array = std::array; - using OtherArray = std::array; + using Out = extent; + using Array = std::array; + using OtherArray = std::array; auto out = Out {}; @@ -266,7 +266,7 @@ namespace stormkit { inline namespace core { namespace math { template STORMKIT_PURE constexpr auto operator<=>(const Extent& first, const Extent& second) noexcept -> typename Extent::OrderingType { - using Array = std::array; + using Array = std::array; using OrderingType = typename Extent::OrderingType; static constexpr auto RANK = Extent::RANK; @@ -284,7 +284,7 @@ namespace stormkit { inline namespace core { namespace math { template STORMKIT_PURE constexpr auto operator==(const Extent& first, const Extent& second) noexcept -> bool { - using Array = std::array; + using Array = std::array; static constexpr auto RANK = Extent::RANK; const auto& values = *std::bit_cast(&first); @@ -316,10 +316,10 @@ namespace stormkit { inline namespace core { namespace math { ///////////////////////////////////// template STORMKIT_PURE - constexpr auto operator*=(Extent& extent, typename Extent::ElementType factor) noexcept -> Extent& { - using ElementType = typename Extent::ElementType; + constexpr auto operator*=(Extent& extent, typename Extent::ValueType factor) noexcept -> Extent& { + using ValueType = typename Extent::ValueType; static constexpr auto RANK = Extent::RANK; - auto& values = *std::bit_cast>(&extent); + auto& values = *std::bit_cast>(&extent); for (auto&& val : values) val *= factor; return extent; } @@ -328,10 +328,10 @@ namespace stormkit { inline namespace core { namespace math { ///////////////////////////////////// template STORMKIT_PURE - constexpr auto operator/=(Extent& extent, typename Extent::ElementType factor) noexcept -> Extent& { - using ElementType = typename Extent::ElementType; + constexpr auto operator/=(Extent& extent, typename Extent::ValueType factor) noexcept -> Extent& { + using ValueType = typename Extent::ValueType; static constexpr auto RANK = Extent::RANK; - auto& values = *std::bit_cast>(&extent); + auto& values = *std::bit_cast>(&extent); for (auto&& val : values) val /= factor; return extent; } diff --git a/modules/stormkit/core/math/geometry.cppm b/modules/stormkit/core/math/geometry.cppm index 46c1db9fe..6cb72a4cb 100644 --- a/modules/stormkit/core/math/geometry.cppm +++ b/modules/stormkit/core/math/geometry.cppm @@ -20,13 +20,15 @@ import :math.linear.vector; export namespace stormkit { inline namespace core { namespace math { template struct rect { - T x = T { 0 }; - T y = T { 0 }; - Positive width = T { 0 }; - Positive height = T { 0 }; + using ValueType = T; - constexpr auto position() const noexcept -> vec2; - constexpr auto extent() const noexcept -> extent2; + ValueType x = ValueType { 0 }; + ValueType y = ValueType { 0 }; + Positive width = ValueType { 0 }; + Positive height = ValueType { 0 }; + + constexpr auto position() const noexcept -> vec2; + constexpr auto extent() const noexcept -> extent2; template constexpr auto to() const noexcept -> rect; @@ -41,13 +43,15 @@ export namespace stormkit { inline namespace core { namespace math { template struct bounding_rect { - T left = T { 0 }; - T top = T { 0 }; - T right = T { 0 }; - T bottom = T { 0 }; + using ValueType = T; + + ValueType left = ValueType { 0 }; + ValueType top = ValueType { 0 }; + ValueType right = ValueType { 0 }; + ValueType bottom = ValueType { 0 }; - constexpr auto topleft() const noexcept -> vec2; - constexpr auto bottomright() const noexcept -> vec2; + constexpr auto topleft() const noexcept -> vec2; + constexpr auto bottomright() const noexcept -> vec2; template constexpr auto to() const noexcept -> rect; diff --git a/modules/stormkit/core/math/linear-matrix.cppm b/modules/stormkit/core/math/linear-matrix.cppm index f874c157d..f3988bae1 100644 --- a/modules/stormkit/core/math/linear-matrix.cppm +++ b/modules/stormkit/core/math/linear-matrix.cppm @@ -32,23 +32,23 @@ export { // N => columns template struct alignas(std::array) mat { - using value_type = T; - using storage_type = std::array; - using size_type = usize; - using extent_type = u8; + using ValueType = T; + using StorageType = std::array; + using SizeType = usize; + using ExtentType = u8; - static constexpr auto EXTENTS = std::array { M, N }; + static constexpr auto EXTENTS = std::array { M, N }; - storage_type values; + StorageType values; template [[nodiscard]] - constexpr auto operator[](this Self&& self, size_type i) noexcept -> core::meta::ForwardLike&; + constexpr auto operator[](this Self&& self, SizeType i) noexcept -> core::meta::ForwardLike&; template [[nodiscard]] - constexpr auto operator[](this Self&& self, size_type i, size_type j) noexcept - -> core::meta::ForwardLike&; + constexpr auto operator[](this Self&& self, SizeType i, SizeType j) noexcept + -> core::meta::ForwardLike&; template [[nodiscard]] @@ -64,15 +64,15 @@ export { template [[nodiscard]] - constexpr auto data(this Self& self) noexcept -> core::meta::ForwardConst*; + constexpr auto data(this Self& self) noexcept -> core::meta::ForwardConst*; [[nodiscard]] - constexpr auto size() const noexcept -> size_type; + constexpr auto size() const noexcept -> SizeType; [[nodiscard]] - static consteval auto max_size() noexcept -> size_type; + static consteval auto max_size() noexcept -> SizeType; [[nodiscard]] - static constexpr auto identity() noexcept -> mat + static constexpr auto identity() noexcept -> mat requires(M == N); }; @@ -157,7 +157,7 @@ export { inline namespace matrix { template [[nodiscard]] - constexpr auto determinant(const T& mat) noexcept -> typename T::value_type; + constexpr auto determinant(const T& mat) noexcept -> typename T::ValueType; template constexpr auto transpose(const T& mat) noexcept -> T; @@ -175,18 +175,18 @@ export { template [[nodiscard]] - constexpr auto mul(const T& a, typename T::value_type b) noexcept -> T; + constexpr auto mul(const T& a, typename T::ValueType b) noexcept -> T; template [[nodiscard]] - constexpr auto div(const T& a, typename T::value_type b) noexcept -> T; + constexpr auto div(const T& a, typename T::ValueType b) noexcept -> T; template [[nodiscard]] constexpr auto mul(const T& a, const T& b) noexcept -> T; template - requires(core::meta::IsStrict) + requires(core::meta::SameAs) [[nodiscard]] constexpr auto div(const T& a, const U& b) noexcept -> U; @@ -221,21 +221,21 @@ export { template [[nodiscard]] constexpr auto as_view(const T& value) noexcept - -> std::span; + -> std::span; template [[nodiscard]] - constexpr auto as_view_mut(T& value) noexcept -> std::span; + constexpr auto as_view_mut(T& value) noexcept -> std::span; template [[nodiscard]] constexpr auto as_mdspan(const T& value) noexcept - -> MatrixSpan; + -> MatrixSpan; template requires(not core::meta::IsConst) [[nodiscard]] - constexpr auto as_mdspan(T& value) noexcept -> MatrixSpan; + constexpr auto as_mdspan(T& value) noexcept -> MatrixSpan; template auto to_string(const T& value) noexcept -> std::string; @@ -288,8 +288,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m template template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto mat::operator[](this Self&& self, size_type i) noexcept - -> core::meta::ForwardLike& { + constexpr auto mat::operator[](this Self&& self, SizeType i) noexcept -> core::meta::ForwardLike& { return std::forward_like(self.values[i]); } @@ -298,8 +297,8 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m template template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto mat::operator[](this Self&& self, size_type i, size_type j) noexcept - -> core::meta::ForwardLike& { + constexpr auto mat::operator[](this Self&& self, SizeType i, SizeType j) noexcept + -> core::meta::ForwardLike& { return std::forward_like(self.operator[](((i * EXTENTS[0]) + j))); } @@ -342,7 +341,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m template template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto mat::data(this Self& self) noexcept -> core::meta::ForwardConst* { + constexpr auto mat::data(this Self& self) noexcept -> core::meta::ForwardConst* { return stdr::data(self.values); } @@ -350,7 +349,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto mat::size() const noexcept -> size_type { + constexpr auto mat::size() const noexcept -> SizeType { return stdr::size(values); } @@ -358,7 +357,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - consteval auto mat::max_size() noexcept -> size_type { + consteval auto mat::max_size() noexcept -> SizeType { return M * N; } @@ -366,10 +365,10 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto mat::identity() noexcept -> mat + constexpr auto mat::identity() noexcept -> mat requires(M == N) { - auto matrix = mat {}; + auto matrix = mat {}; for (auto i = 0u; i < M; ++i) { matrix[i, i] = T { 1 }; } @@ -380,7 +379,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto determinant(const T& mat) noexcept -> typename T::value_type { + constexpr auto determinant(const T& mat) noexcept -> typename T::ValueType { return math::determinant(as_mdspan(mat)); } @@ -424,7 +423,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto mul(const T& a, typename T::value_type b) noexcept -> T { + constexpr auto mul(const T& a, typename T::ValueType b) noexcept -> T { auto out = T {}; math::mul(as_mdspan(a), b, as_mdspan_mut(out)); @@ -436,7 +435,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto div(const T& a, typename T::value_type b) noexcept -> T { + constexpr auto div(const T& a, typename T::ValueType b) noexcept -> T { auto out = T {}; math::div(as_mdspan(a), b, as_mdspan_mut(out)); @@ -459,7 +458,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m //////////////////////////////////////// //////////////////////////////////////// template - requires(core::meta::IsStrict) + requires(core::meta::SameAs) STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto div(const T& a, const U& b) noexcept -> U { auto out = T {}; @@ -557,26 +556,26 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto as_view(const T& value) noexcept -> std::span { - return std::span { stdr::data(value), - T::EXTENTS[0] * T::EXTENTS[1] }; + constexpr auto as_view(const T& value) noexcept -> std::span { + return std::span { stdr::data(value), + T::EXTENTS[0] * T::EXTENTS[1] }; } //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto as_view_mut(T& value) noexcept -> std::span { - return std::span { stdr::data(value), - T::EXTENTS[0] * T::EXTENTS[1] }; + constexpr auto as_view_mut(T& value) noexcept -> std::span { + return std::span { stdr::data(value), + T::EXTENTS[0] * T::EXTENTS[1] }; } //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto as_mdspan(const T& value) noexcept -> MatrixSpan { - return MatrixSpan { stdr::data(value), T::EXTENTS }; + constexpr auto as_mdspan(const T& value) noexcept -> MatrixSpan { + return MatrixSpan { stdr::data(value), T::EXTENTS }; } //////////////////////////////////////// @@ -584,8 +583,8 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m template requires(not core::meta::IsConst) STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto as_mdspan_mut(T& value) noexcept -> MatrixSpan { - return MatrixSpan { stdr::data(value), T::EXTENTS }; + constexpr auto as_mdspan_mut(T& value) noexcept -> MatrixSpan { + return MatrixSpan { stdr::data(value), T::EXTENTS }; } //////////////////////////////////////// @@ -610,7 +609,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m auto out = ctx.out(); auto max_digit = 0u; - if constexpr (stormkit::meta::IsSigned) + if constexpr (stormkit::meta::IsSigned) for (auto v : as_view(mat)) { max_digit = std::max(max_digit, narrow(v) == 0 ? 2 : narrow(std::log10(v) + 2)); if (v < 0) max_digit = max_digit + 1; @@ -626,7 +625,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m if (row != 0 && col == 0) format_to(out, " "); - if constexpr (stormkit::meta::IsIntegral) { + if constexpr (stormkit::meta::IsIntegral) { if (col < T::EXTENTS[1] - 1) format_to(out, "{:>{}}, ", mat[i], max_digit); else { if (row < T::EXTENTS[0] - 1) format_to(out, "{:>{}}\n", mat[i], max_digit); @@ -652,7 +651,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m #endif #define DETERMINANT_INSTANCIATE(mat_type) \ - template STORMKIT_CORE_API auto determinant(const mat_type&) noexcept -> typename mat_type::value_type + template STORMKIT_CORE_API auto determinant(const mat_type&) noexcept -> typename mat_type::ValueType DETERMINANT_INSTANCIATE(fmat2); DETERMINANT_INSTANCIATE(fmat3); @@ -761,7 +760,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m #undef IS_ORTHOGONAL_INSTANCIATE #define MUL_INSTANCIATE(mat_type) \ - template STORMKIT_CORE_API auto mul(const mat_type&, typename mat_type::value_type) noexcept -> mat_type + template STORMKIT_CORE_API auto mul(const mat_type&, typename mat_type::ValueType) noexcept -> mat_type MUL_INSTANCIATE(fmat2); MUL_INSTANCIATE(fmat2x3); @@ -794,7 +793,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m #undef MUL_INSTANCIATE #define DIV_INSTANCIATE(mat_type) \ - template STORMKIT_CORE_API auto div(const mat_type&, typename mat_type::value_type) noexcept -> mat_type + template STORMKIT_CORE_API auto div(const mat_type&, typename mat_type::ValueType) noexcept -> mat_type DIV_INSTANCIATE(fmat2); DIV_INSTANCIATE(fmat2x3); diff --git a/modules/stormkit/core/math/linear-vector.cppm b/modules/stormkit/core/math/linear-vector.cppm index bcd228a53..85c25dcca 100644 --- a/modules/stormkit/core/math/linear-vector.cppm +++ b/modules/stormkit/core/math/linear-vector.cppm @@ -26,17 +26,17 @@ export namespace stormkit { inline namespace core { namespace math { inline namespace vector { template struct alignas(std::array) vec2 { - using value_type = T; - using size_type = usize; - using extent_type = u8; + using ValueType = T; + using SizeType = usize; + using ExtentType = u8; - static constexpr auto EXTENT = std::array { 2uz }; + static constexpr auto EXTENT = std::array { 2uz }; - T x; - T y; + ValueType x; + ValueType y; template - constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst&; + constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst&; template constexpr auto to() const noexcept -> vec2; @@ -48,18 +48,18 @@ export namespace stormkit { inline namespace core { namespace math { template struct alignas(std::array) vec3 { - using value_type = T; - using size_type = usize; - using extent_type = u8; + using ValueType = T; + using SizeType = usize; + using ExtentType = u8; - static constexpr auto EXTENT = std::array { 3uz }; + static constexpr auto EXTENT = std::array { 3uz }; - T x; - T y; - T z; + ValueType x; + ValueType y; + ValueType z; template - constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst&; + constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst&; template constexpr auto to() const noexcept -> vec3; @@ -71,19 +71,19 @@ export namespace stormkit { inline namespace core { namespace math { template struct alignas(std::array) vec4 { - using value_type = T; - using size_type = usize; - using extent_type = u8; + using ValueType = T; + using SizeType = usize; + using ExtentType = u8; - static constexpr auto EXTENT = std::array { 4uz }; + static constexpr auto EXTENT = std::array { 4uz }; - T x; - T y; - T z; - T w; + ValueType x; + ValueType y; + ValueType z; + ValueType w; template - constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst&; + constexpr auto operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst&; template constexpr auto to() const noexcept -> vec4; @@ -123,15 +123,15 @@ export namespace stormkit { inline namespace core { namespace math { template [[nodiscard]] - constexpr auto mul(const T& a, typename T::value_type b) noexcept -> T; + constexpr auto mul(const T& a, typename T::ValueType b) noexcept -> T; template [[nodiscard]] - constexpr auto div(const T& a, typename T::value_type b) noexcept -> T; + constexpr auto div(const T& a, typename T::ValueType b) noexcept -> T; template [[nodiscard]] - constexpr auto dot(const T& a, const T& b) noexcept -> typename T::value_type; + constexpr auto dot(const T& a, const T& b) noexcept -> typename T::ValueType; template [[nodiscard]] @@ -143,20 +143,20 @@ export namespace stormkit { inline namespace core { namespace math { template [[nodiscard]] - constexpr auto as_view(const T& value) noexcept -> std::span; + constexpr auto as_view(const T& value) noexcept -> std::span; template [[nodiscard]] - constexpr auto as_view_mut(T& value) noexcept -> std::span; + constexpr auto as_view_mut(T& value) noexcept -> std::span; template [[nodiscard]] - constexpr auto as_mdspan(const T& value) noexcept -> VectorSpan; + constexpr auto as_mdspan(const T& value) noexcept -> VectorSpan; template requires(not core::meta::IsConst) [[nodiscard]] - constexpr auto as_mdspan_mut(T& value) noexcept -> VectorSpan; + constexpr auto as_mdspan_mut(T& value) noexcept -> VectorSpan; template auto to_string(const vec2& value) noexcept -> std::string; @@ -220,7 +220,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v template template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto vec2::operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst& { + constexpr auto vec2::operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst& { static constexpr auto members = std::array { &vec2::x, &vec2::y }; return std::forward_like(self.*members[i]); @@ -240,7 +240,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v template template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto vec3::operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst& { + constexpr auto vec3::operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst& { static constexpr auto members = std::array { &vec3::x, &vec3::y, &vec3::z }; return std::forward_like(self.*members[i]); @@ -260,7 +260,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v template template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto vec4::operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst& { + constexpr auto vec4::operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst& { static constexpr auto members = std::array { &vec4::x, &vec4::y, &vec4::z, &vec4::w }; return std::forward_like(self.*members[i]); @@ -315,7 +315,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto mul(const T& a, typename T::value_type b) noexcept -> T { + constexpr auto mul(const T& a, typename T::ValueType b) noexcept -> T { auto out = T {}; math::mul(as_mdspan(a), b, as_mdspan_mut(out)); @@ -327,7 +327,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto div(const T& a, typename T::value_type b) noexcept -> T { + constexpr auto div(const T& a, typename T::ValueType b) noexcept -> T { auto out = T {}; math::div(as_mdspan(a), b, as_mdspan_mut(out)); @@ -339,7 +339,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto dot(const T& a, const T& b) noexcept -> typename T::value_type { + constexpr auto dot(const T& a, const T& b) noexcept -> typename T::ValueType { return math::dot(as_mdspan(a), as_mdspan(b)); } @@ -359,24 +359,24 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto as_view(const T& value) noexcept -> std::span { - return std::span { &value.x, T::EXTENT[0] }; + constexpr auto as_view(const T& value) noexcept -> std::span { + return std::span { &value.x, T::EXTENT[0] }; } //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto as_view_mut(T& value) noexcept -> std::span { - return std::span { &value.x, T::EXTENT[0] }; + constexpr auto as_view_mut(T& value) noexcept -> std::span { + return std::span { &value.x, T::EXTENT[0] }; } //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto as_mdspan(const T& value) noexcept -> VectorSpan { - return VectorSpan { &value.x, T::EXTENT }; + constexpr auto as_mdspan(const T& value) noexcept -> VectorSpan { + return VectorSpan { &value.x, T::EXTENT }; } //////////////////////////////////////// @@ -384,8 +384,8 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v template requires(not core::meta::IsConst) STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto as_mdspan_mut(T& value) noexcept -> VectorSpan { - return VectorSpan { &value.x, T::EXTENT }; + constexpr auto as_mdspan_mut(T& value) noexcept -> VectorSpan { + return VectorSpan { &value.x, T::EXTENT }; } //////////////////////////////////////// @@ -496,7 +496,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v #undef SUB_INSTANCIATE #define MUL_INSTANCIATE(vec_type) \ - template STORMKIT_CORE_API auto mul(const vec_type&, typename vec_type::value_type) noexcept -> vec_type + template STORMKIT_CORE_API auto mul(const vec_type&, typename vec_type::ValueType) noexcept -> vec_type MUL_INSTANCIATE(fvec2); MUL_INSTANCIATE(fvec3); @@ -511,7 +511,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v #undef MUL_INSTANCIATE #define DIV_INSTANCIATE(vec_type) \ - template STORMKIT_CORE_API auto div(const vec_type&, typename vec_type::value_type) noexcept -> vec_type + template STORMKIT_CORE_API auto div(const vec_type&, typename vec_type::ValueType) noexcept -> vec_type DIV_INSTANCIATE(fvec2); DIV_INSTANCIATE(fvec3); @@ -526,7 +526,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v #undef DIV_INSTANCIATE #define DOT_INSTANCIATE(vec_type) \ - template STORMKIT_CORE_API auto dot(const vec_type&, const vec_type&) noexcept -> typename vec_type::value_type + template STORMKIT_CORE_API auto dot(const vec_type&, const vec_type&) noexcept -> typename vec_type::ValueType DOT_INSTANCIATE(fvec2); DOT_INSTANCIATE(fvec3); diff --git a/modules/stormkit/core/utils/deferinit.cppm b/modules/stormkit/core/utils/deferinit.cppm index f8282bf9c..27e9c7105 100644 --- a/modules/stormkit/core/utils/deferinit.cppm +++ b/modules/stormkit/core/utils/deferinit.cppm @@ -26,9 +26,8 @@ export namespace stormkit { inline namespace core { using ReferenceType = ValueType&; // STL compatible - using value_type = ValueType; - using pointer_type = PointerType; - using reference_type = ReferenceType; + using value_type = ValueType; + using pointer = PointerType; constexpr DeferInit(); constexpr ~DeferInit(); @@ -48,7 +47,7 @@ export namespace stormkit { inline namespace core { constexpr auto operator=(T&& value) noexcept(noexcept(std::is_nothrow_move_constructible_v)) -> void; - constexpr auto get(this auto&& self) noexcept -> decltype(auto); + constexpr auto value(this auto&& self) noexcept -> decltype(auto); constexpr auto operator->(this auto& self) noexcept -> decltype(auto); constexpr auto operator*(this auto&& self) noexcept -> decltype(auto); @@ -56,7 +55,7 @@ export namespace stormkit { inline namespace core { constexpr operator const T&() const noexcept; constexpr explicit operator bool() const noexcept; - constexpr auto initialized() const noexcept -> bool; + constexpr auto has_value() const noexcept -> bool; private: constexpr auto reset() noexcept -> void; @@ -74,12 +73,14 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - STORMKIT_FORCE_INLINE constexpr DeferInit::DeferInit() = default; + STORMKIT_FORCE_INLINE + constexpr DeferInit::DeferInit() = default; //////////////////////////////////////// //////////////////////////////////////// template - STORMKIT_FORCE_INLINE constexpr DeferInit::~DeferInit() { + STORMKIT_FORCE_INLINE + constexpr DeferInit::~DeferInit() { reset(); } @@ -90,8 +91,8 @@ namespace stormkit { inline namespace core { constexpr DeferInit::DeferInit(DeferInit&& other) noexcept(noexcept(std::is_nothrow_move_constructible_v)) { reset(); - if (other.initialized()) [[likely]] { - m_pointer = new (std::data(m_data)) T { std::move(other.get()) }; + if (other.has_value()) [[likely]] { + m_pointer = new (std::data(m_data)) T { std::move(other.value()) }; other.reset(); } @@ -108,8 +109,8 @@ namespace stormkit { inline namespace core { reset(); - if (other.initialized()) [[likely]] { - m_pointer = new (std::data(m_data)) T { std::move(other.get()) }; + if (other.has_value()) [[likely]] { + m_pointer = new (std::data(m_data)) T { std::move(other.value()) }; other.reset(); } @@ -158,14 +159,14 @@ namespace stormkit { inline namespace core { template STORMKIT_FORCE_INLINE constexpr DeferInit::operator bool() const noexcept { - return initialized(); + return has_value(); } //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto DeferInit::initialized() const noexcept -> bool { + constexpr auto DeferInit::has_value() const noexcept -> bool { return m_pointer != nullptr; } @@ -175,7 +176,7 @@ namespace stormkit { inline namespace core { STORMKIT_FORCE_INLINE constexpr auto DeferInit::reset() noexcept -> void { if (m_pointer) [[likely]] { - get().~T(); + value().~T(); m_pointer = nullptr; } } @@ -184,8 +185,8 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto DeferInit::get(this auto&& self) noexcept -> decltype(auto) { - expects(self.initialized(), "Underlying object is not initialized"); + constexpr auto DeferInit::value(this auto&& self) noexcept -> decltype(auto) { + expects(self.has_value(), "Underlying object is not has_value"); return std::forward_like(*self.m_pointer); } @@ -195,7 +196,7 @@ namespace stormkit { inline namespace core { template STORMKIT_FORCE_INLINE constexpr auto DeferInit::operator->(this auto& self) noexcept -> decltype(auto) { - expects(self.initialized(), "Underlying object is not initialized"); + expects(self.has_value(), "Underlying object is not has_value"); return std::forward_like(self.m_pointer); } @@ -205,7 +206,7 @@ namespace stormkit { inline namespace core { template STORMKIT_FORCE_INLINE constexpr auto DeferInit::operator*(this auto&& self) noexcept -> decltype(auto) { - return std::forward_like(self.get()); + return std::forward_like(self.value()); } ///////////////////////////////////// @@ -213,7 +214,7 @@ namespace stormkit { inline namespace core { template STORMKIT_FORCE_INLINE constexpr DeferInit::operator T&() noexcept { - return get(); + return value(); } ///////////////////////////////////// @@ -221,8 +222,8 @@ namespace stormkit { inline namespace core { template STORMKIT_FORCE_INLINE constexpr DeferInit::operator const T&() const noexcept { - return get(); + return value(); } }} // namespace stormkit::core -static_assert(stormkit::meta::IsContainedSemantics>); +static_assert(stormkit::meta::IsContainer>); diff --git a/modules/stormkit/gpu/core.cppm b/modules/stormkit/gpu/core.cppm index 51b782769..118ef0c6b 100644 --- a/modules/stormkit/gpu/core.cppm +++ b/modules/stormkit/gpu/core.cppm @@ -4,9 +4,13 @@ export module stormkit.gpu.core; +export import :base; export import :loader; -export import :device; +export import :physical_device; export import :instance; +export import :debug_callback; +export import :surface; +export import :device; export import :structs; export import :sync; export import :vulkan; diff --git a/modules/stormkit/gpu/core/base.cppm b/modules/stormkit/gpu/core/base.cppm new file mode 100644 index 000000000..da9ff7c8e --- /dev/null +++ b/modules/stormkit/gpu/core/base.cppm @@ -0,0 +1,403 @@ +// Copyright (C) 2023 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include +#include + +#include +#include + +export module stormkit.gpu.core:base; + +import std; + +import stormkit.core; + +import :structs; +import :vulkan; + +namespace cmeta = stormkit::core::meta; + +export namespace stormkit::gpu { + template + class Owned; + + namespace meta { + template + struct ObjectInfo; + + template + concept HasRequiresInfo = requires(ObjectInfo value) { value; }; + + template + concept CreateAllocateDisabled = HasRequiresInfo and requires() { + { ObjectInfo::DISABLE_CREATE_ALLOCATE } -> cmeta::IsBooleanTestable; + } and ObjectInfo::DISABLE_CREATE_ALLOCATE; + + template + concept IsOwnedByOther = HasRequiresInfo and requires(T) { typename ObjectInfo::OwnedBy; }; + + template + concept IsOwned = HasRequiresInfo; + } // namespace meta + + template + class View; + + namespace meta { + template + concept IsView = not IsOwned and requires(const T& value) { + typename T::ElementType; + typename T::ViewType; + { value.native_handle() } -> cmeta::Is; + }; + + template + concept IsOwnedOrView = IsOwned or IsView; + + template + concept DoInitReturnExpected = requires(T& foo, Args&&... args) { + { foo.do_init(T::PRIVATE, std::forward(args)...) } -> cmeta::SameAs>; + }; + template + concept DoInitReturnVoid = requires(T& foo, Args&&... args) { + { foo.do_init(T::PRIVATE, std::forward(args)...) } -> cmeta::SameAs; + }; + } // namespace meta + + STORMKIT_GPU_API + auto initialize_backend() -> Expected; + + template + class View { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using ViewType = ObjectInfo::ViewType; + + View(const T& of) noexcept; + template U> + View(const U& of) noexcept; + ~View() noexcept; + + View(const View&) noexcept; + auto operator=(const View&) noexcept -> View&; + + View(View&&) noexcept; + auto operator=(View&&) noexcept -> View&; + + [[nodiscard]] + auto native_handle() const noexcept -> ElementType; + + operator ElementType() const noexcept; + + protected: + ElementType m_vk_handle; + }; + + template + class Owned { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using DeleterType = ObjectInfo::DeleterType; + using ViewType = ObjectInfo::ViewType; + ~Owned() noexcept; + + Owned(const Owned&) = delete; + auto operator=(const Owned&) noexcept -> Owned& = delete; + + Owned(Owned&&) noexcept; + auto operator=(Owned&&) noexcept -> Owned&; + + template + [[nodiscard]] + static auto create(Args&&... args) noexcept -> decltype(auto) + requires(not meta::CreateAllocateDisabled); + + template + [[nodiscard]] + static auto allocate(Args&&... args) noexcept -> decltype(auto) + requires(not meta::CreateAllocateDisabled); + + [[nodiscard]] + auto native_handle() const noexcept -> ElementType; + + operator ElementType() const noexcept; + + protected: + static constexpr struct PrivateTag { + } PRIVATE; + + explicit Owned(DeleterType&& deleter_ptr) noexcept; + + ElementType m_vk_handle; + DeleterType m_deleter_ptr; + }; + + template + auto to_view(T value) noexcept -> T; + + template + auto to_view(const T& value) noexcept -> typename T::ViewType; + + template U> + auto to_view(const U& value) noexcept -> typename T::ViewType; + + template class Out = std::array, typename... Args> + auto to_views(const Args&... args) noexcept -> decltype(auto); + + template class Out = std::vector, typename... Args> + auto to_views(const Args&... args) noexcept -> decltype(auto); +} // namespace stormkit::gpu + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit::gpu { + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline Owned::Owned(DeleterType&& deleter_ptr) noexcept + : m_deleter_ptr { std::move(deleter_ptr) } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline Owned::~Owned() noexcept { + if constexpr (cmeta::SameAs) { + if (m_deleter_ptr != nullptr and m_vk_handle != VK_NULL_HANDLE) vk::call(m_deleter_ptr, m_vk_handle, nullptr); + m_vk_handle = VK_NULL_HANDLE; + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline Owned::Owned(Owned&& other) noexcept + : m_vk_handle { std::exchange(other.m_vk_handle, VK_NULL_HANDLE) }, m_deleter_ptr { std::move(other.m_deleter_ptr) } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Owned::operator=(Owned&& other) noexcept -> Owned& { + if (&other == this) [[unlikely]] + return *this; + + m_vk_handle = std::exchange(other.m_vk_handle, VK_NULL_HANDLE); + m_deleter_ptr = std::move(other.m_deleter_ptr); + + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Owned::native_handle() const noexcept -> ElementType { + EXPECTS(m_vk_handle != VK_NULL_HANDLE); + return m_vk_handle; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline Owned::operator ElementType() const noexcept { + return native_handle(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + template + STORMKIT_FORCE_INLINE + inline auto Owned::create(Args&&... args) noexcept -> decltype(auto) + requires(not meta::CreateAllocateDisabled) + { + if constexpr (meta::IsOwnedByOther) { + auto out = T { PRIVATE, std::forward(args...[0]) }; + return [](auto&& out, auto&&, Args2&&... args2) static noexcept -> decltype(auto) { + if constexpr (meta::DoInitReturnExpected) { + auto out_expected = Expected { std::in_place, std::move(out) }; + if (auto result = out.do_init(PRIVATE, std::forward(args2)...); not result) + out_expected = std::unexpected { std::move(result).error() }; + + return out_expected; + } else if constexpr (meta::DoInitReturnVoid) { + out.do_init(PRIVATE, std::forward(args2)...); + return out; + } + }(std::move(out), std::forward(args)...); + } else { + auto out = T { PRIVATE }; + if constexpr (meta::DoInitReturnExpected) { + auto out_expected = Expected { std::in_place, std::move(out) }; + if (auto result = out.do_init(PRIVATE, std::forward(args)...); not result) + out_expected = std::unexpected { std::move(result).error() }; + + return out_expected; + } else if constexpr (meta::DoInitReturnVoid) { + out.do_init(PRIVATE, std::forward(args)...); + return out; + } + } + + std::unreachable(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + template + STORMKIT_FORCE_INLINE + inline auto Owned::allocate(Args&&... args) noexcept -> decltype(auto) + requires(not meta::CreateAllocateDisabled) + { + if constexpr (meta::IsOwnedByOther) { + auto out = core::allocate_unsafe(PRIVATE, std::forward(args...[0])); + return [](auto&& out, auto&&, Args2&&... args2) static noexcept -> Expected> { + if constexpr (meta::DoInitReturnExpected) { + auto out_expected = Expected> { std::in_place, std::move(out) }; + if (auto result = out->do_init(PRIVATE, std::forward(args2)...); not result) + out_expected = std::unexpected { std::move(result).error() }; + + return out_expected; + } else if constexpr (meta::DoInitReturnVoid) { + out->do_init(PRIVATE, std::forward(args2)...); + return out; + } + }(std::move(out), std::forward(args)...); + } else { + auto out = core::allocate_unsafe(PRIVATE); + if constexpr (meta::DoInitReturnExpected) { + auto out_expected = Expected> { std::in_place, std::move(out) }; + if (auto result = out.do_init(PRIVATE, std::forward(args)...); not result) + out_expected = std::unexpected { std::move(result).error() }; + + return out_expected; + } else if constexpr (meta::DoInitReturnVoid) { + out->do_init(PRIVATE, std::forward(args)...); + return out; + } + } + + std::unreachable(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline View::View(const T& of) noexcept + : m_vk_handle { of.native_handle() } { + ENSURES(m_vk_handle != VK_NULL_HANDLE); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + template U> + STORMKIT_FORCE_INLINE + inline View::View(const U& object) noexcept + : m_vk_handle { object->native_handle() } { + ENSURES(m_vk_handle != VK_NULL_HANDLE); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline View::~View() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline View::View(const View&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto View::operator=(const View&) noexcept -> View& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline View::View(View&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto View::operator=(View&&) noexcept -> View& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto View::native_handle() const noexcept -> ElementType { + EXPECTS(m_vk_handle != VK_NULL_HANDLE); + return m_vk_handle; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline View::operator ElementType() const noexcept { + return native_handle(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto to_view(T&& value) noexcept -> T { + return std::forward(value); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto to_view(const T& value) noexcept -> typename T::ViewType { + return typename T::ViewType { value }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template U> + STORMKIT_FORCE_INLINE + inline auto to_view(const U& value) noexcept -> typename T::ViewType { + return to_view(*value); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template class Out = std::array, typename... Args> + STORMKIT_FORCE_INLINE + inline auto to_views(Args&&... args) noexcept -> decltype(auto) { + return Out { to_view(std::forward(args))... }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template class Out = std::vector, typename... Args> + STORMKIT_FORCE_INLINE + inline auto to_views(const Args&... args) noexcept -> decltype(auto) { + return Out { to_view(std::forward(args))... }; + } +} // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/core/debug_callback.cppm b/modules/stormkit/gpu/core/debug_callback.cppm new file mode 100644 index 000000000..e61be8ad3 --- /dev/null +++ b/modules/stormkit/gpu/core/debug_callback.cppm @@ -0,0 +1,92 @@ +// Copyright (C) 2023 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include +#include + +export module stormkit.gpu.core:debug_callback; + +import std; + +import stormkit.core; + +import :base; +import :vulkan; +import :structs; +import :instance; + +export namespace stormkit::gpu { + class DebugCallback; + + namespace view { + using DebugCallback = View; + } + + namespace meta { + template<> + struct ObjectInfo { + using Of = DebugCallback; + using ElementType = VkDebugUtilsMessengerEXT; + using DeleterType = PFN_vkDestroyDebugUtilsMessengerEXT; + using ViewType = view::DebugCallback; + using OwnedBy = Instance; + + static constexpr auto DEBUG_TYPE = DebugObjectType::DEBUG_UTILS_MESSENGER; + }; + } // namespace meta + + class STORMKIT_GPU_API DebugCallback: public OwnedByInstance { + public: + static constexpr auto DEBUG_TYPE = DebugObjectType::DEBUG_UTILS_MESSENGER; + + using Closure = PFN_vkDebugUtilsMessengerCallbackEXT; + + ~DebugCallback(); + + DebugCallback(const DebugCallback&) = delete; + auto operator=(const DebugCallback&) -> DebugCallback& = delete; + + DebugCallback(DebugCallback&&) noexcept; + auto operator=(DebugCallback&&) noexcept -> DebugCallback&; + + // clang-format off + // private: + // clang-format on + DebugCallback(PrivateTag, view::Instance) noexcept; + auto do_init(PrivateTag, Closure, void* = nullptr) noexcept -> Expected; + }; +} // namespace stormkit::gpu + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit::gpu { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline DebugCallback::DebugCallback(PrivateTag, view::Instance instance) noexcept + : OwnedByInstance { std::move(instance), auto(vkDestroyDebugUtilsMessengerEXT) } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline DebugCallback::~DebugCallback() = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline DebugCallback::DebugCallback(DebugCallback&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto DebugCallback::operator=(DebugCallback&&) noexcept -> DebugCallback& = default; + +} // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/core/device.cppm b/modules/stormkit/gpu/core/device.cppm index 9ff191961..e1dc849bd 100644 --- a/modules/stormkit/gpu/core/device.cppm +++ b/modules/stormkit/gpu/core/device.cppm @@ -16,124 +16,209 @@ export module stormkit.gpu.core:device; import std; import stormkit.core; -import :vulkan; +import :vulkan; +import :base; +import :physical_device; import :structs; +import :instance; + +namespace cmeta = stormkit::core::meta; using namespace stormkit; -export { - namespace stormkit::gpu { - class PhysicalDevice; - class Instance; +export namespace stormkit::gpu { + namespace view { + class Device; class Fence; - class Semaphore; + } // namespace view - class STORMKIT_GPU_API Device { - struct PrivateFuncTag {}; + class Device; + + namespace meta { + template<> + struct ObjectInfo { + using Of = Device; + using ElementType = VkDevice; + using DeleterType = PFN_vkDestroyDevice VolkDeviceTable::*; + using ViewType = view::Device; + using OwnedBy = PhysicalDevice; - public: static constexpr auto DEBUG_TYPE = DebugObjectType::DEVICE; + }; + } // namespace meta + + class STORMKIT_GPU_API Device: public OwnedByPhysicalDevice { + public: + struct QueueEntry { + u32 id; + u32 count; + QueueFlag flags = QueueFlag {}; + }; - struct QueueEntry { - u32 id; - u32 count; - QueueFlag flags = QueueFlag {}; - }; + struct CreateInfo { + bool enable_swapchain = true; + bool enable_raytracing = false; + }; - struct Info { - bool enable_swapchain = true; - bool enable_raytracing = false; - }; + ~Device() noexcept; + + Device(const Device&) = delete; + auto operator=(const Device&) -> Device& = delete; + + Device(Device&&) noexcept; + auto operator=(Device&&) noexcept -> Device&; + + auto wait_idle() const noexcept -> Expected; + + auto wait_for_fences(std::span fences, + bool wait_all = true, + const std::chrono::milliseconds& timeout = std::chrono::milliseconds::max()) const noexcept + -> Expected; + auto wait_for_fence(view::Fence fence, + const std::chrono::milliseconds& timeout = std::chrono::milliseconds::max()) const noexcept + -> Expected; + + auto reset_fences(std::span fences) const noexcept -> Expected; + auto reset_fence(view::Fence fence) const noexcept -> Expected; + + template + auto set_object_name(const T& object, std::string_view name) const -> Expected; + + auto set_object_name(u64 object, DebugObjectType type, std::string_view name) const -> Expected; + + [[nodiscard]] + auto queue_entries() const noexcept -> const std::vector&; + + [[nodiscard]] + auto device_table() const noexcept -> const VolkDeviceTable&; + + [[nodiscard]] + auto allocator() const noexcept -> vk::Observer; + + Device(PrivateTag, view::PhysicalDevice) noexcept; + auto do_init(PrivateTag, const CreateInfo& = { true, false }) noexcept -> Expected; + + private: + std::vector m_queue_entries; - static auto create(const PhysicalDevice& physical_device, - const Instance& instance, - const Info& info = { true, false }) noexcept -> Expected; - static auto allocate(const PhysicalDevice& physical_device, - const Instance& instance, - const Info& info = { true, false }) noexcept -> Expected>; + VolkDeviceTable m_vk_device_table = {}; + VmaVulkanFunctions m_vma_function_table = {}; + vk::Owned m_vma_allocator = { vmaDestroyAllocator }; + }; + + namespace view { + class STORMKIT_GPU_API Device: public PhysicalDeviceObject { + public: + Device(const gpu::Device& of) noexcept; + template T> + Device(const T& of) noexcept; ~Device() noexcept; - Device(const Device&) = delete; - auto operator=(const Device&) -> Device& = delete; + Device(const Device&) noexcept; + auto operator=(const Device&) noexcept -> Device&; Device(Device&&) noexcept; auto operator=(Device&&) noexcept -> Device&; auto wait_idle() const noexcept -> Expected; - auto wait_for_fences(std::span> fences, - bool wait_all = true, - const std::chrono::milliseconds& timeout = std::chrono::milliseconds::max()) const noexcept + auto wait_for_fences(std::span fences, + bool wait_all = true, + const std::chrono::milliseconds& timeout = std::chrono::milliseconds::max()) const noexcept -> Expected; - auto wait_for_fence(const Fence& fence, + auto wait_for_fence(view::Fence fence, const std::chrono::milliseconds& timeout = std::chrono::milliseconds::max()) const noexcept -> Expected; - auto reset_fences(std::span> fences) const noexcept -> Expected; - auto reset_fence(const Fence& fence) const noexcept -> Expected; - - [[nodiscard]] - auto raster_queue_entry() const noexcept -> const QueueEntry&; - [[nodiscard]] - auto async_transfer_queue_entry() const noexcept -> const QueueEntry&; - [[nodiscard]] - auto async_compute_queue_entry() const noexcept -> const QueueEntry&; - - [[nodiscard]] - auto has_async_transfer_queue() const noexcept -> bool; - [[nodiscard]] - auto has_async_compute_queue() const noexcept -> bool; - - [[nodiscard]] - auto physical_device() const noexcept -> const PhysicalDevice&; + auto reset_fences(std::span fences) const noexcept -> Expected; + auto reset_fence(view::Fence fence) const noexcept -> Expected; - template + template auto set_object_name(const T& object, std::string_view name) const -> Expected; auto set_object_name(u64 object, DebugObjectType type, std::string_view name) const -> Expected; [[nodiscard]] - auto native_handle() const noexcept -> VkDevice; + auto queue_entries() const noexcept -> const std::vector&; [[nodiscard]] auto device_table() const noexcept -> const VolkDeviceTable&; [[nodiscard]] - auto allocator() const noexcept -> VmaAllocator; - - Device(const PhysicalDevice&, PrivateFuncTag) noexcept; + auto allocator() const noexcept -> vk::Observer; private: - auto do_init(const Instance&, const Info&) noexcept -> Expected; + std::vector m_queue_entries; + + VolkDeviceTable m_vk_device_table; + vk::Observer m_vma_allocator; + }; + + template + class DeviceObject: public PhysicalDeviceObject { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using ViewType = ObjectInfo::ViewType; + + DeviceObject(const T& child) noexcept; + template U> + DeviceObject(const U& child) noexcept; + ~DeviceObject() noexcept; + + DeviceObject(const DeviceObject&) noexcept; + auto operator=(const DeviceObject&) noexcept -> DeviceObject&; - Ref m_physical_device; + DeviceObject(DeviceObject&&) noexcept; + auto operator=(DeviceObject&&) noexcept -> DeviceObject&; - QueueEntry m_raster_queue; - std::optional m_async_transfert_queue; - std::optional m_async_compute_queue; + [[nodiscard]] + auto device() const noexcept -> const view::Device&; - VolkDeviceTable m_vk_device_table = zeroed(); - VkRAIIHandle m_vk_handle = { [](auto) static noexcept {} }; - VmaVulkanFunctions m_vma_function_table = zeroed(); - VkRAIIHandle m_vma_allocator = { [](auto handle) static noexcept { vmaDestroyAllocator(handle); } }; + protected: + Device m_device; }; + } // namespace view - STORMKIT_GPU_API - auto imgui_vk_loader(const char* func_name, void*) noexcept -> PFN_vkVoidFunction; - } // namespace stormkit::gpu + template + class OwnedByDevice: public OwnedByPhysicalDevice { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using DeleterType = ObjectInfo::DeleterType; + using ViewType = ObjectInfo::ViewType; - template - struct std::formatter { - template - [[nodiscard]] - constexpr auto parse(ParseContext& ctx) noexcept -> ParseContext::iterator; + ~OwnedByDevice() noexcept; + + OwnedByDevice(const OwnedByDevice&) = delete; + auto operator=(const OwnedByDevice&) -> OwnedByDevice& = delete; + + OwnedByDevice(OwnedByDevice&&) noexcept; + auto operator=(OwnedByDevice&&) noexcept -> OwnedByDevice&; - template [[nodiscard]] - auto format(const gpu::Device::QueueEntry& queue, FormatContext& ctx) const noexcept -> decltype(ctx.out()); + auto device() const noexcept -> const view::Device&; + + protected: + using Parent = OwnedByPhysicalDevice; + OwnedByDevice(view::Device&& device, DeleterType&& deleter_ptr) noexcept; + + view::Device m_device; }; -} + + namespace vk { + STORMKIT_GPU_API auto imgui_vk_loader(const char* func_name, void*) noexcept -> PFN_vkVoidFunction; + } + + template + auto format_as(const Device::QueueEntry& physical_device, FormatContext& ctx) noexcept -> decltype(ctx.out()); + + namespace monadic { + template + constexpr auto find_queue() noexcept -> decltype(auto); + } // namespace monadic +} // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// /// IMPLEMENTATION /// @@ -142,131 +227,258 @@ export { namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - inline Device::Device(const PhysicalDevice& physical_device, PrivateFuncTag) noexcept - : m_physical_device { as_ref(physical_device) } { + STORMKIT_FORCE_INLINE + inline Device::Device(PrivateTag, view::PhysicalDevice physical_device) noexcept + : OwnedByPhysicalDevice { std::move(physical_device), &VolkDeviceTable::vkDestroyDevice } { } ///////////////////////////////////// ///////////////////////////////////// - inline Device::~Device() noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Device::create(const PhysicalDevice& physical_device, const Instance& instance, const Info& info) noexcept - -> Expected { - auto device = Device { physical_device, PrivateFuncTag {} }; - return device.do_init(instance, info).transform(core::monadic::consume(device)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Device::allocate(const PhysicalDevice& physical_device, const Instance& instance, const Info& info) noexcept - -> Expected> { - auto device = core::allocate_unsafe(physical_device, PrivateFuncTag {}); - return device->do_init(instance, info).transform(core::monadic::consume(device)); + STORMKIT_FORCE_INLINE + inline Device::~Device() noexcept { + if (m_deleter_ptr != nullptr and m_vk_handle != VK_NULL_HANDLE) + vk::call(m_vk_device_table.*Parent::m_deleter_ptr, m_vk_handle, nullptr); + m_vk_handle = VK_NULL_HANDLE; } ///////////////////////////////////// ///////////////////////////////////// + STORMKIT_FORCE_INLINE inline Device::Device(Device&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// + STORMKIT_FORCE_INLINE inline auto Device::operator=(Device&&) noexcept -> Device& = default; ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::wait_for_fence(const Fence& fence, const std::chrono::milliseconds& timeout) const noexcept - -> Expected { - return wait_for_fences(as_refs(fence), true, timeout); - } + STORMKIT_FORCE_INLINE + template + inline auto Device::set_object_name(const T& object, std::string_view name) const -> Expected { + if (not vkSetDebugUtilsObjectNameEXT) return {}; - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Device::reset_fence(const Fence& fence) const noexcept -> Expected { - return reset_fences(as_refs(fence)); + auto&& vk_object = vk::to_vk(object); + return set_object_name(std::bit_cast(static_cast(vk_object)), + meta::ObjectInfo::DEBUG_TYPE, + std::move(name)); } ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::raster_queue_entry() const noexcept -> const QueueEntry& { - return m_raster_queue; + STORMKIT_FORCE_INLINE + inline auto Device::queue_entries() const noexcept -> const std::vector& { + return m_queue_entries; } ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::async_transfer_queue_entry() const noexcept -> const QueueEntry& { - EXPECTS(m_async_transfert_queue != std::nullopt); - - return *m_async_transfert_queue; + STORMKIT_FORCE_INLINE + inline auto Device::device_table() const noexcept -> const VolkDeviceTable& { + return m_vk_device_table; } ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::async_compute_queue_entry() const noexcept -> const QueueEntry& { - EXPECTS(m_async_compute_queue != std::nullopt); - - return *m_async_compute_queue; + STORMKIT_FORCE_INLINE + inline auto Device::allocator() const noexcept -> vk::Observer { + return m_vma_allocator; } - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Device::has_async_transfer_queue() const noexcept -> bool { - return m_async_transfert_queue != std::nullopt; + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Device::Device(const gpu::Device& of) noexcept + : PhysicalDeviceObject { of }, + m_queue_entries { of.queue_entries() }, + m_vk_device_table { of.device_table() }, + m_vma_allocator { of.allocator() } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + template T> + STORMKIT_FORCE_INLINE + inline Device::Device(const T& of) noexcept + : PhysicalDeviceObject { of }, + m_queue_entries { of->queue_entries() }, + m_vk_device_table { of->device_table() }, + m_vma_allocator { of->allocator() } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Device::~Device() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Device::Device(const Device&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Device::operator=(const Device&) noexcept -> Device& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Device::Device(Device&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Device::operator=(Device&&) noexcept -> Device& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Device::set_object_name(const T& object, std::string_view name) const -> Expected { + if (not vkSetDebugUtilsObjectNameEXT) return {}; + + auto&& vk_object = vk::to_vk(object); + return set_object_name(std::bit_cast(static_cast(vk_object)), T::DEBUG_TYPE, std::move(name)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Device::queue_entries() const noexcept -> const std::vector& { + return m_queue_entries; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Device::device_table() const noexcept -> const VolkDeviceTable& { + return m_vk_device_table; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Device::allocator() const noexcept -> vk::Observer { + return m_vma_allocator; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline DeviceObject::DeviceObject(const T& child) noexcept + : PhysicalDeviceObject { child }, m_device { child.device() } { + } + + /////////////////////////////////// + /////////////////////////////////// + template + template U> + STORMKIT_FORCE_INLINE + inline DeviceObject::DeviceObject(const U& child) noexcept + : PhysicalDeviceObject { child }, m_device { child->device() } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline DeviceObject::~DeviceObject() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline DeviceObject::DeviceObject(const DeviceObject&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto DeviceObject::operator=(const DeviceObject&) noexcept -> DeviceObject& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline DeviceObject::DeviceObject(DeviceObject&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto DeviceObject::operator=(DeviceObject&&) noexcept -> DeviceObject& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto DeviceObject::device() const noexcept -> const Device& { + return m_device; + } + } // namespace view + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline OwnedByDevice::OwnedByDevice(view::Device&& device, DeleterType&& deleter_ptr) noexcept + : Parent { clone(device.physical_device()), std::move(deleter_ptr) }, m_device { std::move(device) } { } ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::has_async_compute_queue() const noexcept -> bool { - return m_async_compute_queue != std::nullopt; + template + STORMKIT_FORCE_INLINE + inline OwnedByDevice::~OwnedByDevice() noexcept { + if constexpr (cmeta::SameAs) { + const auto& device_table = device().device_table(); + auto& vk_handle = Parent::m_vk_handle; + auto& deleter_ptr = Parent::m_deleter_ptr; + if (deleter_ptr != nullptr and vk_handle != VK_NULL_HANDLE) + vk::call(device_table.*Parent::deleter_ptr, vk_handle, nullptr); + vk_handle = VK_NULL_HANDLE; + } } ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::physical_device() const noexcept -> const PhysicalDevice& { - return m_physical_device; - } + template + STORMKIT_FORCE_INLINE + inline OwnedByDevice::OwnedByDevice(OwnedByDevice&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - template - inline auto Device::set_object_name(const T& object, std::string_view name) const -> Expected { - if (not vkSetDebugUtilsObjectNameEXT) return {}; - - auto&& vk_object = to_vk(object); - return set_object_name(std::bit_cast(static_cast(vk_object)), T::DEBUG_TYPE, name); - } + template + STORMKIT_FORCE_INLINE + inline auto OwnedByDevice::operator=(OwnedByDevice&&) noexcept -> OwnedByDevice& = default; ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::native_handle() const noexcept -> VkDevice { - EXPECTS(m_vk_handle.value() != nullptr); - return m_vk_handle.value(); + template + STORMKIT_FORCE_INLINE + inline auto OwnedByDevice::device() const noexcept -> const view::Device& { + return m_device; } ///////////////////////////////////// ///////////////////////////////////// - inline auto Device::device_table() const noexcept -> const VolkDeviceTable& { - return m_vk_device_table; + template + inline auto format_as(const Device::QueueEntry& queue, FormatContext& ctx) noexcept -> decltype(ctx.out()) { + return std::format_to(ctx.out(), "[QueueEntry: .id = {}, .count = {}, .flags = {}]", queue.id, queue.count, queue.flags); } - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Device::allocator() const noexcept -> VmaAllocator { - return m_vma_allocator; - } -} // namespace stormkit::gpu + namespace monadic { + ///////////////////////////////////// + ///////////////////////////////////// + template + constexpr auto find_queue() noexcept -> decltype(auto) { + return [](const auto& family) static noexcept { + return core::check_flag_bit(family.flags, flag) and (not core::check_flag_bit(family.flags, no_flag) and ...); + }; + } + } // namespace monadic -template -template -constexpr auto std::formatter::parse(ParseContext& ctx) noexcept -> ParseContext::iterator { - return ctx.begin(); -} - -template -template -auto std::formatter::format(const gpu::Device::QueueEntry& queue, - FormatContext& ctx) const noexcept -> decltype(ctx.out()) { - auto&& out = ctx.out(); - return format_to(out, "[Device::QueueEntry: .id = {}, .count = {}, .flags = {}]", queue.id, queue.count, queue.flags); -} +} // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/core/instance.cppm b/modules/stormkit/gpu/core/instance.cppm index 1e9aab715..c004ab7f6 100644 --- a/modules/stormkit/gpu/core/instance.cppm +++ b/modules/stormkit/gpu/core/instance.cppm @@ -6,6 +6,7 @@ module; #include #include +#include #include #include @@ -17,230 +18,119 @@ import std; import stormkit.core; import stormkit.wsi; +import :base; import :vulkan; import :structs; -import :device; -export { - namespace stormkit::gpu { - class PhysicalDevice; +export namespace stormkit::gpu { + class PhysicalDevice; - class STORMKIT_GPU_API Instance { - struct PrivateFuncTag {}; + class Instance; + class InstanceObject; - public: - static constexpr auto DEBUG_TYPE = DebugObjectType::INSTANCE; - - [[nodiscard]] - static auto create(std::string app_name = "", bool verbose = (STORMKIT_BUILD_TYPE == "DEBUG")) noexcept - -> Expected; - [[nodiscard]] - static auto allocate(std::string app_name = "", bool verbose = (STORMKIT_BUILD_TYPE == "DEBUG")) noexcept - -> Expected>; - ~Instance(); - - Instance(const Instance&) = delete; - auto operator=(const Instance&) -> Instance& = delete; - - Instance(Instance&&) noexcept; - auto operator=(Instance&&) noexcept -> Instance&; - - [[nodiscard]] - auto physical_devices() const noexcept -> const std::vector&; - - [[nodiscard]] - auto native_handle() const noexcept -> VkInstance; + namespace view { + using Instance = View; + } - constexpr Instance(std::string app_name, bool verbose, PrivateFuncTag) noexcept; + namespace meta { + template<> + struct ObjectInfo { + using Of = Instance; + using ElementType = VkInstance; + using DeleterType = PFN_vkDestroyInstance; + using ViewType = view::Instance; - private: - auto do_init() noexcept -> Expected; - auto do_load_instance() noexcept -> VulkanExpected; - auto do_init_debug_report_callback() noexcept -> VulkanExpected; - auto do_retrieve_physical_devices() noexcept -> VulkanExpected; + static constexpr auto DEBUG_TYPE = DebugObjectType::INSTANCE; + }; + } // namespace meta - std::string m_app_name; - bool m_validation_layers_enabled; + class STORMKIT_GPU_API Instance: public Owned { + public: + ~Instance(); - std::vector m_extensions; - std::vector m_physical_devices; + Instance(const Instance&) = delete; + auto operator=(const Instance&) -> Instance& = delete; - VkRAIIHandle m_vk_handle = { [](auto handle) static noexcept { vkDestroyInstance(handle, nullptr); } }; - VkRAIIHandle m_vk_debug_utils_handle = { [](auto) static noexcept {} }; - }; + Instance(Instance&&) noexcept; + auto operator=(Instance&&) noexcept -> Instance&; [[nodiscard]] - STORMKIT_GPU_API auto score_physical_device(const PhysicalDevice& physical_device) noexcept -> u64; + auto physical_devices() const noexcept -> const std::vector&; - class STORMKIT_GPU_API PhysicalDevice { - public: - static constexpr auto DEBUG_TYPE = DebugObjectType::PHYSICAL_DEVICE; - - ~PhysicalDevice(); + // clang-format off + // private: + // clang-format on + explicit Instance(PrivateTag) noexcept; + auto do_init(PrivateTag, std::string = "", bool = (STORMKIT_BUILD_TYPE == "DEBUG")) noexcept -> Expected; - PhysicalDevice(const PhysicalDevice&) = delete; - auto operator=(const PhysicalDevice&) -> PhysicalDevice& = delete; + private: + auto do_load_instance() noexcept -> Expected; + auto do_retrieve_physical_devices() noexcept -> Expected; - PhysicalDevice(PhysicalDevice&&) noexcept; - auto operator=(PhysicalDevice&&) noexcept -> PhysicalDevice&; - - [[nodiscard]] - auto check_extension_support(std::string_view extension) const noexcept -> bool; - [[nodiscard]] - auto check_extension_support(std::span extensions) const noexcept -> bool; - [[nodiscard]] - auto check_extension_support(std::span extensions) const noexcept -> bool; + std::vector m_extensions; + std::vector m_physical_devices; + }; - [[nodiscard]] - auto info() const noexcept -> const PhysicalDeviceInfo&; - [[nodiscard]] - auto capabilities() const noexcept -> const RenderCapabilities&; - [[nodiscard]] - auto memory_types() const noexcept -> const std::vector&; + namespace view { + template + class InstanceObject: public View { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using ViewType = ObjectInfo::ViewType; - [[nodiscard]] - auto queue_families() const noexcept -> const std::vector&; + InstanceObject(const T& child) noexcept; + template U> + InstanceObject(const U& child) noexcept; + ~InstanceObject() noexcept; - [[nodiscard]] - auto extensions() const noexcept -> const std::vector&; + InstanceObject(const InstanceObject&) noexcept; + auto operator=(const InstanceObject&) noexcept -> InstanceObject&; - [[nodiscard]] - auto formats_properties() const noexcept -> const std::vector>&; + InstanceObject(InstanceObject&&) noexcept; + auto operator=(InstanceObject&&) noexcept -> InstanceObject&; [[nodiscard]] - auto native_handle() const noexcept -> VkPhysicalDevice; - - private: - explicit PhysicalDevice(VkPhysicalDevice physical_device) noexcept; - - PhysicalDeviceInfo m_device_info; - RenderCapabilities m_capabilities; - std::vector m_memory_types; + auto instance() const noexcept -> const Instance&; - std::vector m_queue_families; - std::vector m_extensions; - std::vector> m_format_properties; - - VkPhysicalDevice m_vk_handle = nullptr; - friend class Instance; + protected: + Instance m_instance; }; + } // namespace view - class STORMKIT_GPU_API Surface { - struct PrivateFuncTag {}; - - public: - static constexpr auto DEBUG_TYPE = DebugObjectType::SURFACE; - - ~Surface(); + template + class OwnedByInstance: public Owned { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using DeleterType = ObjectInfo::DeleterType; + using ViewType = ObjectInfo::ViewType; - Surface(const Surface&) = delete; - auto operator=(const Surface&) -> Surface& = delete; + ~OwnedByInstance() noexcept; - Surface(Surface&&) noexcept; - auto operator=(Surface&&) noexcept -> Surface&; + OwnedByInstance(const OwnedByInstance&) = delete; + auto operator=(const OwnedByInstance&) -> OwnedByInstance& = delete; -#if false - [[nodiscard]] - static auto create_offscreen(const Instance& instance) noexcept -> Expected; - [[nodiscard]] - static auto allocate_offscreen(const Instance& instance) noexcept - -> Expected>; -#endif + OwnedByInstance(OwnedByInstance&&) noexcept; + auto operator=(OwnedByInstance&&) noexcept -> OwnedByInstance&; - [[nodiscard]] - static auto create_from_window(const Instance& instance, const wsi::Window& window) noexcept -> Expected; - [[nodiscard]] - static auto allocate_from_window(const Instance& instance, const wsi::Window& window) noexcept - -> Expected>; - - [[nodiscard]] - auto native_handle() const noexcept -> VkSurfaceKHR; + [[nodiscard]] + auto instance() const noexcept -> const view::Instance&; - constexpr explicit Surface(PrivateFuncTag) noexcept; + protected: + using Parent = Owned; - private: - auto do_init_offscreen(const Instance&) noexcept -> Expected; - auto do_init_from_window(const Instance&, const wsi::Window&) noexcept -> Expected; + OwnedByInstance(view::Instance&&, DeleterType&&) noexcept; - VkInstance m_vk_instance = nullptr; - VkRAIIHandle m_vk_handle = { [](auto) static noexcept {} }; - }; - } // namespace stormkit::gpu - - namespace std { - template - struct formatter { - template - STORMKIT_FORCE_INLINE - constexpr auto parse(ParseContext& ctx) -> decltype(auto) { - return ctx.begin(); - } - - template - STORMKIT_FORCE_INLINE - auto format(const stormkit::gpu::PhysicalDevice& device, FormatContext& ctx) const -> decltype(auto) { - auto&& out = ctx.out(); - const auto& info = device.info(); - return format_to(out, - "[name: {}, vendor: {}, id: {}, vulkan: {}.{}.{}, driver version: " - "{}.{}.{}]", - info.device_name, - info.vendor_name, - info.device_id, - info.api_major_version, - info.api_minor_version, - info.api_patch_version, - info.driver_major_version, - info.driver_minor_version, - info.driver_patch_version); - } - }; - } // namespace std -} + view::Instance m_instance; + }; +} // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// /// IMPLEMENTATION /// //////////////////////////////////////////////////////////////////// namespace stormkit::gpu { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - constexpr Instance::Instance(std::string app_name, bool enable_validation, PrivateFuncTag) noexcept - : m_app_name { std::move(app_name) }, m_validation_layers_enabled { enable_validation } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Instance::create(std::string app_name, bool enable_validation) noexcept -> Expected { - auto instance = Instance { std::move(app_name), enable_validation, PrivateFuncTag {} }; - return instance.do_init().transform(core::monadic::consume(instance)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Instance::allocate(std::string app_name, bool enable_validation) noexcept -> Expected> { - auto instance = core::allocate_unsafe(std::move(app_name), enable_validation, PrivateFuncTag {}); - return instance->do_init().transform(core::monadic::consume(instance)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Instance::~Instance() = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Instance::Instance(Instance&&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Instance::operator=(Instance&&) noexcept -> Instance& = default; - ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE @@ -248,126 +138,101 @@ namespace stormkit::gpu { return m_physical_devices; } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Instance::native_handle() const noexcept -> VkInstance { - EXPECTS(m_vk_handle); - return m_vk_handle; - } + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline InstanceObject::InstanceObject(const T& child) noexcept + : View { child }, m_instance { child.instance() } { + } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::info() const noexcept -> const PhysicalDeviceInfo& { - return m_device_info; - } + ///////////////////////////////////// + ///////////////////////////////////// + template + template U> + STORMKIT_FORCE_INLINE + inline InstanceObject::InstanceObject(const U& child) noexcept + : View { child }, m_instance { child->instance() } { + } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::capabilities() const noexcept -> const RenderCapabilities& { - return m_capabilities; - } + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline InstanceObject::~InstanceObject() noexcept = default; - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::memory_types() const noexcept -> const std::vector& { - return m_memory_types; - } + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline InstanceObject::InstanceObject(const InstanceObject&) noexcept = default; - ///////////////////////////////////// - ///////////////////////////////////// + ///////////////////////////////////// + ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::queue_families() const noexcept -> const std::vector& { - return m_queue_families; - } + inline auto InstanceObject::operator=(const InstanceObject&) noexcept -> InstanceObject& = default; - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::extensions() const noexcept -> const std::vector& { - return m_extensions; - } + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline InstanceObject::InstanceObject(InstanceObject&&) noexcept = default; - ///////////////////////////////////// - ///////////////////////////////////// + ///////////////////////////////////// + ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::formats_properties() const noexcept - -> const std::vector>& { - return m_format_properties; - } + inline auto InstanceObject::operator=(InstanceObject&&) noexcept -> InstanceObject& = default; - ///////////////////////////////////// - ///////////////////////////////////// + ///////////////////////////////////// + ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::native_handle() const noexcept -> VkPhysicalDevice { - EXPECTS(m_vk_handle); - return m_vk_handle; - } + inline auto InstanceObject::instance() const noexcept -> const view::Instance& { + return m_instance; + } + } // namespace view ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - constexpr Surface::Surface(PrivateFuncTag) noexcept { + inline OwnedByInstance::OwnedByInstance(view::Instance&& instance, DeleterType&& deleter_ptr) noexcept + : Parent { std::move(deleter_ptr) }, m_instance { std::move(instance) } { } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline Surface::~Surface() = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Surface::Surface(Surface&&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Surface::operator=(Surface&&) noexcept -> Surface& = default; - -#if false - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE inline auto Surface::create_offscreen(const Instance& instance) noexcept - -> Expected { - auto surface = Surface { PrivateFuncTag {} }; - return surface.do_init_offscreen(instance).transform(core::monadic::consume(instance)); + inline OwnedByInstance::~OwnedByInstance() noexcept { + if constexpr (cmeta::SameAs) { + auto& vk_handle = Parent::m_vk_handle; + auto& deleter_ptr = Parent::m_deleter_ptr; + if (deleter_ptr != nullptr and vk_handle != VK_NULL_HANDLE) vk::call(deleter_ptr, m_instance, vk_handle, nullptr); + vk_handle = VK_NULL_HANDLE; + } } ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE inline auto Surface::allocate_offscreen(const Instance& instance) noexcept - -> Expected> { - auto surface = core::allocate_unsafe(PrivateFuncTag {}); - return surface->do_init_offscreen(instance).transform(core::monadic::consume(instance)); - } -#endif - - ///////////////////////////////////// - ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto Surface::create_from_window(const Instance& instance, const wsi::Window& window) noexcept -> Expected { - auto surface = Surface { PrivateFuncTag {} }; - return surface.do_init_from_window(instance, window).transform(core::monadic::consume(surface)); - } + inline OwnedByInstance::OwnedByInstance(OwnedByInstance&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto Surface::allocate_from_window(const Instance& instance, const wsi::Window& window) noexcept - -> Expected> { - auto surface = core::allocate_unsafe(PrivateFuncTag {}); - return surface->do_init_from_window(instance, window).transform(core::monadic::consume(surface)); - } + inline auto OwnedByInstance::operator=(OwnedByInstance&&) noexcept -> OwnedByInstance& = default; ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto Surface::native_handle() const noexcept -> VkSurfaceKHR { - EXPECTS(m_vk_handle); - return m_vk_handle; + inline auto OwnedByInstance::instance() const noexcept -> const view::Instance& { + return m_instance; } } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/core/physical_device.cppm b/modules/stormkit/gpu/core/physical_device.cppm new file mode 100644 index 000000000..1add27cab --- /dev/null +++ b/modules/stormkit/gpu/core/physical_device.cppm @@ -0,0 +1,408 @@ +// Copyright (C) 2023 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include +#include + +#include +#include + +export module stormkit.gpu.core:physical_device; + +import std; + +import stormkit.core; + +import :base; +import :vulkan; +import :structs; +import :instance; + +export namespace stormkit::gpu { + namespace view { + class PhysicalDevice; + } + + class PhysicalDevice; + class PhysicalDeviceObject; + + namespace meta { + template<> + struct ObjectInfo { + using Of = PhysicalDevice; + using ElementType = VkPhysicalDevice; + using DeleterType = decltype(monadic::noop()); + using ViewType = view::PhysicalDevice; + using OwnedBy = Instance; + + static constexpr auto DEBUG_TYPE = DebugObjectType::PHYSICAL_DEVICE; + }; + } // namespace meta + + class STORMKIT_GPU_API PhysicalDevice: public OwnedByInstance { + public: + ~PhysicalDevice(); + + PhysicalDevice(const PhysicalDevice&) = delete; + auto operator=(const PhysicalDevice&) -> PhysicalDevice& = delete; + + PhysicalDevice(PhysicalDevice&&) noexcept; + auto operator=(PhysicalDevice&&) noexcept -> PhysicalDevice&; + + [[nodiscard]] + auto check_extension_support(std::string_view extension) const noexcept -> bool; + [[nodiscard]] + auto check_extension_support(std::span extensions) const noexcept -> bool; + [[nodiscard]] + auto check_extension_support(std::span extensions) const noexcept -> bool; + + [[nodiscard]] + auto info() const noexcept -> const PhysicalDeviceInfo&; + [[nodiscard]] + auto capabilities() const noexcept -> const RenderCapabilities&; + [[nodiscard]] + auto memory_types() const noexcept -> const std::vector&; + + [[nodiscard]] + auto queue_families() const noexcept -> const std::vector&; + + [[nodiscard]] + auto extensions() const noexcept -> const std::vector&; + + [[nodiscard]] + auto formats_properties() const noexcept -> const std::vector>&; + + // clang-format off + // private: + // clang-format on + explicit PhysicalDevice(PrivateTag, view::Instance) noexcept; + auto do_init(PrivateTag, VkPhysicalDevice) noexcept -> void; + + private: + mutable PhysicalDeviceInfo m_device_info; + mutable RenderCapabilities m_capabilities; + mutable std::vector m_memory_types; + + mutable std::vector m_queue_families; + mutable std::vector m_extensions; + mutable std::vector> m_format_properties; + }; + + namespace view { + class STORMKIT_GPU_API PhysicalDevice: public InstanceObject { + public: + PhysicalDevice(const gpu::PhysicalDevice& of) noexcept; + template T> + PhysicalDevice(const T& of) noexcept; + ~PhysicalDevice() noexcept; + + PhysicalDevice(const PhysicalDevice&) noexcept; + auto operator=(const PhysicalDevice&) noexcept -> PhysicalDevice&; + + PhysicalDevice(PhysicalDevice&&) noexcept; + auto operator=(PhysicalDevice&&) noexcept -> PhysicalDevice&; + + [[nodiscard]] + auto check_extension_support(std::string_view extension) const noexcept -> bool; + [[nodiscard]] + auto check_extension_support(std::span extensions) const noexcept -> bool; + [[nodiscard]] + auto check_extension_support(std::span extensions) const noexcept -> bool; + + [[nodiscard]] + auto info() const noexcept -> const PhysicalDeviceInfo&; + [[nodiscard]] + auto capabilities() const noexcept -> const RenderCapabilities&; + [[nodiscard]] + auto memory_types() const noexcept -> const std::vector&; + + [[nodiscard]] + auto queue_families() const noexcept -> const std::vector&; + + [[nodiscard]] + auto extensions() const noexcept -> const std::vector&; + + [[nodiscard]] + auto formats_properties() const noexcept -> const std::vector>&; + + private: + mutable PhysicalDeviceInfo m_device_info; + mutable RenderCapabilities m_capabilities; + mutable std::vector m_memory_types; + + mutable std::vector m_queue_families; + mutable std::vector m_extensions; + mutable std::vector> m_format_properties; + }; + + template + class PhysicalDeviceObject: public InstanceObject { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using ViewType = ObjectInfo::ViewType; + + PhysicalDeviceObject(const T& child) noexcept; + template U> + PhysicalDeviceObject(const U& child) noexcept; + ~PhysicalDeviceObject() noexcept; + + PhysicalDeviceObject(const PhysicalDeviceObject&) noexcept; + auto operator=(const PhysicalDeviceObject&) noexcept -> PhysicalDeviceObject&; + + PhysicalDeviceObject(PhysicalDeviceObject&&) noexcept; + auto operator=(PhysicalDeviceObject&&) noexcept -> PhysicalDeviceObject&; + + [[nodiscard]] + auto physical_device() const noexcept -> const PhysicalDevice&; + + protected: + PhysicalDevice m_physical_device; + }; + } // namespace view + + template + class OwnedByPhysicalDevice: public OwnedByInstance { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using DeleterType = ObjectInfo::DeleterType; + using ViewType = ObjectInfo::ViewType; + + ~OwnedByPhysicalDevice() noexcept; + + OwnedByPhysicalDevice(const OwnedByPhysicalDevice&) = delete; + auto operator=(const OwnedByPhysicalDevice&) -> OwnedByPhysicalDevice& = delete; + + OwnedByPhysicalDevice(OwnedByPhysicalDevice&&) noexcept; + auto operator=(OwnedByPhysicalDevice&&) noexcept -> OwnedByPhysicalDevice&; + + [[nodiscard]] + auto physical_device() const noexcept -> const view::PhysicalDevice&; + + protected: + using Parent = OwnedByInstance; + + OwnedByPhysicalDevice(view::PhysicalDevice&&, DeleterType&&) noexcept; + + view::PhysicalDevice m_physical_device; + }; + + [[nodiscard]] + STORMKIT_GPU_API auto score_physical_device(view::PhysicalDevice physical_device) noexcept -> u64; + + template + auto format_as(view::PhysicalDevice physical_device, FormatContext& ctx) noexcept -> decltype(ctx.out()); + + template + auto format_as(const PhysicalDevice& physical_device, FormatContext& ctx) noexcept -> decltype(ctx.out()); +} // namespace stormkit::gpu + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit::gpu { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline PhysicalDevice::PhysicalDevice(PrivateTag, view::Instance instance) noexcept + : OwnedByInstance { std::move(instance), monadic::noop() } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline PhysicalDevice::~PhysicalDevice() = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline PhysicalDevice::PhysicalDevice(PhysicalDevice&& other) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto PhysicalDevice::operator=(PhysicalDevice&& other) noexcept -> PhysicalDevice& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto PhysicalDevice::do_init(PrivateTag, VkPhysicalDevice physical_device) noexcept -> void { + m_vk_handle = physical_device; + } + + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline PhysicalDevice::PhysicalDevice(const gpu::PhysicalDevice& of) noexcept + : InstanceObject { of } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + template T> + STORMKIT_FORCE_INLINE + inline PhysicalDevice::PhysicalDevice(const T& of) noexcept + : InstanceObject { of } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline PhysicalDevice::~PhysicalDevice() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline PhysicalDevice::PhysicalDevice(const PhysicalDevice&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto PhysicalDevice::operator=(const PhysicalDevice&) noexcept -> PhysicalDevice& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline PhysicalDevice::PhysicalDevice(PhysicalDevice&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto PhysicalDevice::operator=(PhysicalDevice&&) noexcept -> PhysicalDevice& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline PhysicalDeviceObject::PhysicalDeviceObject(const T& child) noexcept + : InstanceObject { child }, m_physical_device { child.physical_device() } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + template U> + STORMKIT_FORCE_INLINE + inline PhysicalDeviceObject::PhysicalDeviceObject(const U& child) noexcept + : InstanceObject { child }, m_physical_device { child->physical_device() } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline PhysicalDeviceObject::~PhysicalDeviceObject() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline PhysicalDeviceObject::PhysicalDeviceObject(const PhysicalDeviceObject&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto PhysicalDeviceObject::operator=(const PhysicalDeviceObject&) noexcept -> PhysicalDeviceObject& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline PhysicalDeviceObject::PhysicalDeviceObject(PhysicalDeviceObject&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto PhysicalDeviceObject::operator=(PhysicalDeviceObject&&) noexcept -> PhysicalDeviceObject& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto PhysicalDeviceObject::physical_device() const noexcept -> const PhysicalDevice& { + return m_physical_device; + } + } // namespace view + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline OwnedByPhysicalDevice::OwnedByPhysicalDevice(view::PhysicalDevice&& physical_device, + DeleterType&& deleter_ptr) noexcept + : Parent { clone(physical_device.instance()), std::move(deleter_ptr) }, m_physical_device { std::move(physical_device) } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline OwnedByPhysicalDevice::~OwnedByPhysicalDevice() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline OwnedByPhysicalDevice::OwnedByPhysicalDevice(OwnedByPhysicalDevice&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto OwnedByPhysicalDevice::operator=(OwnedByPhysicalDevice&&) noexcept + -> OwnedByPhysicalDevice& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto OwnedByPhysicalDevice::physical_device() const noexcept -> const view::PhysicalDevice& { + return m_physical_device; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + inline auto format_as(const view::PhysicalDevice& physical_device, FormatContext& ctx) noexcept -> decltype(ctx.out()) { + const auto& info = physical_device.info(); + return std::format_to(ctx.out(), + "[name: {}, vendor: {}, id: {}, vulkan: {}.{}.{}, driver version: " + "{}.{}.{}]", + info.device_name, + info.vendor_name, + info.device_id, + info.api_major_version, + info.api_minor_version, + info.api_patch_version, + info.driver_major_version, + info.driver_minor_version, + info.driver_patch_version); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + inline auto format_as(const PhysicalDevice& physical_device, FormatContext& ctx) noexcept -> decltype(ctx.out()) { + const auto& info = physical_device.info(); + return std::format_to(ctx.out(), + "[name: {}, vendor: {}, id: {}, vulkan: {}.{}.{}, driver version: " + "{}.{}.{}]", + info.device_name, + info.vendor_name, + info.device_id, + info.api_major_version, + info.api_minor_version, + info.api_patch_version, + info.driver_major_version, + info.driver_minor_version, + info.driver_patch_version); + } +} // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/core/surface.cppm b/modules/stormkit/gpu/core/surface.cppm new file mode 100644 index 000000000..53ef8f708 --- /dev/null +++ b/modules/stormkit/gpu/core/surface.cppm @@ -0,0 +1,135 @@ +// Copyright (C) 2023 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include +#include +#include + +#include +#include + +export module stormkit.gpu.core:surface; + +import std; + +import stormkit.core; +import stormkit.wsi; + +import :base; +import :vulkan; +import :structs; +import :instance; + +export namespace stormkit::gpu { + class Surface; + + namespace view { + using Surface = InstanceObject; + } + + namespace meta { + template<> + struct ObjectInfo { + using Of = Surface; + using ElementType = VkSurfaceKHR; + using DeleterType = PFN_vkDestroySurfaceKHR; + using ViewType = view::Surface; + using OwnedBy = Instance; + + static constexpr auto DEBUG_TYPE = DebugObjectType::SURFACE; + }; + } // namespace meta + + class STORMKIT_GPU_API Surface: public OwnedByInstance { + public: + ~Surface(); + + Surface(const Surface&) = delete; + auto operator=(const Surface&) -> Surface& = delete; + + Surface(Surface&&) noexcept; + auto operator=(Surface&&) noexcept -> Surface&; + +#if false + [[nodiscard]] + static auto create_offscreen(view::Instance instance) noexcept -> Expected; + [[nodiscard]] + static auto allocate_offscreen(view::Instance instance) noexcept + -> Expected>; +#endif + + [[nodiscard]] + static auto create_from_window(view::Instance instance, const wsi::Window& window) noexcept -> Expected; + [[nodiscard]] + static auto allocate_from_window(view::Instance instance, const wsi::Window& window) noexcept -> Expected>; + + // clang-format off + // private: + // clang-format on + Surface(PrivateTag, view::Instance) noexcept; + auto do_init(PrivateTag) noexcept -> Expected; + auto do_init(PrivateTag, const wsi::Window&) noexcept -> Expected; + }; +} // namespace stormkit::gpu + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit::gpu { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Surface::Surface(PrivateTag, view::Instance instance) noexcept + : OwnedByInstance { std::move(instance), auto(vkDestroySurfaceKHR) } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Surface::~Surface() = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Surface::Surface(Surface&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Surface::operator=(Surface&&) noexcept -> Surface& = default; + +#if false + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE inline auto Surface::create_offscreen(view::Instance instance) noexcept + -> Expected { + return create(std::move(instance)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE inline auto Surface::allocate_offscreen(view::Instance instance) noexcept + -> Expected> { + return allocate(std::move(instance)); + } +#endif + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Surface::create_from_window(view::Instance instance, const wsi::Window& window) noexcept -> Expected { + return create(std::move(instance), window); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Surface::allocate_from_window(view::Instance instance, const wsi::Window& window) noexcept + -> Expected> { + return allocate(std::move(instance), window); + } +} // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/core/sync.cppm b/modules/stormkit/gpu/core/sync.cppm index fb4c62104..3f7c82a7b 100644 --- a/modules/stormkit/gpu/core/sync.cppm +++ b/modules/stormkit/gpu/core/sync.cppm @@ -6,6 +6,7 @@ module; #include #include +#include #include #include @@ -21,27 +22,47 @@ import :structs; import :device; export namespace stormkit::gpu { - class Device; + class Fence; + class Semaphore; + + namespace view { + class Fence; + using Semaphore = DeviceObject; + } // namespace view + + namespace meta { + template<> + struct ObjectInfo { + using Of = Fence; + using ElementType = VkFence; + using DeleterType = PFN_vkDestroyFence VolkDeviceTable::*; + using ViewType = view::Fence; + using OwnedBy = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::FENCE; + }; - class STORMKIT_GPU_API Fence { - struct PrivateFuncTag {}; + template<> + struct ObjectInfo { + using Of = Semaphore; + using ElementType = VkSemaphore; + using DeleterType = PFN_vkDestroySemaphore VolkDeviceTable::*; + using ViewType = view::Semaphore; + using OwnedBy = Device; - public: - static constexpr auto DEBUG_TYPE = DebugObjectType::FENCE; + static constexpr auto DEBUG_TYPE = DebugObjectType::SEMAPHORE; + }; + } // namespace meta + class STORMKIT_GPU_API Fence: public OwnedByDevice { + public: enum class Status { SIGNALED, UNSIGNALED, }; - [[nodiscard]] - static auto create(const Device& device, bool signaled = false) noexcept -> Expected; - [[nodiscard]] - static auto create_signaled(const Device& device) noexcept -> Expected; - [[nodiscard]] - static auto allocate(const Device& device, bool signaled = false) noexcept -> Expected>; - [[nodiscard]] - static auto allocate_signaled(const Device& device) noexcept -> Expected>; + static auto create_signaled(view::Device device) noexcept -> Expected; + static auto allocate_signaled(view::Device device) noexcept -> Expected>; ~Fence(); Fence(const Fence&) = delete; @@ -50,36 +71,36 @@ export namespace stormkit::gpu { Fence(Fence&&) noexcept; auto operator=(Fence&&) noexcept -> Fence&; - [[nodiscard]] - auto wait(const std::chrono::milliseconds& wait_for = std::chrono::milliseconds::max()) const -> Expected; - auto reset() -> Expected; - - [[nodiscard]] auto status() const noexcept -> Expected; + auto wait(const std::chrono::milliseconds& wait_for = std::chrono::milliseconds::max()) const noexcept + -> Expected; + auto reset() const noexcept -> Expected; + + // clang-format off + // private: + // clang-format on + Fence(PrivateTag, view::Device) noexcept; + auto do_init(PrivateTag, bool = false) noexcept -> Expected; + }; - [[nodiscard]] - auto native_handle() const noexcept -> VkFence; - - Fence(const Device&, PrivateFuncTag) noexcept; - - private: - auto do_init(bool) noexcept -> Expected; + namespace view { + class STORMKIT_GPU_API Fence: public view::DeviceObject { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using ViewType = ObjectInfo::ViewType; - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; - }; + using view::DeviceObject::DeviceObject; - class STORMKIT_GPU_API Semaphore { - struct PrivateFuncTag {}; + auto status() const noexcept -> Expected; + auto wait(const std::chrono::milliseconds& wait_for = std::chrono::milliseconds::max()) const noexcept + -> Expected; + auto reset() const noexcept -> Expected; + }; + } // namespace view + class STORMKIT_GPU_API Semaphore: public OwnedByDevice { public: - static constexpr auto DEBUG_TYPE = DebugObjectType::SEMAPHORE; - - [[nodiscard]] - static auto create(const Device& device) noexcept -> Expected; - [[nodiscard]] - static auto allocate(const Device& device) noexcept -> Expected>; ~Semaphore(); Semaphore(const Semaphore&) = delete; @@ -88,17 +109,11 @@ export namespace stormkit::gpu { Semaphore(Semaphore&&) noexcept; auto operator=(Semaphore&&) noexcept -> Semaphore&; - [[nodiscard]] - auto native_handle() const noexcept -> VkSemaphore; - - Semaphore(const Device&, PrivateFuncTag) noexcept; - - private: - auto do_init() noexcept -> Expected; - - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; + // clang-format off + // private: + // clang-format on + Semaphore(PrivateTag, view::Device) noexcept; + auto do_init(PrivateTag) noexcept -> Expected; }; } // namespace stormkit::gpu @@ -110,42 +125,22 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Fence::Fence(const Device& device, PrivateFuncTag) noexcept - : m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { - vk_device_table.vkDestroyFence(vk_device, handle, nullptr); - } } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Fence::create(const Device& device, bool signaled) noexcept -> Expected { - auto fence = Fence { device, PrivateFuncTag {} }; - return fence.do_init(signaled).transform(core::monadic::consume(fence)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Fence::create_signaled(const Device& device) noexcept -> Expected { - return create(device, true); + inline Fence::Fence(PrivateTag, view::Device device) noexcept + : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyFence } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Fence::allocate(const Device& device, bool signaled) noexcept -> Expected> { - auto fence = core::allocate_unsafe(device, PrivateFuncTag {}); - return fence->do_init(signaled).transform(core::monadic::consume(fence)); + inline auto Fence::create_signaled(view::Device device) noexcept -> Expected { + return create(std::move(device), true); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Fence::allocate_signaled(const Device& device) noexcept -> Expected> { - return allocate(device, true); + inline auto Fence::allocate_signaled(view::Device device) noexcept -> Expected> { + return allocate(std::move(device), true); } ///////////////////////////////////// @@ -166,88 +161,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Fence::status() const noexcept -> Expected { - static constexpr auto POSSIBLE_RESULTS = std::array { VK_SUCCESS, VK_NOT_READY }; - return vk_call(m_vk_device_table->vkGetFenceStatus, as_view(POSSIBLE_RESULTS), m_vk_device, m_vk_handle) - .transform([](auto&& result) static noexcept { - if (result == VK_NOT_READY) return Status::UNSIGNALED; - return Status::SIGNALED; - }) - .transform_error(monadic::from_vk()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Fence::wait(const std::chrono::milliseconds& wait_for) const -> Expected { - static constexpr auto POSSIBLE_RESULTS = std::array { VK_SUCCESS, VK_NOT_READY }; - return vk_call(m_vk_device_table->vkWaitForFences, - as_view(POSSIBLE_RESULTS), - m_vk_device, - 1u, - &m_vk_handle.value(), - true, - std::chrono::duration_cast(wait_for).count()) - .transform(monadic::from_vk()) - .transform_error(monadic::from_vk()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Fence::reset() -> Expected { - return vk_call(m_vk_device_table->vkResetFences, m_vk_device, 1u, &m_vk_handle.value()) - .transform_error(monadic::from_vk()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Fence::native_handle() const noexcept -> VkFence { - EXPECTS(m_vk_handle); - return m_vk_handle; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Fence::do_init(bool signaled) noexcept -> Expected { - const auto flags = (signaled) ? VkFenceCreateFlags { VK_FENCE_CREATE_SIGNALED_BIT } : VkFenceCreateFlags {}; - - const auto create_info = VkFenceCreateInfo { .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, - .pNext = nullptr, - .flags = flags }; - - return vk_call(m_vk_device_table->vkCreateFence, m_vk_device, &create_info, nullptr) - .transform(core::monadic::set(m_vk_handle)) - .transform_error(monadic::from_vk()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Semaphore::Semaphore(const Device& device, PrivateFuncTag) noexcept - : m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { - vk_device_table.vkDestroySemaphore(vk_device, handle, nullptr); - } } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Semaphore::create(const Device& device) noexcept -> Expected { - auto semaphore = Semaphore { device, PrivateFuncTag {} }; - return semaphore.do_init().transform(core::monadic::consume(semaphore)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Semaphore::allocate(const Device& device) noexcept -> Expected> { - auto semaphore = core::allocate_unsafe(device, PrivateFuncTag {}); - return semaphore->do_init().transform(core::monadic::consume(semaphore)); + inline Semaphore::Semaphore(PrivateTag, view::Device device) noexcept + : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroySemaphore } { } ///////////////////////////////////// @@ -268,23 +183,32 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Semaphore::native_handle() const noexcept -> VkSemaphore { - EXPECTS(m_vk_handle); - return m_vk_handle; + inline auto Device::wait_for_fence(view::Fence fence, const std::chrono::milliseconds& timeout) const noexcept + -> Expected { + return wait_for_fences(to_views(std::move(fence)), true, timeout); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Semaphore::do_init() noexcept -> Expected { - const auto create_info = VkSemaphoreCreateInfo { - .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - }; - - return vk_call(m_vk_device_table->vkCreateSemaphore, m_vk_device, &create_info, nullptr) - .transform(core::monadic::set(m_vk_handle)) - .transform_error(monadic::from_vk()); + inline auto Device::reset_fence(view::Fence fence) const noexcept -> Expected { + return reset_fences(to_views(std::move(fence))); } + + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Device::wait_for_fence(view::Fence fence, const std::chrono::milliseconds& timeout) const noexcept + -> Expected { + return wait_for_fences(to_views(std::move(fence)), true, timeout); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Device::reset_fence(view::Fence fence) const noexcept -> Expected { + return reset_fences(to_views(std::move(fence))); + } + } // namespace view } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/core/vulkan/enums.cppm b/modules/stormkit/gpu/core/vulkan/enums.cppm index eab76d793..0f4c96abe 100644 --- a/modules/stormkit/gpu/core/vulkan/enums.cppm +++ b/modules/stormkit/gpu/core/vulkan/enums.cppm @@ -222,6 +222,7 @@ export { COMMAND_BUFFER = VK_OBJECT_TYPE_COMMAND_BUFFER, COMMAND_POOL = VK_OBJECT_TYPE_COMMAND_POOL, DEBUG_REPORT_CALLBACK = VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT, + DEBUG_UTILS_MESSENGER = VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT, DESCRIPTOR_POOL = VK_OBJECT_TYPE_DESCRIPTOR_POOL, DESCRIPTOR_SET = VK_OBJECT_TYPE_DESCRIPTOR_SET, DESCRIPTOR_SET_LAYOUT = VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, @@ -796,15 +797,17 @@ export { inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - template - requires(core::meta::IsPlainEnumeration or core::meta::Is) - [[nodiscard]] - constexpr auto to_vk(U value) noexcept -> T; + namespace vk { + template + requires(core::meta::IsPlainEnumeration or core::meta::Is) + [[nodiscard]] + constexpr auto to_vk(U value) noexcept -> T; - template - requires(core::meta::IsPlainEnumeration or core::meta::Is) - [[nodiscard]] - constexpr auto from_vk(U value) noexcept -> T; + template + requires(core::meta::IsPlainEnumeration or core::meta::Is) + [[nodiscard]] + constexpr auto from_vk(U value) noexcept -> T; + } [[nodiscard]] constexpr auto from_image(image::Image::Format format) -> PixelFormat; @@ -1445,6 +1448,7 @@ export { stormkit::gpu::DebugObjectType::COMMAND_BUFFER, stormkit::gpu::DebugObjectType::COMMAND_POOL, stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK, + stormkit::gpu::DebugObjectType::DEBUG_UTILS_MESSENGER, stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL, stormkit::gpu::DebugObjectType::DESCRIPTOR_SET, stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT, @@ -1483,6 +1487,7 @@ export { case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: return "DebugObjectType::COMMAND_BUFFER"; case stormkit::gpu::DebugObjectType::COMMAND_POOL: return "DebugObjectType::COMMAND_POOL"; case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: return "DebugObjectType::DEBUG_REPORT_CALLBACK"; + case stormkit::gpu::DebugObjectType::DEBUG_UTILS_MESSENGER: return "DebugObjectType::DEBUG_UTILS_MESSENGER"; case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: return "DebugObjectType::DESCRIPTOR_POOL"; case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: return "DebugObjectType::DESCRIPTOR_SET"; case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; @@ -1521,6 +1526,7 @@ export { case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: return "DebugObjectType::COMMAND_BUFFER"; case stormkit::gpu::DebugObjectType::COMMAND_POOL: return "DebugObjectType::COMMAND_POOL"; case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: return "DebugObjectType::DEBUG_REPORT_CALLBACK"; + case stormkit::gpu::DebugObjectType::DEBUG_UTILS_MESSENGER: return "DebugObjectType::DEBUG_UTILS_MESSENGER"; case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: return "DebugObjectType::DESCRIPTOR_POOL"; case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: return "DebugObjectType::DESCRIPTOR_SET"; case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; @@ -3538,26 +3544,28 @@ namespace stormkit::gpu { return 0u; } - ///////////////////////////////////// - ///////////////////////////////////// - template - requires(core::meta::IsPlainEnumeration or core::meta::Is) - STORMKIT_FORCE_INLINE - STORMKIT_CONST - STORMKIT_INTRINSIC - constexpr auto to_vk(U value) noexcept -> T{ - return narrow(value); - } + namespace vk { + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(core::meta::IsPlainEnumeration or core::meta::Is) + STORMKIT_FORCE_INLINE + STORMKIT_CONST + STORMKIT_INTRINSIC + constexpr auto to_vk(U value) noexcept -> T{ + return narrow(value); + } - ///////////////////////////////////// - ///////////////////////////////////// - template - requires(core::meta::IsPlainEnumeration or core::meta::Is) - STORMKIT_FORCE_INLINE - STORMKIT_CONST - STORMKIT_INTRINSIC - constexpr auto from_vk(U value) noexcept -> T { - return narrow(value); + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(core::meta::IsPlainEnumeration or core::meta::Is) + STORMKIT_FORCE_INLINE + STORMKIT_CONST + STORMKIT_INTRINSIC + constexpr auto from_vk(U value) noexcept -> T { + return narrow(value); + } } ///////////////////////////////////// @@ -3637,416 +3645,416 @@ namespace stormkit::gpu { template - stormkit::gpu::AccessFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::AccessFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::AccessFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkAccessFlagBits); + stormkit::gpu::AccessFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkAccessFlagBits); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::AccessFlag); template - VkAccessFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AccessFlag); + VkAccessFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::AccessFlag); template - stormkit::gpu::AttachmentLoadOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::AttachmentLoadOperation STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::AttachmentLoadOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkAttachmentLoadOp); + stormkit::gpu::AttachmentLoadOperation STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkAttachmentLoadOp); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::AttachmentLoadOperation); template - VkAttachmentLoadOp STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentLoadOperation); + VkAttachmentLoadOp STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::AttachmentLoadOperation); template - stormkit::gpu::AttachmentStoreOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::AttachmentStoreOperation STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::AttachmentStoreOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkAttachmentStoreOp); + stormkit::gpu::AttachmentStoreOperation STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkAttachmentStoreOp); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::AttachmentStoreOperation); template - VkAttachmentStoreOp STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::AttachmentStoreOperation); + VkAttachmentStoreOp STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::AttachmentStoreOperation); template - stormkit::gpu::BlendFactor STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::BlendFactor STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::BlendFactor STORMKIT_GPU_API stormkit::gpu::from_vk(VkBlendFactor); + stormkit::gpu::BlendFactor STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkBlendFactor); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BlendFactor); template - VkBlendFactor STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BlendFactor); + VkBlendFactor STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BlendFactor); template - stormkit::gpu::BlendOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::BlendOperation STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::BlendOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkBlendOp); + stormkit::gpu::BlendOperation STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkBlendOp); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BlendOperation); template - VkBlendOp STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BlendOperation); + VkBlendOp STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BlendOperation); template - stormkit::gpu::BorderColor STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::BorderColor STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::BorderColor STORMKIT_GPU_API stormkit::gpu::from_vk(VkBorderColor); + stormkit::gpu::BorderColor STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkBorderColor); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BorderColor); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BorderColor); template - VkBorderColor STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BorderColor); + VkBorderColor STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BorderColor); template - stormkit::gpu::BufferUsageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::BufferUsageFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::BufferUsageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkBufferUsageFlagBits); + stormkit::gpu::BufferUsageFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkBufferUsageFlagBits); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BufferUsageFlag); template - VkBufferUsageFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::BufferUsageFlag); + VkBufferUsageFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BufferUsageFlag); template - stormkit::gpu::ColorComponentFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::ColorComponentFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::ColorComponentFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkColorComponentFlagBits); + stormkit::gpu::ColorComponentFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkColorComponentFlagBits); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ColorComponentFlag); template - VkColorComponentFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ColorComponentFlag); + VkColorComponentFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ColorComponentFlag); template - stormkit::gpu::ColorSpace STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::ColorSpace STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::ColorSpace STORMKIT_GPU_API stormkit::gpu::from_vk(VkColorSpaceKHR); + stormkit::gpu::ColorSpace STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkColorSpaceKHR); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ColorSpace); template - VkColorSpaceKHR STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ColorSpace); + VkColorSpaceKHR STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ColorSpace); template - stormkit::gpu::CommandBufferLevel STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::CommandBufferLevel STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::CommandBufferLevel STORMKIT_GPU_API stormkit::gpu::from_vk(VkCommandBufferLevel); + stormkit::gpu::CommandBufferLevel STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkCommandBufferLevel); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::CommandBufferLevel); template - VkCommandBufferLevel STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CommandBufferLevel); + VkCommandBufferLevel STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::CommandBufferLevel); template - stormkit::gpu::CompareOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::CompareOperation STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::CompareOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkCompareOp); + stormkit::gpu::CompareOperation STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkCompareOp); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::CompareOperation); template - VkCompareOp STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CompareOperation); + VkCompareOp STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::CompareOperation); template - stormkit::gpu::CullModeFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::CullModeFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::CullModeFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkCullModeFlagBits); + stormkit::gpu::CullModeFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkCullModeFlagBits); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::CullModeFlag); template - VkCullModeFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::CullModeFlag); + VkCullModeFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::CullModeFlag); template - stormkit::gpu::DebugObjectType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::DebugObjectType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::DebugObjectType STORMKIT_GPU_API stormkit::gpu::from_vk(VkObjectType); + stormkit::gpu::DebugObjectType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkObjectType); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DebugObjectType); template - VkObjectType STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DebugObjectType); + VkObjectType STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DebugObjectType); template - stormkit::gpu::DependencyFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::DependencyFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::DependencyFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkDependencyFlagBits); + stormkit::gpu::DependencyFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkDependencyFlagBits); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DependencyFlag); template - VkDependencyFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DependencyFlag); + VkDependencyFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DependencyFlag); template - stormkit::gpu::DescriptorType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::DescriptorType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::DescriptorType STORMKIT_GPU_API stormkit::gpu::from_vk(VkDescriptorType); + stormkit::gpu::DescriptorType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkDescriptorType); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DescriptorType); template - VkDescriptorType STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DescriptorType); + VkDescriptorType STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DescriptorType); template - stormkit::gpu::DynamicState STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::DynamicState STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::DynamicState STORMKIT_GPU_API stormkit::gpu::from_vk(VkDynamicState); + stormkit::gpu::DynamicState STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkDynamicState); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DynamicState); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DynamicState); template - VkDynamicState STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::DynamicState); + VkDynamicState STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DynamicState); template - stormkit::gpu::Filter STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::Filter STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::Filter STORMKIT_GPU_API stormkit::gpu::from_vk(VkFilter); + stormkit::gpu::Filter STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFilter); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::Filter); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::Filter); template - VkFilter STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::Filter); + VkFilter STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::Filter); template - stormkit::gpu::FormatFeatureFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::FormatFeatureFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::FormatFeatureFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFormatFeatureFlagBits); + stormkit::gpu::FormatFeatureFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFormatFeatureFlagBits); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::FormatFeatureFlag); template - VkFormatFeatureFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::FormatFeatureFlag); + VkFormatFeatureFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::FormatFeatureFlag); template - stormkit::gpu::FrontFace STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::FrontFace STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::FrontFace STORMKIT_GPU_API stormkit::gpu::from_vk(VkFrontFace); + stormkit::gpu::FrontFace STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFrontFace); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::FrontFace); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::FrontFace); template - VkFrontFace STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::FrontFace); + VkFrontFace STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::FrontFace); template - stormkit::gpu::GeometryFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::GeometryFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::GeometryFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkGeometryFlagBitsKHR); + stormkit::gpu::GeometryFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkGeometryFlagBitsKHR); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::GeometryFlag); template - VkGeometryFlagBitsKHR STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::GeometryFlag); + VkGeometryFlagBitsKHR STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::GeometryFlag); template - stormkit::gpu::GeometryType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::GeometryType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::GeometryType STORMKIT_GPU_API stormkit::gpu::from_vk(VkGeometryTypeKHR); + stormkit::gpu::GeometryType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkGeometryTypeKHR); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::GeometryType); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::GeometryType); template - VkGeometryTypeKHR STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::GeometryType); + VkGeometryTypeKHR STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::GeometryType); template - stormkit::gpu::ImageAspectFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::ImageAspectFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::ImageAspectFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkImageAspectFlagBits); + stormkit::gpu::ImageAspectFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkImageAspectFlagBits); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageAspectFlag); template - VkImageAspectFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageAspectFlag); + VkImageAspectFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageAspectFlag); template - stormkit::gpu::ImageCreateFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::ImageCreateFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::ImageCreateFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkImageCreateFlagBits); + stormkit::gpu::ImageCreateFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkImageCreateFlagBits); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageCreateFlag); template - VkImageCreateFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageCreateFlag); + VkImageCreateFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageCreateFlag); template - stormkit::gpu::ImageLayout STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::ImageLayout STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::ImageLayout STORMKIT_GPU_API stormkit::gpu::from_vk(VkImageLayout); + stormkit::gpu::ImageLayout STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkImageLayout); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageLayout); template - VkImageLayout STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageLayout); + VkImageLayout STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageLayout); template - stormkit::gpu::ImageTiling STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::ImageTiling STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::ImageTiling STORMKIT_GPU_API stormkit::gpu::from_vk(VkImageTiling); + stormkit::gpu::ImageTiling STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkImageTiling); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageTiling); template - VkImageTiling STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageTiling); + VkImageTiling STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageTiling); template - stormkit::gpu::ImageType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::ImageType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::ImageType STORMKIT_GPU_API stormkit::gpu::from_vk(VkImageType); + stormkit::gpu::ImageType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkImageType); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageType); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageType); template - VkImageType STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageType); + VkImageType STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageType); template - stormkit::gpu::ImageUsageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::ImageUsageFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::ImageUsageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkImageUsageFlagBits); + stormkit::gpu::ImageUsageFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkImageUsageFlagBits); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageUsageFlag); template - VkImageUsageFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageUsageFlag); + VkImageUsageFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageUsageFlag); template - stormkit::gpu::ImageViewType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::ImageViewType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::ImageViewType STORMKIT_GPU_API stormkit::gpu::from_vk(VkImageViewType); + stormkit::gpu::ImageViewType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkImageViewType); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageViewType); template - VkImageViewType STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ImageViewType); + VkImageViewType STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageViewType); template - stormkit::gpu::LogicOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::LogicOperation STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::LogicOperation STORMKIT_GPU_API stormkit::gpu::from_vk(VkLogicOp); + stormkit::gpu::LogicOperation STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkLogicOp); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::LogicOperation); template - VkLogicOp STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::LogicOperation); + VkLogicOp STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::LogicOperation); template - stormkit::gpu::MemoryPropertyFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::MemoryPropertyFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::MemoryPropertyFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkMemoryPropertyFlagBits); + stormkit::gpu::MemoryPropertyFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkMemoryPropertyFlagBits); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::MemoryPropertyFlag); template - VkMemoryPropertyFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::MemoryPropertyFlag); + VkMemoryPropertyFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::MemoryPropertyFlag); template - stormkit::gpu::PhysicalDeviceType STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::PhysicalDeviceType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::PhysicalDeviceType STORMKIT_GPU_API stormkit::gpu::from_vk(VkPhysicalDeviceType); + stormkit::gpu::PhysicalDeviceType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkPhysicalDeviceType); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PhysicalDeviceType); template - VkPhysicalDeviceType STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PhysicalDeviceType); + VkPhysicalDeviceType STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PhysicalDeviceType); template - stormkit::gpu::PipelineBindPoint STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::PipelineBindPoint STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::PipelineBindPoint STORMKIT_GPU_API stormkit::gpu::from_vk(VkPipelineBindPoint); + stormkit::gpu::PipelineBindPoint STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkPipelineBindPoint); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PipelineBindPoint); template - VkPipelineBindPoint STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PipelineBindPoint); + VkPipelineBindPoint STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PipelineBindPoint); template - stormkit::gpu::PipelineStageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::PipelineStageFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::PipelineStageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkPipelineStageFlagBits); + stormkit::gpu::PipelineStageFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkPipelineStageFlagBits); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PipelineStageFlag); template - VkPipelineStageFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PipelineStageFlag); + VkPipelineStageFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PipelineStageFlag); template - stormkit::gpu::PixelFormat STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::PixelFormat STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::PixelFormat STORMKIT_GPU_API stormkit::gpu::from_vk(VkFormat); + stormkit::gpu::PixelFormat STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFormat); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PixelFormat); template - VkFormat STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PixelFormat); + VkFormat STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PixelFormat); template - stormkit::gpu::PolygonMode STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::PolygonMode STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::PolygonMode STORMKIT_GPU_API stormkit::gpu::from_vk(VkPolygonMode); + stormkit::gpu::PolygonMode STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkPolygonMode); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PolygonMode); template - VkPolygonMode STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PolygonMode); + VkPolygonMode STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PolygonMode); template - stormkit::gpu::PresentMode STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::PresentMode STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::PresentMode STORMKIT_GPU_API stormkit::gpu::from_vk(VkPresentModeKHR); + stormkit::gpu::PresentMode STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkPresentModeKHR); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PresentMode); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PresentMode); template - VkPresentModeKHR STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PresentMode); + VkPresentModeKHR STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PresentMode); template - stormkit::gpu::PrimitiveTopology STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::PrimitiveTopology STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::PrimitiveTopology STORMKIT_GPU_API stormkit::gpu::from_vk(VkPrimitiveTopology); + stormkit::gpu::PrimitiveTopology STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkPrimitiveTopology); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PrimitiveTopology); template - VkPrimitiveTopology STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::PrimitiveTopology); + VkPrimitiveTopology STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PrimitiveTopology); template - stormkit::gpu::QueueFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::QueueFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::QueueFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkQueueFlagBits); + stormkit::gpu::QueueFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkQueueFlagBits); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::QueueFlag); template - VkQueueFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::QueueFlag); + VkQueueFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::QueueFlag); template - stormkit::gpu::ResolveModeFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::ResolveModeFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::ResolveModeFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkResolveModeFlagBits); + stormkit::gpu::ResolveModeFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkResolveModeFlagBits); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ResolveModeFlag); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ResolveModeFlag); template - VkResolveModeFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ResolveModeFlag); + VkResolveModeFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ResolveModeFlag); template - stormkit::gpu::Result STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::Result STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::Result STORMKIT_GPU_API stormkit::gpu::from_vk(VkResult); + stormkit::gpu::Result STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkResult); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::Result); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::Result); template - VkResult STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::Result); + VkResult STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::Result); template - stormkit::gpu::SampleCountFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::SampleCountFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::SampleCountFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkSampleCountFlagBits); + stormkit::gpu::SampleCountFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkSampleCountFlagBits); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::SampleCountFlag); template - VkSampleCountFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SampleCountFlag); + VkSampleCountFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::SampleCountFlag); template - stormkit::gpu::SamplerAddressMode STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::SamplerAddressMode STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::SamplerAddressMode STORMKIT_GPU_API stormkit::gpu::from_vk(VkSamplerAddressMode); + stormkit::gpu::SamplerAddressMode STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkSamplerAddressMode); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::SamplerAddressMode); template - VkSamplerAddressMode STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SamplerAddressMode); + VkSamplerAddressMode STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::SamplerAddressMode); template - stormkit::gpu::SamplerMipmapMode STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::SamplerMipmapMode STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::SamplerMipmapMode STORMKIT_GPU_API stormkit::gpu::from_vk(VkSamplerMipmapMode); + stormkit::gpu::SamplerMipmapMode STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkSamplerMipmapMode); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::SamplerMipmapMode); template - VkSamplerMipmapMode STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::SamplerMipmapMode); + VkSamplerMipmapMode STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::SamplerMipmapMode); template - stormkit::gpu::ShaderStageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::ShaderStageFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::ShaderStageFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkShaderStageFlagBits); + stormkit::gpu::ShaderStageFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkShaderStageFlagBits); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ShaderStageFlag); template - VkShaderStageFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::ShaderStageFlag); + VkShaderStageFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ShaderStageFlag); template - stormkit::gpu::StencilFaceFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::StencilFaceFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::StencilFaceFlag STORMKIT_GPU_API stormkit::gpu::from_vk(VkStencilFaceFlagBits); + stormkit::gpu::StencilFaceFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkStencilFaceFlagBits); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::StencilFaceFlag); template - VkStencilFaceFlagBits STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::StencilFaceFlag); + VkStencilFaceFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::StencilFaceFlag); template - stormkit::gpu::VertexInputRate STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::VertexInputRate STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::VertexInputRate STORMKIT_GPU_API stormkit::gpu::from_vk(VkVertexInputRate); + stormkit::gpu::VertexInputRate STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkVertexInputRate); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::VertexInputRate); template - VkVertexInputRate STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::VertexInputRate); + VkVertexInputRate STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::VertexInputRate); diff --git a/modules/stormkit/gpu/core/vulkan/enums.cppm.tpl b/modules/stormkit/gpu/core/vulkan/enums.cppm.tpl index 97941c6d6..f57ddda58 100644 --- a/modules/stormkit/gpu/core/vulkan/enums.cppm.tpl +++ b/modules/stormkit/gpu/core/vulkan/enums.cppm.tpl @@ -45,15 +45,17 @@ export { inline constexpr auto details::IS_VULKAN_ENUMERATION<{% outfile:write(name) %}> = true; {% end %} - template - requires(core::meta::IsPlainEnumeration or core::meta::Is) - [[nodiscard]] - constexpr auto to_vk(U value) noexcept -> T; - - template - requires(core::meta::IsPlainEnumeration or core::meta::Is) - [[nodiscard]] - constexpr auto from_vk(U value) noexcept -> T; + namespace vk { + template + requires(core::meta::IsPlainEnumeration or core::meta::Is) + [[nodiscard]] + constexpr auto to_vk(U value) noexcept -> T; + + template + requires(core::meta::IsPlainEnumeration or core::meta::Is) + [[nodiscard]] + constexpr auto from_vk(U value) noexcept -> T; + } [[nodiscard]] constexpr auto from_image(image::Image::Format format) -> PixelFormat; @@ -300,26 +302,28 @@ namespace stormkit::gpu { return 0u; } - ///////////////////////////////////// - ///////////////////////////////////// - template - requires(core::meta::IsPlainEnumeration or core::meta::Is) - STORMKIT_FORCE_INLINE - STORMKIT_CONST - STORMKIT_INTRINSIC - constexpr auto to_vk(U value) noexcept -> T{ - return narrow(value); - } + namespace vk { + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(core::meta::IsPlainEnumeration or core::meta::Is) + STORMKIT_FORCE_INLINE + STORMKIT_CONST + STORMKIT_INTRINSIC + constexpr auto to_vk(U value) noexcept -> T{ + return narrow(value); + } - ///////////////////////////////////// - ///////////////////////////////////// - template - requires(core::meta::IsPlainEnumeration or core::meta::Is) - STORMKIT_FORCE_INLINE - STORMKIT_CONST - STORMKIT_INTRINSIC - constexpr auto from_vk(U value) noexcept -> T { - return narrow(value); + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(core::meta::IsPlainEnumeration or core::meta::Is) + STORMKIT_FORCE_INLINE + STORMKIT_CONST + STORMKIT_INTRINSIC + constexpr auto from_vk(U value) noexcept -> T { + return narrow(value); + } } ///////////////////////////////////// @@ -399,11 +403,11 @@ namespace stormkit::gpu { {% for name, enumeration in table.orderpairs(json_data) do %} template - stormkit::gpu::{% outfile:write(name) %} STORMKIT_GPU_API stormkit::gpu::from_vk(VkFlags); + stormkit::gpu::{% outfile:write(name) %} STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); template - stormkit::gpu::{% outfile:write(name) %} STORMKIT_GPU_API stormkit::gpu::from_vk({% outfile:write(enumeration.vktype) %}); + stormkit::gpu::{% outfile:write(name) %} STORMKIT_GPU_API stormkit::gpu::vk::from_vk({% outfile:write(enumeration.vktype) %}); template - VkFlags STORMKIT_GPU_API stormkit::gpu::to_vk(stormkit::gpu::{% outfile:write(name) %}); + VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::{% outfile:write(name) %}); template - {% outfile:write(enumeration.vktype) %} STORMKIT_GPU_API stormkit::gpu::to_vk<{% outfile:write(enumeration.vktype) %}>(stormkit::gpu::{% outfile:write(name) %}); + {% outfile:write(enumeration.vktype) %} STORMKIT_GPU_API stormkit::gpu::vk::to_vk<{% outfile:write(enumeration.vktype) %}>(stormkit::gpu::{% outfile:write(name) %}); {% end %} diff --git a/modules/stormkit/gpu/core/vulkan/mapping.json b/modules/stormkit/gpu/core/vulkan/mapping.json index 33d262724..81b3b7de6 100644 --- a/modules/stormkit/gpu/core/vulkan/mapping.json +++ b/modules/stormkit/gpu/core/vulkan/mapping.json @@ -565,8 +565,9 @@ "COMMAND_POOL": { "vulkan": "VK_OBJECT_TYPE_COMMAND_POOL", "webgpu": "" }, "SURFACE": { "vulkan": "VK_OBJECT_TYPE_SURFACE_KHR", "webgpu": "" }, "SWAPCHAIN": { "vulkan": "VK_OBJECT_TYPE_SWAPCHAIN_KHR", "webgpu": "" }, + "DISPLAY": { "vulkan": "VK_OBJECT_TYPE_DISPLAY_KHR", "webgpu": "" }, "DEBUG_REPORT_CALLBACK": { "vulkan": "VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT", "webgpu": "" }, - "DISPLAY": { "vulkan": "VK_OBJECT_TYPE_DISPLAY_KHR", "webgpu": "" } + "DEBUG_UTILS_MESSENGER": { "vulkan": "VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT", "webgpu": "" } } }, "AccessFlag": { diff --git a/modules/stormkit/gpu/core/vulkan/structs.cppm b/modules/stormkit/gpu/core/vulkan/structs.cppm index 9d25b8775..0ffdbc97c 100644 --- a/modules/stormkit/gpu/core/vulkan/structs.cppm +++ b/modules/stormkit/gpu/core/vulkan/structs.cppm @@ -14,15 +14,13 @@ import :structs; import :vulkan.volk; -export namespace stormkit::gpu { +export namespace stormkit::gpu::vk { template requires( requires { std::declval().native_handle(); } or requires { std::declval()->native_handle(); }) [[nodiscard]] auto to_vk(const T& value) noexcept -> decltype(auto); - struct ToVec; - template [[nodiscard]] constexpr auto to_vk(const math::ivec2& vector) noexcept -> Out; @@ -72,9 +70,9 @@ export namespace stormkit::gpu { template [[nodiscard]] constexpr auto from_vk(const VkExtent3D& viewport) noexcept -> Out; -} // namespace stormkit::gpu +} // namespace stormkit::gpu::vk -namespace stormkit::gpu { +namespace stormkit::gpu::vk { ///////////////////////////////////// ///////////////////////////////////// @@ -221,4 +219,4 @@ namespace stormkit::gpu { using T = typename Out::ElementType; return Out { .width = as(extent.width), .height = as(extent.height) }; } -} // namespace stormkit::gpu +} // namespace stormkit::gpu::vk diff --git a/modules/stormkit/gpu/core/vulkan/utils.cppm b/modules/stormkit/gpu/core/vulkan/utils.cppm index b30569be9..f0d619ea2 100644 --- a/modules/stormkit/gpu/core/vulkan/utils.cppm +++ b/modules/stormkit/gpu/core/vulkan/utils.cppm @@ -20,109 +20,144 @@ import :vulkan.structs; namespace stdr = std::ranges; -export namespace stormkit::gpu { +namespace cmeta = stormkit::core::meta; +namespace cmonadic = stormkit::core::monadic; + +export namespace stormkit::gpu::vk { + namespace meta { + template + concept IsVulkanFunc = std::invocable; + + template + concept HasOutValueAsArgument = IsVulkanFunc; + + template + concept HasNoReturnValue = IsVulkanFunc and cmeta::Is, void>; + + template + concept HasResultReturnValue = IsVulkanFunc and cmeta::Is, VkResult>; + } // namespace meta + template [[nodiscard]] - constexpr auto vk_make_version(T major, T minor, T patch) noexcept -> u32; + constexpr auto make_version(T major, T minor, T patch) noexcept -> u32; [[nodiscard]] - constexpr auto vk_version_major(std::integral auto version) noexcept -> u32; + constexpr auto version_major(std::integral auto version) noexcept -> u32; [[nodiscard]] - constexpr auto vk_version_minor(std::integral auto version) noexcept -> u32; + constexpr auto version_minor(std::integral auto version) noexcept -> u32; [[nodiscard]] - constexpr auto vk_version_patch(std::integral auto version) noexcept -> u32; + constexpr auto version_patch(std::integral auto version) noexcept -> u32; - template - using VulkanExpected = std::expected; + template Func> + requires meta::HasNoReturnValue + auto call(const Func& func, Args&&... args) noexcept -> void; - template - concept IsVulkanFuncWithResult = core::meta::Is, VkResult>; - - template - auto vk_call(const Func& func, Args&&... args) noexcept -> decltype(auto); - - template - requires(IsVulkanFuncWithResult) + template Func> + requires(not meta::HasNoReturnValue) [[nodiscard]] - auto vk_call(const Func& func, Args&&... args) noexcept -> decltype(auto); + auto call(const Func& func, Args&&... args) noexcept -> Out; - template + template Func> + requires meta::HasNoReturnValue [[nodiscard]] - auto vk_call(const Func& func, Args&&... args) noexcept -> decltype(auto); + auto call(const Func& func, Args&&... args) noexcept -> Out; + + template Func> + auto call_checked(const Func& func, Args&&... args) noexcept -> Expected; + + template Out, VkResult... SUCCESS_RESULTS, typename... Args, meta::HasResultReturnValue Func> + auto call_checked(const Func& func, Args&&... args) noexcept -> Expected; + + template Func> + requires meta::HasResultReturnValue + auto call_checked(const Func& func, Args&&... args) noexcept -> Expected; - template + template Func> + auto call_unchecked(const Func& func, Args&&... args) noexcept -> void; + + template Out, typename... Args, meta::HasResultReturnValue Func> [[nodiscard]] - auto vk_call(const Func& func, std::span success_result, Args&&... args) noexcept -> T; + auto call_unchecked(const Func& func, Args&&... args) noexcept -> VkResult; - template - requires(IsVulkanFuncWithResult or IsVulkanFuncWithResult) + template Func> + requires meta::HasResultReturnValue [[nodiscard]] - auto vk_call(const Func& func, std::span success_result, Args&&... args) noexcept -> VulkanExpected; + auto call_unchecked(const Func& func, Args&&... args) noexcept -> Out; - template - requires(IsVulkanFuncWithResult) + template Func> + requires(meta::HasNoReturnValue and not cmeta::SameAs) [[nodiscard]] - auto vk_allocate(usize count, const Func& func, Args&&... args) noexcept -> VulkanExpected>; + auto allocate(usize count, const Func& func, Args&&... args) noexcept -> std::vector; + + template Func> + requires(meta::HasResultReturnValue and not cmeta::SameAs) + auto allocate_checked(usize count, const Func& func, Args&&... args) noexcept -> Expected>; - template - requires(IsVulkanFuncWithResult) + template Func> + requires(meta::HasResultReturnValue and not cmeta::SameAs) [[nodiscard]] - auto vk_allocate(usize count, const Func& func, std::span possible_results, Args&&... args) noexcept - -> VulkanExpected>; + auto allocate_unchecked(usize count, const Func& func, Args&&... args) noexcept -> std::vector; - template + template Func> + requires(meta::HasNoReturnValue and not cmeta::SameAs) [[nodiscard]] - auto vk_enumerate(const Func& func, Args&&... args) noexcept -> decltype(auto); + auto enumerate(const Func& func, Args&&... args) noexcept -> std::vector; + + template Func> + requires(meta::HasResultReturnValue and not cmeta::SameAs) + auto enumerate_checked(const Func& func, Args&&... args) noexcept -> Expected>; - template - requires(IsVulkanFuncWithResult) + template Func> + requires(meta::HasResultReturnValue and not cmeta::SameAs) [[nodiscard]] - auto vk_enumerate(const Func& func, std::span possible_results, Args&&... args) noexcept - -> VulkanExpected>; + auto enumerate_unchecked(const Func& func, Args&&... args) noexcept -> std::vector; template - class VkRAIIHandle { + class Owned { public: // TODO function using Deleter = std::function; - constexpr VkRAIIHandle(Deleter deleter) noexcept : m_deleter { std::move(deleter) } {} + Owned(Deleter deleter) noexcept; + ~Owned() noexcept; - constexpr ~VkRAIIHandle() noexcept { - if (m_value) { - m_deleter(m_value); - m_value = nullptr; - } - } + Owned(const Owned&) = delete; + auto operator=(const Owned&) -> Owned& = delete; - VkRAIIHandle(const VkRAIIHandle&) = delete; - auto operator=(const VkRAIIHandle&) -> VkRAIIHandle& = delete; + Owned(Owned&& other) noexcept; + auto operator=(Owned&& other) noexcept -> Owned&; - constexpr VkRAIIHandle(VkRAIIHandle&& other) noexcept - : m_value { std::exchange(other.m_value, nullptr) }, m_deleter { std::move(other.m_deleter) } {} + auto operator=(T&& value) noexcept -> void; - constexpr auto operator=(VkRAIIHandle&& other) noexcept -> VkRAIIHandle& { - if (this == &other) [[unlikely]] - return *this; + auto value() const noexcept -> T; - m_value = std::exchange(other.m_value, nullptr); - m_deleter = std::move(other.m_deleter); + operator T() const noexcept; - return *this; - } + private: + T m_value = VK_NULL_HANDLE; + Deleter m_deleter; + }; - constexpr auto operator=(T&& value) noexcept -> void { - if (m_value == value) return; - if (m_value) m_deleter(m_value); - m_value = std::move(value); - } + template + class Observer { + public: + Observer(T value) noexcept; + Observer(const Owned& value) noexcept; + + ~Observer() noexcept; + + Observer(const Observer&) noexcept; + auto operator=(const Observer&) noexcept -> Observer&; + + Observer(Observer&&) noexcept; + auto operator=(Observer&&) noexcept -> Observer&; - constexpr auto value() const noexcept -> const T& { return m_value; } + auto value() const noexcept -> T; - constexpr operator T() const noexcept { return value(); } + operator T() const noexcept; private: - T m_value = nullptr; - Deleter m_deleter; + T m_value; }; namespace monadic { @@ -140,171 +175,382 @@ export namespace stormkit::gpu { [[nodiscard]] constexpr auto from_vk() noexcept -> decltype(auto); } // namespace monadic -} // namespace stormkit::gpu +} // namespace stormkit::gpu::vk //////////////////////////////////////////////////////////////////// /// IMPLEMENTATION /// //////////////////////////////////////////////////////////////////// -namespace stormkit::gpu { +namespace stormkit::gpu::vk { ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto vk_make_version(T major, T minor, T patch) noexcept -> u32 { - return vk_version_major(major) | vk_version_minor(minor) | vk_version_patch(patch); + constexpr auto make_version(T major, T minor, T patch) noexcept -> u32 { + return version_major(major) | version_minor(minor) | version_patch(patch); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST STORMKIT_INTRINSIC - constexpr auto vk_version_major(std::integral auto version) noexcept -> u32 { + constexpr auto version_major(std::integral auto version) noexcept -> u32 { return as(version) >> 22u; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST STORMKIT_INTRINSIC - constexpr auto vk_version_minor(std::integral auto version) noexcept -> u32 { + constexpr auto version_minor(std::integral auto version) noexcept -> u32 { return ((as(version) >> 12u) & 0x3ffu); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST STORMKIT_INTRINSIC - constexpr auto vk_version_patch(std::integral auto version) noexcept -> u32 { + constexpr auto version_patch(std::integral auto version) noexcept -> u32 { return as(version) & 0xfffu; } ///////////////////////////////////// ///////////////////////////////////// - template + template Func> + requires meta::HasNoReturnValue STORMKIT_FORCE_INLINE - inline auto vk_call(const Func& func, Args&&... args) noexcept -> decltype(auto) { + inline auto call(const Func& func, Args&&... args) noexcept -> void { std::invoke(func, std::forward(args)...); } ///////////////////////////////////// ///////////////////////////////////// - template - requires(IsVulkanFuncWithResult) + template Func> + requires(not meta::HasNoReturnValue) STORMKIT_FORCE_INLINE - inline auto vk_call(const Func& func, Args&&... args) noexcept -> decltype(auto) { - static constexpr auto POSSIBLE_RESULTS = std::array { VK_SUCCESS }; - return vk_call(func, as_view(POSSIBLE_RESULTS), std::forward(args)...); + inline auto call(const Func& func, Args&&... args) noexcept -> Out { + return std::invoke(func, std::forward(args)...); } ///////////////////////////////////// ///////////////////////////////////// - template + template Func> + requires meta::HasNoReturnValue STORMKIT_FORCE_INLINE - inline auto vk_call(const Func& func, Args&&... args) noexcept -> decltype(auto) { - static constexpr auto POSSIBLE_RESULTS = std::array { VK_SUCCESS }; - if constexpr (IsVulkanFuncWithResult or IsVulkanFuncWithResult) - return vk_call(func, as_view(POSSIBLE_RESULTS), std::forward(args)...); - else if constexpr (not core::meta::Is) { - auto out = T {}; - std::invoke(func, std::forward(args)..., &out); - return out; - } else - std::invoke(func, std::forward(args)...); + inline auto call(const Func& func, Args&&... args) noexcept -> Out { + auto out = Out {}; + std::invoke(func, std::forward(args)..., &out); + return out; } ///////////////////////////////////// ///////////////////////////////////// - template - requires(IsVulkanFuncWithResult or IsVulkanFuncWithResult) - inline auto vk_call(const Func& func, std::span success_result, Args&&... args) noexcept - -> VulkanExpected { - using Out = VulkanExpected; - auto out = Out { std::in_place }; + template Func> + inline auto call_checked(const Func& func, Args&&... args) noexcept -> Expected { + static constexpr auto SUCCESS_RESULTS = std::array { VK_SUCCESS, _SUCCESS_RESULTS... }; - const auto result = [&] noexcept { - if constexpr (core::meta::IsAnyOf) return std::invoke(func, std::forward(args)...); - else if constexpr (core::meta::Is) { - const auto _result = std::invoke(func, std::forward(args)...); - out = _result; - return _result; - } else - return std::invoke(func, std::forward(args)..., &(*out)); - }(); + using OutExpected = Expected; + auto out_expected = OutExpected { std::in_place }; - if (not stdr::any_of(success_result, core::monadic::is_equal(result))) [[likely]] - out = Out { std::unexpect, result }; + const auto result = std::invoke(func, std::forward(args)...); + if (not stdr::any_of(SUCCESS_RESULTS, cmonadic::is_equal(result))) [[likely]] + out_expected = std::unexpected { vk::from_vk(result) }; - return out; + return out_expected; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template Out, VkResult... _SUCCESS_RESULTS, typename... Args, meta::HasResultReturnValue Func> + inline auto call_checked(const Func& func, Args&&... args) noexcept -> Expected { + static constexpr auto SUCCESS_RESULTS = std::array { VK_SUCCESS, _SUCCESS_RESULTS... }; + + using OutExpected = Expected; + auto out_expected = OutExpected { std::in_place }; + + const auto result = std::invoke(func, std::forward(args)...); + if (not stdr::any_of(SUCCESS_RESULTS, cmonadic::is_equal(result))) [[likely]] + out_expected = std::unexpected { vk::from_vk(result) }; + else + out_expected = result; + + return out_expected; } ///////////////////////////////////// ///////////////////////////////////// - template - requires(IsVulkanFuncWithResult) + template Func> + requires meta::HasResultReturnValue + inline auto call_checked(const Func& func, Args&&... args) noexcept -> Expected { + static constexpr auto SUCCESS_RESULTS = std::array { VK_SUCCESS, _SUCCESS_RESULTS... }; + + using OutExpected = Expected; + auto out_expected = OutExpected { std::in_place }; + + auto out = Out {}; + const auto result = std::invoke(func, std::forward(args)..., &out); + if (not stdr::any_of(SUCCESS_RESULTS, cmonadic::is_equal(result))) [[likely]] + out_expected = std::unexpected { vk::from_vk(result) }; + else + out_expected = out; + + return out_expected; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template Func> STORMKIT_FORCE_INLINE - inline auto vk_allocate(usize count, const Func& func, Args&&... args) noexcept -> VulkanExpected> { - static constexpr auto POSSIBLE_RESULTS = std::array { VK_SUCCESS }; - return vk_allocate(count, func, as_view(POSSIBLE_RESULTS), std::forward(args)...); + inline auto call_unchecked(const Func& func, Args&&... args) noexcept -> void { + const auto _ = std::invoke(func, std::forward(args)...); } ///////////////////////////////////// ///////////////////////////////////// - template - requires(IsVulkanFuncWithResult) - inline auto vk_allocate(usize count, const Func& func, std::span possible_results, Args&&... args) noexcept - -> VulkanExpected> { - using Out = VulkanExpected>; - auto out = Out { std::in_place, count }; - auto result = std::invoke(func, std::forward(args)..., stdr::data(*out)); - if (not stdr::any_of(possible_results, core::monadic::is_equal(result))) [[unlikely]] - out = Out { std::unexpect, result }; + template Out, typename... Args, meta::HasResultReturnValue Func> + STORMKIT_FORCE_INLINE + inline auto call_unchecked(const Func& func, Args&&... args) noexcept -> Out { + return std::invoke(func, std::forward(args)...); + } + ///////////////////////////////////// + ///////////////////////////////////// + template Func> + requires meta::HasResultReturnValue + STORMKIT_FORCE_INLINE + inline auto call_unchecked(const Func& func, Args&&... args) noexcept -> Out { + auto out = Out {}; + const auto _ = std::invoke(func, std::forward(args)..., &out); return out; } ///////////////////////////////////// ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto vk_enumerate(const Func& func, Args&&... args) noexcept -> decltype(auto) { - static constexpr auto POSSIBLE_RESULTS = std::array { VK_SUCCESS }; - if constexpr (IsVulkanFuncWithResult) - return vk_enumerate(func, as_view(POSSIBLE_RESULTS), std::forward(args)...); - else { - auto out = std::vector {}; - - auto size = Size { 0 }; - std::invoke(func, std::forward(args)..., &size, nullptr); - out.resize(size); - std::invoke(func, std::forward(args)..., &size, stdr::data(out)); - - return out; - } + template Func> + requires(meta::HasNoReturnValue and not cmeta::SameAs) + inline auto allocate(usize count, const Func& func, Args&&... args) noexcept -> std::vector { + auto out = std::vector {}; + out.resize(count, VK_NULL_HANDLE); + std::invoke(func, std::forward(args)..., stdr::data(out)); + return out; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template Func> + requires(meta::HasResultReturnValue and not cmeta::SameAs) + inline auto allocate_checked(usize count, const Func& func, Args&&... args) noexcept -> Expected> { + static constexpr auto SUCCESS_RESULTS = std::array { VK_SUCCESS, _SUCCESS_RESULTS... }; + + using OutExpected = Expected>; + auto out_expected = OutExpected { std::in_place }; + + auto out = std::vector {}; + out.resize(count, VK_NULL_HANDLE); + const auto result = std::invoke(func, std::forward(args)..., stdr::data(out)); + if (not stdr::any_of(SUCCESS_RESULTS, cmonadic::is_equal(result))) [[likely]] + out_expected = std::unexpected { vk::from_vk(result) }; + else + out_expected = std::move(out); + + return out_expected; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template Func> + requires(meta::HasResultReturnValue and not cmeta::SameAs) + inline auto allocate_unchecked(usize count, const Func& func, Args&&... args) noexcept -> std::vector { + auto out = std::vector {}; + out.resize(count, VK_NULL_HANDLE); + const auto _ = std::invoke(func, std::forward(args)..., stdr::data(out)); + return out; } ///////////////////////////////////// ///////////////////////////////////// - template - requires(IsVulkanFuncWithResult) - inline auto vk_enumerate(const Func& func, std::span possible_results, Args&&... args) noexcept - -> VulkanExpected> { - using Out = VulkanExpected>; - auto out = Out {}; + template Func> + requires(meta::HasNoReturnValue and not cmeta::SameAs) + inline auto enumerate(const Func& func, Args&&... args) noexcept -> std::vector { + auto out = std::vector {}; + auto size = 0_u32; + std::invoke(func, std::forward(args)..., &size, nullptr); + out.resize(size); + std::invoke(func, std::forward(args)..., &size, stdr::data(out)); - auto size = Size { 0 }; - auto result = std::invoke(func, std::forward(args)..., &size, nullptr); - if (not stdr::any_of(possible_results, core::monadic::is_equal(result))) [[unlikely]] - out = Out { std::unexpect, result }; + return out; + } - out = Out { std::in_place, size }; - if (out) [[likely]] { - result = std::invoke(func, std::forward(args)..., &size, stdr::data(*out)); - if (not stdr::any_of(possible_results, core::monadic::is_equal(result))) [[unlikely]] - out = Out { std::unexpect, result }; + ///////////////////////////////////// + ///////////////////////////////////// + template Func> + requires(meta::HasResultReturnValue and not cmeta::SameAs) + inline auto enumerate_checked(const Func& func, Args&&... args) noexcept -> Expected> { + static constexpr auto SUCCESS_RESULTS = std::array { VK_SUCCESS, _SUCCESS_RESULTS... }; + + using OutExpected = Expected>; + auto out_expected = OutExpected { std::in_place }; + + auto out = std::vector {}; + auto size = 0_u32; + { + const auto result = std::invoke(func, std::forward(args)..., &size, nullptr); + if (not stdr::any_of(SUCCESS_RESULTS, cmonadic::is_equal(result))) [[likely]] + out_expected = std::unexpected { vk::from_vk(result) }; } + out.resize(size); + { + const auto result = std::invoke(func, std::forward(args)..., &size, stdr::data(out)); + if (not stdr::any_of(SUCCESS_RESULTS, cmonadic::is_equal(result))) [[likely]] + out_expected = std::unexpected { vk::from_vk(result) }; + else + out_expected = std::move(out); + } + + return out_expected; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template Func> + requires(meta::HasResultReturnValue and not cmeta::SameAs) + inline auto enumerate_unchecked(const Func& func, Args&&... args) noexcept -> std::vector { + auto out = std::vector {}; + auto size = 0_u32; + const auto _ = std::invoke(func, std::forward(args)..., &size, nullptr); + out.resize(size); + const auto _ = std::invoke(func, std::forward(args)..., &size, stdr::data(out)); return out; } + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline Owned::Owned(Deleter deleter) noexcept + : m_deleter { std::move(deleter) } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline Owned::~Owned() noexcept { + if (m_value != VK_NULL_HANDLE) { + m_deleter(m_value); + m_value = VK_NULL_HANDLE; + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline Owned::Owned(Owned&& other) noexcept + : m_value { std::exchange(other.m_value, VK_NULL_HANDLE) }, m_deleter { std::move(other.m_deleter) } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Owned::operator=(Owned&& other) noexcept -> Owned& { + if (this == &other) [[unlikely]] + return *this; + + m_value = std::exchange(other.m_value, VK_NULL_HANDLE); + m_deleter = std::move(other.m_deleter); + + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Owned::operator=(T&& value) noexcept -> void { + if (m_value == value) return; + if (m_value) m_deleter(m_value); + m_value = std::move(value); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Owned::value() const noexcept -> T { + return m_value; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline Owned::operator T() const noexcept { + return value(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline Observer::Observer(T value) noexcept + : m_value { value } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline Observer::Observer(const Owned& value) noexcept + : m_value { value.value() } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline Observer::~Observer() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline Observer::Observer(const Observer&) noexcept = default; + ///////////////////////////////////// + ///////////////////////////////////// + + template + STORMKIT_FORCE_INLINE + inline auto Observer::operator=(const Observer&) noexcept -> Observer& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline Observer::Observer(Observer&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Observer::operator=(Observer&&) noexcept -> Observer& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Observer::value() const noexcept -> T { + return m_value; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline Observer::operator T() const noexcept { + return value(); + } + namespace monadic { ///////////////////////////////////// ///////////////////////////////////// @@ -312,22 +558,22 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto to_vk() noexcept -> decltype(auto) { return [](const U& value) static noexcept -> decltype(auto) - requires(requires { gpu::to_vk(std::declval()); }) - { return gpu::to_vk(value); }; + requires(requires { gpu::vk::to_vk(std::declval()); }) + { return gpu::vk::to_vk(value); }; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto to_vk() noexcept -> decltype(auto) { - return [](const T& value) static noexcept -> decltype(auto) { return gpu::to_vk(value); }; + return [](const T& value) static noexcept -> decltype(auto) { return gpu::vk::to_vk(value); }; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto from_vk() noexcept -> decltype(auto) { - return [](auto val) static noexcept -> decltype(auto) { return gpu::from_vk(val); }; + return [](auto val) static noexcept -> decltype(auto) { return gpu::vk::from_vk(val); }; } ///////////////////////////////////// @@ -337,8 +583,8 @@ namespace stormkit::gpu { STORMKIT_CONST constexpr auto from_vk() noexcept -> decltype(auto) { return [](U val) static noexcept -> T - requires(requires { gpu::from_vk(std::declval()); }) - { return gpu::from_vk(val); }; + requires(requires { gpu::vk::from_vk(std::declval()); }) + { return gpu::vk::from_vk(val); }; } } // namespace monadic -} // namespace stormkit::gpu +} // namespace stormkit::gpu::vk diff --git a/modules/stormkit/gpu/execution/command_buffer.cppm b/modules/stormkit/gpu/execution/command_buffer.cppm index 3c67d9956..6cb91c1fc 100644 --- a/modules/stormkit/gpu/execution/command_buffer.cppm +++ b/modules/stormkit/gpu/execution/command_buffer.cppm @@ -25,24 +25,66 @@ import :swapchain; namespace stdr = std::ranges; -export namespace stormkit::gpu { - struct SubmitInfo { - std::span> wait_semaphores = {}; - std::span wait_dst_stages = {}; - std::span> command_buffers = {}; - std::span> signal_semaphores = {}; - }; +namespace cmonadic = stormkit::core::monadic; +export namespace stormkit::gpu { class SwapChain; + class Queue; + class CommandBuffer; + class CommandPool; + + namespace view { + class Queue; + class CommandBuffer; + class CommandPool; + } // namespace view + + namespace meta { + template<> + struct ObjectInfo { + using Of = Queue; + using ElementType = VkQueue; + using DeleterType = decltype(cmonadic::noop()); + using ViewType = view::Queue; + using OwnedBy = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::QUEUE; + }; + + template<> + struct ObjectInfo { + using Of = CommandBuffer; + using ElementType = VkCommandBuffer; + using DeleterType = decltype(cmonadic::noop()); + using ViewType = view::CommandBuffer; + using OwnedBy = Device; - class STORMKIT_GPU_API Queue { - struct PrivateFuncTag {}; + static constexpr auto DISABLE_CREATE_ALLOCATE = true; + static constexpr auto DEBUG_TYPE = DebugObjectType::COMMAND_BUFFER; + }; + + template<> + struct ObjectInfo { + using Of = CommandPool; + using ElementType = VkCommandPool; + using DeleterType = PFN_vkDestroyCommandPool VolkDeviceTable::*; + using ViewType = view::CommandPool; + using OwnedBy = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::COMMAND_POOL; + }; + } // namespace meta + + class STORMKIT_GPU_API Queue: public OwnedByDevice { public: - static constexpr auto DEBUG_TYPE = DebugObjectType::QUEUE; + struct SubmitInfo { + std::span wait_semaphores = {}; + std::span wait_dst_stages = {}; + std::span command_buffers = {}; + std::span signal_semaphores = {}; + }; - static auto create(const Device& device, const Device::QueueEntry& entry) noexcept -> Queue; - static auto allocate(const Device& device, const Device::QueueEntry& entry) noexcept -> Heap; ~Queue() noexcept; Queue(const Queue&) = delete; @@ -53,39 +95,70 @@ export namespace stormkit::gpu { auto wait_idle() const noexcept -> Expected; - auto submit(std::span submit_infos, OptionalRef fence = std::nullopt) const noexcept + auto submit(std::span submit_infos, std::optional fence = std::nullopt) const noexcept -> Expected; - auto submit(const SubmitInfo& submit_info, OptionalRef fence = std::nullopt) const noexcept + auto submit(const SubmitInfo& submit_info, std::optional fence = std::nullopt) const noexcept -> Expected; [[nodiscard]] - auto present(std::span> swapchains, - std::span> wait_semaphores, - std::span image_indices) const noexcept -> Expected; + auto present(std::span swapchains, + std::span wait_semaphores, + std::span image_indices) const noexcept -> Expected; [[nodiscard]] auto entry() const noexcept -> const Device::QueueEntry&; - [[nodiscard]] - auto native_handle() const noexcept -> VkQueue; - - Queue(const Device& device, const Device::QueueEntry& entry, PrivateFuncTag) noexcept; + // clang-format off + // private: + // clang-format on + Queue(PrivateTag, view::Device&& device) noexcept; + auto do_init(const Device::QueueEntry&) -> void; private: Device::QueueEntry m_entry; - - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkQueue m_vk_handle = nullptr; }; - class CommandPool; + namespace view { + class Queue: DeviceObject { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using ViewType = ObjectInfo::ViewType; + + Queue(const gpu::Queue& of) noexcept; + template T> + Queue(const T& of) noexcept; + ~Queue() noexcept; + + Queue(const Queue&) noexcept; + auto operator=(const Queue&) noexcept -> Queue&; + + Queue(Queue&&) noexcept; + auto operator=(Queue&&) noexcept -> Queue&; + + auto wait_idle() const noexcept -> Expected; + + auto submit(std::span submit_infos, + std::optional fence = std::nullopt) const noexcept -> Expected; + + auto submit(const gpu::Queue::SubmitInfo& submit_info, std::optional fence = std::nullopt) const noexcept + -> Expected; + + [[nodiscard]] + auto present(std::span swapchains, + std::span wait_semaphores, + std::span image_indices) const noexcept -> Expected; + + [[nodiscard]] + auto entry() const noexcept -> const gpu::Device::QueueEntry&; + }; + } // namespace view struct RenderPassInheritanceInfo { - OptionalRef render_pass = std::nullopt; - u32 subpass = 0; - OptionalRef framebuffer = std::nullopt; + std::optional render_pass = std::nullopt; + u32 subpass = 0; + std::optional framebuffer = std::nullopt; }; struct RenderingInheritanceInfo { @@ -101,9 +174,9 @@ export namespace stormkit::gpu { struct RenderingInfo { struct Attachment { struct Resolve { - Ref image_view; - ResolveModeFlag mode; - gpu::ImageLayout layout = ImageLayout::ATTACHMENT_OPTIMAL; + gpu::view::ImageView image_view; + ResolveModeFlag mode; + gpu::ImageLayout layout = ImageLayout::ATTACHMENT_OPTIMAL; }; Ref image_view; @@ -126,9 +199,7 @@ export namespace stormkit::gpu { std::optional stencil_attachment = std::nullopt; }; - class STORMKIT_GPU_API CommandBuffer { - struct PrivateFuncTag {}; - + class STORMKIT_GPU_API CommandBuffer: public OwnedByDevice { public: enum class State { INITIAL, @@ -136,9 +207,8 @@ export namespace stormkit::gpu { EXECUTABLE, }; - static constexpr auto DEBUG_TYPE = DebugObjectType::COMMAND_BUFFER; - - using Deleter = std::function; + using RecordClosure = FunctionRef(CommandBuffer&)>; + using Deleter = std::function; ~CommandBuffer() noexcept; CommandBuffer(const CommandBuffer&) = delete; @@ -147,141 +217,132 @@ export namespace stormkit::gpu { CommandBuffer(CommandBuffer&&) noexcept; auto operator=(CommandBuffer&&) noexcept -> CommandBuffer&; - auto reset() noexcept -> Expected>; - auto submit(const Queue& queue, - std::span> wait_semaphores = {}, - std::span wait_dst_stages = {}, - std::span> signal_semaphores = {}, - OptionalRef fence = std::nullopt) const noexcept -> Expected; - [[nodiscard]] auto state() const noexcept -> State; [[nodiscard]] auto level() const noexcept -> CommandBufferLevel; - auto begin(bool one_time_submit = false, InheritanceInfo inheritance_info = std::monostate {}) noexcept - -> Expected>; - auto end() noexcept -> Expected>; - - auto begin_debug_region(std::string_view name, const fcolor_rgb& color = colors::WHITE) noexcept -> CommandBuffer&; - auto insert_debug_label(std::string_view name, const fcolor_rgb& color = colors::WHITE) noexcept -> CommandBuffer&; - auto end_debug_region() noexcept -> CommandBuffer&; - - auto begin_rendering(const RenderingInfo& info, bool secondary_commandbuffers = false) noexcept -> CommandBuffer&; - auto begin_render_pass(const RenderPass& render_pass, - const FrameBuffer& framebuffer, - std::span clear_values = std::array { ClearValue { + auto record(RecordClosure record_closure, + bool one_time_submit = false, + InheritanceInfo inheritance_info = std::monostate {}) noexcept -> Expected; + + auto reset() noexcept -> Expected; + auto begin(bool one_time_submit = false, InheritanceInfo inheritance_info = std::monostate {}) noexcept -> Expected; + auto end() noexcept -> Expected; + + auto begin_debug_region(std::string_view name, const fcolor_rgb& color = colors::WHITE) const noexcept + -> const CommandBuffer&; + auto insert_debug_label(std::string_view name, const fcolor_rgb& color = colors::WHITE) const noexcept + -> const CommandBuffer&; + auto end_debug_region() const noexcept -> const CommandBuffer&; + + auto begin_rendering(const RenderingInfo& info, bool secondary_commandbuffers = false) const noexcept + -> const CommandBuffer&; + auto begin_render_pass(view::RenderPass render_pass, + view::FrameBuffer framebuffer, + std::span clear_values = std::array { ClearValue { ClearColor { .color = colors::SILVER } } }, - bool secondary_commandbuffers = false) noexcept -> CommandBuffer&; - auto next_sub_pass() noexcept -> CommandBuffer&; - auto end_render_pass() noexcept -> CommandBuffer&; - auto end_rendering() noexcept -> CommandBuffer&; - - auto bind_pipeline(const Pipeline& pipeline) noexcept -> CommandBuffer&; - auto set_viewport(u32 first_viewport, std::span viewports) noexcept -> CommandBuffer&; - auto set_scissor(u32 first_scissor, std::span scissors) noexcept -> CommandBuffer&; - auto set_line_width(f32 width) noexcept -> CommandBuffer&; - auto set_depth_bias(f32 constant_factor, f32 clamp, f32 slope_factor) noexcept -> CommandBuffer&; - auto set_blend_constants(std::span constants) noexcept -> CommandBuffer&; + bool secondary_commandbuffers = false) const noexcept -> const CommandBuffer&; + auto next_sub_pass() const noexcept -> const CommandBuffer&; + auto end_render_pass() const noexcept -> const CommandBuffer&; + auto end_rendering() const noexcept -> const CommandBuffer&; + + auto bind_pipeline(const Pipeline& pipeline) const noexcept -> const CommandBuffer&; + auto set_viewport(u32 first_viewport, std::span viewports) const noexcept -> const CommandBuffer&; + auto set_scissor(u32 first_scissor, std::span scissors) const noexcept -> const CommandBuffer&; + auto set_line_width(f32 width) const noexcept -> const CommandBuffer&; + auto set_depth_bias(f32 constant_factor, f32 clamp, f32 slope_factor) const noexcept -> const CommandBuffer&; + auto set_blend_constants(std::span constants) const noexcept -> const CommandBuffer&; auto set_depth_bounds(f32 min, f32 max) noexcept -> CommandBuffer&; - auto set_stencil_compare_mask(StencilFaceFlag face, u32 mask) noexcept -> CommandBuffer&; - auto set_stencil_write_mask(StencilFaceFlag face, u32 mask) noexcept -> CommandBuffer&; - auto set_stencil_reference(StencilFaceFlag face, u32 reference) noexcept -> CommandBuffer&; + auto set_stencil_compare_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBuffer&; + auto set_stencil_write_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBuffer&; + auto set_stencil_reference(StencilFaceFlag face, u32 reference) const noexcept -> const CommandBuffer&; - auto dispatch(u32 group_count_x, u32 group_count_y, u32 group_count_z) noexcept -> CommandBuffer&; + auto dispatch(u32 group_count_x, u32 group_count_y, u32 group_count_z) const noexcept -> const CommandBuffer&; - auto draw(u32 vertex_count, u32 instance_count = 1u, u32 first_vertex = 0, u32 first_instance = 0) noexcept - -> CommandBuffer&; + auto draw(u32 vertex_count, u32 instance_count = 1u, u32 first_vertex = 0, u32 first_instance = 0) const noexcept + -> const CommandBuffer&; auto draw_indexed(u32 index_count, u32 instance_count = 1u, u32 first_index = 0u, i32 vertex_offset = 0, u32 first_instance = 0u) noexcept -> CommandBuffer&; - auto draw_indirect(const Buffer& buffer, usize offset, u32 draw_count, u32 stride) noexcept -> CommandBuffer&; - auto draw_indexed_indirect(const Buffer& buffer, usize offset, u32 draw_count, u32 stride) noexcept -> CommandBuffer&; - - auto bind_vertex_buffers(std::span> buffers, std::span offsets) noexcept - -> CommandBuffer&; - auto bind_index_buffer(const Buffer& buffer, u64 offset = 0, bool large_indices = false) noexcept -> CommandBuffer&; - auto bind_descriptor_sets(const Pipeline& pipeline, - const PipelineLayout& layout, - std::span> descriptor_sets, - std::span dynamic_offsets = {}) noexcept -> CommandBuffer&; - - auto copy_buffer(const Buffer& src, const Buffer& dst, usize size, u64 src_offset = 0u, u64 dst_offset = 0u) noexcept - -> CommandBuffer&; - auto copy_buffer_to_image(const Buffer& src, - const Image& dst, - std::span buffer_image_copies = {}) noexcept -> CommandBuffer&; - auto copy_image_to_buffer(const Image& src, - const Buffer& dst, - std::span buffer_image_copies = {}) noexcept -> CommandBuffer&; - auto copy_image(const Image& src, - const Image& dst, + auto draw_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept -> const CommandBuffer&; + auto draw_indexed_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept + -> const CommandBuffer&; + + auto bind_vertex_buffers(std::span buffers, std::span offsets) const noexcept + -> const CommandBuffer&; + auto bind_index_buffer(view::Buffer buffer, u64 offset = 0, bool large_indices = false) const noexcept + -> const CommandBuffer&; + auto bind_descriptor_sets(view::Pipeline pipeline, + view::PipelineLayout layout, + std::span descriptor_sets, + std::span dynamic_offsets = {}) const noexcept -> const CommandBuffer&; + + auto copy_buffer(view::Buffer src, view::Buffer dst, usize size, u64 src_offset = 0u, u64 dst_offset = 0u) const noexcept + -> const CommandBuffer&; + auto copy_buffer_to_image(view::Buffer src, view::Image dst, std::span buffer_image_copies = {}) + const noexcept -> const CommandBuffer&; + auto copy_image_to_buffer(view::Image src, view::Buffer dst, std::span buffer_image_copies = {}) + const noexcept -> const CommandBuffer&; + auto copy_image(view::Image src, + view::Image dst, ImageLayout src_layout, ImageLayout dst_layout, const ImageSubresourceLayers& src_subresource_layers, const ImageSubresourceLayers& dst_subresource_layers, - const math::uextent3& extent) noexcept -> CommandBuffer&; + const math::uextent3& extent) const noexcept -> const CommandBuffer&; - auto resolve_image(const Image& src, - const Image& dst, + auto resolve_image(view::Image src, + view::Image dst, ImageLayout src_layout, ImageLayout dst_layout, const ImageSubresourceLayers& src_subresource_layers = {}, - const ImageSubresourceLayers& dst_subresource_layers = {}) noexcept -> CommandBuffer&; + const ImageSubresourceLayers& dst_subresource_layers = {}) const noexcept -> const CommandBuffer&; - auto blit_image(const Image& src, - const Image& dst, + auto blit_image(view::Image src, + view::Image dst, ImageLayout src_layout, ImageLayout dst_layout, std::span regions, - Filter filter) noexcept -> CommandBuffer&; + Filter filter) const noexcept -> const CommandBuffer&; - auto transition_image_layout(const Image& image, + auto transition_image_layout(view::Image image, ImageLayout src_layout, ImageLayout dst_layout, - const ImageSubresourceRange& subresource_range = {}) noexcept -> CommandBuffer&; + const ImageSubresourceRange& subresource_range = {}) const noexcept -> const CommandBuffer&; - auto execute_sub_command_buffers(std::span> commandbuffers) noexcept -> CommandBuffer&; + auto execute_sub_command_buffers(std::span commandbuffers) const noexcept + -> const CommandBuffer&; auto pipeline_barrier(PipelineStageFlag src_mask, PipelineStageFlag dst_mask, DependencyFlag dependency, std::span memory_barriers, std::span buffer_memory_barriers, - std::span image_memory_barriers) noexcept -> CommandBuffer&; + std::span image_memory_barriers) const noexcept -> const CommandBuffer&; - auto push_constants(const PipelineLayout& pipeline_layout, + auto push_constants(view::PipelineLayout pipeline_layout, ShaderStageFlag stage, std::span data, - u32 offset = 0u) noexcept -> CommandBuffer&; + u32 offset = 0u) const noexcept -> const CommandBuffer&; - [[nodiscard]] - auto native_handle() const noexcept -> VkCommandBuffer; + auto submit(view::Queue queue, + std::span wait_semaphores = {}, + std::span wait_dst_stages = {}, + std::span signal_semaphores = {}, + std::optional fence = std::nullopt) const noexcept -> Expected; - CommandBuffer(VkDevice, - VkCommandPool, - Ref, - CommandBufferLevel, - VkCommandBuffer&&, - Deleter&&, - PrivateFuncTag) noexcept; + CommandBuffer(PrivateTag, view::Device&&); + auto do_init(PrivateTag, view::CommandPool&&, CommandBufferLevel, VkCommandBuffer&&, Deleter&&) noexcept + -> Expected; private: - static auto create(VkDevice, - VkCommandPool, - Ref, - CommandBufferLevel, - VkCommandBuffer&&, - Deleter&&) noexcept -> CommandBuffer; - static auto allocate(VkDevice, - VkCommandPool, - Ref, - CommandBufferLevel, - VkCommandBuffer&&, - Deleter&&) noexcept -> Heap; - friend class CommandPool; + static auto create(view::Device, view::CommandPool, CommandBufferLevel, VkCommandBuffer&&, Deleter&&) noexcept + -> CommandBuffer; + static auto allocate(view::Device, view::CommandPool, CommandBufferLevel, VkCommandBuffer&&, Deleter&&) noexcept + -> Heap; CommandBufferLevel m_level = CommandBufferLevel::PRIMARY; @@ -289,18 +350,155 @@ export namespace stormkit::gpu { State m_state = State::INITIAL; - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkCommandPool m_vk_pool = nullptr; - VkRAIIHandle m_vk_handle; + friend class CommandPool; }; - class STORMKIT_GPU_API CommandPool { - struct PrivateFuncTag {}; + namespace view { + class STORMKIT_GPU_API CommandBuffer: public OwnedByDevice { + public: + CommandBuffer(const gpu::CommandBuffer& of) noexcept; + template T> + CommandBuffer(const T& of) noexcept; + ~CommandBuffer() noexcept; + + CommandBuffer(const CommandBuffer&) noexcept; + auto operator=(const CommandBuffer&) noexcept -> CommandBuffer&; + + CommandBuffer(CommandBuffer&&) noexcept; + auto operator=(CommandBuffer&&) noexcept -> CommandBuffer&; + + [[nodiscard]] + auto state() const noexcept -> State; + [[nodiscard]] + auto level() const noexcept -> CommandBufferLevel; + + auto record(RecordClosure record_closure, + bool one_time_submit = false, + InheritanceInfo inheritance_info = std::monostate {}) noexcept -> Expected; + + auto reset() noexcept -> Expected; + auto begin(bool one_time_submit = false, InheritanceInfo inheritance_info = std::monostate {}) noexcept + -> Expected; + auto end() noexcept -> Expected; + + auto begin_debug_region(std::string_view name, const fcolor_rgb& color = colors::WHITE) const noexcept + -> const CommandBuffer&; + auto insert_debug_label(std::string_view name, const fcolor_rgb& color = colors::WHITE) const noexcept + -> const CommandBuffer&; + auto end_debug_region() const noexcept -> const CommandBuffer&; + + auto begin_rendering(const RenderingInfo& info, bool secondary_commandbuffers = false) const noexcept + -> const CommandBuffer&; + auto begin_render_pass(view::RenderPass render_pass, + view::FrameBuffer framebuffer, + std::span clear_values = std::array { ClearValue { + ClearColor { .color = colors::SILVER } } }, + bool secondary_commandbuffers = false) const noexcept -> const CommandBuffer&; + auto next_sub_pass() const noexcept -> const CommandBuffer&; + auto end_render_pass() const noexcept -> const CommandBuffer&; + auto end_rendering() const noexcept -> const CommandBuffer&; + + auto bind_pipeline(const Pipeline& pipeline) const noexcept -> const CommandBuffer&; + auto set_viewport(u32 first_viewport, std::span viewports) const noexcept -> const CommandBuffer&; + auto set_scissor(u32 first_scissor, std::span scissors) const noexcept -> const CommandBuffer&; + auto set_line_width(f32 width) const noexcept -> const CommandBuffer&; + auto set_depth_bias(f32 constant_factor, f32 clamp, f32 slope_factor) const noexcept -> const CommandBuffer&; + auto set_blend_constants(std::span constants) const noexcept -> const CommandBuffer&; + auto set_depth_bounds(f32 min, f32 max) noexcept -> CommandBuffer&; + auto set_stencil_compare_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBuffer&; + auto set_stencil_write_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBuffer&; + auto set_stencil_reference(StencilFaceFlag face, u32 reference) const noexcept -> const CommandBuffer&; + + auto dispatch(u32 group_count_x, u32 group_count_y, u32 group_count_z) const noexcept -> const CommandBuffer&; + + auto draw(u32 vertex_count, u32 instance_count = 1u, u32 first_vertex = 0, u32 first_instance = 0) const noexcept + -> const CommandBuffer&; + auto draw_indexed(u32 index_count, + u32 instance_count = 1u, + u32 first_index = 0u, + i32 vertex_offset = 0, + u32 first_instance = 0u) const noexcept -> const CommandBuffer&; + auto draw_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept + -> const CommandBuffer&; + auto draw_indexed_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept + -> const CommandBuffer&; + + auto bind_vertex_buffers(std::span buffers, std::span offsets) const noexcept + -> const CommandBuffer&; + auto bind_index_buffer(view::Buffer buffer, u64 offset = 0, bool large_indices = false) const noexcept + -> const CommandBuffer&; + auto bind_descriptor_sets(view::Pipeline pipeline, + view::PipelineLayout layout, + std::span descriptor_sets, + std::span dynamic_offsets = {}) const noexcept -> const CommandBuffer&; + + auto copy_buffer(view::Buffer src, view::Buffer dst, usize size, u64 src_offset = 0u, u64 dst_offset = 0u) noexcept + -> const CommandBuffer&; + auto copy_buffer_to_image(view::Buffer src, + view::Image dst, + std::span buffer_image_copies = {}) const noexcept + -> const CommandBuffer&; + auto copy_image_to_buffer(view::Image src, + view::Buffer dst, + std::span buffer_image_copies = {}) const noexcept + -> const CommandBuffer&; + auto copy_image(view::Image src, + view::Image dst, + ImageLayout src_layout, + ImageLayout dst_layout, + const ImageSubresourceLayers& src_subresource_layers, + const ImageSubresourceLayers& dst_subresource_layers, + const math::uextent3& extent) const noexcept -> const CommandBuffer&; + + auto resolve_image(view::Image src, + view::Image dst, + ImageLayout src_layout, + ImageLayout dst_layout, + const ImageSubresourceLayers& src_subresource_layers = {}, + const ImageSubresourceLayers& dst_subresource_layers = {}) const noexcept -> const CommandBuffer&; + + auto blit_image(view::Image src, + view::Image dst, + ImageLayout src_layout, + ImageLayout dst_layout, + std::span regions, + Filter filter) const noexcept -> const CommandBuffer&; + + auto transition_image_layout(view::Image image, + ImageLayout src_layout, + ImageLayout dst_layout, + const ImageSubresourceRange& subresource_range = {}) const noexcept + -> const CommandBuffer&; + + auto execute_sub_command_buffers(std::span commandbuffers) const noexcept + -> const CommandBuffer&; + + auto pipeline_barrier(PipelineStageFlag src_mask, + PipelineStageFlag dst_mask, + DependencyFlag dependency, + std::span memory_barriers, + std::span buffer_memory_barriers, + std::span image_memory_barriers) const noexcept + -> const CommandBuffer&; + + auto push_constants(view::PipelineLayout pipeline_layout, + ShaderStageFlag stage, + std::span data, + u32 offset = 0u) const noexcept -> const CommandBuffer&; + + auto submit(view::Queue queue, + std::span wait_semaphores = {}, + std::span wait_dst_stages = {}, + std::span signal_semaphores = {}, + std::optional fence = std::nullopt) const noexcept -> Expected; + + private: + CommandBufferLevel m_level = CommandBufferLevel::PRIMARY; + }; + } // namespace view + class STORMKIT_GPU_API CommandPool: public OwnedByDevice { public: - static auto create(const Device& device) noexcept -> Expected; - static auto allocate(const Device& device) noexcept -> Expected>; ~CommandPool() noexcept; CommandPool(const CommandPool&) = delete; @@ -311,35 +509,83 @@ export namespace stormkit::gpu { auto create_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept -> Expected; + + template class Out = std::array> + auto create_command_buffers(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected>; + + template class Out = std::vector> auto create_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>; + -> Expected>; auto allocate_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept -> Expected>; - auto allocate_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>>; - [[nodiscard]] - auto native_handle() const noexcept -> VkCommandPool; + template class Out = std::array> + auto allocate_command_buffers(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected>; + + template class Out = std::vector> + auto allocate_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected>>; - CommandPool(const Device& device, PrivateFuncTag) noexcept; + // clang-format off + // private: + // clang-format on + CommandPool(PrivateTag, view::Device&& device) noexcept; + auto do_init(PrivateTag) noexcept -> Expected; private: - auto do_init() noexcept -> Expected; - auto create_vk_command_buffers(usize count, CommandBufferLevel level) const noexcept - -> VulkanExpected>; - static auto delete_vk_command_buffers(VkDevice device, - VkCommandPool, - const VolkDeviceTable&, - VkCommandBuffer cmb) noexcept -> void; - - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; - - // std::mutex m_reuse_mutex; - std::vector m_reusable_command_buffers; + auto create_vk_command_buffers(usize, CommandBufferLevel) const noexcept -> Expected>; + + static auto delete_vk_command_buffers(Device, CommandPool, VkCommandBuffer) noexcept -> void; }; + + namespace view { + class CommandPool: DeviceObject { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using ViewType = ObjectInfo::ViewType; + + using DeviceObject::DeviceObject(); + ~CommandPool() noexcept; + + CommandPool(const CommandPool&) noexcept; + auto operator=(const CommandPool&) noexcept -> CommandPool&; + + CommandPool(CommandPool&&) noexcept; + auto operator=(CommandPool&&) noexcept -> CommandPool&; + + auto create_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected; + + template class Out = std::array> + auto create_command_buffers(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected>; + + template class Out = std::vector> + auto create_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected>; + + auto allocate_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected>; + + template class Out = std::array> + auto allocate_command_buffers(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected>; + + template class Out = std::vector> + auto allocate_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected>>; + + private: + auto create_vk_command_buffers(usize, CommandBufferLevel) const noexcept -> Expected>; + + static auto delete_vk_command_buffers(Device, CommandPool, VkCommandBuffer) noexcept -> void; + }; + } // namespace view + } // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// @@ -350,9 +596,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Queue::Queue(const Device& device, const Device::QueueEntry& entry, PrivateFuncTag) noexcept - : m_entry { entry }, m_vk_device { device.native_handle() }, m_vk_device_table { as_ref(device.device_table()) } { - m_vk_handle = vk_call(m_vk_device_table->vkGetDeviceQueue, m_vk_device, m_entry.id, 0); + inline Queue::Queue(PrivateTag, view::Device&& device) noexcept + : OwnedByDevice { std::move(device), cmonadic::noop() } { } ///////////////////////////////////// @@ -373,29 +618,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Queue::create(const Device& device, const Device::QueueEntry& entry) noexcept -> Queue { - return Queue { device, entry, PrivateFuncTag {} }; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Queue::allocate(const Device& device, const Device::QueueEntry& entry) noexcept -> Heap { - return core::allocate_unsafe(device, entry, PrivateFuncTag {}); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Queue::wait_idle() const noexcept -> Expected { - return vk_call(m_vk_device_table->vkQueueWaitIdle, m_vk_handle).transform_error(monadic::from_vk()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - // - STORMKIT_FORCE_INLINE - inline auto Queue::submit(const SubmitInfo& submit_info, OptionalRef fence) const noexcept -> Expected { + inline auto Queue::submit(const SubmitInfo& submit_info, std::optional fence) const noexcept -> Expected { return submit({ &submit_info, 1 }, std::move(fence)); } @@ -406,59 +629,104 @@ namespace stormkit::gpu { return m_entry; } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Queue::native_handle() const noexcept -> VkQueue { - return m_vk_handle; - } + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Queue::Queue(const gpu::Queue& of) noexcept + : DeviceObject { of }, m_entry { of.entry() } { + } + + /////////////////////////////////// + /////////////////////////////////// + template T> + STORMKIT_FORCE_INLINE + inline Queue::Queue(const T& of) noexcept + : DeviceObject { of }, m_entry { of->entry() } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Queue::~Queue() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Queue::Queue(const Queue&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Queue::operator=(const Queue&) noexcept -> Queue& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Queue::Queue(const Queue&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Queue::operator=(const Queue&) noexcept -> Queue& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Queue::Queue(Queue&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Queue::operator=(Queue&&) noexcept -> Queue& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Queue::submit(const SubmitInfo& submit_info, std::optional fence) const noexcept + -> Expected { + return submit({ &submit_info, 1 }, std::move(fence)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Queue::entry() const noexcept -> const gpu::Device::QueueEntry& { + return m_entry; + } + } // namespace view ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline CommandBuffer::CommandBuffer(VkDevice device, - VkCommandPool pool, - Ref device_table, - CommandBufferLevel level, - VkCommandBuffer&& command_buffer, - Deleter&& deleter, - PrivateFuncTag) noexcept - : m_level { level }, - m_vk_device { device }, - m_vk_device_table { device_table }, - m_vk_pool { pool }, - m_vk_handle { - { [vk_device = m_vk_device, - vk_pool = m_vk_pool, - vk_device_table = *m_vk_device_table, - deleter = std::move(deleter)](auto handle) noexcept { deleter(vk_device, vk_pool, vk_device_table, handle); } } - } { - m_vk_handle = std::move(command_buffer); + inline CommandBuffer::CommandBuffer(PrivateTag, view::Device&& device) noexcept + : OwnedByDevice { std::move(device), cmonadic::noop() } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::create(VkDevice device, - VkCommandPool pool, - Ref device_table, - CommandBufferLevel level, - VkCommandBuffer&& cmb, - Deleter&& deleter) noexcept -> CommandBuffer { - return CommandBuffer { device, pool, device_table, level, std::move(cmb), std::move(deleter), PrivateFuncTag {} }; + inline auto CommandBuffer::create(view::Device device, + view::CommandPool pool, + CommandBufferLevel level, + VkCommandBuffer&& cmb, + Deleter deleter) noexcept -> CommandBuffer { + auto out = CommandBuffer { PrivateTag, std::move(device) }; + out.do_init(std::move(pool), level, std::move(cmb), std::move(deleter)); + return out; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::allocate(VkDevice device, - VkCommandPool pool, - Ref device_table, - CommandBufferLevel level, - VkCommandBuffer&& cmb, - Deleter&& deleter) noexcept -> Heap { - return *allocate(device, pool, device_table, level, std::move(cmb), std::move(deleter), PrivateFuncTag {}) - .transform_error(core::monadic::assert()); + inline auto CommandBuffer::create(view::Device device, + view::CommandPool pool, + CommandBufferLevel level, + VkCommandBuffer&& cmb, + Deleter deleter) noexcept -> CommandBuffer { + auto out = Heap { PrivateTag, std::move(device) }; + out->do_init(std::move(pool), level, std::move(cmb), std::move(deleter)); + return out; } ///////////////////////////////////// @@ -479,33 +747,19 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::reset() noexcept -> Expected> { - return vk_call(m_vk_device_table->vkResetCommandBuffer, m_vk_handle, 0) - .transform([this, &self = *this] { - m_state = State::INITIAL; - return as_ref_mut(self); - }) - .transform_error(monadic::from_vk()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandBuffer::submit(const Queue& queue, - std::span> wait_semaphores, - std::span wait_dst_stages, - std::span> signal_semaphores, - OptionalRef fence) const noexcept -> Expected { - auto cmbs = as_refs(*this); - - return queue.submit( - std::array { - SubmitInfo { .wait_semaphores = wait_semaphores, - .wait_dst_stages = wait_dst_stages, - .command_buffers = cmbs, - .signal_semaphores = signal_semaphores } - }, - std::move(fence)); + inline auto CommandBuffer::submit(view::Queue queue, + std::span wait_semaphores, + std::span wait_dst_stages, + std::span signal_semaphores, + std::optional fence) const noexcept -> Expected { + auto cmbs = to_views(*this); + auto submit_infos = into_array(SubmitInfo { + .wait_semaphores = wait_semaphores, + .wait_dst_stages = wait_dst_stages, + .command_buffers = cmbs, + .signal_semaphores = signal_semaphores }); + + return queue.submit(submit_infos, std::move(fence)); } ///////////////////////////////////// @@ -522,337 +776,261 @@ namespace stormkit::gpu { return m_level; } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandBuffer::end() noexcept -> Expected> { - EXPECTS(m_state == State::RECORDING); - - return vk_call(m_vk_device_table->vkEndCommandBuffer, m_vk_handle) - .transform([this, &self = *this] noexcept { - m_state = State::EXECUTABLE; - return as_ref_mut(self); - }) - .transform_error(monadic::from_vk()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandBuffer::begin_debug_region(std::string_view name, const fcolor_rgb& color) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - if (not vkCmdBeginDebugUtilsLabelEXT) [[unlikely]] - return *this; - - const auto info = VkDebugUtilsLabelEXT { - .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, - .pNext = nullptr, - .pLabelName = stdr::data(name), - .color = { color.r, color.g, color.b, 1.f } - }; - - vk_call(vkCmdBeginDebugUtilsLabelEXT, m_vk_handle, &info); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandBuffer::insert_debug_label(std::string_view name, const fcolor_rgb& color) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - if (not vkCmdInsertDebugUtilsLabelEXT) [[unlikely]] - return *this; - - const auto info = VkDebugUtilsLabelEXT { - .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, - .pNext = nullptr, - .pLabelName = stdr::data(name), - .color = { color.r, color.g, color.b, 1.f } - }; - - vk_call(vkCmdInsertDebugUtilsLabelEXT, m_vk_handle, &info); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandBuffer::end_debug_region() noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - if (not vkCmdEndDebugUtilsLabelEXT) [[unlikely]] - return *this; - - vk_call(vkCmdEndDebugUtilsLabelEXT, m_vk_handle); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandBuffer::next_sub_pass() noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - vk_call(m_vk_device_table->vkCmdNextSubpass, m_vk_handle, VK_SUBPASS_CONTENTS_INLINE); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandBuffer::end_render_pass() noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - vk_call(m_vk_device_table->vkCmdEndRenderPass, m_vk_handle); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandBuffer::end_rendering() noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - vk_call(m_vk_device_table->vkCmdEndRendering, m_vk_handle); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandBuffer::bind_pipeline(const Pipeline& pipeline) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - const auto bind_point = (pipeline.type() == Pipeline::Type::RASTER) ? VK_PIPELINE_BIND_POINT_GRAPHICS - : VK_PIPELINE_BIND_POINT_COMPUTE; - - vk_call(m_vk_device_table->vkCmdBindPipeline, m_vk_handle, bind_point, to_vk(pipeline)); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandBuffer::set_line_width(f32 width) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - vk_call(m_vk_device_table->vkCmdSetLineWidth, m_vk_handle, width); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandBuffer::set_depth_bias(f32 constant_factor, f32 clamp, f32 slope_factor) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - vk_call(m_vk_device_table->vkCmdSetDepthBias, m_vk_handle, constant_factor, clamp, slope_factor); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandBuffer::set_blend_constants(std::span constants) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - f32 data[] = { constants[0], constants[1], constants[2], constants[3] }; - - vk_call(m_vk_device_table->vkCmdSetBlendConstants, m_vk_handle, data); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandBuffer::set_depth_bounds(f32 min, f32 max) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - vk_call(m_vk_device_table->vkCmdSetDepthBounds, m_vk_handle, min, max); - return *this; - } + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline CommandBuffer::CommandBuffer(const gpu::CommandBuffer& of) noexcept + : DeviceObject { of }, m_state { of.state() }, m_level { of.level() } { + } + + /////////////////////////////////// + /////////////////////////////////// + template T> + STORMKIT_FORCE_INLINE + inline CommandBuffer::CommandBuffer(const T& of) noexcept + : DeviceObject { of }, m_state { of->state() }, m_level { of->level() } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline CommandBuffer::~CommandBuffer() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline CommandBuffer::CommandBuffer(const CommandBuffer&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto CommandBuffer::operator=(const CommandBuffer&) noexcept -> CommandBuffer& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline CommandBuffer::CommandBuffer(CommandBuffer&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto CommandBuffer::operator=(CommandBuffer&&) noexcept -> CommandBuffer& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto CommandBuffer::submit(Queue queue, + std::span wait_semaphores, + std::span wait_dst_stages, + std::span signal_semaphores, + std::optional fence) const noexcept -> Expected { + auto cmbs = to_views(*this); + auto submit_infos = into_array(SubmitInfo { + .wait_semaphores = wait_semaphores, + .wait_dst_stages = wait_dst_stages, + .command_buffers = cmbs, + .signal_semaphores = signal_semaphores }); + + return queue.submit(submit_infos, std::move(fence)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto CommandBuffer::state() const noexcept -> State { + return m_state; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto CommandBuffer::level() const noexcept -> CommandBufferLevel { + return m_level; + } + } // namespace view ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::set_stencil_compare_mask(StencilFaceFlag face, u32 mask) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - vk_call(m_vk_device_table->vkCmdSetStencilCompareMask, m_vk_handle, to_vk(face), mask); - return *this; + inline CommandPool::CommandPool(PrivateTag, view::Device&& device) noexcept + : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyCommandPool } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::set_stencil_write_mask(StencilFaceFlag face, u32 mask) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - vk_call(m_vk_device_table->vkCmdSetStencilWriteMask, m_vk_handle, to_vk(face), mask); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandBuffer::set_stencil_reference(StencilFaceFlag face, u32 reference) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - vk_call(m_vk_device_table->vkCmdSetStencilReference, m_vk_handle, to_vk(face), reference); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandBuffer::dispatch(u32 group_count_x, u32 group_count_y, u32 group_count_z) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - vk_call(m_vk_device_table->vkCmdDispatch, m_vk_handle, group_count_x, group_count_y, group_count_z); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandBuffer::draw(u32 vertex_count, u32 instance_count, u32 first_vertex, u32 first_instance) noexcept - -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - EXPECTS(vertex_count > 0); - - vk_call(m_vk_device_table->vkCmdDraw, m_vk_handle, vertex_count, instance_count, first_vertex, first_instance); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandBuffer::draw_indexed(u32 index_count, - u32 instance_count, - u32 first_index, - i32 vertex_offset, - u32 first_instance) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - EXPECTS(index_count > 0); - - vk_call(m_vk_device_table->vkCmdDrawIndexed, - m_vk_handle, - index_count, - instance_count, - first_index, - vertex_offset, - first_instance); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandBuffer::draw_indirect(const Buffer& buffer, usize offset, u32 draw_count, u32 stride) noexcept - -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - EXPECTS(draw_count > 0); - - vk_call(m_vk_device_table->vkCmdDrawIndirect, m_vk_handle, to_vk(buffer), offset, draw_count, stride); - return *this; - } + inline CommandPool::~CommandPool() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::draw_indexed_indirect(const Buffer& buffer, usize offset, u32 draw_count, u32 stride) noexcept - -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - EXPECTS(draw_count > 0); - - vk_call(m_vk_device_table->vkCmdDrawIndexedIndirect, m_vk_handle, to_vk(buffer), offset, draw_count, stride); - return *this; - } + inline CommandPool::CommandPool(CommandPool&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::bind_index_buffer(const Buffer& buffer, u64 offset, bool large_indices) noexcept - -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - vk_call(m_vk_device_table->vkCmdBindIndexBuffer, - m_vk_handle, - to_vk(buffer), - offset, - (large_indices) ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32); - return *this; - } + inline auto CommandPool::operator=(CommandPool&&) noexcept -> CommandPool& = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::native_handle() const noexcept -> VkCommandBuffer { - return m_vk_handle; + inline auto CommandPool::create_command_buffer(CommandBufferLevel level) const noexcept -> Expected { + auto cmbs = Try(create_command_buffers(1, level)); + Return std::move(cmbs.front()); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline CommandPool::CommandPool(const Device& device, PrivateFuncTag) noexcept - : m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { - vk_device_table.vkDestroyCommandPool(vk_device, handle, nullptr); - } } } { + template class Out = std::array> + inline auto CommandPool::create_command_buffers(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected> { + Return Try(create_vk_command_buffers(count, level)) + | stdv::transform([this, &count, &level](auto vk_handle) static noexcept { + return CommandBuffer::create(device(), *this, level, std::move(vk_handle), delete_vk_command_buffers); + }) + | stdr::to(); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandPool::create(const Device& device) noexcept -> Expected { - auto pool = CommandPool { device, PrivateFuncTag {} }; - return pool.do_init().transform(core::monadic::consume(pool)); + template class Out = std::vector> + inline auto CommandPool::create_command_buffers(usize count, + CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected> { + Return transform(Try(create_vk_command_buffers(count, level)), [this, &count, &level](auto vk_handle) static noexcept { + return CommandBuffer::create(device(), *this, level, std::move(vk_handle), delete_vk_command_buffers); + }); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandPool::allocate(const Device& device) noexcept -> Expected> { - auto pool = *core::allocate(device, PrivateFuncTag {}).transform_error(core::monadic::assert()); - return pool->do_init().transform(core::monadic::consume(pool)); + inline auto CommandPool::allocate_command_buffer(CommandBufferLevel level) const noexcept -> Expected> { + auto cmbs = Try(allocate_command_buffers(1, level)); + Return std::move(cmbs.front()); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline CommandPool::~CommandPool() noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline CommandPool::CommandPool(CommandPool&&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandPool::operator=(CommandPool&&) noexcept -> CommandPool& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandPool::create_command_buffer(CommandBufferLevel level) const noexcept -> Expected { - return create_command_buffers(1, level).transform([](auto&& cmbs) static noexcept { return std::move(cmbs.front()); }); + template class Out = std::array> + inline auto CommandPool::allocate_command_buffers(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected, COUNT>> { + Return Try(create_vk_command_buffers(count, level)) + | stdv::transform([this, &count, &level](auto vk_handle) static noexcept { + return CommandBuffer::allocate(device(), *this, level, std::move(vk_handle), delete_vk_command_buffers); + }) + | stdr::to(); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandPool::allocate_command_buffer(CommandBufferLevel level) const noexcept -> Expected> { - return allocate_command_buffers(1, level).transform([](auto&& cmbs) static noexcept { return std::move(cmbs.front()); }); + template class Out = std::vector> + inline auto CommandPool::allocate_command_buffers(usize count, + CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected> { + Return transform(Try(create_vk_command_buffers(count, level)), [this, &count, &level](auto vk_handle) static noexcept { + return CommandBuffer::allocate(device(), *this, level, std::move(vk_handle), delete_vk_command_buffers); + }); } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandPool::native_handle() const noexcept -> VkCommandPool { - return m_vk_handle; - } + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline CommandPool::~CommandPool() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline CommandPool::CommandPool(const CommandPool&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto CommandPool::operator=(const CommandPool&) noexcept -> CommandPool& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline CommandPool::CommandPool(CommandPool&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto CommandPool::operator=(CommandPool&&) noexcept -> CommandPool& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto CommandPool::create_command_buffer(CommandBufferLevel level) const noexcept -> Expected { + auto cmbs = Try(create_command_buffers(1, level)); + Return std::move(cmbs.front()); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + template class Out = std::array> + inline auto CommandPool::create_command_buffers(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected> { + Return Try(create_vk_command_buffers(count, level)) + | stdv::transform([this, &count, &level](auto vk_handle) static noexcept { + return gpu::CommandBuffer::create(device(), *this, level, std::move(vk_handle), delete_vk_command_buffers); + }) + | stdr::to(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + template class Out = std::vector> + inline auto CommandPool::create_command_buffers(usize count, + CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected> { + Return + transform(Try(create_vk_command_buffers(count, level)), [this, &count, &level](auto vk_handle) static noexcept { + return gpu::CommandBuffer::create(device(), *this, level, std::move(vk_handle), delete_vk_command_buffers); + }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto CommandPool::allocate_command_buffer(CommandBufferLevel level) const noexcept + -> Expected> { + auto cmbs = Try(allocate_command_buffers(1, level)); + Return std::move(cmbs.front()); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + template class Out = std::array> + inline auto CommandPool::allocate_command_buffers(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected, COUNT>> { + Return Try(create_vk_command_buffers(count, level)) + | stdv::transform([this, &count, &level](auto vk_handle) static noexcept { + return gpu::CommandBuffer::allocate(device(), *this, level, std::move(vk_handle), delete_vk_command_buffers); + }) + | stdr::to(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + template class Out = std::vector> + inline auto CommandPool::allocate_command_buffers(usize count, + CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected> { + Return + transform(Try(create_vk_command_buffers(count, level)), [this, &count, &level](auto vk_handle) static noexcept { + return gpu::CommandBuffer::allocate(device(), *this, level, std::move(vk_handle), delete_vk_command_buffers); + }); + } + } // namespace view } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/execution/descriptors.cppm b/modules/stormkit/gpu/execution/descriptors.cppm index 4113b2a6d..9d84ceb22 100644 --- a/modules/stormkit/gpu/execution/descriptors.cppm +++ b/modules/stormkit/gpu/execution/descriptors.cppm @@ -25,7 +25,7 @@ export namespace stormkit::gpu { struct BufferDescriptor { DescriptorType type = DescriptorType::UNIFORM_BUFFER; u32 binding; - Ref buffer; + view::Buffer buffer; std::optional range = std::nullopt; u32 offset = 0; }; @@ -120,10 +120,10 @@ export namespace stormkit::gpu { std::vector m_bindings; - hash64 m_hash = 0; - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; + hash64 m_hash = 0; + VkDevice m_vk_device = nullptr; + Ref m_vk_device_table; + vk::Owned m_vk_handle; }; class STORMKIT_GPU_API DescriptorPool { @@ -164,12 +164,12 @@ export namespace stormkit::gpu { private: auto do_init(std::span, u32) noexcept -> Expected; - auto create_vk_descriptor_sets(usize, const DescriptorSetLayout&) const -> VulkanExpected>; + auto create_vk_descriptor_sets(usize, const DescriptorSetLayout&) const -> Expected>; static auto delete_vk_descriptor_set(VkDescriptorSet) -> void; - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; + VkDevice m_vk_device = nullptr; + Ref m_vk_device_table; + vk::Owned m_vk_handle; }; template @@ -252,7 +252,7 @@ namespace stormkit::gpu { [vk_handle = m_vk_handle, &buffers, &writes](const BufferDescriptor& descriptor) noexcept -> decltype(auto) { buffers.push_back(VkDescriptorBufferInfo { - .buffer = to_vk(descriptor.buffer), + .buffer = descriptor.buffer, .offset = descriptor.offset, .range = descriptor.range.value_or(VK_WHOLE_SIZE), }); @@ -265,7 +265,7 @@ namespace stormkit::gpu { .dstBinding = descriptor.binding, .dstArrayElement = 0, .descriptorCount = 1, - .descriptorType = to_vk(descriptor.type), + .descriptorType = vk::to_vk(descriptor.type), .pImageInfo = nullptr, .pBufferInfo = &buffer_descriptor, .pTexelBufferView = nullptr, @@ -274,8 +274,10 @@ namespace stormkit::gpu { [vk_handle = m_vk_handle, &images, &writes](const ImageDescriptor& descriptor) noexcept -> decltype(auto) { images.push_back(VkDescriptorImageInfo { - .sampler = to_vk(descriptor.sampler), - .imageView = to_vk(descriptor.image_view), + // .sampler = descriptor.sampler, + // .imageView = descriptor.image_view, + .sampler = descriptor.sampler->native_handle(), + .imageView = descriptor.image_view->native_handle(), .imageLayout = narrow(descriptor.layout), }); const auto& image_descriptor = images.back(); @@ -287,7 +289,7 @@ namespace stormkit::gpu { .dstBinding = descriptor.binding, .dstArrayElement = 0, .descriptorCount = 1, - .descriptorType = to_vk(descriptor.type), + .descriptorType = vk::to_vk(descriptor.type), .pImageInfo = &image_descriptor, .pBufferInfo = nullptr, .pTexelBufferView = nullptr, @@ -297,7 +299,7 @@ namespace stormkit::gpu { return std::tuple { std::move(buffers), std::move(images), std::move(writes) }; }(); - vk_call(m_vk_device_table->vkUpdateDescriptorSets, m_vk_device, stdr::size(_writes), stdr::data(_writes), 0, nullptr); + vk::call(m_vk_device_table->vkUpdateDescriptorSets, m_vk_device, stdr::size(_writes), stdr::data(_writes), 0, nullptr); } ///////////////////////////////////// @@ -390,9 +392,9 @@ namespace stormkit::gpu { | std::views::transform([](const DescriptorSetLayoutBinding& binding) static noexcept { return VkDescriptorSetLayoutBinding { .binding = binding.binding, - .descriptorType = to_vk(binding.type), + .descriptorType = vk::to_vk(binding.type), .descriptorCount = as(binding.descriptor_count), - .stageFlags = to_vk(binding.stages), + .stageFlags = vk::to_vk(binding.stages), .pImmutableSamplers = nullptr, }; }) @@ -406,9 +408,11 @@ namespace stormkit::gpu { .pBindings = std::ranges::data(vk_bindings) }; - return vk_call(m_vk_device_table->vkCreateDescriptorSetLayout, m_vk_device, &create_info, nullptr) - .transform(core::monadic::set(m_vk_handle)) - .transform_error(monadic::from_vk()); + return vk::call_checked(m_vk_device_table->vkCreateDescriptorSetLayout, + m_vk_device, + &create_info, + nullptr) + .transform(core::monadic::set(m_vk_handle)); } ///////////////////////////////////// @@ -468,20 +472,18 @@ namespace stormkit::gpu { inline auto DescriptorPool::create_descriptor_sets(usize count, const DescriptorSetLayout& layout) const noexcept -> Expected> { auto tag = DescriptorSet::PrivateFuncTag {}; - return create_vk_descriptor_sets(count, layout) - .transform([this, &tag](std::vector&& sets) noexcept { - return std::move(sets) - | stdv::as_rvalue - | stdv::transform([this, &tag](VkDescriptorSet&& set) noexcept -> decltype(auto) { - return DescriptorSet { m_vk_device, - *m_vk_device_table, - std::move(set), - DescriptorPool::delete_vk_descriptor_set, - tag }; - }) - | stdr::to(); - }) - .transform_error(monadic::from_vk()); + return create_vk_descriptor_sets(count, layout).transform([this, &tag](std::vector&& sets) noexcept { + return std::move(sets) + | stdv::as_rvalue + | stdv::transform([this, &tag](VkDescriptorSet&& set) noexcept -> decltype(auto) { + return DescriptorSet { m_vk_device, + *m_vk_device_table, + std::move(set), + DescriptorPool::delete_vk_descriptor_set, + tag }; + }) + | stdr::to(); + }); } ///////////////////////////////////// @@ -498,20 +500,18 @@ namespace stormkit::gpu { inline auto DescriptorPool::allocate_descriptor_sets(usize count, const DescriptorSetLayout& layout) const noexcept -> Expected>> { auto tag = DescriptorSet::PrivateFuncTag {}; - return create_vk_descriptor_sets(count, layout) - .transform([this, &tag](std::vector&& sets) noexcept { - return std::move(sets) - | stdv::as_rvalue - | stdv::transform([this, &tag](VkDescriptorSet&& set) noexcept -> decltype(auto) { - return core::allocate_unsafe(m_vk_device, - *m_vk_device_table, - std::move(set), - DescriptorPool::delete_vk_descriptor_set, - tag); - }) - | stdr::to(); - }) - .transform_error(monadic::from_vk()); + return create_vk_descriptor_sets(count, layout).transform([this, &tag](std::vector&& sets) noexcept { + return std::move(sets) + | stdv::as_rvalue + | stdv::transform([this, &tag](VkDescriptorSet&& set) noexcept -> decltype(auto) { + return core::allocate_unsafe(m_vk_device, + *m_vk_device_table, + std::move(set), + DescriptorPool::delete_vk_descriptor_set, + tag); + }) + | stdr::to(); + }); } ///////////////////////////////////// @@ -528,7 +528,7 @@ namespace stormkit::gpu { const auto pool_sizes = sizes | std::views::transform([](const Size& size) static noexcept { return VkDescriptorPoolSize { - .type = to_vk(size.type), + .type = vk::to_vk(size.type), .descriptorCount = size.descriptor_count, }; }) @@ -543,16 +543,15 @@ namespace stormkit::gpu { .pPoolSizes = std::ranges::data(pool_sizes), }; - return vk_call(m_vk_device_table->vkCreateDescriptorPool, m_vk_device, &create_info, nullptr) - .transform(core::monadic::set(m_vk_handle)) - .transform_error(monadic::from_vk()); + return vk::call_checked(m_vk_device_table->vkCreateDescriptorPool, m_vk_device, &create_info, nullptr) + .transform(core::monadic::set(m_vk_handle)); } ///////////////////////////////////// ///////////////////////////////////// inline auto DescriptorPool::create_vk_descriptor_sets(usize count, const DescriptorSetLayout& layout) const - -> VulkanExpected> { - const auto vk_layout = to_vk(layout); + -> Expected> { + const auto vk_layout = vk::to_vk(layout); const auto allocate_info = VkDescriptorSetAllocateInfo { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, .pNext = nullptr, @@ -561,7 +560,10 @@ namespace stormkit::gpu { .pSetLayouts = &vk_layout, }; - return vk_allocate(count, m_vk_device_table->vkAllocateDescriptorSets, m_vk_device, &allocate_info); + return vk::allocate_checked(count, + m_vk_device_table->vkAllocateDescriptorSets, + m_vk_device, + &allocate_info); } ///////////////////////////////////// diff --git a/modules/stormkit/gpu/execution/pipeline.cppm b/modules/stormkit/gpu/execution/pipeline.cppm index e3de6c929..6896f06cb 100644 --- a/modules/stormkit/gpu/execution/pipeline.cppm +++ b/modules/stormkit/gpu/execution/pipeline.cppm @@ -22,20 +22,63 @@ import stormkit.gpu.core; import :raster_pipeline; import :render_pass; +namespace stdfs = std::filesystem; + +namespace cmeta = stormkit::core::meta; + export namespace stormkit::gpu { - class CommandBuffer; + class PipelineCache; + class Pipeline; + class PipelineLayout; + + namespace view { + class PipelineCache; + class Pipeline; + class PipelineLayout; + } // namespace view + + namespace meta { + template<> + struct ObjectInfo { + using Of = PipelineCache; + using ElementType = VkFramebuffer; + using DeleterType = PFN_vkDestroyFramebuffer VolkDeviceTable::*; + using ViewType = view::PipelineCache; + using OwnedBy = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::PIPELINE_CACHE; + }; + + template<> + struct ObjectInfo { + using Of = Pipeline; + using ElementType = VkPipeline; + using DeleterType = PFN_vkDestroyPipeline VolkDeviceTable::*; + using ViewType = view::Pipeline; + using OwnedBy = Device; - class STORMKIT_GPU_API PipelineCache { - struct PrivateFuncTag {}; + static constexpr auto DEBUG_TYPE = DebugObjectType::PIPELINE; + }; + + template<> + struct ObjectInfo { + using Of = PipelineLayout; + using ElementType = VkPipelineLayout; + using DeleterType = PFN_vkDestroyPipelineLayout VolkDeviceTable::*; + using ViewType = view::PipelineLayout; + using OwnedBy = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::PIPELINE_LAYOUT; + }; + } // namespace meta + class STORMKIT_GPU_API PipelineCache: public OwnedByDevice { public: using LoadSaveError = DecoratedError>; template using LoadSaveExpected = core::Expected; - static constexpr auto DEBUG_TYPE = DebugObjectType::PIPELINE_CACHE; - - static auto try_load(const Device& device, std::filesystem::path cache_path) noexcept -> LoadSaveExpected; + static auto load_from_file(const Device& device, stdfs::path cache_path) noexcept -> LoadSaveExpected; ~PipelineCache() noexcept; PipelineCache(const PipelineCache&) = delete; @@ -44,13 +87,10 @@ export namespace stormkit::gpu { PipelineCache(PipelineCache&&) noexcept; auto operator=(PipelineCache&&) noexcept -> PipelineCache&; - [[nodiscard]] - auto native_handle() const noexcept -> VkPipelineCache; - - PipelineCache(const Device&, std::filesystem::path, PrivateFuncTag) noexcept; + PipelineCache(PrivateTag, view::Device&&) noexcept; + auto do_init(PrivateTag, stdfs::path&&) noexcept -> LoadSaveExpected; private: - auto do_init(const Device&) noexcept -> LoadSaveExpected; auto create_new_pipeline_cache(const Device&) noexcept -> LoadSaveExpected; auto read_pipeline_cache(const Device&) noexcept -> LoadSaveExpected; auto save_cache() noexcept -> LoadSaveExpected; @@ -76,20 +116,15 @@ export namespace stormkit::gpu { } uuid; } m_serialized; - std::filesystem::path m_path; - - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; + stdfs::path m_path; }; - class STORMKIT_GPU_API PipelineLayout { - struct PrivateFuncTag {}; + namespace view { + using PipelineCache = DeviceObject; + } + class STORMKIT_GPU_API PipelineLayout { public: - static constexpr auto DEBUG_TYPE = DebugObjectType::PIPELINE_LAYOUT; - - static auto create(const Device& device, const RasterPipelineLayout& layout) noexcept -> Expected; ~PipelineLayout() noexcept; PipelineLayout(const PipelineLayout&) = delete; @@ -101,42 +136,28 @@ export namespace stormkit::gpu { [[nodiscard]] auto raster_layout() const noexcept -> const RasterPipelineLayout&; - [[nodiscard]] - auto native_handle() const noexcept -> VkPipelineLayout; - - PipelineLayout(const Device& device, const RasterPipelineLayout& layout, PrivateFuncTag) noexcept; + // clang-format off + // private: + // clang-format on + PipelineLayout(view::Device&& device) noexcept; + auto do_init(PrivateTag, const RasterPipelineLayout&) noexcept -> Expected; private: - auto do_init() noexcept -> Expected; - - RasterPipelineLayout m_layout; - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; + RasterPipelineLayout m_layout; }; - class STORMKIT_GPU_API Pipeline { - struct PrivateFuncTag {}; + namespace view { + using PipelineLayout = DeviceObject; + } + class STORMKIT_GPU_API Pipeline { public: enum class Type { RASTER, COMPUTE, + RAYTRACING, }; - static constexpr auto DEBUG_TYPE = DebugObjectType::PIPELINE; - - static auto create(const Device& device, - const RasterPipelineState& state, - const PipelineLayout& layout, - const RenderPass& render_pass, - OptionalRef cache = std::nullopt) noexcept -> Expected; - - static auto create(const Device& device, - const RasterPipelineState& state, - const PipelineLayout& layout, - const RasterPipelineRenderingInfo& rendering_info, - OptionalRef cache = std::nullopt) noexcept -> Expected; ~Pipeline() noexcept; Pipeline(const Pipeline&) = delete; @@ -145,30 +166,29 @@ export namespace stormkit::gpu { Pipeline(Pipeline&&) noexcept; auto operator=(Pipeline&&) noexcept -> Pipeline&; - // auto bind(CommandBuffer& commandbuffer) const noexcept -> void; - [[nodiscard]] auto type() const noexcept -> Type; [[nodiscard]] auto raster_state() const noexcept -> const RasterPipelineState&; - [[nodiscard]] - auto native_handle() const noexcept -> VkPipeline; - - Pipeline(const Device&, const RasterPipelineState&, PrivateFuncTag) noexcept; + // clang-format off + // private: + // clang-format on + Pipeline(PrivateTag, view::Device&&) noexcept; + auto do_init(PrivateTag, + const RasterPipelineState&, + const PipelineLayout&, + std::optional, + std::optional) noexcept -> Expected; + auto do_init(PrivateTag, + const RasterPipelineState&, + const PipelineLayout&, + std::optional, + std::optional) noexcept -> Expected; private: - auto do_init(const PipelineLayout&, - OptionalRef, - OptionalRef, - OptionalRef) noexcept -> Expected; - Type m_type; std::variant m_state; - - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; }; } // namespace stormkit::gpu @@ -180,7 +200,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline PipelineCache::PipelineCache(const Device& device, std::filesystem::path path, PrivateFuncTag) noexcept + inline PipelineCache::PipelineCache(const Device& device, stdfs::path path, PrivateFuncTag) noexcept : m_path { std::move(path) }, m_vk_device { device.native_handle() }, m_vk_device_table { as_ref(device.device_table()) }, @@ -202,7 +222,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto PipelineCache::try_load(const Device& device, std::filesystem::path cache_path) noexcept + inline auto PipelineCache::load_from_file(const Device& device, stdfs::path cache_path) noexcept -> LoadSaveExpected { auto cache = PipelineCache { device, std::move(cache_path), PrivateFuncTag {} }; Try(cache.do_init(device)); @@ -275,18 +295,16 @@ namespace stormkit::gpu { namespace stdr = std::ranges; const auto set_layouts = m_layout.descriptor_set_layouts | stdv::transform(core::monadic::unref()) - | stdv::transform(monadic::to_vk()) + | stdv::transform(vk::monadic::to_vk()) | stdr::to(); - const auto push_constant_ranges = m_layout.push_constant_ranges - | stdv::transform([](auto&& push_constant_range) noexcept { - return VkPushConstantRange { - .stageFlags = to_vk(push_constant_range.stages), - .offset = push_constant_range.offset, - .size = as(push_constant_range.size), - }; - }) - | stdr::to(); + const auto push_constant_ranges = transform(m_layout.push_constant_ranges, [](auto&& push_constant_range) noexcept { + return VkPushConstantRange { + .stageFlags = vk::to_vk(push_constant_range.stages), + .offset = push_constant_range.offset, + .size = as(push_constant_range.size), + }; + }); const auto create_info = VkPipelineLayoutCreateInfo { .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, @@ -298,8 +316,10 @@ namespace stormkit::gpu { .pPushConstantRanges = stdr::data(push_constant_ranges), }; - m_vk_handle = Try(vk_call(m_vk_device_table->vkCreatePipelineLayout, m_vk_device, &create_info, nullptr) - .transform_error(monadic::from_vk())); + m_vk_handle = Try(vk::call_checked(m_vk_device_table->vkCreatePipelineLayout, + m_vk_device, + &create_info, + nullptr)); Return {}; } diff --git a/modules/stormkit/gpu/execution/render_pass.cppm b/modules/stormkit/gpu/execution/render_pass.cppm index 8cf9a5113..e932aeb1f 100644 --- a/modules/stormkit/gpu/execution/render_pass.cppm +++ b/modules/stormkit/gpu/execution/render_pass.cppm @@ -6,6 +6,7 @@ module; #include #include +#include #include #include @@ -18,23 +19,46 @@ import stormkit.core; import stormkit.gpu.core; import stormkit.gpu.resource; +namespace cmeta = stormkit::core::meta; + export namespace stormkit::gpu { + class FrameBuffer; class RenderPass; - class STORMKIT_GPU_API FrameBuffer { - struct PrivateFuncTag {}; + namespace view { + class FrameBuffer; + class RenderPass; + } // namespace view + + namespace meta { + template<> + struct ObjectInfo { + using Of = FrameBuffer; + using ElementType = VkFramebuffer; + using DeleterType = PFN_vkDestroyFramebuffer VolkDeviceTable::*; + using ViewType = view::FrameBuffer; + using OwnedBy = Device; + + static constexpr auto DISABLE_CREATE_ALLOCATE = true; + static constexpr auto DEBUG_TYPE = DebugObjectType::FRAMEBUFFER; + }; + + template<> + struct ObjectInfo { + using Of = RenderPass; + using ElementType = VkRenderPass; + using DeleterType = PFN_vkDestroyRenderPass VolkDeviceTable::*; + using ViewType = view::RenderPass; + using OwnedBy = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::RENDER_PASS; + }; + } // namespace meta + + class RenderPass; + class STORMKIT_GPU_API FrameBuffer: public OwnedByDevice { public: - static constexpr auto DEBUG_TYPE = DebugObjectType::FRAMEBUFFER; - - static auto create(const Device& device, - const RenderPass& render_pass, - const math::uextent2& extent, - std::vector> attachments) noexcept -> Expected; - static auto allocate(const Device& device, - const RenderPass& render_pass, - const math::uextent2& extent, - std::vector> attachments) noexcept -> Expected>; ~FrameBuffer() noexcept; FrameBuffer(const FrameBuffer&) = delete; @@ -46,23 +70,57 @@ export namespace stormkit::gpu { [[nodiscard]] auto extent() const noexcept -> const math::uextent2&; [[nodiscard]] - auto attachments() const noexcept -> const std::vector>&; + auto attachments() const noexcept -> std::span; - [[nodiscard]] - auto native_handle() const noexcept -> VkFramebuffer; - - FrameBuffer(const Device&, const math::uextent2&, std::vector>, PrivateFuncTag) noexcept; + FrameBuffer(PrivateTag, view::Device&&) noexcept; private: - auto do_init(const RenderPass&) noexcept -> Expected; + static auto create(view::Device&& device, + view::RenderPass render_pass, + const math::uextent2& extent, + std::vector&& attachments) noexcept -> Expected; + static auto allocate(view::Device&& device, + view::RenderPass render_pass, + const math::uextent2& extent, + std::vector&& attachments) noexcept -> Expected>; + + auto do_init(view::RenderPass&&, const math::uextent2&, std::vector&&) noexcept -> Expected; + + math::uextent2 m_extent = { 0, 0 }; + std::vector m_attachments; + + friend class RenderPass; + friend class view::RenderPass; + }; - math::uextent2 m_extent = { 0, 0 }; - std::vector> m_attachments; + namespace view { + class STORMKIT_GPU_API FrameBuffer: public DeviceObject { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using ViewType = ObjectInfo::ViewType; - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; - }; + FrameBuffer(const gpu::FrameBuffer& of) noexcept; + template T> + FrameBuffer(const T& of) noexcept; + ~FrameBuffer() noexcept; + + FrameBuffer(const FrameBuffer&) noexcept; + auto operator=(const FrameBuffer&) noexcept -> FrameBuffer&; + + FrameBuffer(FrameBuffer&&) noexcept; + auto operator=(FrameBuffer&&) noexcept -> FrameBuffer&; + + [[nodiscard]] + auto extent() const noexcept -> const math::uextent2&; + [[nodiscard]] + auto attachments() const noexcept -> std::span; + + private: + math::uextent2 m_extent = { 0, 0 }; + std::span m_attachments; + }; + } // namespace view struct AttachmentDescription { PixelFormat format; @@ -104,15 +162,8 @@ export namespace stormkit::gpu { auto is_compatible(const RenderPassDescription& description) const noexcept -> bool; }; - class STORMKIT_GPU_API RenderPass { - struct PrivateFuncTag {}; - + class STORMKIT_GPU_API RenderPass: public OwnedByDevice { public: - static constexpr auto DEBUG_TYPE = DebugObjectType::RENDER_PASS; - - static auto create(const Device& device, const RenderPassDescription& description) noexcept -> Expected; - static auto allocate(const Device& device, const RenderPassDescription& description) noexcept - -> Expected>; ~RenderPass() noexcept; RenderPass(const RenderPass&) = delete; @@ -121,36 +172,59 @@ export namespace stormkit::gpu { RenderPass(RenderPass&&) noexcept; auto operator=(RenderPass&&) noexcept -> RenderPass&; - auto create_frame_buffer(const Device& device, - const math::uextent2& extent, - std::vector> attachments) const noexcept -> Expected; - auto allocate_frame_buffer(const Device& device, - const math::uextent2& extent, - std::vector> attachments) const noexcept -> Expected>; + auto create_framebuffer(view::Device device, + const math::uextent2& extent, + std::vector attachments) const noexcept -> Expected; + auto allocate_framebuffer(view::Device device, + const math::uextent2& extent, + std::vector attachments) const noexcept -> Expected>; [[nodiscard]] - auto is_compatible(const RenderPass& render_pass) const noexcept -> bool; + auto is_compatible(view::RenderPass render_pass) const noexcept -> bool; [[nodiscard]] auto is_compatible(const RenderPassDescription& description) const noexcept -> bool; [[nodiscard]] auto description() const noexcept -> const RenderPassDescription&; - [[nodiscard]] - auto native_handle() const noexcept -> VkRenderPass; - - RenderPass(const Device& device, const RenderPassDescription& description, PrivateFuncTag) noexcept; + // clang-format off + // private: + // clang-format on + RenderPass(PrivateTag, view::Device&&) noexcept; + auto do_init(PrivateTag, const RenderPassDescription&) noexcept -> Expected; private: - auto do_init() noexcept -> Expected; - RenderPassDescription m_description = {}; - - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; }; + namespace view { + class STORMKIT_GPU_API RenderPass: public DeviceObject { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using ViewType = ObjectInfo::ViewType; + + // RenderPass(const gpu::RenderPass& of) noexcept; + // template T> + // RenderPass(const T& of) noexcept; + using DeviceObject::DeviceObject; + ~RenderPass() noexcept; + + RenderPass(const RenderPass&) noexcept; + auto operator=(const RenderPass&) noexcept -> RenderPass&; + + RenderPass(RenderPass&&) noexcept; + auto operator=(RenderPass&&) noexcept -> RenderPass&; + + auto create_framebuffer(Device device, + const math::uextent2& extent, + std::vector attachments) const noexcept -> Expected; + auto allocate_framebuffer(view::Device device, + const math::uextent2& extent, + std::vector attachments) const noexcept -> Expected>; + }; + } // namespace view + template constexpr auto hasher(const AttachmentDescription& value) noexcept -> Ret; template @@ -169,39 +243,32 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline FrameBuffer::FrameBuffer(const Device& device, - const math::uextent2& extent, - std::vector> attachments, - PrivateFuncTag) noexcept - : m_extent { extent }, - m_attachments { std::move(attachments) }, - m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { - vk_device_table.vkDestroyFramebuffer(vk_device, handle, nullptr); - } } } { + inline FrameBuffer::FrameBuffer(PrivateTag, view::Device&& device) noexcept + : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyFramebuffer } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto FrameBuffer::create(const Device& device, - const RenderPass& render_pass, - const math::uextent2& extent, - std::vector> attachments) noexcept -> Expected { - auto frame_buffer = FrameBuffer { device, extent, std::move(attachments), PrivateFuncTag {} }; - return frame_buffer.do_init(render_pass).transform(core::monadic::consume(frame_buffer)); + inline auto FrameBuffer::create(view::Device&& device, + view::RenderPass render_pass, + const math::uextent2& extent, + std::vector&& attachments) noexcept -> Expected { + auto frame_buffer = FrameBuffer { PRIVATE, std::move(device) }; + Try(frame_buffer.do_init(std::move(render_pass), extent, std::move(attachments))); + Return frame_buffer; } ////////////////////////////////////p/ ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto FrameBuffer::allocate(const Device& device, - const RenderPass& render_pass, - const math::uextent2& extent, - std::vector> attachments) noexcept -> Expected> { - auto frame_buffer = allocate_unsafe(device, extent, std::move(attachments), PrivateFuncTag {}); - return frame_buffer->do_init(render_pass).transform(core::monadic::consume(frame_buffer)); + inline auto FrameBuffer::allocate(view::Device&& device, + view::RenderPass render_pass, + const math::uextent2& extent, + std::vector&& attachments) noexcept -> Expected> { + auto frame_buffer = core::allocate_unsafe(PRIVATE, std::move(device)); + Try(frame_buffer->do_init(std::move(render_pass), extent, std::move(attachments))); + Return frame_buffer; } ///////////////////////////////////// @@ -212,12 +279,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline FrameBuffer::FrameBuffer(FrameBuffer&& other) noexcept = default; + inline FrameBuffer::FrameBuffer(FrameBuffer&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto FrameBuffer::operator=(FrameBuffer&& other) noexcept -> FrameBuffer& = default; + inline auto FrameBuffer::operator=(FrameBuffer&&) noexcept -> FrameBuffer& = default; ///////////////////////////////////// ///////////////////////////////////// @@ -229,69 +296,71 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto FrameBuffer::attachments() const noexcept -> const std::vector>& { + inline auto FrameBuffer::attachments() const noexcept -> std::span { return m_attachments; } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto FrameBuffer::native_handle() const noexcept -> VkFramebuffer { - return m_vk_handle; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto FrameBuffer::do_init(const RenderPass& render_pass) noexcept -> Expected { - const auto vk_attachments = m_attachments - | std::views::transform(core::monadic::unref()) - | std::views::transform(monadic::to_vk()) - | std::ranges::to(); - - const auto create_info = VkFramebufferCreateInfo { - .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .renderPass = to_vk(render_pass), - .attachmentCount = as(std::ranges::size(vk_attachments)), - .pAttachments = std::ranges::data(vk_attachments), - .width = m_extent.width, - .height = m_extent.height, - .layers = 1, - }; - - return vk_call(m_vk_device_table->vkCreateFramebuffer, m_vk_device, &create_info, nullptr) - .transform(core::monadic::set(m_vk_handle)) - .transform_error(monadic::from_vk()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline RenderPass::RenderPass(const Device& device, const RenderPassDescription& description, PrivateFuncTag) noexcept - : m_description { description }, - m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { - vk_device_table.vkDestroyRenderPass(vk_device, handle, nullptr); - } } } { - } + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline FrameBuffer::FrameBuffer(const gpu::FrameBuffer& of) noexcept + : DeviceObject { of }, m_extent { of.extent() }, m_attachments { of.attachments() } { + } + + /////////////////////////////////// + /////////////////////////////////// + template T> + STORMKIT_FORCE_INLINE + inline FrameBuffer::FrameBuffer(const T& of) noexcept + : DeviceObject { of }, m_extent { of->extent() }, m_attachments { of->attachments() } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline FrameBuffer::~FrameBuffer() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline FrameBuffer::FrameBuffer(const FrameBuffer&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto FrameBuffer::operator=(const FrameBuffer&) noexcept -> FrameBuffer& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline FrameBuffer::FrameBuffer(FrameBuffer&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto FrameBuffer::operator=(FrameBuffer&&) noexcept -> FrameBuffer& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto FrameBuffer::extent() const noexcept -> const math::uextent2& { + return m_extent; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto FrameBuffer::attachments() const noexcept -> std::span { + return m_attachments; + } + } // namespace view ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - auto RenderPass::create(const Device& device, const RenderPassDescription& description) noexcept -> Expected { - auto render_pass = RenderPass { device, description, PrivateFuncTag {} }; - return render_pass.do_init().transform(core::monadic::consume(render_pass)); - } - - ////////////////////////////////////p/ - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto RenderPass::allocate(const Device& device, const RenderPassDescription& description) noexcept - -> Expected> { - auto render_pass = allocate_unsafe(device, description, PrivateFuncTag {}); - return render_pass->do_init().transform(core::monadic::consume(render_pass)); + inline RenderPass::RenderPass(PrivateTag, view::Device&& device) noexcept + : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyRenderPass } { } ///////////////////////////////////// @@ -302,41 +371,40 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline RenderPass::RenderPass(RenderPass&& other) noexcept = default; + inline RenderPass::RenderPass(RenderPass&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto RenderPass::operator=(RenderPass&& other) noexcept -> RenderPass& = default; + inline auto RenderPass::operator=(RenderPass&&) noexcept -> RenderPass& = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto RenderPass::create_frame_buffer(const Device& device, - const math::uextent2& extent, - std::vector> attachments) const noexcept - -> Expected { - return FrameBuffer::create(device, *this, extent, std::move(attachments)); + inline auto RenderPass::create_framebuffer(view::Device device, + const math::uextent2& extent, + std::vector attachments) const noexcept -> Expected { + return FrameBuffer::create(std::move(device), *this, extent, std::move(attachments)); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto RenderPass::allocate_frame_buffer(const Device& device, - const math::uextent2& extent, - std::vector> attachments) const noexcept + inline auto RenderPass::allocate_framebuffer(view::Device device, + const math::uextent2& extent, + std::vector attachments) const noexcept -> Expected> { - return FrameBuffer::allocate(device, *this, extent, std::move(attachments)); + return FrameBuffer::allocate(std::move(device), *this, extent, std::move(attachments)); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto RenderPass::is_compatible(const RenderPass& render_pass) const noexcept -> bool { + inline auto RenderPass::is_compatible(view::RenderPass) const noexcept -> bool { // TODO implement proper compatibility check // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/chap7.html#renderpass-compatibility - return &render_pass == this; + return false; } ///////////////////////////////////// @@ -346,12 +414,52 @@ namespace stormkit::gpu { return m_description; } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto RenderPass::native_handle() const noexcept -> VkRenderPass { - return m_vk_handle; - } + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline RenderPass::~RenderPass() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline RenderPass::RenderPass(const RenderPass&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto RenderPass::operator=(const RenderPass&) noexcept -> RenderPass& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline RenderPass::RenderPass(RenderPass&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto RenderPass::operator=(RenderPass&&) noexcept -> RenderPass& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto RenderPass::create_framebuffer(Device device, + const math::uextent2& extent, + std::vector attachments) const noexcept + -> Expected { + return gpu::FrameBuffer::create(std::move(device), *this, extent, std::move(attachments)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto RenderPass::allocate_framebuffer(Device device, + const math::uextent2& extent, + std::vector attachments) const noexcept + -> Expected> { + return gpu::FrameBuffer::allocate(std::move(device), *this, extent, std::move(attachments)); + } + } // namespace view ///////////////////////////////////// ///////////////////////////////////// diff --git a/modules/stormkit/gpu/execution/swapchain.cppm b/modules/stormkit/gpu/execution/swapchain.cppm index 17c4d50bb..61fe12653 100644 --- a/modules/stormkit/gpu/execution/swapchain.cppm +++ b/modules/stormkit/gpu/execution/swapchain.cppm @@ -17,13 +17,30 @@ import stormkit.core; import stormkit.gpu.core; import stormkit.gpu.resource; +namespace cmeta = stormkit::core::meta; + export namespace stormkit::gpu { - class STORMKIT_GPU_API SwapChain { - struct PrivateFuncTag {}; + class SwapChain; + + namespace view { + class SwapChain; + } // namespace view + + namespace meta { + template<> + struct ObjectInfo { + using Of = SwapChain; + using ElementType = VkSwapchainKHR; + using DeleterType = PFN_vkDestroySwapchainKHR VolkDeviceTable::*; + using ViewType = view::SwapChain; + using OwnedBy = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::SWAPCHAIN; + }; + } // namespace meta + class STORMKIT_GPU_API SwapChain: public OwnedByDevice { public: - static constexpr auto DEBUG_TYPE = DebugObjectType::SWAPCHAIN; - using ImageID = u32; struct NextImage { @@ -31,15 +48,7 @@ export namespace stormkit::gpu { ImageID id; }; - static auto create(const Device& device, - const Surface& surface, - const math::uextent2& extent, - OptionalRef old_swapchain = std::nullopt) noexcept -> Expected; - static auto allocate(const Device& device, - const Surface& surface, - const math::uextent2& extent, - OptionalRef old_swapchain = std::nullopt) noexcept -> Expected>; - ~SwapChain(); + ~SwapChain() noexcept; SwapChain(const SwapChain&) = delete; auto operator=(const SwapChain&) -> SwapChain& = delete; @@ -50,27 +59,57 @@ export namespace stormkit::gpu { [[nodiscard]] auto pixel_format() const noexcept -> PixelFormat; [[nodiscard]] - auto images() const noexcept -> const std::vector&; - auto acquire_next_image(std::chrono::nanoseconds wait, const Semaphore& image_available) const noexcept + auto images() const noexcept -> std::span; + auto acquire_next_image(std::chrono::nanoseconds wait, view::Semaphore image_available) const noexcept -> Expected; - [[nodiscard]] - auto native_handle() const noexcept -> VkSwapchainKHR; - - SwapChain(const Device&, PrivateFuncTag) noexcept; + // clang-format off + // private: + // clang-format on + SwapChain(PrivateTag, view::Device&&) noexcept; + auto do_init(PrivateTag, view::Surface&&, const math::uextent2&) noexcept -> Expected; private: - auto do_init(const Device&, const Surface&, const math::uextent2&, VkSwapchainKHR) noexcept -> Expected; - math::uextent2 m_extent; PixelFormat m_pixel_format; u32 m_image_count; - VkDevice m_vk_device; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; - std::vector m_images; + std::vector m_images; }; + + namespace view { + class STORMKIT_GPU_API SwapChain: public DeviceObject { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using ViewType = ObjectInfo::ViewType; + + SwapChain(const gpu::SwapChain& of) noexcept; + template T> + SwapChain(const T& of) noexcept; + ~SwapChain() noexcept; + + SwapChain(const SwapChain&) noexcept; + auto operator=(const SwapChain&) noexcept -> SwapChain&; + + SwapChain(SwapChain&&) noexcept; + auto operator=(SwapChain&&) noexcept -> SwapChain&; + + [[nodiscard]] + auto pixel_format() const noexcept -> PixelFormat; + [[nodiscard]] + auto images() const noexcept -> std::span; + auto acquire_next_image(std::chrono::nanoseconds wait, Semaphore image_available) const noexcept + -> Expected; + + private: + math::uextent2 m_extent; + PixelFormat m_pixel_format; + u32 m_image_count; + + std::span m_images; + }; + } // namespace view } // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// @@ -79,18 +118,14 @@ export namespace stormkit::gpu { namespace stormkit::gpu { STORMKIT_FORCE_INLINE - inline SwapChain::SwapChain(const Device& device, PrivateFuncTag) noexcept - : m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto&& handle) noexcept { - vk_device_table.vkDestroySwapchainKHR(vk_device, handle, nullptr); - } } { + inline SwapChain::SwapChain(PrivateTag, view::Device&& device) noexcept + : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroySwapchainKHR } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline SwapChain::~SwapChain() = default; + inline SwapChain::~SwapChain() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// @@ -102,30 +137,6 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto SwapChain::operator=(SwapChain&&) noexcept -> SwapChain& = default; - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto SwapChain::create(const Device& device, - const Surface& surface, - const math::uextent2& extent, - OptionalRef old_swapchain) noexcept -> Expected { - auto swapchain = SwapChain { device, PrivateFuncTag {} }; - return swapchain.do_init(device, surface, extent, old_swapchain ? old_swapchain->native_handle() : nullptr) - .transform(core::monadic::consume(swapchain)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto SwapChain::allocate(const Device& device, - const Surface& surface, - const math::uextent2& extent, - OptionalRef old_swapchain) noexcept -> Expected> { - auto swapchain = std::make_unique(device, PrivateFuncTag {}); - return swapchain->do_init(device, surface, extent, old_swapchain ? old_swapchain->native_handle() : nullptr) - .transform(core::monadic::consume(swapchain)); - } - ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE @@ -136,14 +147,63 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto SwapChain::images() const noexcept -> const std::vector& { + inline auto SwapChain::images() const noexcept -> std::span { return m_images; } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto SwapChain::native_handle() const noexcept -> VkSwapchainKHR { - return m_vk_handle; - } + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline SwapChain::SwapChain(const gpu::SwapChain& of) noexcept + : view::DeviceObject { of }, m_pixel_format { of.pixel_format() }, m_images { of.images() } { + } + + /////////////////////////////////// + /////////////////////////////////// + template T> + STORMKIT_FORCE_INLINE + inline SwapChain::SwapChain(const T& of) noexcept + : view::DeviceObject { of }, m_pixel_format { of->pixel_format() }, m_images { of->images() } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline SwapChain::~SwapChain() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline SwapChain::SwapChain(const SwapChain&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto SwapChain::operator=(const SwapChain&) noexcept -> SwapChain& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline SwapChain::SwapChain(SwapChain&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto SwapChain::operator=(SwapChain&&) noexcept -> SwapChain& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto SwapChain::pixel_format() const noexcept -> PixelFormat { + return m_pixel_format; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto SwapChain::images() const noexcept -> std::span { + return m_images; + } + } // namespace view } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/resource/buffer.cppm b/modules/stormkit/gpu/resource/buffer.cppm index edc0eb319..c467ca084 100644 --- a/modules/stormkit/gpu/resource/buffer.cppm +++ b/modules/stormkit/gpu/resource/buffer.cppm @@ -6,6 +6,7 @@ module; #include #include +#include #include #include @@ -19,18 +20,42 @@ import stormkit.gpu.core; namespace stdr = std::ranges; +namespace cmeta = stormkit::core::meta; +namespace cmonadic = stormkit::core::monadic; + +namespace stormkit::gpu { + struct BufferAPI; +} + export namespace stormkit::gpu { - class STORMKIT_GPU_API Buffer { - struct PrivateFuncTag {}; + class Buffer; + + namespace view { + class Buffer; + } // namespace view + + namespace meta { + template<> + struct ObjectInfo { + using Of = Buffer; + using ElementType = VkBuffer; + using DeleterType = PFN_vkDestroyBuffer VolkDeviceTable::*; + using ViewType = view::Buffer; + using OwnedBy = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::BUFFER; + }; + } // namespace meta + class STORMKIT_GPU_API Buffer: public OwnedByDevice { public: struct CreateInfo { BufferUsageFlag usages; usize size; - MemoryPropertyFlag property = MemoryPropertyFlag::HOST_VISIBLE | MemoryPropertyFlag::HOST_COHERENT; - }; + MemoryPropertyFlag properties = MemoryPropertyFlag::HOST_VISIBLE | MemoryPropertyFlag::HOST_COHERENT; - static constexpr auto DEBUG_TYPE = DebugObjectType::BUFFER; + bool persistently_mapped = false; + }; ~Buffer(); @@ -40,17 +65,14 @@ export namespace stormkit::gpu { Buffer(Buffer&&) noexcept; auto operator=(Buffer&&) noexcept -> Buffer&; - static auto create(const Device& device, const CreateInfo& info, bool persistently_mapped = false) noexcept - -> Expected; - static auto allocate(const Device& device, const CreateInfo& info, bool persistently_mapped = false) noexcept - -> Expected>; - [[nodiscard]] auto usages() const noexcept -> BufferUsageFlag; [[nodiscard]] auto size() const noexcept -> usize; [[nodiscard]] - auto memory_property() const noexcept -> MemoryPropertyFlag; + auto memory_properties() const noexcept -> MemoryPropertyFlag; + [[nodiscard]] + auto is_persistently_mapped() const noexcept -> bool; auto map(ioffset offset) noexcept -> Expected; auto map(ioffset offset, usize size) noexcept -> Expected>; @@ -60,11 +82,11 @@ export namespace stormkit::gpu { template [[nodiscard]] - auto data(this Self& self) noexcept -> core::meta::ForwardConst*; + auto data(this Self& self) noexcept -> cmeta::ForwardConst*; template [[nodiscard]] auto data(this Self& self, usize size) noexcept - -> core::meta::If, std::span, std::span>; + -> cmeta::If, std::span, std::span>; template [[nodiscard]] @@ -73,9 +95,6 @@ export namespace stormkit::gpu { auto flush(ioffset offset, usize size) noexcept -> Expected; auto unmap() noexcept -> void; - [[nodiscard]] - auto is_persistently_mapped() const noexcept -> bool; - auto upload(std::span data, ioffset offset = 0) noexcept -> Expected; template @@ -83,9 +102,13 @@ export namespace stormkit::gpu { auto upload(const T& data, ioffset offset = 0) noexcept -> Expected; [[nodiscard]] - auto native_handle() const noexcept -> VkBuffer; + auto allocation() const noexcept -> vk::Observer; - Buffer(const Device& device, const CreateInfo& info, bool persistently_mapping, PrivateFuncTag) noexcept; + // clang-format off + // private: + // clang-format on + Buffer(PrivateTag, view::Device) noexcept; + auto do_init(PrivateTag, const CreateInfo&) noexcept -> Expected; private: static auto find_memory_type(u32, @@ -93,22 +116,89 @@ export namespace stormkit::gpu { const VkPhysicalDeviceMemoryProperties&, const VkMemoryRequirements&) noexcept -> u32; - auto do_init(MemoryPropertyFlag memory_properties) noexcept -> Expected; - - BufferUsageFlag m_usages = {}; - usize m_size = 0; - MemoryPropertyFlag m_memory_property = {}; + BufferUsageFlag m_usages = {}; + usize m_size = 0; + MemoryPropertyFlag m_memory_properties = {}; bool m_is_persistently_mapped = false; byte* m_mapped_pointer = nullptr; - VkDevice m_vk_device; - Ref m_vk_device_table; - VmaAllocator m_vma_allocator; - VkRAIIHandle m_vma_allocation = { [](auto) static noexcept {} }; - VkRAIIHandle m_vk_handle; + vk::Owned m_vma_allocation = { cmonadic::discard() }; + + friend struct BufferAPI; }; + namespace view { + class STORMKIT_GPU_API Buffer: public DeviceObject { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using ViewType = ObjectInfo::ViewType; + + Buffer(const gpu::Buffer& of) noexcept; + template T> + Buffer(const T& of) noexcept; + ~Buffer() noexcept; + + Buffer(const Buffer&) noexcept; + auto operator=(const Buffer&) noexcept -> Buffer&; + + Buffer(Buffer&&) noexcept; + auto operator=(Buffer&&) noexcept -> Buffer&; + + [[nodiscard]] + auto usages() const noexcept -> BufferUsageFlag; + [[nodiscard]] + auto size() const noexcept -> usize; + [[nodiscard]] + auto memory_properties() const noexcept -> MemoryPropertyFlag; + [[nodiscard]] + auto is_persistently_mapped() const noexcept -> bool; + + auto map(ioffset offset) noexcept -> Expected; + auto map(ioffset offset, usize size) noexcept -> Expected>; + + template + auto map_as(ioffset offset) noexcept -> Expected>; + + template + [[nodiscard]] + auto data(this Self& self) noexcept -> cmeta::ForwardConst*; + template + [[nodiscard]] + auto data(this Self& self, usize size) noexcept + -> cmeta::If, std::span, std::span>; + + template + [[nodiscard]] + auto data_as(this auto& self) noexcept -> Ref; + + auto flush(ioffset offset, usize size) noexcept -> Expected; + auto unmap() noexcept -> void; + + auto upload(std::span data, ioffset offset = 0) noexcept -> Expected; + + template + requires(not stormkit::meta::IsSpecializationWithNTTPOf) + auto upload(const T& data, ioffset offset = 0) noexcept -> Expected; + + [[nodiscard]] + auto allocation() const noexcept -> vk::Observer; + + private: + BufferUsageFlag m_usages = {}; + usize m_size = 0; + MemoryPropertyFlag m_memory_properties = {}; + + bool m_is_persistently_mapped = false; + byte* m_mapped_pointer = nullptr; + + vk::Observer m_vma_allocation; + + friend struct gpu::BufferAPI; + }; + } // namespace view + struct BufferMemoryBarrier { AccessFlag src; AccessFlag dst; @@ -121,7 +211,7 @@ export namespace stormkit::gpu { u64 offset = 0; }; - template + template constexpr auto hasher(const Buffer::CreateInfo& create_info) noexcept -> Ret; } // namespace stormkit::gpu @@ -132,25 +222,18 @@ export namespace stormkit::gpu { namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - inline Buffer::Buffer(const Device& device, const CreateInfo& info, bool persistently_mapped, PrivateFuncTag) noexcept - : m_usages { info.usages }, - m_size { info.size }, - m_memory_property { info.property }, - m_is_persistently_mapped { persistently_mapped }, - m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vma_allocator { device.allocator() }, - m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { - vk_device_table.vkDestroyBuffer(vk_device, handle, nullptr); - } } { + inline Buffer::Buffer(PrivateTag, view::Device device) noexcept + : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyBuffer } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE inline Buffer::~Buffer() { - if (m_vma_allocation and m_mapped_pointer) { - vk_call(vmaUnmapMemory, m_vma_allocator, m_vma_allocation); + if (m_mapped_pointer != nullptr and m_vma_allocation) { + const auto& allocator = device().allocator(); + + vk::call(vmaUnmapMemory, allocator, m_vma_allocation); m_mapped_pointer = nullptr; } @@ -166,24 +249,6 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto Buffer::operator=(Buffer&& other) noexcept -> Buffer& = default; - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Buffer::create(const Device& device, const CreateInfo& info, bool persistently_mapped) noexcept - -> Expected { - auto buffer = Buffer { device, info, persistently_mapped, PrivateFuncTag {} }; - return buffer.do_init(info.property).transform(core::monadic::consume(buffer)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Buffer::allocate(const Device& device, const CreateInfo& info, bool persistently_mapped) noexcept - -> Expected> { - auto buffer = std::make_unique(device, info, persistently_mapped, PrivateFuncTag {}); - return buffer->do_init(info.property).transform(core::monadic::consume(buffer)); - } - ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE @@ -203,17 +268,15 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Buffer::map(ioffset offset) noexcept -> Expected { - EXPECTS(m_vma_allocation and m_vk_handle); - EXPECTS(offset < as(m_size)); - - return vk_call(vmaMapMemory, m_vma_allocator, m_vma_allocation) - .transform([this, &offset](auto&& ptr) noexcept { - m_mapped_pointer = std::bit_cast(ptr); - m_mapped_pointer += offset; - return m_mapped_pointer; - }) - .transform_error(monadic::from_vk()); + inline auto Buffer::memory_properties() const noexcept -> MemoryPropertyFlag { + return m_memory_properties; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::is_persistently_mapped() const noexcept -> bool { + return m_is_persistently_mapped; } ///////////////////////////////////// @@ -221,7 +284,8 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto Buffer::map(ioffset offset, usize size) noexcept -> Expected> { EXPECTS(m_vma_allocation and m_vk_handle); - return map(offset).transform([&size](auto&& ptr) noexcept { return as_bytes_mut(ptr, size); }); + auto ptr = Try(map(offset)); + Return as_bytes_mut(ptr, size); } ///////////////////////////////////// @@ -231,20 +295,19 @@ namespace stormkit::gpu { inline auto Buffer::map_as(ioffset offset) noexcept -> Expected> { EXPECTS(m_vma_allocation and m_vk_handle); - return map(offset) - .transform([](auto&& ptr) static noexcept { return std::bit_cast(ptr); }) - .transform(core::monadic::as_ref_mut); + const auto ptr = Try(map(offset)); + Return from_bytes_mut(ptr); } ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Buffer::data(this Self& self) noexcept -> core::meta::ForwardConst* { + inline auto Buffer::data(this Self& self) noexcept -> cmeta::ForwardConst* { EXPECTS(self.m_vma_allocation and self.m_vk_handle); EXPECTS(self.m_mapped_pointer); - using Out = core::meta::ForwardConst*; + using Out = cmeta::ForwardConst*; return std::bit_cast(self.m_mapped_pointer); } @@ -253,11 +316,11 @@ namespace stormkit::gpu { template STORMKIT_FORCE_INLINE inline auto Buffer::data(this Self& self, usize size) noexcept - -> core::meta::If, std::span, std::span> { + -> cmeta::If, std::span, std::span> { EXPECTS(self.m_vma_allocation and self.m_vk_handle); EXPECTS(self.m_mapped_pointer); - using Out = core::meta::If, std::span, std::span>; + using Out = std::span>; return Out { std::bit_cast(self.m_mapped_pointer), size }; } @@ -269,73 +332,177 @@ namespace stormkit::gpu { EXPECTS(self.m_vma_allocation and self.m_vk_handle); EXPECTS(self.m_mapped_pointer); - using Type = core::meta::ForwardConst*; + using Type = cmeta::ForwardConst*; return as_ref_like(std::bit_cast(self.data())); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Buffer::flush(ioffset offset, usize size) noexcept -> Expected { - EXPECTS(m_vma_allocation and m_vk_handle); - EXPECTS(offset <= as(m_size)); - EXPECTS(size <= m_size); - - return vk_call(vmaFlushAllocation, m_vma_allocator, m_vma_allocation, offset, size) - .transform_error(monadic::from_vk()); + inline auto Buffer::allocation() const noexcept -> vk::Observer { + return m_vma_allocation; } ///////////////////////////////////// ///////////////////////////////////// + template + requires(not stormkit::meta::IsSpecializationWithNTTPOf) STORMKIT_FORCE_INLINE - inline auto Buffer::unmap() noexcept -> void { - EXPECTS(m_vma_allocation and m_vk_handle); - expects(not m_is_persistently_mapped, "unmapping persistent buffer !"); + inline auto Buffer::upload(const T& data, ioffset offset) noexcept -> Expected { + const auto bytes = as_bytes(data); + return upload(bytes, offset); + } - vk_call(vmaUnmapMemory, m_vma_allocator, m_vma_allocation); + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Buffer::Buffer(const gpu::Buffer& of) noexcept + : DeviceObject { of }, + m_usages { of.usages() }, + m_size { of.size() }, + m_memory_properties { of.memory_properties() }, + m_is_persistently_mapped { of.is_persistently_mapped() }, + m_mapped_pointer { std::bit_cast(of.data()) }, + m_vma_allocation { of.allocation() } { + } - m_mapped_pointer = nullptr; - } + /////////////////////////////////// + /////////////////////////////////// + template T> + STORMKIT_FORCE_INLINE + inline Buffer::Buffer(const T& of) noexcept + : DeviceObject { of }, + m_usages { of->usages() }, + m_size { of->size() }, + m_memory_properties { of->memory_properties() }, + m_is_persistently_mapped { of->is_persistently_mapped() }, + m_mapped_pointer { std::bit_cast(of->data()) }, + m_vma_allocation { of->allocation() } { + } - ///////////////////////////////////// - ///////////////////////////////////// + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Buffer::~Buffer() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Buffer::Buffer(const Buffer& other) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::operator=(const Buffer& other) noexcept -> Buffer& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Buffer::Buffer(Buffer&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::operator=(Buffer&&) noexcept -> Buffer& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::usages() const noexcept -> BufferUsageFlag { + return m_usages; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::size() const noexcept -> usize { + return m_size; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::memory_properties() const noexcept -> MemoryPropertyFlag { + return m_memory_properties; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::is_persistently_mapped() const noexcept -> bool { + return m_is_persistently_mapped; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::map(ioffset offset, usize size) noexcept -> Expected> { + EXPECTS(m_vma_allocation and m_vk_handle); + auto ptr = Try(map(offset)); + Return as_bytes_mut(ptr, size); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto Buffer::upload(std::span data, ioffset offset) noexcept -> Expected { - EXPECTS(stdr::size(data) <= m_size); + inline auto Buffer::map_as(ioffset offset) noexcept -> Expected> { + EXPECTS(m_vma_allocation and m_vk_handle); - if (m_is_persistently_mapped) { - stdr::copy(data, m_mapped_pointer); - return {}; + const auto ptr = Try(map(offset)); + Return from_bytes_mut(ptr); } - return map(offset, stdr::size(data)).transform([this, &data](auto&& out) noexcept -> void { - stdr::copy(data, stdr::begin(out)); - unmap(); - }); - } + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Buffer::data(this Self& self) noexcept -> cmeta::ForwardConst* { + EXPECTS(self.m_vma_allocation and self.m_vk_handle); + EXPECTS(self.m_mapped_pointer); - ///////////////////////////////////// - ///////////////////////////////////// - template - requires(not stormkit::meta::IsSpecializationWithNTTPOf) + using Out = cmeta::ForwardConst*; + return std::bit_cast(self.m_mapped_pointer); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto Buffer::upload(const T& data, ioffset offset) noexcept -> Expected { - const auto bytes = as_bytes(data); - return upload(bytes, offset); - } + inline auto Buffer::data(this Self& self, usize size) noexcept + -> cmeta::If, std::span, std::span> { + EXPECTS(self.m_vma_allocation and self.m_vk_handle); + EXPECTS(self.m_mapped_pointer); - ///////////////////////////////////// - ///////////////////////////////////// + using Out = std::span>; + return Out { std::bit_cast(self.m_mapped_pointer), size }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto Buffer::native_handle() const noexcept -> VkBuffer { - EXPECTS(m_vk_handle); - return m_vk_handle; - } + inline auto Buffer::data_as(this Self& self) noexcept -> Ref { + EXPECTS(self.m_vma_allocation and self.m_vk_handle); + EXPECTS(self.m_mapped_pointer); + + using Type = cmeta::ForwardConst*; + return as_ref_like(std::bit_cast(self.data())); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::allocation() const noexcept -> vk::Observer { + return m_vma_allocation; + } + } // namespace view ///////////////////////////////////// ///////////////////////////////////// - template + template constexpr auto hasher(const Buffer::CreateInfo& create_info) noexcept -> Ret { - return hash(create_info.usages, create_info.size, create_info.property); + return hash(create_info.usages, create_info.size, create_info.properties); } } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/resource/image.cppm b/modules/stormkit/gpu/resource/image.cppm index ad36186a0..6c86e0faf 100644 --- a/modules/stormkit/gpu/resource/image.cppm +++ b/modules/stormkit/gpu/resource/image.cppm @@ -18,10 +18,56 @@ import stormkit.core; import stormkit.image; import stormkit.gpu.core; +namespace cmeta = stormkit::core::meta; +namespace cmonadic = stormkit::core::monadic; + export namespace stormkit::gpu { - class STORMKIT_GPU_API Sampler { - struct PrivateFuncTag {}; + class Sampler; + class ImageView; + class Image; + + namespace view { + class Sampler; + class ImageView; + class Image; + } // namespace view + + namespace meta { + template<> + struct ObjectInfo { + using Of = Sampler; + using ElementType = VkSampler; + using DeleterType = PFN_vkDestroySampler VolkDeviceTable::*; + using ViewType = view::Sampler; + using OwnedBy = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::SAMPLER; + }; + + template<> + struct ObjectInfo { + using Of = ImageView; + using ElementType = VkImageView; + using DeleterType = PFN_vkDestroyImageView VolkDeviceTable::*; + using ViewType = view::ImageView; + using OwnedBy = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::IMAGE_VIEW; + }; + template<> + struct ObjectInfo { + using Of = Image; + using ElementType = VkImage; + using DeleterType = PFN_vkDestroyImage VolkDeviceTable::*; + using ViewType = view::Image; + using OwnedBy = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::IMAGE; + }; + } // namespace meta + + class STORMKIT_GPU_API Sampler: public OwnedByDevice { public: struct Settings { Filter mag_filter = Filter::LINEAR; @@ -48,10 +94,6 @@ export namespace stormkit::gpu { f32 max_lod = 0.f; }; - static constexpr auto DEBUG_TYPE = DebugObjectType::SAMPLER; - - static auto create(const Device& device, const Settings& settings) noexcept -> Expected; - static auto allocate(const Device& device, const Settings& settings) noexcept -> Expected>; ~Sampler(); Sampler(const Sampler&) = delete; @@ -63,37 +105,44 @@ export namespace stormkit::gpu { [[nodiscard]] auto settings() const noexcept -> const Settings&; - [[nodiscard]] - auto native_handle() const noexcept -> VkSampler; - - Sampler(const Device& device, const Settings& settings, PrivateFuncTag) noexcept; + // clang-format off + // private: + // clang-format on + Sampler(PrivateTag, view::Device) noexcept; + auto do_init(PrivateTag, const Settings&) noexcept -> Expected; private: - auto do_init() noexcept -> Expected; - Settings m_settings = {}; - - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; }; - class Image; + namespace view { + class STORMKIT_GPU_API Sampler: public view::DeviceObject { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using ViewType = ObjectInfo::ViewType; + + Sampler(const gpu::Sampler& of) noexcept; + template T> + Sampler(const T& of) noexcept; + ~Sampler() noexcept; + + Sampler(const Sampler&) noexcept; + auto operator=(const Sampler&) noexcept -> Sampler&; - class STORMKIT_GPU_API ImageView { - struct PrivateFuncTag {}; + Sampler(Sampler&&) noexcept; + auto operator=(Sampler&&) noexcept -> Sampler&; + + [[nodiscard]] + auto settings() const noexcept -> const gpu::Sampler::Settings&; + + private: + gpu::Sampler::Settings m_settings; + }; + } // namespace view + class STORMKIT_GPU_API ImageView: public OwnedByDevice { public: - static constexpr auto DEBUG_TYPE = DebugObjectType::IMAGE_VIEW; - - static auto create(const Device& device, - const Image& image, - ImageViewType type = ImageViewType::T2D, - const ImageSubresourceRange& subresource_range = {}) noexcept -> Expected; - static auto allocate(const Device& device, - const Image& image, - ImageViewType type = ImageViewType::T2D, - const ImageSubresourceRange& subresource_range = {}) noexcept -> Expected>; ~ImageView(); ImageView(const ImageView&) = delete; @@ -107,25 +156,48 @@ export namespace stormkit::gpu { [[nodiscard]] auto subresource_range() const noexcept -> const ImageSubresourceRange&; - [[nodiscard]] - auto native_handle() const noexcept -> VkImageView; - - ImageView(const Device&, ImageViewType, const ImageSubresourceRange&, PrivateFuncTag) noexcept; + // clang-format off + // private: + // clang-format on + ImageView(PrivateTag, view::Device) noexcept; + auto do_init(PrivateTag, view::Image, ImageViewType = ImageViewType::T2D, const ImageSubresourceRange& = {}) noexcept + -> Expected; private: - auto do_init(const Image&) noexcept -> Expected; - ImageViewType m_type = {}; ImageSubresourceRange m_subresource_range = {}; - - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; }; - class STORMKIT_GPU_API Image { - struct PrivateFuncTag {}; + namespace view { + class STORMKIT_GPU_API ImageView: public view::DeviceObject { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using ViewType = ObjectInfo::ViewType; + + ImageView(const gpu::ImageView& of) noexcept; + template T> + ImageView(const T& of) noexcept; + ~ImageView() noexcept; + + ImageView(const ImageView&) noexcept; + auto operator=(const ImageView&) noexcept -> ImageView&; + ImageView(ImageView&&) noexcept; + auto operator=(ImageView&&) noexcept -> ImageView&; + + [[nodiscard]] + auto type() const noexcept -> ImageViewType; + [[nodiscard]] + auto subresource_range() const noexcept -> const ImageSubresourceRange&; + + private: + ImageViewType m_type = {}; + ImageSubresourceRange m_subresource_range = {}; + }; + } // namespace view + + class STORMKIT_GPU_API Image: public OwnedByDevice { public: struct CreateInfo { math::uextent3 extent; @@ -137,13 +209,10 @@ export namespace stormkit::gpu { SampleCountFlag samples = SampleCountFlag::C1; ImageUsageFlag usages = ImageUsageFlag::SAMPLED | ImageUsageFlag::TRANSFER_DST | ImageUsageFlag::TRANSFER_SRC; ImageTiling tiling = ImageTiling::OPTIMAL; - MemoryPropertyFlag property = MemoryPropertyFlag::DEVICE_LOCAL; + MemoryPropertyFlag properties = MemoryPropertyFlag::DEVICE_LOCAL; }; - static constexpr auto DEBUG_TYPE = DebugObjectType::IMAGE; - - static auto create(const Device& device, const CreateInfo& info) noexcept -> Expected; - static auto allocate(const Device& device, const CreateInfo& create_info) noexcept -> Expected>; + static auto from_existing(view::Device device, const CreateInfo& create_info, VkImage image) noexcept -> Image; ~Image(); Image(const Image&) = delete; @@ -168,18 +237,17 @@ export namespace stormkit::gpu { auto mip_levels() const noexcept -> u32; [[nodiscard]] auto usages() const noexcept -> ImageUsageFlag; - [[nodiscard]] - auto native_handle() const noexcept -> VkImage; - - Image(const Device&, const CreateInfo&, PrivateFuncTag) noexcept; + auto allocation() const noexcept -> vk::Observer; - [[nodiscard]] - static auto create(const Device&, const CreateInfo&, VkImage&&) noexcept -> Image; + // clang-format off + // private: + // clang-format on + Image(PrivateTag, view::Device) noexcept; + auto do_init(PrivateTag, const CreateInfo&) noexcept -> Expected; private: - auto do_init(const CreateInfo&) noexcept -> Expected; - auto do_init(const VkImageCreateInfo&, MemoryPropertyFlag) noexcept -> Expected; + bool m_no_delete = false; math::uextent3 m_extent = { 0, 0, 0 }; PixelFormat m_format = {}; @@ -191,13 +259,63 @@ export namespace stormkit::gpu { SampleCountFlag m_samples = {}; ImageUsageFlag m_usages = {}; - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VmaAllocator m_vma_allocator = nullptr; - VkRAIIHandle m_vma_allocation = { [](auto) static noexcept {} }; - VkRAIIHandle m_vk_handle; + vk::Owned m_vma_allocation = { cmonadic::discard() }; + + friend class view::Image; }; + namespace view { + class STORMKIT_GPU_API Image: public view::DeviceObject { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using ViewType = ObjectInfo::ViewType; + + Image(const gpu::Image& of) noexcept; + template T> + Image(const T& of) noexcept; + ~Image() noexcept; + + Image(const Image&) noexcept; + auto operator=(const Image&) noexcept -> Image&; + + Image(Image&&) noexcept; + auto operator=(Image&&) noexcept -> Image&; + + [[nodiscard]] + auto extent() const noexcept -> const math::uextent3&; + [[nodiscard]] + auto format() const noexcept -> PixelFormat; + [[nodiscard]] + auto type() const noexcept -> ImageType; + [[nodiscard]] + auto samples() const noexcept -> SampleCountFlag; + [[nodiscard]] + auto layers() const noexcept -> u32; + [[nodiscard]] + auto faces() const noexcept -> u32; + [[nodiscard]] + auto mip_levels() const noexcept -> u32; + [[nodiscard]] + auto usages() const noexcept -> ImageUsageFlag; + [[nodiscard]] + auto allocation() const noexcept -> vk::Observer; + + private: + math::uextent3 m_extent = { 0, 0, 0 }; + PixelFormat m_format = {}; + u32 m_layers = 0; + u32 m_faces = 0; + u32 m_mip_levels = 0; + ImageType m_type = {}; + ImageCreateFlag m_flags = {}; + SampleCountFlag m_samples = {}; + ImageUsageFlag m_usages = {}; + + vk::Observer m_vma_allocation = VK_NULL_HANDLE; + }; + } // namespace view + struct ImageMemoryBarrier { AccessFlag src; AccessFlag dst; @@ -224,42 +342,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Sampler::do_init() noexcept -> Expected { - const auto create_info = VkSamplerCreateInfo { - .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .magFilter = to_vk(m_settings.mag_filter), - .minFilter = to_vk(m_settings.min_filter), - .mipmapMode = to_vk(m_settings.mipmap_mode), - .addressModeU = to_vk(m_settings.address_mode_u), - .addressModeV = to_vk(m_settings.address_mode_v), - .addressModeW = to_vk(m_settings.address_mode_w), - .mipLodBias = m_settings.mip_lod_bias, - .anisotropyEnable = m_settings.enable_anisotropy, - .maxAnisotropy = m_settings.max_anisotropy, - .compareEnable = m_settings.compare_enable, - .compareOp = to_vk(m_settings.compare_operation), - .minLod = m_settings.min_lod, - .maxLod = m_settings.max_lod, - .borderColor = to_vk(m_settings.border_color), - .unnormalizedCoordinates = m_settings.unnormalized_coordinates - }; - return vk_call(m_vk_device_table->vkCreateSampler, m_vk_device, &create_info, nullptr) - .transform(core::monadic::set(m_vk_handle)) - .transform_error(monadic::from_vk()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Sampler::Sampler(const Device& device, const Settings& settings, PrivateFuncTag) noexcept - : m_settings { settings }, - m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto&& handle) noexcept { - vk_device_table.vkDestroySampler(vk_device, handle, nullptr); - } } { + inline Sampler::Sampler(PrivateTag, view::Device device) noexcept + : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroySampler } { } ///////////////////////////////////// @@ -277,22 +361,6 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto Sampler::operator=(Sampler&&) noexcept -> Sampler& = default; - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Sampler::create(const Device& device, const Settings& settings) noexcept -> Expected { - auto sampler = Sampler { device, settings, PrivateFuncTag {} }; - return sampler.do_init().transform(core::monadic::consume(sampler)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Sampler::allocate(const Device& device, const Settings& settings) noexcept -> Expected> { - auto sampler = std::make_unique(device, settings, PrivateFuncTag {}); - return sampler->do_init().transform(core::monadic::consume(sampler)); - } - ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE @@ -300,59 +368,60 @@ namespace stormkit::gpu { return m_settings; } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Sampler::native_handle() const noexcept -> VkSampler { - EXPECTS(m_vk_handle); - return m_vk_handle; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto ImageView::do_init(const Image& image) noexcept -> Expected { - const auto vk_subresource_range = VkImageSubresourceRange { - .aspectMask = to_vk(m_subresource_range.aspect_mask), - .baseMipLevel = m_subresource_range.base_mip_level, - .levelCount = m_subresource_range.level_count, - .baseArrayLayer = m_subresource_range.base_array_layer, - .layerCount = m_subresource_range.layer_count, - }; - - const auto create_info = VkImageViewCreateInfo { - .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .image = image.native_handle(), - .viewType = to_vk(m_type), - .format = to_vk(image.format()), - .components = { .r = VK_COMPONENT_SWIZZLE_R, - .g = VK_COMPONENT_SWIZZLE_G, - .b = VK_COMPONENT_SWIZZLE_B, - .a = VK_COMPONENT_SWIZZLE_A }, - .subresourceRange = vk_subresource_range, - }; - - return vk_call(m_vk_device_table->vkCreateImageView, m_vk_device, &create_info, nullptr) - .transform(core::monadic::set(m_vk_handle)) - .transform_error(monadic::from_vk()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline ImageView::ImageView(const Device& device, - ImageViewType type, - const ImageSubresourceRange& subresource_range, - PrivateFuncTag) noexcept - : m_type { type }, - m_subresource_range { subresource_range }, - m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto&& handle) noexcept { - vk_device_table.vkDestroyImageView(vk_device, handle, nullptr); - } } { + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Sampler::Sampler(const gpu::Sampler& of) noexcept + : view::DeviceObject { of }, m_settings { of.settings() } { + } + + /////////////////////////////////// + /////////////////////////////////// + template T> + STORMKIT_FORCE_INLINE + inline Sampler::Sampler(const T& of) noexcept + : view::DeviceObject { of }, m_settings { of->settings() } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Sampler::~Sampler() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Sampler::Sampler(const Sampler&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Sampler::operator=(const Sampler&) noexcept -> Sampler& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Sampler::Sampler(Sampler&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Sampler::operator=(Sampler&&) noexcept -> Sampler& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Sampler::settings() const noexcept -> const gpu::Sampler::Settings& { + return m_settings; + } + } // namespace view + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline ImageView::ImageView(PrivateTag, view::Device device) noexcept + : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyImageView } { } ///////////////////////////////////// @@ -370,28 +439,6 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto ImageView::operator=(ImageView&&) noexcept -> ImageView& = default; - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto ImageView::create(const Device& device, - const Image& image, - ImageViewType type, - const ImageSubresourceRange& subresource_range) noexcept -> Expected { - auto image_view = ImageView { device, type, subresource_range, PrivateFuncTag {} }; - return image_view.do_init(image).transform(core::monadic::consume(image_view)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto ImageView::allocate(const Device& device, - const Image& image, - ImageViewType type, - const ImageSubresourceRange& subresource_range) noexcept -> Expected> { - auto image_view = std::make_unique(device, type, subresource_range, PrivateFuncTag {}); - return image_view->do_init(image).transform(core::monadic::consume(image_view)); - } - ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE @@ -406,39 +453,81 @@ namespace stormkit::gpu { return m_subresource_range; } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto ImageView::native_handle() const noexcept -> VkImageView { - EXPECTS(m_vk_handle); - return m_vk_handle; + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline ImageView::ImageView(const gpu::ImageView& of) noexcept + : view::DeviceObject { of }, m_type { of.type() }, m_subresource_range { of.subresource_range() } { + } + + /////////////////////////////////// + /////////////////////////////////// + template T> + STORMKIT_FORCE_INLINE + inline ImageView::ImageView(const T& of) noexcept + : view::DeviceObject { of }, m_type { of.type() }, m_subresource_range { of.subresource_range() } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline ImageView::~ImageView() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline ImageView::ImageView(const ImageView&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto ImageView::operator=(const ImageView&) noexcept -> ImageView& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline ImageView::ImageView(ImageView&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto ImageView::operator=(ImageView&&) noexcept -> ImageView& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto ImageView::type() const noexcept -> ImageViewType { + return m_type; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto ImageView::subresource_range() const noexcept -> const ImageSubresourceRange& { + return m_subresource_range; + } + } // namespace view + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Image::Image(PrivateTag, view::Device device) noexcept + : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyImage } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Image::Image(const Device& device, const CreateInfo& info, PrivateFuncTag) noexcept - : m_extent { info.extent }, - m_format { info.format }, - m_layers { info.layers }, - m_faces { 1 }, - m_mip_levels { info.mip_levels }, - m_type { info.type }, - m_flags { info.flags }, - m_samples { info.samples }, - m_usages { info.usages }, - m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vma_allocator { device.allocator() }, - m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { - vk_device_table.vkDestroyImage(vk_device, handle, nullptr); - } } { - } + inline Image::~Image() { + if (not m_no_delete) [[unlikely]] + if (m_vk_handle != VK_NULL_HANDLE) { + const auto& device = this->device(); + vk::call(device.device_table().*m_deleter_ptr, device, m_vk_handle, nullptr); + } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Image::~Image() = default; + m_vk_handle = VK_NULL_HANDLE; + } ///////////////////////////////////// ///////////////////////////////////// @@ -450,22 +539,6 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto Image::operator=(Image&&) noexcept -> Image& = default; - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::create(const Device& device, const CreateInfo& create_info) noexcept -> Expected { - auto image = Image { device, create_info, PrivateFuncTag {} }; - return image.do_init(create_info).transform(core::monadic::consume(image)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::allocate(const Device& device, const CreateInfo& create_info) noexcept -> Expected> { - auto image = std::make_unique(device, create_info, PrivateFuncTag {}); - return image->do_init(create_info).transform(core::monadic::consume(image)); - } - ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE @@ -525,46 +598,158 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Image::native_handle() const noexcept -> VkImage { - EXPECTS(m_vk_handle); - return m_vk_handle; + inline auto Image::allocation() const noexcept -> vk::Observer { + EXPECTS(m_vma_allocation != VK_NULL_HANDLE); + return m_vma_allocation; } ///////////////////////////////////// ///////////////////////////////////// - inline auto Image::create(const Device& device, const CreateInfo& info, VkImage&& vk_image) noexcept -> Image { - auto image = Image { device, info, PrivateFuncTag {} }; + inline auto Image::from_existing(view::Device device, const CreateInfo& create_info, VkImage vk_image) noexcept -> Image { + auto image = Image { PrivateTag {}, std::move(device) }; + image.m_extent = create_info.extent; + image.m_format = create_info.format; + image.m_layers = create_info.layers; + image.m_faces = 1; + image.m_mip_levels = create_info.mip_levels; + image.m_type = create_info.type; + image.m_flags = create_info.flags; + image.m_samples = create_info.samples; + image.m_usages = create_info.usages; + image.m_vma_allocation = { core::monadic::noop() }; - image.m_vk_handle = { core::monadic::noop() }; image.m_vk_handle = std::move(vk_image); + image.m_no_delete = true; + return image; } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::do_init(const CreateInfo& info) noexcept -> Expected { - if (core::check_flag_bit(m_flags, gpu::ImageCreateFlag::CUBE_COMPATIBLE)) m_faces = 6u; - const auto create_info = VkImageCreateInfo { - .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, - .pNext = nullptr, - .flags = to_vk(m_flags), - .imageType = to_vk(m_type), - .format = to_vk(m_format), - .extent = { m_extent.width, m_extent.height, m_extent.depth }, - .mipLevels = m_mip_levels, - .arrayLayers = m_layers * m_faces, - .samples = to_vk(m_samples), - .tiling = to_vk(info.tiling), - .usage = to_vk(m_usages), - .sharingMode = VK_SHARING_MODE_EXCLUSIVE, - .queueFamilyIndexCount = 0, // TODO CHECK IF VALID VALUE - .pQueueFamilyIndices = nullptr, - .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, - }; - - return do_init(create_info, info.property); - } + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Image::Image(const gpu::Image& of) noexcept + : view::DeviceObject { of }, + m_extent { of.extent() }, + m_format { of.format() }, + m_layers { of.layers() }, + m_faces { of.faces() }, + m_mip_levels { of.mip_levels() }, + m_type { of.type() }, + m_flags { of.m_flags }, + m_samples { of.samples() }, + m_usages { of.usages() } { + if (not of.m_no_delete) m_vma_allocation = of.allocation(); + } + + /////////////////////////////////// + /////////////////////////////////// + template T> + STORMKIT_FORCE_INLINE + inline Image::Image(const T& of) noexcept + : view::DeviceObject { of }, + m_extent { of->extent() }, + m_format { of->format() }, + m_layers { of->layers() }, + m_faces { of->faces() }, + m_mip_levels { of->mip_levels() }, + m_type { of->type() }, + m_flags { of->m_flags }, + m_samples { of->samples() }, + m_usages { of->usages() }, + m_vma_allocation { of->allocation() } { + if (not of->m_no_delete) m_vma_allocation = of->allocation(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Image::~Image() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Image::Image(const Image&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::operator=(const Image&) noexcept -> Image& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Image::Image(Image&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::operator=(Image&&) noexcept -> Image& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::extent() const noexcept -> const math::uextent3& { + return m_extent; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::format() const noexcept -> PixelFormat { + return m_format; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::type() const noexcept -> ImageType { + return m_type; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::samples() const noexcept -> SampleCountFlag { + return m_samples; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::layers() const noexcept -> u32 { + return m_layers; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::faces() const noexcept -> u32 { + return m_faces; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::mip_levels() const noexcept -> u32 { + return m_mip_levels; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::usages() const noexcept -> ImageUsageFlag { + return m_usages; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Image::allocation() const noexcept -> vk::Observer { + EXPECTS(m_vma_allocation != VK_NULL_HANDLE); + return m_vma_allocation; + } + } // namespace view ///////////////////////////////////// ///////////////////////////////////// @@ -579,6 +764,6 @@ namespace stormkit::gpu { create_info.samples, create_info.usages, create_info.tiling, - create_info.property); + create_info.properties); } } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/resource/shader.cppm b/modules/stormkit/gpu/resource/shader.cppm index 870f46df7..0ce3a31e8 100644 --- a/modules/stormkit/gpu/resource/shader.cppm +++ b/modules/stormkit/gpu/resource/shader.cppm @@ -6,6 +6,7 @@ module; #include #include +#include #include #include @@ -18,35 +19,55 @@ import stormkit.core; import stormkit.gpu.core; namespace stdr = std::ranges; +namespace stdv = std::views; + +namespace cmeta = stormkit::core::meta; export namespace stormkit::gpu { - class STORMKIT_GPU_API Shader { - struct PrivateFuncTag {}; + class Shader; + + namespace view { + class Shader; + } // namespace view + + namespace meta { + template<> + struct ObjectInfo { + using Of = Shader; + using ElementType = VkShaderModule; + using DeleterType = PFN_vkDestroyShaderModule VolkDeviceTable::*; + using ViewType = view::Shader; + using OwnedBy = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::SHADER_MODULE; + }; + } // namespace meta + class STORMKIT_GPU_API Shader: public OwnedByDevice { public: enum class Error { INVALID_SPIRV, }; + using LoadError = std::variant; template - using LoadExpected = std::expected; - static constexpr auto DEBUG_TYPE = DebugObjectType::SHADER_MODULE; + using LoadExpected = std::expected; - static auto load_from_file(const Device& device, const std::filesystem::path& filepath, ShaderStageFlag type) noexcept + static auto load_from_file(view::Device device, const std::filesystem::path& filepath, ShaderStageFlag type) noexcept -> LoadExpected; - static auto load_from_bytes(const Device& device, std::span data, ShaderStageFlag type) noexcept + static auto load_from_bytes(view::Device device, std::span data, ShaderStageFlag type) noexcept -> Expected; - static auto load_from_spirvid(const Device& device, std::span data, ShaderStageFlag type) noexcept + static auto load_from_spirv(view::Device device, std::span data, ShaderStageFlag type) noexcept -> Expected; - static auto allocate_and_load_from_file(const Device& device, + static auto allocate_and_load_from_file(view::Device device, const std::filesystem::path& filepath, - ShaderStageFlag type) noexcept -> LoadExpected>; - static auto allocate_and_load_from_bytes(const Device& device, std::span data, ShaderStageFlag type) noexcept - -> Expected>; - static auto allocate_and_load_from_spirvid(const Device& device, - std::span data, - ShaderStageFlag type) noexcept -> Expected>; + ShaderStageFlag type) noexcept -> LoadExpected>; + static auto allocate_and_load_from_bytes(view::Device device, std::span data, ShaderStageFlag type) noexcept + -> Expected>; + static auto allocate_and_load_from_spirv(view::Device device, + std::span data, + ShaderStageFlag type) noexcept -> Expected>; ~Shader(); Shader(const Shader&) = delete; @@ -60,24 +81,46 @@ export namespace stormkit::gpu { [[nodiscard]] auto source() const noexcept -> const std::vector&; [[nodiscard]] - auto source_as_bytes() const noexcept -> std::span; + auto source_as_bytes() const noexcept -> std::span; - [[nodiscard]] - auto native_handle() const noexcept -> VkShaderModule; - - Shader(const Device&, std::vector, ShaderStageFlag, PrivateFuncTag) noexcept; + // clang-format off + // private: + // clang-format on + Shader(PrivateTag, view::Device) noexcept; + auto do_init(PrivateTag, std::vector, ShaderStageFlag) -> Expected; private: - auto do_init() -> Expected; auto reflect() noexcept -> void; ShaderStageFlag m_type = ShaderStageFlag::NONE; std::vector m_source = {}; - - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - VkRAIIHandle m_vk_handle; }; + + namespace view { + class STORMKIT_GPU_API Shader: public view::DeviceObject { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using ViewType = ObjectInfo::ViewType; + + Shader(const gpu::Shader& of) noexcept; + template T> + Shader(const T& of) noexcept; + ~Shader() noexcept; + + Shader(const Shader&) noexcept; + auto operator=(const Shader&) noexcept -> Shader&; + + Shader(Shader&&) noexcept; + auto operator=(Shader&&) noexcept -> Shader&; + + [[nodiscard]] + auto type() const noexcept -> ShaderStageFlag; + + private: + ShaderStageFlag m_type = ShaderStageFlag::NONE; + }; + } // namespace view } // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// @@ -102,31 +145,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::do_init() -> Expected { - const auto create_info = VkShaderModuleCreateInfo { - .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .codeSize = stdr::size(m_source) * sizeof(SpirvID), - .pCode = stdr::data(m_source) - }; - - return vk_call(m_vk_device_table->vkCreateShaderModule, m_vk_device, &create_info, nullptr) - .transform(core::monadic::set(m_vk_handle)) - .transform_error(monadic::from_vk()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Shader::Shader(const Device& device, std::vector data, ShaderStageFlag type, PrivateFuncTag) noexcept - : m_type { type }, - m_source { std::move(data) }, - m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto&& handle) noexcept { - vk_device_table.vkDestroyShaderModule(vk_device, handle, nullptr); - } } { + inline Shader::Shader(PrivateTag, view::Device device) noexcept + : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyShaderModule } { } ///////////////////////////////////// @@ -147,87 +167,64 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::load_from_file(const Device& device, const std::filesystem::path& filepath, ShaderStageFlag type) noexcept + inline auto Shader::load_from_file(view::Device device, const std::filesystem::path& filepath, ShaderStageFlag type) noexcept -> LoadExpected { - return io::File::open(filepath, io::Access::READ) - .transform_error(sys_to_load_error) - .and_then([](auto&& file) static noexcept -> LoadExpected> { - const auto size = file.size(); - if (size % sizeof(SpirvID) != 0) return std::unexpected { LoadError { Error::INVALID_SPIRV } }; - auto spirv = std::vector(size / sizeof(SpirvID)); - return file.read_to(as_bytes_mut(spirv)) - .transform(core::monadic::consume(spirv)) - .transform_error(sys_to_load_error); - }) - .and_then([&type, &device](auto&& spirv) noexcept { - auto shader = Shader { device, std::move(spirv), type, PrivateFuncTag {} }; - return shader.do_init().transform_error(result_to_load_error).transform(core::monadic::consume(shader)); - }); + expects(std::filesystem::is_regular_file(filepath), std::format("{} is not a file", filepath.string())); + + const auto data = TryTransformError(io::read(filepath), sys_to_load_error); + const auto spirv = std::vector { std::from_range, bytes_as_span(data) }; + Return TryTransformError(create(std::move(device), std::move(spirv), type), result_to_load_error); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::load_from_bytes(const Device& device, std::span data, ShaderStageFlag type) noexcept + inline auto Shader::load_from_bytes(view::Device device, std::span data, ShaderStageFlag type) noexcept -> Expected { - auto shader = Shader { device, bytes_as_span(data) | stdr::to(), type, PrivateFuncTag {} }; - return shader.do_init().transform(core::monadic::consume(shader)); + const auto spirv = std::vector { std::from_range, bytes_as_span(data) }; + return create(std::move(device), std::move(spirv), type); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::load_from_spirvid(const Device& device, std::span data, ShaderStageFlag type) noexcept + inline auto Shader::load_from_spirv(view::Device device, std::span data, ShaderStageFlag type) noexcept -> Expected { - auto shader = Shader { device, data | stdr::to(), type, PrivateFuncTag {} }; - return shader.do_init().transform(core::monadic::consume(shader)); + const auto spirv = std::vector { std::from_range, data }; + return create(std::move(device), std::move(spirv), type); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::allocate_and_load_from_file(const Device& device, + inline auto Shader::allocate_and_load_from_file(view::Device device, const std::filesystem::path& filepath, - ShaderStageFlag type) noexcept -> LoadExpected> { + ShaderStageFlag type) noexcept -> LoadExpected> { expects(std::filesystem::is_regular_file(filepath), std::format("{} is not a file", filepath.string())); - return io::File::open(filepath, io::Access::READ) - .transform_error(sys_to_load_error) - .and_then([](auto&& file) static noexcept { - const auto size = file.size(); - - auto spirv = std::vector(size / sizeof(SpirvID)); - return file.read_to(as_bytes_mut(spirv)) - .transform(core::monadic::consume(spirv)) - .transform_error(sys_to_load_error); - }) - .and_then([&type, &device](auto&& spirv) noexcept { - auto shader = std::make_unique(device, std::move(spirv), type, PrivateFuncTag {}); - return shader->do_init().transform(core::monadic::consume(shader)).transform_error(result_to_load_error); - }); + const auto data = TryTransformError(io::read(filepath), sys_to_load_error); + const auto spirv = std::vector { std::from_range, bytes_as_span(data) }; + Return TryTransformError(allocate(std::move(device), std::move(spirv), type), result_to_load_error); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::allocate_and_load_from_bytes(const Device& device, - std::span data, - ShaderStageFlag type) noexcept -> Expected> { - auto shader = std::make_unique(device, - bytes_as_span(data) | stdr::to(), - type, - PrivateFuncTag {}); - return shader->do_init().transform(core::monadic::consume(shader)); + inline auto Shader::allocate_and_load_from_bytes(view::Device device, + std::span data, + ShaderStageFlag type) noexcept -> Expected> { + const auto spirv = std::vector { std::from_range, bytes_as_span(data) }; + return allocate(std::move(device), std::move(spirv), type); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::allocate_and_load_from_spirvid(const Device& device, - std::span data, - ShaderStageFlag type) noexcept -> Expected> { - auto shader = std::make_unique(device, data | stdr::to(), type, PrivateFuncTag {}); - return shader->do_init().transform(core::monadic::consume(shader)); + inline auto Shader::allocate_and_load_from_spirv(view::Device device, + std::span data, + ShaderStageFlag type) noexcept -> Expected> { + const auto spirv = std::vector { std::from_range, data }; + return allocate(std::move(device), std::move(spirv), type); } ///////////////////////////////////// @@ -247,14 +244,56 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::source_as_bytes() const noexcept -> std::span { + inline auto Shader::source_as_bytes() const noexcept -> std::span { return as_bytes(m_source); } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Shader::native_handle() const noexcept -> VkShaderModule { - return m_vk_handle; - } + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Shader::Shader(const gpu::Shader& of) noexcept + : view::DeviceObject { of }, m_type { of.type() } { + } + + /////////////////////////////////// + /////////////////////////////////// + template T> + STORMKIT_FORCE_INLINE + inline Shader::Shader(const T& of) noexcept + : view::DeviceObject { of }, m_type { of->type() } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Shader::~Shader() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Shader::Shader(const Shader& other) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Shader::operator=(const Shader& other) noexcept -> Shader& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Shader::Shader(Shader&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Shader::operator=(Shader&&) noexcept -> Shader& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Shader::type() const noexcept -> ShaderStageFlag { + return m_type; + } + } // namespace view } // namespace stormkit::gpu diff --git a/src/gpu/core/debug_callback.cpp b/src/gpu/core/debug_callback.cpp new file mode 100644 index 000000000..02167c3c5 --- /dev/null +++ b/src/gpu/core/debug_callback.cpp @@ -0,0 +1,49 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +module stormkit.gpu.core; + +import std; + +import stormkit.core; +import stormkit.log; + +namespace stdr = std::ranges; +namespace stdv = std::views; + +namespace stormkit::gpu { + ///////////////////////////////////// + ///////////////////////////////////// + auto DebugCallback::do_init(PrivateTag, Closure closure, void* user_data) noexcept -> Expected { + constexpr auto severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; + + constexpr auto type = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT + | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; + + const auto create_info = VkDebugUtilsMessengerCreateInfoEXT { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, + .pNext = nullptr, + .flags = 0, + .messageSeverity = severity, + .messageType = type, + .pfnUserCallback = closure, + .pUserData = user_data, + }; + + m_vk_handle = Try(vk::call_checked(vkCreateDebugUtilsMessengerEXT, + instance(), + &create_info, + nullptr)); + Return {}; + } +} // namespace stormkit::gpu diff --git a/src/gpu/core/device.cpp b/src/gpu/core/device.cpp index 782dbac9c..d76237bc3 100644 --- a/src/gpu/core/device.cpp +++ b/src/gpu/core/device.cpp @@ -6,6 +6,8 @@ module; #include #include +#include + #include #include @@ -22,6 +24,8 @@ using namespace std::literals; namespace stdr = std::ranges; namespace stdv = std::views; +namespace cmonadic = stormkit::core::monadic; + namespace { constexpr auto RAYTRACING_EXTENSIONS = to_array({ VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, @@ -193,89 +197,150 @@ namespace { } // namespace namespace stormkit::gpu { - NAMED_LOGGER(device_logger, "stormkit.gpu:core.Device") - - template - constexpr auto find_queue() { - return [](const auto& family) static noexcept { - return core::check_flag_bit(family.flags, flag) and (not core::check_flag_bit(family.flags, no_flag) and ...); + namespace { + struct DeviceAPI { + template + static auto wait_idle(const DeviceType& device) noexcept -> Expected { + const auto& table = device.device_table(); + const auto& handle = device.native_handle(); + Try(vk::call_checked(table.vkDeviceWaitIdle, handle)); + Return {}; + } + + template + static auto wait_for_fences(const DeviceType& device, + std::span fences, + bool wait_all = true, + const std::chrono::milliseconds& timeout = std::chrono::milliseconds::max()) noexcept + -> Expected { + const auto& device_table = device.device_table(); + const auto _fences = transform(fences, vk::monadic::to_vk()); + + const auto result = Try((vk::call_checked(device_table.vkWaitForFences, + device, + stdr::size(_fences), + stdr::data(_fences), + wait_all, + std::chrono::duration_cast< + std::chrono::nanoseconds>(timeout) + .count()))); + return vk::from_vk(result); + } + + template + static auto reset_fences(const DeviceType& device, std::span fences) noexcept -> Expected { + const auto& device_table = device.device_table(); + + const auto _fences = transform(fences, vk::monadic::to_vk()); + Try(vk::call_checked(table.vkResetFences, device, stdr::size(_fences), stdr::data(_fences))); + Return {}; + } + + template + static auto set_object_name(const DeviceType& device, + u64 object, + DebugObjectType type, + std::string_view name) noexcept -> Expected { + if (not vkSetDebugUtilsObjectNameEXT) return {}; + + const auto& handle = device.native_handle(); + const auto info = VkDebugUtilsObjectNameInfoEXT { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, + .pNext = nullptr, + .objectType = vk::to_vk(type), + .objectHandle = object, + .pObjectName = stdr::data(name), + }; + + Try(vk::call_checked(vkSetDebugUtilsObjectNameEXT, device, &info)); + Return {}; + } }; - } + } // namespace ///////////////////////////////////// ///////////////////////////////////// auto Device::wait_idle() const noexcept -> Expected { - return vk_call(m_vk_device_table.vkDeviceWaitIdle, m_vk_handle).transform_error(core::monadic::narrow()); + return DeviceAPI::wait_idle(*this); } ///////////////////////////////////// ///////////////////////////////////// - auto Device::do_init(const Instance& instance, const Info& info) noexcept -> Expected { - const auto& queue_families = m_physical_device->queue_families(); - - struct Queue_ { - std::optional id = std::nullopt; - u32 count = 0u; - std::array _ = {}; // padding - QueueFlag flags = QueueFlag {}; - }; - - const auto raster_queue = [&queue_families]() -> Queue_ { - const auto it = stdr::find_if(queue_families, find_queue()); - if (it == stdr::cend(queue_families)) return {}; - - return { - .id = as(std::distance(stdr::cbegin(queue_families), it)), - .count = it->count, - .flags = it->flags, - }; - }(); + auto Device::wait_for_fences(std::span fences, + bool wait_all, + const std::chrono::milliseconds& timeout) const noexcept -> Expected { + return DeviceAPI::wait_for_fences(*this, std::move(fences), wait_all, timeout); + } - const auto compute_queue = [&queue_families]() -> Queue_ { - const auto it = stdr::find_if(queue_families, find_queue()); - if (it == stdr::cend(queue_families)) return {}; + ///////////////////////////////////// + ///////////////////////////////////// + auto Device::reset_fences(std::span fences) const noexcept -> Expected { + return DeviceAPI::reset_fences(*this, std::move(fences)); + } - return { .id = as(std::distance(stdr::cbegin(queue_families), it)), .count = it->count, .flags = it->flags }; - }(); + ///////////////////////////////////// + ///////////////////////////////////// + auto Device::set_object_name(u64 object, DebugObjectType type, std::string_view name) const -> Expected { + return DeviceAPI::set_object_name(*this, object, type, std::move(name)); + } - const auto transfert_queue = [&queue_families]() -> Queue_ { - const auto it = stdr::find_if(queue_families, - find_queue()); - if (it == stdr::cend(queue_families)) return {}; + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + auto Device::wait_idle() const noexcept -> Expected { + return DeviceAPI::wait_idle(*this); + } - return { .id = as(std::distance(stdr::cbegin(queue_families), it)), .count = it->count, .flags = it->flags }; - }(); + ///////////////////////////////////// + ///////////////////////////////////// + auto Device::wait_for_fences(std::span fences, + bool wait_all, + const std::chrono::milliseconds& timeout) const noexcept -> Expected { + return DeviceAPI::wait_for_fences(*this, std::move(fences), wait_all, timeout); + } - const auto queues = [&] { - auto q = std::vector {}; - q.reserve(3); + ///////////////////////////////////// + ///////////////////////////////////// + auto Device::reset_fences(std::span fences) const noexcept -> Expected { + return DeviceAPI::reset_fences(*this, std::move(fences)); + } - if (raster_queue.id) q.push_back(&raster_queue); - if (compute_queue.id) q.push_back(&compute_queue); - if (transfert_queue.id) q.push_back(&transfert_queue); + ///////////////////////////////////// + ///////////////////////////////////// + auto Device::set_object_name(u64 object, DebugObjectType type, std::string_view name) const -> Expected { + return DeviceAPI::set_object_name(*this, object, type, std::move(name)); + } + } // namespace view - return q; - }(); + ///////////////////////////////////// + ///////////////////////////////////// + auto Device::do_init(PrivateTag, const CreateInfo& info) noexcept -> Expected { + const auto& queue_families = m_physical_device.queue_families(); + auto i = 0_u32; auto priorities = std::vector> {}; - priorities.reserve(stdr::size(queues)); - - const auto queue_create_infos = transform(queues, [&priorities](auto queue) { + priorities.reserve(stdr::size(queue_families)); + const auto queue_create_infos = transform(queue_families, [this, &i, &priorities](const auto& family) noexcept { auto& priority = priorities.emplace_back(); + priority.resize(family.count, 1.f); - priority.resize(queue->count, 1.f); + m_queue_entries.emplace_back(QueueEntry { + .id = i, + .count = family.count, + .flags = family.flags, + }); return VkDeviceQueueCreateInfo { .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, .pNext = nullptr, .flags = 0, - .queueFamilyIndex = queue->id.value(), - .queueCount = 1, + .queueFamilyIndex = i++, + .queueCount = family.count, .pQueuePriorities = stdr::data(priority), }; }); - // const auto& capabilities = m_physical_device->capabilities(); + // const auto& capabilities = m_physical_device.capabilities(); const auto enabled_1_0_features = init_by([](auto& out) static noexcept { out.multiDrawIndirect = true; out.samplerAnisotropy = true; @@ -295,22 +360,18 @@ namespace stormkit::gpu { out.dynamicRendering = true; }); - const auto device_extensions = m_physical_device->extensions(); - - device_logger.dlog("Device extensions: {}", device_extensions); + const auto device_extensions = m_physical_device.extensions(); const auto swapchain_available = [&] { for (const auto& ext : SWAPCHAIN_EXTENSIONS) - if (stdr::none_of(device_extensions, core::monadic::is_equal(ext))) return false; + if (stdr::none_of(device_extensions, cmonadic::is_equal(ext))) return false; return true; }(); - if (not swapchain_available) device_logger.wlog("Swapchain extension are not available"); - const auto raytracing_available = [&] { for (const auto& ext : RAYTRACING_EXTENSIONS) - if (stdr::none_of(device_extensions, core::monadic::is_equal(ext))) return false; + if (stdr::none_of(device_extensions, cmonadic::is_equal(ext))) return false; return true; }(); @@ -324,7 +385,6 @@ namespace stormkit::gpu { return e; }(); - device_logger.dlog("Enabled device extensions: {}", extensions); // const auto acceleration_feature = [] static noexcept { // auto out = zeroed(); @@ -357,255 +417,199 @@ namespace stormkit::gpu { .pEnabledFeatures = &enabled_1_0_features, }; - auto allocator_create_info = VmaAllocatorCreateInfo { + m_vk_handle = Try(vk::call_checked(vkCreateDevice, m_physical_device.native_handle(), &create_info, nullptr)); + volkLoadDeviceTable(&m_vk_device_table, m_vk_handle); + + const auto physical_device = this->physical_device(); + auto allocator_create_info = VmaAllocatorCreateInfo { .flags = 0, - .physicalDevice = m_physical_device->native_handle(), - .device = nullptr, + .physicalDevice = physical_device, + .device = m_vk_handle, .preferredLargeHeapBlockSize = 0, .pAllocationCallbacks = nullptr, .pDeviceMemoryCallbacks = nullptr, .pHeapSizeLimit = nullptr, .pVulkanFunctions = nullptr, - .instance = instance.native_handle(), - .vulkanApiVersion = vk_make_version(1, 4, 0), + .instance = instance(), + .vulkanApiVersion = vk::make_version(1, 4, 0), .pTypeExternalMemoryHandleTypes = nullptr, }; + m_vma_function_table = Try(vk::call_checked(vma_import_functions_from_volk, + &allocator_create_info, + &m_vk_device_table)); - return vk_call(vkCreateDevice, m_physical_device->native_handle(), &create_info, nullptr) - .transform(core::monadic::set(m_vk_handle)) - .and_then([this, &allocator_create_info] mutable noexcept { - allocator_create_info.device = m_vk_handle; - volkLoadDeviceTable(&m_vk_device_table, m_vk_handle); - auto raw = m_vk_handle.value(); - m_vk_handle = { [vk_device_table = m_vk_device_table](auto handle) noexcept { - vk_device_table.vkDestroyDevice(handle, nullptr); - } }; - m_vk_handle = std::move(raw); - return vk_call(vma_import_functions_from_volk, &allocator_create_info, &m_vk_device_table); - }) - .transform(core::monadic::set(m_vma_function_table)) - .and_then([this, &allocator_create_info] mutable noexcept { - allocator_create_info.pVulkanFunctions = &m_vma_function_table; - - return vk_call(vmaCreateAllocator, &allocator_create_info); - }) - .transform(core::monadic::set(m_vma_allocator)) - .transform_error(monadic::from_vk()) - .and_then([this, &raster_queue] noexcept { - if (raster_queue.id) - m_raster_queue = QueueEntry { .id = *raster_queue.id, - .count = raster_queue.count, - .flags = raster_queue.flags }; - - return set_object_name(*this, std::format("StormKit:Device ({})", m_physical_device->info().device_name)); - }); - } + allocator_create_info.pVulkanFunctions = &m_vma_function_table; - ///////////////////////////////////// - ///////////////////////////////////// - auto Device::wait_for_fences(std::span> fences, - bool wait_all, - const std::chrono::milliseconds& timeout) const noexcept -> Expected { - static constexpr auto POSSIBLE_RESULTS = std::array { VK_SUCCESS, VK_NOT_READY }; - - const auto vk_fences = fences | stdv::transform(monadic::to_vk()) | stdr::to(); - - return vk_call(m_vk_device_table.vkWaitForFences, - as_view(POSSIBLE_RESULTS), - m_vk_handle, - stdr::size(vk_fences), - stdr::data(vk_fences), - wait_all, - std::chrono::duration_cast(timeout).count()) - .transform(core::monadic::narrow()) - .transform_error(core::monadic::narrow()); - } + m_vma_allocator = Try(vk::call_checked(vmaCreateAllocator, &allocator_create_info)); - ///////////////////////////////////// - ///////////////////////////////////// - auto Device::reset_fences(std::span> fences) const noexcept -> Expected { - const auto vk_fences = fences | stdv::transform(monadic::to_vk()) | stdr::to(); + Try(set_object_name(*this, std::format("StormKit:device ({})", physical_device.info().device_name))); - return vk_call(m_vk_device_table.vkResetFences, m_vk_handle, std ::ranges::size(vk_fences), stdr::data(vk_fences)) - .transform_error(core::monadic::narrow()); + Return {}; } - ///////////////////////////////////// - ///////////////////////////////////// - auto Device::set_object_name(u64 object, DebugObjectType type, std::string_view name) const -> Expected { - if (not vkSetDebugUtilsObjectNameEXT) return {}; - - const auto info = VkDebugUtilsObjectNameInfoEXT { - .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, - .pNext = nullptr, - .objectType = to_vk(type), - .objectHandle = object, - .pObjectName = std::data(name), - }; - - return vk_call(vkSetDebugUtilsObjectNameEXT, m_vk_handle, &info).transform_error(monadic::from_vk()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto imgui_vk_loader(const char* _func_name, void* user_data) noexcept -> PFN_vkVoidFunction { - const auto func_name = std::string_view { _func_name }; - const auto& device = *std::bit_cast(user_data); - - if (func_name == "vkAllocateCommandBuffers") - return std::bit_cast(device.device_table().vkAllocateCommandBuffers); - else if (func_name == "vkAllocateDescriptorSets") - return std::bit_cast(device.device_table().vkAllocateDescriptorSets); - else if (func_name == "vkAllocateMemory") - return std::bit_cast(device.device_table().vkAllocateMemory); - else if (func_name == "vkBeginCommandBuffer") - return std::bit_cast(device.device_table().vkBeginCommandBuffer); - else if (func_name == "vkBindBufferMemory") - return std::bit_cast(device.device_table().vkBindBufferMemory); - else if (func_name == "vkBindImageMemory") - return std::bit_cast(device.device_table().vkBindImageMemory); - else if (func_name == "vkCmdBindDescriptorSets") - return std::bit_cast(device.device_table().vkCmdBindDescriptorSets); - else if (func_name == "vkCmdBindIndexBuffer") - return std::bit_cast(device.device_table().vkCmdBindIndexBuffer); - else if (func_name == "vkCmdBindPipeline") - return std::bit_cast(device.device_table().vkCmdBindPipeline); - else if (func_name == "vkCmdBindVertexBuffers") - return std::bit_cast(device.device_table().vkCmdBindVertexBuffers); - else if (func_name == "vkCmdCopyBufferToImage") - return std::bit_cast(device.device_table().vkCmdCopyBufferToImage); - else if (func_name == "vkCmdDrawIndexed") - return std::bit_cast(device.device_table().vkCmdDrawIndexed); - else if (func_name == "vkCmdPipelineBarrier") - return std::bit_cast(device.device_table().vkCmdPipelineBarrier); - else if (func_name == "vkCmdPushConstants") - return std::bit_cast(device.device_table().vkCmdPushConstants); - else if (func_name == "vkCmdSetScissor") - return std::bit_cast(device.device_table().vkCmdSetScissor); - else if (func_name == "vkCmdSetViewport") - return std::bit_cast(device.device_table().vkCmdSetViewport); - else if (func_name == "vkCreateBuffer") - return std::bit_cast(device.device_table().vkCreateBuffer); - else if (func_name == "vkCreateCommandPool") - return std::bit_cast(device.device_table().vkCreateCommandPool); - else if (func_name == "vkCreateDescriptorPool") - return std::bit_cast(device.device_table().vkCreateDescriptorPool); - else if (func_name == "vkCreateDescriptorSetLayout") - return std::bit_cast(device.device_table().vkCreateDescriptorSetLayout); - else if (func_name == "vkCreateFence") - return std::bit_cast(device.device_table().vkCreateFence); - else if (func_name == "vkCreateFramebuffer") - return std::bit_cast(device.device_table().vkCreateFramebuffer); - else if (func_name == "vkCreateGraphicsPipelines") - return std::bit_cast(device.device_table().vkCreateGraphicsPipelines); - else if (func_name == "vkCreateImage") - return std::bit_cast(device.device_table().vkCreateImage); - else if (func_name == "vkCreateImageView") - return std::bit_cast(device.device_table().vkCreateImageView); - else if (func_name == "vkCreatePipelineLayout") - return std::bit_cast(device.device_table().vkCreatePipelineLayout); - else if (func_name == "vkCreateRenderPass") - return std::bit_cast(device.device_table().vkCreateRenderPass); - else if (func_name == "vkCreateSampler") - return std::bit_cast(device.device_table().vkCreateSampler); - else if (func_name == "vkCreateSemaphore") - return std::bit_cast(device.device_table().vkCreateSemaphore); - else if (func_name == "vkCreateShaderModule") - return std::bit_cast(device.device_table().vkCreateShaderModule); - else if (func_name == "vkCreateSwapchainKHR") - return std::bit_cast(device.device_table().vkCreateSwapchainKHR); - else if (func_name == "vkDestroyBuffer") - return std::bit_cast(device.device_table().vkDestroyBuffer); - else if (func_name == "vkDestroyCommandPool") - return std::bit_cast(device.device_table().vkDestroyCommandPool); - else if (func_name == "vkDestroyDescriptorPool") - return std::bit_cast(device.device_table().vkDestroyDescriptorPool); - else if (func_name == "vkDestroyDescriptorSetLayout") - return std::bit_cast(device.device_table().vkDestroyDescriptorSetLayout); - else if (func_name == "vkDestroyFence") - return std::bit_cast(device.device_table().vkDestroyFence); - else if (func_name == "vkDestroyFramebuffer") - return std::bit_cast(device.device_table().vkDestroyFramebuffer); - else if (func_name == "vkDestroyImage") - return std::bit_cast(device.device_table().vkDestroyImage); - else if (func_name == "vkDestroyImageView") - return std::bit_cast(device.device_table().vkDestroyImageView); - else if (func_name == "vkDestroyPipeline") - return std::bit_cast(device.device_table().vkDestroyPipeline); - else if (func_name == "vkDestroyPipelineLayout") - return std::bit_cast(device.device_table().vkDestroyPipelineLayout); - else if (func_name == "vkDestroyRenderPass") - return std::bit_cast(device.device_table().vkDestroyRenderPass); - else if (func_name == "vkDestroySampler") - return std::bit_cast(device.device_table().vkDestroySampler); - else if (func_name == "vkDestroySemaphore") - return std::bit_cast(device.device_table().vkDestroySemaphore); - else if (func_name == "vkDestroyShaderModule") - return std::bit_cast(device.device_table().vkDestroyShaderModule); - else if (func_name == "vkDestroySurfaceKHR") - return std::bit_cast(vkDestroySurfaceKHR); - else if (func_name == "vkDestroySwapchainKHR") - return std::bit_cast(device.device_table().vkDestroySwapchainKHR); - else if (func_name == "vkDeviceWaitIdle") - return std::bit_cast(device.device_table().vkDeviceWaitIdle); - else if (func_name == "vkEnumeratePhysicalDevices") - return std::bit_cast(vkEnumeratePhysicalDevices); - else if (func_name == "vkEndCommandBuffer") - return std::bit_cast(device.device_table().vkEndCommandBuffer); - else if (func_name == "vkFlushMappedMemoryRanges") - return std::bit_cast(device.device_table().vkFlushMappedMemoryRanges); - else if (func_name == "vkFreeCommandBuffers") - return std::bit_cast(device.device_table().vkFreeCommandBuffers); - else if (func_name == "vkFreeDescriptorSets") - return std::bit_cast(device.device_table().vkFreeDescriptorSets); - else if (func_name == "vkFreeMemory") - return std::bit_cast(device.device_table().vkFreeMemory); - else if (func_name == "vkGetBufferMemoryRequirements") - return std::bit_cast(device.device_table().vkGetBufferMemoryRequirements); - else if (func_name == "vkGetDeviceQueue") - return std::bit_cast(device.device_table().vkGetDeviceQueue); - else if (func_name == "vkGetImageMemoryRequirements") - return std::bit_cast(device.device_table().vkGetImageMemoryRequirements); - else if (func_name == "vkGetPhysicalDeviceProperties") - return std::bit_cast(vkGetPhysicalDeviceProperties); - else if (func_name == "vkGetPhysicalDeviceMemoryProperties") - return std::bit_cast(vkGetPhysicalDeviceMemoryProperties); - else if (func_name == "vkGetPhysicalDeviceQueueFamilyProperties") - return std::bit_cast(vkGetPhysicalDeviceQueueFamilyProperties); - else if (func_name == "vkGetPhysicalDeviceSurfaceCapabilitiesKHR") - return std::bit_cast(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); - else if (func_name == "vkGetPhysicalDeviceSurfaceFormatsKHR") - return std::bit_cast(vkGetPhysicalDeviceSurfaceFormatsKHR); - else if (func_name == "vkGetPhysicalDeviceSurfacePresentModesKHR") - return std::bit_cast(vkGetPhysicalDeviceSurfacePresentModesKHR); - else if (func_name == "vkGetSwapchainImagesKHR") - return std::bit_cast(device.device_table().vkGetSwapchainImagesKHR); - else if (func_name == "vkMapMemory") - return std::bit_cast(device.device_table().vkMapMemory); - else if (func_name == "vkQueueSubmit") - return std::bit_cast(device.device_table().vkQueueSubmit); - else if (func_name == "vkQueueWaitIdle") - return std::bit_cast(device.device_table().vkQueueWaitIdle); - else if (func_name == "vkResetCommandPool") - return std::bit_cast(device.device_table().vkResetCommandPool); - else if (func_name == "vkResetFences") - return std::bit_cast(device.device_table().vkResetFences); - else if (func_name == "vkUnmapMemory") - return std::bit_cast(device.device_table().vkUnmapMemory); - else if (func_name == "vkUpdateDescriptorSets") - return std::bit_cast(device.device_table().vkUpdateDescriptorSets); - else if (func_name == "vkWaitForFences") - return std::bit_cast(device.device_table().vkWaitForFences); - else if (func_name == "vkCmdBeginRendering") - return std::bit_cast(device.device_table().vkCmdBeginRendering); - else if (func_name == "vkCmdEndRendering") - return std::bit_cast(device.device_table().vkCmdEndRendering); - else if (func_name == "vkCmdBeginRenderingKHR") - return std::bit_cast(device.device_table().vkCmdBeginRenderingKHR); - else if (func_name == "vkCmdEndRenderingKHR") - return std::bit_cast(device.device_table().vkCmdEndRenderingKHR); - - ensures(false, std::format("Unhandled vk func {}", func_name)); - std::unreachable(); - } + namespace vk { + ///////////////////////////////////// + ///////////////////////////////////// + auto imgui_vk_loader(const char* _func_name, void* user_data) noexcept -> PFN_vkVoidFunction { + const auto func_name = std::string_view { _func_name }; + const auto& device = *std::bit_cast(user_data); + const auto& device_table = device.device_table(); + + if (func_name == "vkAllocateCommandBuffers") + return std::bit_cast(device_table.vkAllocateCommandBuffers); + else if (func_name == "vkAllocateDescriptorSets") + return std::bit_cast(device_table.vkAllocateDescriptorSets); + else if (func_name == "vkAllocateMemory") + return std::bit_cast(device_table.vkAllocateMemory); + else if (func_name == "vkBeginCommandBuffer") + return std::bit_cast(device_table.vkBeginCommandBuffer); + else if (func_name == "vkBindBufferMemory") + return std::bit_cast(device_table.vkBindBufferMemory); + else if (func_name == "vkBindImageMemory") + return std::bit_cast(device_table.vkBindImageMemory); + else if (func_name == "vkCmdBindDescriptorSets") + return std::bit_cast(device_table.vkCmdBindDescriptorSets); + else if (func_name == "vkCmdBindIndexBuffer") + return std::bit_cast(device_table.vkCmdBindIndexBuffer); + else if (func_name == "vkCmdBindPipeline") + return std::bit_cast(device_table.vkCmdBindPipeline); + else if (func_name == "vkCmdBindVertexBuffers") + return std::bit_cast(device_table.vkCmdBindVertexBuffers); + else if (func_name == "vkCmdCopyBufferToImage") + return std::bit_cast(device_table.vkCmdCopyBufferToImage); + else if (func_name == "vkCmdDrawIndexed") + return std::bit_cast(device_table.vkCmdDrawIndexed); + else if (func_name == "vkCmdPipelineBarrier") + return std::bit_cast(device_table.vkCmdPipelineBarrier); + else if (func_name == "vkCmdPushConstants") + return std::bit_cast(device_table.vkCmdPushConstants); + else if (func_name == "vkCmdSetScissor") + return std::bit_cast(device_table.vkCmdSetScissor); + else if (func_name == "vkCmdSetViewport") + return std::bit_cast(device_table.vkCmdSetViewport); + else if (func_name == "vkCreateBuffer") + return std::bit_cast(device_table.vkCreateBuffer); + else if (func_name == "vkCreateCommandPool") + return std::bit_cast(device_table.vkCreateCommandPool); + else if (func_name == "vkCreateDescriptorPool") + return std::bit_cast(device_table.vkCreateDescriptorPool); + else if (func_name == "vkCreateDescriptorSetLayout") + return std::bit_cast(device_table.vkCreateDescriptorSetLayout); + else if (func_name == "vkCreateFence") + return std::bit_cast(device_table.vkCreateFence); + else if (func_name == "vkCreateFramebuffer") + return std::bit_cast(device_table.vkCreateFramebuffer); + else if (func_name == "vkCreateGraphicsPipelines") + return std::bit_cast(device_table.vkCreateGraphicsPipelines); + else if (func_name == "vkCreateImage") + return std::bit_cast(device_table.vkCreateImage); + else if (func_name == "vkCreateImageView") + return std::bit_cast(device_table.vkCreateImageView); + else if (func_name == "vkCreatePipelineLayout") + return std::bit_cast(device_table.vkCreatePipelineLayout); + else if (func_name == "vkCreateRenderPass") + return std::bit_cast(device_table.vkCreateRenderPass); + else if (func_name == "vkCreateSampler") + return std::bit_cast(device_table.vkCreateSampler); + else if (func_name == "vkCreateSemaphore") + return std::bit_cast(device_table.vkCreateSemaphore); + else if (func_name == "vkCreateShaderModule") + return std::bit_cast(device_table.vkCreateShaderModule); + else if (func_name == "vkCreateSwapchainKHR") + return std::bit_cast(device_table.vkCreateSwapchainKHR); + else if (func_name == "vkDestroyBuffer") + return std::bit_cast(device_table.vkDestroyBuffer); + else if (func_name == "vkDestroyCommandPool") + return std::bit_cast(device_table.vkDestroyCommandPool); + else if (func_name == "vkDestroyDescriptorPool") + return std::bit_cast(device_table.vkDestroyDescriptorPool); + else if (func_name == "vkDestroyDescriptorSetLayout") + return std::bit_cast(device_table.vkDestroyDescriptorSetLayout); + else if (func_name == "vkDestroyFence") + return std::bit_cast(device_table.vkDestroyFence); + else if (func_name == "vkDestroyFramebuffer") + return std::bit_cast(device_table.vkDestroyFramebuffer); + else if (func_name == "vkDestroyImage") + return std::bit_cast(device_table.vkDestroyImage); + else if (func_name == "vkDestroyImageView") + return std::bit_cast(device_table.vkDestroyImageView); + else if (func_name == "vkDestroyPipeline") + return std::bit_cast(device_table.vkDestroyPipeline); + else if (func_name == "vkDestroyPipelineLayout") + return std::bit_cast(device_table.vkDestroyPipelineLayout); + else if (func_name == "vkDestroyRenderPass") + return std::bit_cast(device_table.vkDestroyRenderPass); + else if (func_name == "vkDestroySampler") + return std::bit_cast(device_table.vkDestroySampler); + else if (func_name == "vkDestroySemaphore") + return std::bit_cast(device_table.vkDestroySemaphore); + else if (func_name == "vkDestroyShaderModule") + return std::bit_cast(device_table.vkDestroyShaderModule); + else if (func_name == "vkDestroySurfaceKHR") + return std::bit_cast(vkDestroySurfaceKHR); + else if (func_name == "vkDestroySwapchainKHR") + return std::bit_cast(device_table.vkDestroySwapchainKHR); + else if (func_name == "vkDeviceWaitIdle") + return std::bit_cast(device_table.vkDeviceWaitIdle); + else if (func_name == "vkEnumeratePhysicalDevices") + return std::bit_cast(vkEnumeratePhysicalDevices); + else if (func_name == "vkEndCommandBuffer") + return std::bit_cast(device_table.vkEndCommandBuffer); + else if (func_name == "vkFlushMappedMemoryRanges") + return std::bit_cast(device_table.vkFlushMappedMemoryRanges); + else if (func_name == "vkFreeCommandBuffers") + return std::bit_cast(device_table.vkFreeCommandBuffers); + else if (func_name == "vkFreeDescriptorSets") + return std::bit_cast(device_table.vkFreeDescriptorSets); + else if (func_name == "vkFreeMemory") + return std::bit_cast(device_table.vkFreeMemory); + else if (func_name == "vkGetBufferMemoryRequirements") + return std::bit_cast(device_table.vkGetBufferMemoryRequirements); + else if (func_name == "vkGetDeviceQueue") + return std::bit_cast(device_table.vkGetDeviceQueue); + else if (func_name == "vkGetImageMemoryRequirements") + return std::bit_cast(device_table.vkGetImageMemoryRequirements); + else if (func_name == "vkGetPhysicalDeviceProperties") + return std::bit_cast(vkGetPhysicalDeviceProperties); + else if (func_name == "vkGetPhysicalDeviceMemoryProperties") + return std::bit_cast(vkGetPhysicalDeviceMemoryProperties); + else if (func_name == "vkGetPhysicalDeviceQueueFamilyProperties") + return std::bit_cast(vkGetPhysicalDeviceQueueFamilyProperties); + else if (func_name == "vkGetPhysicalDeviceSurfaceCapabilitiesKHR") + return std::bit_cast(vkGetPhysicalDeviceSurfaceCapabilitiesKHR); + else if (func_name == "vkGetPhysicalDeviceSurfaceFormatsKHR") + return std::bit_cast(vkGetPhysicalDeviceSurfaceFormatsKHR); + else if (func_name == "vkGetPhysicalDeviceSurfacePresentModesKHR") + return std::bit_cast(vkGetPhysicalDeviceSurfacePresentModesKHR); + else if (func_name == "vkGetSwapchainImagesKHR") + return std::bit_cast(device_table.vkGetSwapchainImagesKHR); + else if (func_name == "vkMapMemory") + return std::bit_cast(device_table.vkMapMemory); + else if (func_name == "vkQueueSubmit") + return std::bit_cast(device_table.vkQueueSubmit); + else if (func_name == "vkQueueWaitIdle") + return std::bit_cast(device_table.vkQueueWaitIdle); + else if (func_name == "vkResetCommandPool") + return std::bit_cast(device_table.vkResetCommandPool); + else if (func_name == "vkResetFences") + return std::bit_cast(device_table.vkResetFences); + else if (func_name == "vkUnmapMemory") + return std::bit_cast(device_table.vkUnmapMemory); + else if (func_name == "vkUpdateDescriptorSets") + return std::bit_cast(device_table.vkUpdateDescriptorSets); + else if (func_name == "vkWaitForFences") + return std::bit_cast(device_table.vkWaitForFences); + else if (func_name == "vkCmdBeginRendering") + return std::bit_cast(device_table.vkCmdBeginRendering); + else if (func_name == "vkCmdEndRendering") + return std::bit_cast(device_table.vkCmdEndRendering); + else if (func_name == "vkCmdBeginRenderingKHR") + return std::bit_cast(device_table.vkCmdBeginRenderingKHR); + else if (func_name == "vkCmdEndRenderingKHR") + return std::bit_cast(device_table.vkCmdEndRenderingKHR); + + ensures(false, std::format("Unhandled vk func {}", func_name)); + std::unreachable(); + } + } // namespace vk } // namespace stormkit::gpu diff --git a/src/gpu/core/fence.cpp b/src/gpu/core/fence.cpp new file mode 100644 index 000000000..2e5ecec38 --- /dev/null +++ b/src/gpu/core/fence.cpp @@ -0,0 +1,122 @@ +// Copyright (C) 2023 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include +#include +#include + +#include +#include + +module stormkit.gpu.core; + +import std; + +import stormkit.core; + +import :vulkan; + +namespace stormkit::gpu { + namespace { + struct FenceAPI { + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto status(const FenceType& fence) noexcept -> Expected { + const auto& device = fence.device(); + + const auto + result = Try((vk::call_checked(device.device_table().vkGetFenceStatus, device, fence))); + if (result == VK_NOT_READY) Return Fence::Status::UNSIGNALED; + Return Fence::Status::SIGNALED; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto wait(const FenceType& fence, const std::chrono::milliseconds& wait_for) noexcept -> Expected { + const auto& device = fence.device(); + const auto handle = fence.native_handle(); + + const auto + result = Try((vk::call_checked(device.device_table().vkWaitForFences, + device, + 1u, + &handle, + true, + std::chrono::duration_cast(wait_for) + .count()))); + + Return vk::from_vk(result); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto reset(const FenceType& fence) noexcept -> Expected { + const auto& device = fence.device(); + const auto handle = fence.native_handle(); + + Try(vk::call_checked(device.device_table().vkResetFences, device, 1u, &handle)); + + Return {}; + } + }; + } // namespace + + ///////////////////////////////////// + ///////////////////////////////////// + auto Fence::status() const noexcept -> Expected { + return FenceAPI::status(*this); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto Fence::wait(const std::chrono::milliseconds& wait_for) const noexcept -> Expected { + return FenceAPI::wait(*this, wait_for); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto Fence::reset() const noexcept -> Expected { + return FenceAPI::reset(*this); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto Fence::do_init(PrivateTag, bool signaled) noexcept -> Expected { + const auto flags = (signaled) ? VkFenceCreateFlags { VK_FENCE_CREATE_SIGNALED_BIT } : VkFenceCreateFlags {}; + + const auto create_info = VkFenceCreateInfo { .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, + .pNext = nullptr, + .flags = flags }; + + m_vk_handle = Try(vk::call_checked(m_device.device_table().vkCreateFence, m_device, &create_info, nullptr)); + + Return {}; + } + + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + auto Fence::status() const noexcept -> Expected { + return FenceAPI::status(*this); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto Fence::wait(const std::chrono::milliseconds& wait_for) const noexcept -> Expected { + return FenceAPI::wait(*this, wait_for); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto Fence::reset() const noexcept -> Expected { + return FenceAPI::reset(*this); + } + } // namespace view +} // namespace stormkit::gpu diff --git a/src/gpu/core/instance.cpp b/src/gpu/core/instance.cpp index 66323249e..54ab3c7dc 100644 --- a/src/gpu/core/instance.cpp +++ b/src/gpu/core/instance.cpp @@ -6,7 +6,7 @@ module; #include #include -#include +#include #define STORMKIT_DEFINE_VK_PLATFORM #include @@ -16,78 +16,52 @@ module stormkit.gpu.core; import std; import stormkit.core; -import stormkit.log; namespace stdr = std::ranges; namespace stdv = std::views; -namespace stormkit::gpu { - LOGGER("stormkit.gpu") +using namespace std::literals; +namespace stormkit::gpu { namespace { - constexpr auto VALIDATION_LAYERS = std::array { - "VK_LAYER_KHRONOS_validation", - // "VK_LAYER_LUNARG_api_dump", - "VK_LAYER_LUNARG_monitor", - }; - constexpr auto OPTIONAL_VALIDATION_LAYERS = std::array { - // "VK_LAYER_MESA_overlay", - }; + constexpr auto VALIDATION_LAYERS = into_array_of("VK_LAYER_KHRONOS_validation", + // "VK_LAYER_LUNARG_api_dump", + "VK_LAYER_LUNARG_monitor" + // "VK_LAYER_MESA_overlay", + ); - [[maybe_unused]] - constexpr auto VALIDATION_FEATURES = std::array { - VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT, - VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT, - }; + // [[maybe_unused]] + // constexpr auto VALIDATION_FEATURES = into_array_of(VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT, + // VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT); - constexpr auto STORMKIT_VK_VERSION = vk_make_version(STORMKIT_MAJOR_VERSION, - STORMKIT_MINOR_VERSION, - STORMKIT_PATCH_VERSION); + constexpr auto STORMKIT_VK_VERSION = vk::make_version(STORMKIT_MAJOR_VERSION, + STORMKIT_MINOR_VERSION, + STORMKIT_PATCH_VERSION); - constexpr auto BASE_EXTENSIONS = std::array { VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, + constexpr auto BASE_EXTENSIONS = into_array_of(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME #ifdef STORMKIT_OS_APPLE - VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME + , + VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME #endif - }; + ); - constexpr auto SURFACE_EXTENSIONS = std::array { - VK_KHR_SURFACE_EXTENSION_NAME, - VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, - // VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME, - }; + constexpr auto SURFACE_EXTENSIONS = into_array_of(VK_KHR_SURFACE_EXTENSION_NAME, + VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME + // VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME, + ); - constexpr auto WSI_SURFACE_EXTENSIONS = std::array { + constexpr auto WSI_SURFACE_EXTENSIONS = into_array_of( #ifdef STORMKIT_OS_WINDOWS - VK_KHR_WIN32_SURFACE_EXTENSION_NAME, + VK_KHR_WIN32_SURFACE_EXTENSION_NAME #elif defined(STORMKIT_OS_LINUX) - VK_KHR_XCB_SURFACE_EXTENSION_NAME, - VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, + VK_KHR_XCB_SURFACE_EXTENSION_NAME, + VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME #elif defined(STORMKIT_OS_MACOS) - VK_MVK_MACOS_SURFACE_EXTENSION_NAME, + VK_MVK_MACOS_SURFACE_EXTENSION_NAME #elif defined(STORMKIT_OS_IOS) - VK_MVK_IOS_SURFACE_EXTENSION_NAME, + VK_MVK_IOS_SURFACE_EXTENSION_NAME #endif - }; - - ///////////////////////////////////// - ///////////////////////////////////// - auto debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, - VkDebugUtilsMessageTypeFlagsEXT, - const VkDebugUtilsMessengerCallbackDataEXT* callback_data, - void*) noexcept -> u32 { - EXPECTS(callback_data); - auto message = std::format("{}", callback_data->pMessage); - - if (check_flag_bit(severity, VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT)) ilog("{}", message); - else if (check_flag_bit(severity, VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT)) - dlog("{}", message); - else if (check_flag_bit(severity, VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)) - elog("{}", message); - else if (check_flag_bit(severity, VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT)) - wlog("{}", message); - - return 0; - } + ); ///////////////////////////////////// ///////////////////////////////////// @@ -104,144 +78,98 @@ namespace stormkit::gpu { ///////////////////////////////////// auto check_extension_support(std::span supported_extensions, std::span extensions) noexcept -> bool { - const auto ext = extensions | stdv::transform(core::monadic::init()) | stdr::to(); + const auto ext = transform(extensions, core::monadic::init()); return check_extension_support(supported_extensions, ext); } } // namespace ///////////////////////////////////// ///////////////////////////////////// - auto Instance::do_init() noexcept -> Expected { - return vk_enumerate(vkEnumerateInstanceExtensionProperties, nullptr) - .and_then([this](auto&& exts) noexcept { - m_extensions = exts - | stdv::transform([](auto&& extension) static noexcept { - return std::string { extension.extensionName }; - }) - | stdr::to(); - - dlog("Instance extensions: {}", m_extensions); - - const auto validation_layers = init_by>([this](auto& out) noexcept { - if (not m_validation_layers_enabled) return; - - auto result = vk_enumerate(vkEnumerateInstanceLayerProperties); - if (not result) return; - const auto layers = std::move(result).value() | stdv::transform([](auto&& layer) static noexcept { - return std::string_view { layer.layerName }; - }); - - dlog("Layers found: {}", layers); - - for (const auto layer_name : VALIDATION_LAYERS) { - if (not stdr::contains(layers, std::string_view { layer_name })) return; - } - - out = VALIDATION_LAYERS | stdr::to(); - - for (const auto layer_name : OPTIONAL_VALIDATION_LAYERS) { - if (stdr::contains(layers, std::string_view { layer_name })) out.push_back(layer_name); - } - }); - - dlog("Enabled layers: {}", validation_layers); - - const auto instance_extensions = [this]() noexcept { - auto e = concat(BASE_EXTENSIONS, SURFACE_EXTENSIONS); - - for (auto&& ext_ : WSI_SURFACE_EXTENSIONS) { - const auto ext = std::array { ext_ }; - if (check_extension_support(m_extensions, ext)) merge(e, ext); - } - - if (m_validation_layers_enabled) merge(e, std::array { VK_EXT_DEBUG_UTILS_EXTENSION_NAME }); - - return e; - }(); - dlog("Enabled instance extensions: {}", instance_extensions); - - constexpr auto ENGINE_NAME = "StormKit"; - - const auto app_info = VkApplicationInfo { - .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, - .pNext = nullptr, - .pApplicationName = std::data(m_app_name), - .applicationVersion = vk_make_version(0, 0, 0), - .pEngineName = ENGINE_NAME, - .engineVersion = STORMKIT_VK_VERSION, - .apiVersion = VK_API_VERSION_1_3, - }; - - const auto create_info = VkInstanceCreateInfo { - .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, - .pNext = nullptr, -#ifdef STORMKIT_OS_APPLE - .flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR, -#else - .flags = 0, -#endif - .pApplicationInfo = &app_info, - .enabledLayerCount = as(stdr::size(validation_layers)), - .ppEnabledLayerNames = stdr::data(validation_layers), - .enabledExtensionCount = as(stdr::size(instance_extensions)), - .ppEnabledExtensionNames = stdr::data(instance_extensions), - }; - return vk_call(vkCreateInstance, &create_info, nullptr); - }) - .transform(core::monadic::set(m_vk_handle)) - .and_then(bind_front(&Instance::do_load_instance, this)) - .and_then(bind_front(&Instance::do_retrieve_physical_devices, this)) - .and_then(bind_front(&Instance::do_init_debug_report_callback, this)) - .transform_error(monadic::from_vk()); + Instance::Instance(PrivateTag) noexcept : Owned { auto(vkDestroyInstance) } { } ///////////////////////////////////// ///////////////////////////////////// - auto Instance::do_load_instance() noexcept -> VulkanExpected { - volkLoadInstanceOnly(m_vk_handle); - return {}; - } + Instance::~Instance() = default; ///////////////////////////////////// ///////////////////////////////////// - auto Instance::do_init_debug_report_callback() noexcept -> VulkanExpected { - if (!m_validation_layers_enabled) return {}; - constexpr auto severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT - | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT - | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; - - constexpr auto type = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT - | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT - | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; - - const auto create_info = VkDebugUtilsMessengerCreateInfoEXT { - .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, - .pNext = nullptr, - .flags = 0, - .messageSeverity = severity, - .messageType = type, - .pfnUserCallback = debug_callback, - .pUserData = nullptr, + Instance::Instance(Instance&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + auto Instance::operator=(Instance&&) noexcept -> Instance& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + auto Instance::do_init(PrivateTag, std::string app_name, bool validation_layers_enabled) noexcept -> Expected { + const auto exts = Try(vk::enumerate_checked(vkEnumerateInstanceExtensionProperties, nullptr)); + m_extensions = transform(exts, [](const auto& ext) static noexcept { return std::string { ext.extensionName }; }); + const auto validation_layers = validation_layers_enabled + ? std::vector() + : transform_if( + Try(vk::enumerate_checked(vkEnumerateInstanceLayerProperties)), + [](const auto& layer) static noexcept { + return stdr::contains(VALIDATION_LAYERS, std::string_view { layer.layerName }); + }, + [](const auto& layer) static noexcept { return layer.layerName; }); + + const auto instance_extensions = [validation_layers_enabled] noexcept { + auto e = concat(BASE_EXTENSIONS, SURFACE_EXTENSIONS, WSI_SURFACE_EXTENSIONS); + if (validation_layers_enabled) e.emplace_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); + return e; + }(); + ensures(check_extension_support(m_extensions, instance_extensions), "Missing extensions!"); + + constexpr auto ENGINE_NAME = "StormKit"; + + const auto app_info = VkApplicationInfo { + .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, + .pNext = nullptr, + .pApplicationName = std::data(app_name), + .applicationVersion = vk::make_version(0, 0, 0), + .pEngineName = ENGINE_NAME, + .engineVersion = STORMKIT_VK_VERSION, + .apiVersion = VK_API_VERSION_1_3, }; - m_vk_debug_utils_handle = { [vk_instance = m_vk_handle.value()](auto handle) noexcept { - vkDestroyDebugUtilsMessengerEXT(vk_instance, handle, nullptr); - } }; + const auto create_info = VkInstanceCreateInfo { + .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, + .pNext = nullptr, +#ifdef STORMKIT_OS_APPLE + .flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR, +#else + .flags = 0, +#endif + .pApplicationInfo = &app_info, + .enabledLayerCount = as(stdr::size(validation_layers)), + .ppEnabledLayerNames = stdr::data(validation_layers), + .enabledExtensionCount = as(stdr::size(instance_extensions)), + .ppEnabledExtensionNames = stdr::data(instance_extensions), + }; + + m_vk_handle = Try(vk::call_checked(vkCreateInstance, &create_info, nullptr)); + + Try(do_load_instance()); + Try(do_retrieve_physical_devices()); + + Return {}; + } - return vk_call(vkCreateDebugUtilsMessengerEXT, m_vk_handle, &create_info, nullptr) - .transform(core::monadic::set(m_vk_debug_utils_handle)) - .transform([] static noexcept { ilog("Vulkan debug callback enabled!"); }); + ///////////////////////////////////// + ///////////////////////////////////// + auto Instance::do_load_instance() noexcept -> Expected { + volkLoadInstanceOnly(m_vk_handle); + Return {}; } ///////////////////////////////////// ///////////////////////////////////// - auto Instance::do_retrieve_physical_devices() noexcept -> VulkanExpected { - return vk_enumerate(vkEnumeratePhysicalDevices, m_vk_handle).transform([this](auto&& physical_devices) { - m_physical_devices = std::forward(physical_devices) - | stdv::transform([](auto&& physical_device) static noexcept { - return PhysicalDevice { std::move(physical_device) }; - }) - | stdr::to(); - }); + auto Instance::do_retrieve_physical_devices() noexcept -> Expected { + m_physical_devices = transform(Try(vk::enumerate_checked(vkEnumeratePhysicalDevices, m_vk_handle)), + [this](auto physical_device) noexcept { + return PhysicalDevice::create(*this, physical_device); + }); + Return {}; } } // namespace stormkit::gpu diff --git a/src/gpu/core/loader.cpp b/src/gpu/core/loader.cpp index e74c971a9..9d21b5206 100644 --- a/src/gpu/core/loader.cpp +++ b/src/gpu/core/loader.cpp @@ -6,6 +6,6 @@ module stormkit.gpu.core; namespace stormkit::gpu { auto initialize_backend() -> Expected { - return vk_call(volkInitialize).transform_error(monadic::from_vk()); + return vk::call_checked(volkInitialize); } } // namespace stormkit::gpu diff --git a/src/gpu/core/physical_device.cpp b/src/gpu/core/physical_device.cpp index 32a01e46e..7d768ef6e 100644 --- a/src/gpu/core/physical_device.cpp +++ b/src/gpu/core/physical_device.cpp @@ -4,6 +4,8 @@ module; +#include + #include module stormkit.gpu.core; @@ -12,11 +14,15 @@ import std; import stormkit.core; +import :vulkan; + using namespace std::literals; namespace stdr = std::ranges; namespace stdv = std::views; +namespace cm = stormkit::core::meta; + namespace stormkit::gpu { namespace { constexpr auto RAYTRACING_EXTENSIONS = std::array { @@ -39,11 +45,332 @@ namespace stormkit::gpu { return "UNKNOWN"; } + + struct PhysicalDeviceAPI { + template + static auto check_extension_support(const PhysicalDeviceType& physical_device, std::string_view extension) noexcept + -> bool { + return stdr::any_of(physical_device.extensions(), [extension](const auto& e) { return e == extension; }); + } + + template + static auto check_extension_support(const PhysicalDeviceType& physical_device, + std::span extensions) noexcept -> bool { + auto required_extensions = HashSet { stdr::begin(extensions), stdr::end(extensions) }; + + for (const auto& extension : physical_device.extensions()) required_extensions.erase(extension); + + return stdr::empty(required_extensions); + } + + template + static auto check_extension_support(const PhysicalDeviceType& physical_device, + std::span extensions) noexcept -> bool { + auto required_extensions = HashSet { stdr::begin(extensions), stdr::end(extensions) }; + + for (const auto& extension : physical_device.extensions()) required_extensions.erase(extension); + + return stdr::empty(required_extensions); + } + + template + static auto info(const _PhysicalDeviceType& physical_device) noexcept -> PhysicalDeviceInfo { + const auto& handle = physical_device.native_handle(); + + auto device_info = PhysicalDeviceInfo {}; + + const auto properties = vk::call(vkGetPhysicalDeviceProperties, handle); + const auto vendor_id = properties.vendorID; + + device_info.device_id = properties.deviceID; + + const auto device_name_size = std::char_traits::length(properties.deviceName); + + device_info.device_name.resize(device_name_size); + stdr::copy(std::string_view { properties.deviceName, device_name_size }, std::begin(device_info.device_name)); + + device_info.vendor_id = vendor_id; + device_info.vendor_name = vendor_name_by_id(vendor_id); + device_info.api_major_version = vk::version_major(properties.apiVersion); + device_info.api_minor_version = vk::version_minor(properties.apiVersion); + device_info.api_patch_version = vk::version_patch(properties.apiVersion); + + device_info.driver_major_version = vk::version_major(properties.driverVersion); + device_info.driver_minor_version = vk::version_minor(properties.driverVersion); + device_info.driver_patch_version = vk::version_patch(properties.driverVersion); + stdr::copy(properties.pipelineCacheUUID, stdr::begin(device_info.pipeline_cache_uuid)); + + device_info.type = vk::from_vk(properties.deviceType); + + return device_info; + } + + template + static auto capabilities(const PhysicalDeviceType& physical_device) noexcept -> RenderCapabilities { + const auto& handle = physical_device.native_handle(); + + const auto properties = vk::call(vkGetPhysicalDeviceProperties, handle); + // TODO port to vkGetPhysicalDeviceFeatures2 + const auto features = vk::call(vkGetPhysicalDeviceFeatures, handle); + + auto capabilities = RenderCapabilities {}; + capabilities.limits.max_image_dimension_1D = properties.limits.maxImageDimension1D; + capabilities.limits.max_image_dimension_2D = properties.limits.maxImageDimension2D; + capabilities.limits.max_image_dimension_3D = properties.limits.maxImageDimension3D; + capabilities.limits.max_image_dimension_cube = properties.limits.maxImageDimensionCube; + capabilities.limits.max_image_array_layers = properties.limits.maxImageArrayLayers; + capabilities.limits.max_texel_buffer_elements = properties.limits.maxTexelBufferElements; + capabilities.limits.max_uniform_buffer_range = properties.limits.maxUniformBufferRange; + capabilities.limits.max_storage_buffer_range = properties.limits.maxStorageBufferRange; + capabilities.limits.max_push_constants_size = properties.limits.maxPushConstantsSize; + capabilities.limits.max_memory_allocation_count = properties.limits.maxMemoryAllocationCount; + capabilities.limits.max_sampler_allocation_count = properties.limits.maxSamplerAllocationCount; + capabilities.limits.buffer_image_granularity = properties.limits.bufferImageGranularity; + capabilities.limits.sparse_address_space_size = properties.limits.sparseAddressSpaceSize; + capabilities.limits.max_bound_descriptor_sets = properties.limits.maxBoundDescriptorSets; + capabilities.limits.max_per_stage_descriptor_samplers = properties.limits.maxPerStageDescriptorSamplers; + capabilities.limits + .max_per_stage_descriptor_uniform_buffers = properties.limits.maxPerStageDescriptorUniformBuffers; + capabilities.limits + .max_per_stage_descriptor_storage_buffers = properties.limits.maxPerStageDescriptorStorageBuffers; + capabilities.limits + .max_per_stage_descriptor_sampled_images = properties.limits.maxPerStageDescriptorSampledImages; + capabilities.limits + .max_per_stage_descriptor_storage_images = properties.limits.maxPerStageDescriptorStorageImages; + capabilities.limits + .max_per_stage_descriptor_input_attachments = properties.limits.maxPerStageDescriptorInputAttachments; + capabilities.limits.max_per_stage_resources = properties.limits.maxPerStageResources; + capabilities.limits.max_descriptor_set_samplers = properties.limits.maxDescriptorSetSamplers; + capabilities.limits.max_descriptor_set_uniform_buffers = properties.limits.maxDescriptorSetUniformBuffers; + capabilities.limits + .max_descriptor_set_uniform_buffers_dynamic = properties.limits.maxDescriptorSetUniformBuffersDynamic; + capabilities.limits.max_descriptor_set_storage_buffers = properties.limits.maxDescriptorSetStorageBuffers; + capabilities.limits + .max_descriptor_set_storage_buffers_dynamic = properties.limits.maxDescriptorSetStorageBuffersDynamic; + capabilities.limits.max_descriptor_set_sampled_images = properties.limits.maxDescriptorSetSampledImages; + capabilities.limits.max_descriptor_set_storage_images = properties.limits.maxDescriptorSetStorageImages; + capabilities.limits.max_descriptor_set_input_attachments = properties.limits.maxDescriptorSetInputAttachments; + capabilities.limits.max_vertex_input_attributes = properties.limits.maxVertexInputAttributes; + capabilities.limits.max_vertex_input_bindings = properties.limits.maxVertexInputBindings; + capabilities.limits.max_vertex_input_attribute_offset = properties.limits.maxVertexInputAttributeOffset; + capabilities.limits.max_vertex_input_binding_stride = properties.limits.maxVertexInputBindingStride; + capabilities.limits.max_vertex_output_components = properties.limits.maxVertexOutputComponents; + capabilities.limits.max_tessellation_generation_level = properties.limits.maxTessellationGenerationLevel; + capabilities.limits.max_tessellation_patch_size = properties.limits.maxTessellationPatchSize; + capabilities.limits + .max_tessellation_control_per_vertex_input_components = properties.limits + .maxTessellationControlPerVertexInputComponents; + capabilities.limits + .max_tessellation_control_per_vertex_output_components = properties.limits + .maxTessellationControlPerVertexOutputComponents; + capabilities.limits + .max_tessellation_control_per_patch_output_components = properties.limits + .maxTessellationControlPerPatchOutputComponents; + capabilities.limits + .max_tessellation_control_total_output_components = properties.limits + .maxTessellationControlTotalOutputComponents; + capabilities.limits + .max_tessellation_evaluation_input_components = properties.limits.maxTessellationEvaluationInputComponents; + capabilities.limits + .max_tessellation_evaluation_output_components = properties.limits.maxTessellationEvaluationOutputComponents; + capabilities.limits.max_geometry_shader_invocations = properties.limits.maxGeometryShaderInvocations; + capabilities.limits.max_geometry_input_components = properties.limits.maxGeometryInputComponents; + capabilities.limits.max_geometry_output_components = properties.limits.maxGeometryOutputComponents; + capabilities.limits.max_geometry_output_vertices = properties.limits.maxGeometryOutputVertices; + capabilities.limits.max_geometry_total_output_components = properties.limits.maxGeometryTotalOutputComponents; + capabilities.limits.max_fragment_input_components = properties.limits.maxFragmentInputComponents; + capabilities.limits.max_fragment_output_attachments = properties.limits.maxFragmentOutputAttachments; + capabilities.limits.max_fragment_dual_src_attachments = properties.limits.maxFragmentDualSrcAttachments; + capabilities.limits.max_fragment_combined_output_resources = properties.limits.maxFragmentCombinedOutputResources; + capabilities.limits.max_compute_shared_memory_size = properties.limits.maxComputeSharedMemorySize; + stdr::copy(properties.limits.maxComputeWorkGroupCount, + stdr::begin(capabilities.limits.max_compute_work_group_count)); + capabilities.limits.max_compute_work_group_invocations = properties.limits.maxComputeWorkGroupInvocations; + stdr::copy(properties.limits.maxComputeWorkGroupSize, + stdr::begin(capabilities.limits.max_compute_work_group_size)); + capabilities.limits.sub_pixel_precision_bits = properties.limits.subPixelPrecisionBits; + capabilities.limits.sub_texel_precision_bits = properties.limits.subTexelPrecisionBits; + capabilities.limits.mipmap_precision_bits = properties.limits.mipmapPrecisionBits; + capabilities.limits.max_draw_indexed_index_value = properties.limits.maxDrawIndexedIndexValue; + capabilities.limits.max_draw_indirect_count = properties.limits.maxDrawIndirectCount; + capabilities.limits.max_sampler_lod_bias = properties.limits.maxSamplerLodBias; + capabilities.limits.max_sampler_anisotropy = properties.limits.maxSamplerAnisotropy; + capabilities.limits.max_viewports = properties.limits.maxViewports; + stdr::copy(properties.limits.maxViewportDimensions, stdr::begin(capabilities.limits.max_viewport_dimensions)); + stdr::copy(properties.limits.viewportBoundsRange, stdr::begin(capabilities.limits.viewport_bounds_range)); + capabilities.limits.viewport_sub_pixel_bits = properties.limits.viewportSubPixelBits; + capabilities.limits.min_memory_map_alignment = properties.limits.minMemoryMapAlignment; + capabilities.limits.min_texel_buffer_offset_alignment = properties.limits.minTexelBufferOffsetAlignment; + capabilities.limits.min_uniform_buffer_offset_alignment = properties.limits.minUniformBufferOffsetAlignment; + capabilities.limits.min_storage_buffer_offset_alignment = properties.limits.minStorageBufferOffsetAlignment; + capabilities.limits.min_texel_offset = properties.limits.minTexelOffset; + capabilities.limits.max_texel_offset = properties.limits.maxTexelOffset; + capabilities.limits.min_texel_gather_offset = properties.limits.minTexelGatherOffset; + capabilities.limits.max_texel_gather_offset = properties.limits.maxTexelGatherOffset; + capabilities.limits.min_interpolation_offset = properties.limits.minInterpolationOffset; + capabilities.limits.max_interpolation_offset = properties.limits.maxInterpolationOffset; + capabilities.limits.sub_pixel_interpolation_offset_bits = properties.limits.subPixelInterpolationOffsetBits; + capabilities.limits.max_framebuffer_width = properties.limits.maxFramebufferWidth; + capabilities.limits.max_framebuffer_height = properties.limits.maxFramebufferHeight; + capabilities.limits.max_framebuffer_layers = properties.limits.maxFramebufferLayers; + capabilities.limits + .framebuffer_color_sample_counts = narrow(properties.limits.framebufferColorSampleCounts); + capabilities.limits + .framebuffer_depth_sample_counts = narrow(properties.limits.framebufferDepthSampleCounts); + capabilities.limits + .framebuffer_stencil_sample_counts = narrow(properties.limits.framebufferStencilSampleCounts); + capabilities.limits + .framebuffer_no_attachments_sample_counts = narrow(properties.limits + .framebufferNoAttachmentsSampleCounts); + capabilities.limits.max_color_attachments = properties.limits.maxColorAttachments; + capabilities.limits + .sampled_image_color_sample_counts = narrow(properties.limits.sampledImageColorSampleCounts); + capabilities.limits + .sampled_image_integer_sample_counts = narrow(properties.limits + .sampledImageIntegerSampleCounts); + capabilities.limits + .sampled_image_depth_sample_counts = narrow(properties.limits.sampledImageDepthSampleCounts); + capabilities.limits + .sampled_image_stencil_sample_counts = narrow(properties.limits + .sampledImageStencilSampleCounts); + capabilities.limits + .storage_image_sample_counts = narrow(properties.limits.storageImageSampleCounts); + capabilities.limits.max_sample_mask_words = properties.limits.maxSampleMaskWords; + capabilities.limits.timestamp_compute_and_engine = properties.limits.timestampComputeAndGraphics; + capabilities.limits.timestamp_period = properties.limits.timestampPeriod; + capabilities.limits.max_clip_distances = properties.limits.maxClipDistances; + capabilities.limits.max_cull_distances = properties.limits.maxCullDistances; + capabilities.limits.max_combined_clip_and_cull_distances = properties.limits.maxCombinedClipAndCullDistances; + capabilities.limits.discrete_queue_priorities = properties.limits.discreteQueuePriorities; + stdr::copy(properties.limits.pointSizeRange, stdr::begin(capabilities.limits.point_size_range)); + stdr::copy(properties.limits.lineWidthRange, stdr::begin(capabilities.limits.line_width_range)); + capabilities.limits.point_size_granularity = properties.limits.pointSizeGranularity; + capabilities.limits.line_width_granularity = properties.limits.lineWidthGranularity; + capabilities.limits.strict_lines = properties.limits.strictLines; + capabilities.limits.standard_sample_locations = properties.limits.standardSampleLocations; + capabilities.limits.optimal_buffer_copy_offset_alignment = properties.limits.optimalBufferCopyOffsetAlignment; + capabilities.limits + .optimal_buffer_copy_row_pitch_alignment = properties.limits.optimalBufferCopyRowPitchAlignment; + capabilities.limits.non_coherent_atom_size = properties.limits.nonCoherentAtomSize; + + capabilities.features.robust_buffer_access = features.robustBufferAccess; + capabilities.features.full_draw_index_uint32 = features.fullDrawIndexUint32; + capabilities.features.image_cube_array = features.imageCubeArray; + capabilities.features.independent_blend = features.independentBlend; + capabilities.features.geometry_shader = features.geometryShader; + capabilities.features.tessellation_shader = features.tessellationShader; + capabilities.features.sampler_rate_shading = features.sampleRateShading; + capabilities.features.dual_src_blend = features.dualSrcBlend; + capabilities.features.logic_op = features.logicOp; + capabilities.features.multi_draw_indirect = features.multiDrawIndirect; + capabilities.features.draw_indirect_first_instance = features.drawIndirectFirstInstance; + capabilities.features.depth_clamp = features.depthClamp; + capabilities.features.depth_bias_clamp = features.depthBiasClamp; + capabilities.features.fill_Mode_non_solid = features.fillModeNonSolid; + capabilities.features.depth_bounds = features.depthBounds; + capabilities.features.wide_lines = features.wideLines; + capabilities.features.large_points = features.largePoints; + capabilities.features.alpha_to_one = features.alphaToOne; + capabilities.features.multi_viewport = features.multiViewport; + capabilities.features.sampler_anisotropy = features.samplerAnisotropy; + capabilities.features.texture_compression_etc2 = features.textureCompressionETC2; + capabilities.features.texture_compression_astc_ldr = features.textureCompressionASTC_LDR; + capabilities.features.texture_compression_bc = features.textureCompressionBC; + capabilities.features.occlusion_query_precise = features.occlusionQueryPrecise; + capabilities.features.pipeline_statistics_query = features.pipelineStatisticsQuery; + capabilities.features.vertex_pipeline_stores_and_atomics = features.vertexPipelineStoresAndAtomics; + capabilities.features.fragment_stores_and_atomics = features.fragmentStoresAndAtomics; + capabilities.features + .shader_tessellation_and_geometry_point_size = features.shaderTessellationAndGeometryPointSize; + capabilities.features.shader_image_gather_extended = features.shaderImageGatherExtended; + capabilities.features.shader_storage_image_extended_formats = features.shaderStorageImageExtendedFormats; + capabilities.features.shader_storage_image_multisample = features.shaderStorageImageMultisample; + capabilities.features.shader_storage_image_read_without_format = features.shaderStorageImageReadWithoutFormat; + capabilities.features.shader_storage_image_write_without_format = features.shaderStorageImageWriteWithoutFormat; + capabilities.features + .shader_uniform_buffer_array_dynamic_indexing = features.shaderUniformBufferArrayDynamicIndexing; + capabilities.features + .shader_sampled_image_array_dynamic_indexing = features.shaderSampledImageArrayDynamicIndexing; + capabilities.features + .shader_storage_buffer_array_dynamic_indexing = features.shaderStorageBufferArrayDynamicIndexing; + capabilities.features + .shader_storage_image_array_dynamic_indexing = features.shaderStorageImageArrayDynamicIndexing; + capabilities.features.shader_clip_distance = features.shaderClipDistance; + capabilities.features.shader_cull_distance = features.shaderCullDistance; + capabilities.features.shader_float_64 = features.shaderFloat64; + capabilities.features.shader_int_64 = features.shaderInt64; + capabilities.features.shader_int_16 = features.shaderInt16; + capabilities.features.shader_resource_residency = features.shaderResourceResidency; + capabilities.features.shader_resource_min_lod = features.shaderResourceMinLod; + capabilities.features.sparse_binding = features.sparseBinding; + capabilities.features.sparse_residency_buffer = features.sparseResidencyBuffer; + capabilities.features.sparse_residency_image_2D = features.sparseResidencyImage2D; + capabilities.features.sparse_residency_image_3D = features.sparseResidencyImage3D; + capabilities.features.sparse_residency_2_samples = features.sparseResidency2Samples; + capabilities.features.sparse_residency_4_samples = features.sparseResidency4Samples; + capabilities.features.sparse_residency_8_samples = features.sparseResidency8Samples; + capabilities.features.sparse_residency_16_samples = features.sparseResidency16Samples; + capabilities.features.sparse_residency_aliased = features.sparseResidencyAliased; + capabilities.features.variable_multisample_rate = features.variableMultisampleRate; + capabilities.features.inherited_queries = features.inheritedQueries; + + return capabilities; + } + + template + static auto memory_types(const PhysicalDeviceType& physical_device) noexcept -> std::vector { + const auto& handle = physical_device.native_handle(); + const auto vk_memory_properties = vk::call(vkGetPhysicalDeviceMemoryProperties, + handle); + + return transform(std::span { vk_memory_properties.memoryTypes, 32 }, + [](const auto& type) static noexcept { return narrow(type.propertyFlags); }); + } + + template + static auto queue_families(const PhysicalDeviceType& physical_device) noexcept -> std::vector { + const auto& handle = physical_device.native_handle(); + return transform(vk::enumerate(vkGetPhysicalDeviceQueueFamilyProperties, handle), + [](const auto& family) static noexcept { + return QueueFamily { .flags = narrow(family.queueFlags), + .count = family.queueCount }; + }); + } + + template + static auto extensions(const PhysicalDeviceType& physical_device) noexcept -> std::vector { + const auto& handle = physical_device.native_handle(); + const auto& info = physical_device.info(); + const auto + extensions = TryAssert(vk::enumerate_checked(vkEnumerateDeviceExtensionProperties, + handle, + nullptr), + format("Failed to enumerate device {} extensions properties", info.device_name)); + + Return transform(extensions, [](const auto& extension) static noexcept { + const auto string_size = std::char_traits::length(extension.extensionName); + + return std::string { extension.extensionName, string_size }; + }); + } + + template + static auto formats_properties(const PhysicalDeviceType& physical_device) noexcept + -> std::vector> { + const auto& handle = physical_device.native_handle(); + return transform(cm::enumerate(), [&handle](const auto val) noexcept { + return std::make_pair(val, + vk::from_vk(vk::call(vkGetPhysicalDeviceFormatProperties, + handle, + vk::to_vk(val)))); + }); + } + }; } // namespace ///////////////////////////////////// ///////////////////////////////////// - auto score_physical_device(const PhysicalDevice& physical_device) noexcept -> u64 { + auto score_physical_device(const view::PhysicalDevice& physical_device) noexcept -> u64 { const auto support_raytracing = physical_device.check_extension_support(RAYTRACING_EXTENSIONS); auto score = u64 { 0u }; @@ -73,297 +400,148 @@ namespace stormkit::gpu { // TODO implement // https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_KHR_driver_properties.html + ///////////////////////////////////// ///////////////////////////////////// - PhysicalDevice::PhysicalDevice(VkPhysicalDevice physical_device) noexcept : m_vk_handle { physical_device } { - const auto properties = vk_call(vkGetPhysicalDeviceProperties, m_vk_handle); - // TODO port to vkGetPhysicalDeviceFeatures2 - const auto features = vk_call(vkGetPhysicalDeviceFeatures, m_vk_handle); - - const auto vendor_id = properties.vendorID; - - m_device_info.device_id = properties.deviceID; - - const auto device_name_size = std::char_traits::length(properties.deviceName); - - m_device_info.device_name.resize(device_name_size); - stdr::copy(std::string_view { properties.deviceName, device_name_size }, std::begin(m_device_info.device_name)); - // std::char_traits::copy(std::data(m_device_info.device_name), - // std::data(properties.deviceName), - // device_name_size); - // m_device_info.device_name.shrink_to_fit(); - - m_device_info.vendor_id = vendor_id; - m_device_info.vendor_name = vendor_name_by_id(vendor_id); - m_device_info.api_major_version = vk_version_major(properties.apiVersion); - m_device_info.api_minor_version = vk_version_minor(properties.apiVersion); - m_device_info.api_patch_version = vk_version_patch(properties.apiVersion); - - m_device_info.driver_major_version = vk_version_major(properties.driverVersion); - m_device_info.driver_minor_version = vk_version_minor(properties.driverVersion); - m_device_info.driver_patch_version = vk_version_patch(properties.driverVersion); - stdr::copy(properties.pipelineCacheUUID, stdr::begin(m_device_info.pipeline_cache_uuid)); - - m_device_info.type = from_vk(properties.deviceType); - - m_capabilities.limits.max_image_dimension_1D = properties.limits.maxImageDimension1D; - m_capabilities.limits.max_image_dimension_2D = properties.limits.maxImageDimension2D; - m_capabilities.limits.max_image_dimension_3D = properties.limits.maxImageDimension3D; - m_capabilities.limits.max_image_dimension_cube = properties.limits.maxImageDimensionCube; - m_capabilities.limits.max_image_array_layers = properties.limits.maxImageArrayLayers; - m_capabilities.limits.max_texel_buffer_elements = properties.limits.maxTexelBufferElements; - m_capabilities.limits.max_uniform_buffer_range = properties.limits.maxUniformBufferRange; - m_capabilities.limits.max_storage_buffer_range = properties.limits.maxStorageBufferRange; - m_capabilities.limits.max_push_constants_size = properties.limits.maxPushConstantsSize; - m_capabilities.limits.max_memory_allocation_count = properties.limits.maxMemoryAllocationCount; - m_capabilities.limits.max_sampler_allocation_count = properties.limits.maxSamplerAllocationCount; - m_capabilities.limits.buffer_image_granularity = properties.limits.bufferImageGranularity; - m_capabilities.limits.sparse_address_space_size = properties.limits.sparseAddressSpaceSize; - m_capabilities.limits.max_bound_descriptor_sets = properties.limits.maxBoundDescriptorSets; - m_capabilities.limits.max_per_stage_descriptor_samplers = properties.limits.maxPerStageDescriptorSamplers; - m_capabilities.limits.max_per_stage_descriptor_uniform_buffers = properties.limits.maxPerStageDescriptorUniformBuffers; - m_capabilities.limits.max_per_stage_descriptor_storage_buffers = properties.limits.maxPerStageDescriptorStorageBuffers; - m_capabilities.limits.max_per_stage_descriptor_sampled_images = properties.limits.maxPerStageDescriptorSampledImages; - m_capabilities.limits.max_per_stage_descriptor_storage_images = properties.limits.maxPerStageDescriptorStorageImages; - m_capabilities.limits - .max_per_stage_descriptor_input_attachments = properties.limits.maxPerStageDescriptorInputAttachments; - m_capabilities.limits.max_per_stage_resources = properties.limits.maxPerStageResources; - m_capabilities.limits.max_descriptor_set_samplers = properties.limits.maxDescriptorSetSamplers; - m_capabilities.limits.max_descriptor_set_uniform_buffers = properties.limits.maxDescriptorSetUniformBuffers; - m_capabilities.limits - .max_descriptor_set_uniform_buffers_dynamic = properties.limits.maxDescriptorSetUniformBuffersDynamic; - m_capabilities.limits.max_descriptor_set_storage_buffers = properties.limits.maxDescriptorSetStorageBuffers; - m_capabilities.limits - .max_descriptor_set_storage_buffers_dynamic = properties.limits.maxDescriptorSetStorageBuffersDynamic; - m_capabilities.limits.max_descriptor_set_sampled_images = properties.limits.maxDescriptorSetSampledImages; - m_capabilities.limits.max_descriptor_set_storage_images = properties.limits.maxDescriptorSetStorageImages; - m_capabilities.limits.max_descriptor_set_input_attachments = properties.limits.maxDescriptorSetInputAttachments; - m_capabilities.limits.max_vertex_input_attributes = properties.limits.maxVertexInputAttributes; - m_capabilities.limits.max_vertex_input_bindings = properties.limits.maxVertexInputBindings; - m_capabilities.limits.max_vertex_input_attribute_offset = properties.limits.maxVertexInputAttributeOffset; - m_capabilities.limits.max_vertex_input_binding_stride = properties.limits.maxVertexInputBindingStride; - m_capabilities.limits.max_vertex_output_components = properties.limits.maxVertexOutputComponents; - m_capabilities.limits.max_tessellation_generation_level = properties.limits.maxTessellationGenerationLevel; - m_capabilities.limits.max_tessellation_patch_size = properties.limits.maxTessellationPatchSize; - m_capabilities.limits - .max_tessellation_control_per_vertex_input_components = properties.limits - .maxTessellationControlPerVertexInputComponents; - m_capabilities.limits - .max_tessellation_control_per_vertex_output_components = properties.limits - .maxTessellationControlPerVertexOutputComponents; - m_capabilities.limits - .max_tessellation_control_per_patch_output_components = properties.limits - .maxTessellationControlPerPatchOutputComponents; - m_capabilities.limits - .max_tessellation_control_total_output_components = properties.limits.maxTessellationControlTotalOutputComponents; - m_capabilities.limits - .max_tessellation_evaluation_input_components = properties.limits.maxTessellationEvaluationInputComponents; - m_capabilities.limits - .max_tessellation_evaluation_output_components = properties.limits.maxTessellationEvaluationOutputComponents; - m_capabilities.limits.max_geometry_shader_invocations = properties.limits.maxGeometryShaderInvocations; - m_capabilities.limits.max_geometry_input_components = properties.limits.maxGeometryInputComponents; - m_capabilities.limits.max_geometry_output_components = properties.limits.maxGeometryOutputComponents; - m_capabilities.limits.max_geometry_output_vertices = properties.limits.maxGeometryOutputVertices; - m_capabilities.limits.max_geometry_total_output_components = properties.limits.maxGeometryTotalOutputComponents; - m_capabilities.limits.max_fragment_input_components = properties.limits.maxFragmentInputComponents; - m_capabilities.limits.max_fragment_output_attachments = properties.limits.maxFragmentOutputAttachments; - m_capabilities.limits.max_fragment_dual_src_attachments = properties.limits.maxFragmentDualSrcAttachments; - m_capabilities.limits.max_fragment_combined_output_resources = properties.limits.maxFragmentCombinedOutputResources; - m_capabilities.limits.max_compute_shared_memory_size = properties.limits.maxComputeSharedMemorySize; - stdr::copy(properties.limits.maxComputeWorkGroupCount, stdr::begin(m_capabilities.limits.max_compute_work_group_count)); - m_capabilities.limits.max_compute_work_group_invocations = properties.limits.maxComputeWorkGroupInvocations; - stdr::copy(properties.limits.maxComputeWorkGroupSize, stdr::begin(m_capabilities.limits.max_compute_work_group_size)); - m_capabilities.limits.sub_pixel_precision_bits = properties.limits.subPixelPrecisionBits; - m_capabilities.limits.sub_texel_precision_bits = properties.limits.subTexelPrecisionBits; - m_capabilities.limits.mipmap_precision_bits = properties.limits.mipmapPrecisionBits; - m_capabilities.limits.max_draw_indexed_index_value = properties.limits.maxDrawIndexedIndexValue; - m_capabilities.limits.max_draw_indirect_count = properties.limits.maxDrawIndirectCount; - m_capabilities.limits.max_sampler_lod_bias = properties.limits.maxSamplerLodBias; - m_capabilities.limits.max_sampler_anisotropy = properties.limits.maxSamplerAnisotropy; - m_capabilities.limits.max_viewports = properties.limits.maxViewports; - stdr::copy(properties.limits.maxViewportDimensions, stdr::begin(m_capabilities.limits.max_viewport_dimensions)); - stdr::copy(properties.limits.viewportBoundsRange, stdr::begin(m_capabilities.limits.viewport_bounds_range)); - m_capabilities.limits.viewport_sub_pixel_bits = properties.limits.viewportSubPixelBits; - m_capabilities.limits.min_memory_map_alignment = properties.limits.minMemoryMapAlignment; - m_capabilities.limits.min_texel_buffer_offset_alignment = properties.limits.minTexelBufferOffsetAlignment; - m_capabilities.limits.min_uniform_buffer_offset_alignment = properties.limits.minUniformBufferOffsetAlignment; - m_capabilities.limits.min_storage_buffer_offset_alignment = properties.limits.minStorageBufferOffsetAlignment; - m_capabilities.limits.min_texel_offset = properties.limits.minTexelOffset; - m_capabilities.limits.max_texel_offset = properties.limits.maxTexelOffset; - m_capabilities.limits.min_texel_gather_offset = properties.limits.minTexelGatherOffset; - m_capabilities.limits.max_texel_gather_offset = properties.limits.maxTexelGatherOffset; - m_capabilities.limits.min_interpolation_offset = properties.limits.minInterpolationOffset; - m_capabilities.limits.max_interpolation_offset = properties.limits.maxInterpolationOffset; - m_capabilities.limits.sub_pixel_interpolation_offset_bits = properties.limits.subPixelInterpolationOffsetBits; - m_capabilities.limits.max_framebuffer_width = properties.limits.maxFramebufferWidth; - m_capabilities.limits.max_framebuffer_height = properties.limits.maxFramebufferHeight; - m_capabilities.limits.max_framebuffer_layers = properties.limits.maxFramebufferLayers; - m_capabilities.limits - .framebuffer_color_sample_counts = narrow(properties.limits.framebufferColorSampleCounts); - m_capabilities.limits - .framebuffer_depth_sample_counts = narrow(properties.limits.framebufferDepthSampleCounts); - m_capabilities.limits - .framebuffer_stencil_sample_counts = narrow(properties.limits.framebufferStencilSampleCounts); - m_capabilities.limits - .framebuffer_no_attachments_sample_counts = narrow(properties.limits - .framebufferNoAttachmentsSampleCounts); - m_capabilities.limits.max_color_attachments = properties.limits.maxColorAttachments; - m_capabilities.limits - .sampled_image_color_sample_counts = narrow(properties.limits.sampledImageColorSampleCounts); - m_capabilities.limits - .sampled_image_integer_sample_counts = narrow(properties.limits.sampledImageIntegerSampleCounts); - m_capabilities.limits - .sampled_image_depth_sample_counts = narrow(properties.limits.sampledImageDepthSampleCounts); - m_capabilities.limits - .sampled_image_stencil_sample_counts = narrow(properties.limits.sampledImageStencilSampleCounts); - m_capabilities.limits.storage_image_sample_counts = narrow(properties.limits.storageImageSampleCounts); - m_capabilities.limits.max_sample_mask_words = properties.limits.maxSampleMaskWords; - m_capabilities.limits.timestamp_compute_and_engine = properties.limits.timestampComputeAndGraphics; - m_capabilities.limits.timestamp_period = properties.limits.timestampPeriod; - m_capabilities.limits.max_clip_distances = properties.limits.maxClipDistances; - m_capabilities.limits.max_cull_distances = properties.limits.maxCullDistances; - m_capabilities.limits.max_combined_clip_and_cull_distances = properties.limits.maxCombinedClipAndCullDistances; - m_capabilities.limits.discrete_queue_priorities = properties.limits.discreteQueuePriorities; - stdr::copy(properties.limits.pointSizeRange, stdr::begin(m_capabilities.limits.point_size_range)); - stdr::copy(properties.limits.lineWidthRange, stdr::begin(m_capabilities.limits.line_width_range)); - m_capabilities.limits.point_size_granularity = properties.limits.pointSizeGranularity; - m_capabilities.limits.line_width_granularity = properties.limits.lineWidthGranularity; - m_capabilities.limits.strict_lines = properties.limits.strictLines; - m_capabilities.limits.standard_sample_locations = properties.limits.standardSampleLocations; - m_capabilities.limits.optimal_buffer_copy_offset_alignment = properties.limits.optimalBufferCopyOffsetAlignment; - m_capabilities.limits.optimal_buffer_copy_row_pitch_alignment = properties.limits.optimalBufferCopyRowPitchAlignment; - m_capabilities.limits.non_coherent_atom_size = properties.limits.nonCoherentAtomSize; - - m_capabilities.features.robust_buffer_access = features.robustBufferAccess; - m_capabilities.features.full_draw_index_uint32 = features.fullDrawIndexUint32; - m_capabilities.features.image_cube_array = features.imageCubeArray; - m_capabilities.features.independent_blend = features.independentBlend; - m_capabilities.features.geometry_shader = features.geometryShader; - m_capabilities.features.tessellation_shader = features.tessellationShader; - m_capabilities.features.sampler_rate_shading = features.sampleRateShading; - m_capabilities.features.dual_src_blend = features.dualSrcBlend; - m_capabilities.features.logic_op = features.logicOp; - m_capabilities.features.multi_draw_indirect = features.multiDrawIndirect; - m_capabilities.features.draw_indirect_first_instance = features.drawIndirectFirstInstance; - m_capabilities.features.depth_clamp = features.depthClamp; - m_capabilities.features.depth_bias_clamp = features.depthBiasClamp; - m_capabilities.features.fill_Mode_non_solid = features.fillModeNonSolid; - m_capabilities.features.depth_bounds = features.depthBounds; - m_capabilities.features.wide_lines = features.wideLines; - m_capabilities.features.large_points = features.largePoints; - m_capabilities.features.alpha_to_one = features.alphaToOne; - m_capabilities.features.multi_viewport = features.multiViewport; - m_capabilities.features.sampler_anisotropy = features.samplerAnisotropy; - m_capabilities.features.texture_compression_etc2 = features.textureCompressionETC2; - m_capabilities.features.texture_compression_astc_ldr = features.textureCompressionASTC_LDR; - m_capabilities.features.texture_compression_bc = features.textureCompressionBC; - m_capabilities.features.occlusion_query_precise = features.occlusionQueryPrecise; - m_capabilities.features.pipeline_statistics_query = features.pipelineStatisticsQuery; - m_capabilities.features.vertex_pipeline_stores_and_atomics = features.vertexPipelineStoresAndAtomics; - m_capabilities.features.fragment_stores_and_atomics = features.fragmentStoresAndAtomics; - m_capabilities.features.shader_tessellation_and_geometry_point_size = features.shaderTessellationAndGeometryPointSize; - m_capabilities.features.shader_image_gather_extended = features.shaderImageGatherExtended; - m_capabilities.features.shader_storage_image_extended_formats = features.shaderStorageImageExtendedFormats; - m_capabilities.features.shader_storage_image_multisample = features.shaderStorageImageMultisample; - m_capabilities.features.shader_storage_image_read_without_format = features.shaderStorageImageReadWithoutFormat; - m_capabilities.features.shader_storage_image_write_without_format = features.shaderStorageImageWriteWithoutFormat; - m_capabilities.features.shader_uniform_buffer_array_dynamic_indexing = features.shaderUniformBufferArrayDynamicIndexing; - m_capabilities.features.shader_sampled_image_array_dynamic_indexing = features.shaderSampledImageArrayDynamicIndexing; - m_capabilities.features.shader_storage_buffer_array_dynamic_indexing = features.shaderStorageBufferArrayDynamicIndexing; - m_capabilities.features.shader_storage_image_array_dynamic_indexing = features.shaderStorageImageArrayDynamicIndexing; - m_capabilities.features.shader_clip_distance = features.shaderClipDistance; - m_capabilities.features.shader_cull_distance = features.shaderCullDistance; - m_capabilities.features.shader_float_64 = features.shaderFloat64; - m_capabilities.features.shader_int_64 = features.shaderInt64; - m_capabilities.features.shader_int_16 = features.shaderInt16; - m_capabilities.features.shader_resource_residency = features.shaderResourceResidency; - m_capabilities.features.shader_resource_min_lod = features.shaderResourceMinLod; - m_capabilities.features.sparse_binding = features.sparseBinding; - m_capabilities.features.sparse_residency_buffer = features.sparseResidencyBuffer; - m_capabilities.features.sparse_residency_image_2D = features.sparseResidencyImage2D; - m_capabilities.features.sparse_residency_image_3D = features.sparseResidencyImage3D; - m_capabilities.features.sparse_residency_2_samples = features.sparseResidency2Samples; - m_capabilities.features.sparse_residency_4_samples = features.sparseResidency4Samples; - m_capabilities.features.sparse_residency_8_samples = features.sparseResidency8Samples; - m_capabilities.features.sparse_residency_16_samples = features.sparseResidency16Samples; - m_capabilities.features.sparse_residency_aliased = features.sparseResidencyAliased; - m_capabilities.features.variable_multisample_rate = features.variableMultisampleRate; - m_capabilities.features.inherited_queries = features.inheritedQueries; - - m_extensions = *vk_enumerate(vkEnumerateDeviceExtensionProperties, m_vk_handle, nullptr) - .transform_error(core::monadic::assert(format("Failed to enumerate device {} extensions properties", - m_device_info.device_name))) - | stdv::transform([](auto&& extension) noexcept { - const auto string_size = std::char_traits::length(extension.extensionName); - - auto string = std::string {}; - string.resize(string_size); - stdr::copy(std::string_view { extension.extensionName, string_size }, std::begin(string)); - return string; - }) - | stdr::to(); - - const auto vk_memory_properties = vk_call(vkGetPhysicalDeviceMemoryProperties, - m_vk_handle); - m_memory_types = vk_memory_properties.memoryTypes - | stdv::transform([](auto&& type) static noexcept { - return core::narrow(type.propertyFlags); - }) - | stdr::to(); - - m_queue_families = vk_enumerate(vkGetPhysicalDeviceQueueFamilyProperties, m_vk_handle) - | stdv::transform([](auto&& family) static noexcept { - return QueueFamily { .flags = narrow(family.queueFlags), .count = family.queueCount }; - }) - | stdr::to(); - - const auto format_values = core::meta::enumerate(); - for (const auto val : format_values) { - m_format_properties - .emplace_back(val, - from_vk(vk_call(vkGetPhysicalDeviceFormatProperties, - m_vk_handle, - to_vk(val)))); - } + auto PhysicalDevice::check_extension_support(std::string_view extension) const noexcept -> bool { + return PhysicalDeviceAPI::check_extension_support(*this, std::move(extension)); } ///////////////////////////////////// ///////////////////////////////////// - PhysicalDevice::~PhysicalDevice() = default; + auto PhysicalDevice::check_extension_support(std::span extensions) const noexcept -> bool { + return PhysicalDeviceAPI::check_extension_support(*this, std::move(extensions)); + } ///////////////////////////////////// ///////////////////////////////////// - PhysicalDevice::PhysicalDevice(PhysicalDevice&& other) noexcept = default; + auto PhysicalDevice::check_extension_support(std::span extensions) const noexcept -> bool { + return PhysicalDeviceAPI::check_extension_support(*this, std::move(extensions)); + } ///////////////////////////////////// ///////////////////////////////////// - auto PhysicalDevice::operator=(PhysicalDevice&& other) noexcept -> PhysicalDevice& = default; + auto PhysicalDevice::info() const noexcept -> const PhysicalDeviceInfo& { + if (stdr::empty(m_device_info.device_name)) m_device_info = PhysicalDeviceAPI::info(*this); + + return m_device_info; + } ///////////////////////////////////// ///////////////////////////////////// - auto PhysicalDevice::check_extension_support(std::string_view extension) const noexcept -> bool { - return stdr::any_of(m_extensions, [extension](const auto& e) { return e == extension; }); + auto PhysicalDevice::capabilities() const noexcept -> const RenderCapabilities& { + if (m_capabilities.limits.max_image_dimension_2D == 0) [[unlikely]] + m_capabilities = PhysicalDeviceAPI::capabilities(*this); + + return m_capabilities; } ///////////////////////////////////// ///////////////////////////////////// - auto PhysicalDevice::check_extension_support(std::span extensions) const noexcept -> bool { - auto required_extensions = HashSet { stdr::begin(extensions), stdr::end(extensions) }; - // HashSet { stdr::begin(extensions), - // stdr::end(extensions) }; + auto PhysicalDevice::memory_types() const noexcept -> const std::vector& { + if (stdr::empty(m_memory_types)) [[unlikely]] + m_memory_types = PhysicalDeviceAPI::memory_types(*this); - for (const auto& extension : m_extensions) required_extensions.erase(extension); + return m_memory_types; + } - return stdr::empty(required_extensions); + ///////////////////////////////////// + ///////////////////////////////////// + auto PhysicalDevice::queue_families() const noexcept -> const std::vector& { + if (stdr::empty(m_queue_families)) [[unlikely]] + m_queue_families = PhysicalDeviceAPI::queue_families(*this); + + return m_queue_families; } ///////////////////////////////////// ///////////////////////////////////// - auto PhysicalDevice::check_extension_support(std::span extensions) const noexcept -> bool { - auto required_extensions = HashSet { stdr::begin(extensions), stdr::end(extensions) }; + auto PhysicalDevice::extensions() const noexcept -> const std::vector& { + if (stdr::empty(m_extensions)) [[unlikely]] + m_extensions = PhysicalDeviceAPI::extensions(*this); - for (const auto& extension : m_extensions) required_extensions.erase(extension); + return m_extensions; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto PhysicalDevice::formats_properties() const noexcept -> const std::vector>& { + if (stdr::empty(m_format_properties)) [[unlikely]] + m_format_properties = PhysicalDeviceAPI::formats_properties(*this); - return stdr::empty(required_extensions); + return m_format_properties; } + + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + auto PhysicalDevice::check_extension_support(std::string_view extension) const noexcept -> bool { + return PhysicalDeviceAPI::check_extension_support(*this, std::move(extension)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto PhysicalDevice::check_extension_support(std::span extensions) const noexcept -> bool { + return PhysicalDeviceAPI::check_extension_support(*this, std::move(extensions)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto PhysicalDevice::check_extension_support(std::span extensions) const noexcept -> bool { + return PhysicalDeviceAPI::check_extension_support(*this, std::move(extensions)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto PhysicalDevice::info() const noexcept -> const PhysicalDeviceInfo& { + if (stdr::empty(m_device_info.device_name)) m_device_info = PhysicalDeviceAPI::info(*this); + + return m_device_info; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto PhysicalDevice::capabilities() const noexcept -> const RenderCapabilities& { + if (m_capabilities.limits.max_image_dimension_2D == 0) [[unlikely]] + m_capabilities = PhysicalDeviceAPI::capabilities(*this); + + return m_capabilities; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto PhysicalDevice::memory_types() const noexcept -> const std::vector& { + if (stdr::empty(m_memory_types)) [[unlikely]] + m_memory_types = PhysicalDeviceAPI::memory_types(*this); + + return m_memory_types; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto PhysicalDevice::queue_families() const noexcept -> const std::vector& { + if (stdr::empty(m_queue_families)) [[unlikely]] + m_queue_families = PhysicalDeviceAPI::queue_families(*this); + + return m_queue_families; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto PhysicalDevice::extensions() const noexcept -> const std::vector& { + if (stdr::empty(m_extensions)) [[unlikely]] + m_extensions = PhysicalDeviceAPI::extensions(*this); + + return m_extensions; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto PhysicalDevice::formats_properties() const noexcept -> const std::vector>& { + if (stdr::empty(m_format_properties)) [[unlikely]] + m_format_properties = PhysicalDeviceAPI::formats_properties(*this); + + return m_format_properties; + } + } // namespace view } // namespace stormkit::gpu diff --git a/src/gpu/core/semaphore.cpp b/src/gpu/core/semaphore.cpp new file mode 100644 index 000000000..64e412520 --- /dev/null +++ b/src/gpu/core/semaphore.cpp @@ -0,0 +1,37 @@ +// Copyright (C) 2023 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include +#include +#include + +#include +#include + +module stormkit.gpu.core; + +import std; + +import stormkit.core; + +namespace stormkit::gpu { + ///////////////////////////////////// + ///////////////////////////////////// + auto Semaphore::do_init(PrivateTag) noexcept -> Expected { + const auto create_info = VkSemaphoreCreateInfo { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + }; + + m_vk_handle = Try(vk::call_checked(m_device.device_table().vkCreateSemaphore, + m_device, + &create_info, + nullptr)); + + Return {}; + } +} // namespace stormkit::gpu diff --git a/src/gpu/core/surface.cpp b/src/gpu/core/surface.cpp index 85d434e8d..2fc4225c0 100644 --- a/src/gpu/core/surface.cpp +++ b/src/gpu/core/surface.cpp @@ -6,6 +6,7 @@ module; #include #include +#include #if defined(STORMKIT_OS_LINUX) #include @@ -24,32 +25,29 @@ import std; import stormkit.core; import stormkit.wsi; -; - namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto Surface::do_init_offscreen(const Instance& instance) noexcept -> Expected { - m_vk_instance = instance.native_handle(); + auto Surface::do_init(PrivateTag) noexcept -> Expected { assert(false, "not implemented yet"); return {}; } ///////////////////////////////////// ///////////////////////////////////// - auto Surface::do_init_from_window(const Instance& instance, const wsi::Window& window) noexcept -> Expected { + auto Surface::do_init(PrivateTag, const wsi::Window& window) noexcept -> Expected { EXPECTS(window.is_open()); - m_vk_instance = instance.native_handle(); + const auto instance = m_instance; #if defined(STORMKIT_OS_WINDOWS) const auto create_surface = [&window, &instance] { const auto create_info = VkWin32SurfaceCreateInfoKHR { - .sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, - .pNext = nullptr, - .flags = 0, - .hinstance = GetModuleHandleW(nullptr), - .hwnd = std::bit_cast(window.native_handle()) + .sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR, + .pNext = nullptr, + .flags = 0, + .m_hinstance = GetModuleHandleW(nullptr), + .hwnd = std::bit_cast(window.native_handle()) }; - return vk_call(vkCreateWin32SurfaceKHR, instance.native_handle(), &create_info, nullptr); + return vk::call_checked(vkCreateWin32SurfaceKHR, instance, &create_info, nullptr); }; #elif defined(STORMKIT_OS_MACOS) const auto create_surface = [&window, &instance] { @@ -59,8 +57,7 @@ namespace stormkit::gpu { .flags = 0, .pView = window.native_handle() }; - std::println("{}", window.native_handle()); - return vk_call(vkCreateMacOSSurfaceMVK, instance.native_handle(), &create_info, nullptr); + return vk::call_checked(vkCreateMacOSSurfaceMVK, instance, &create_info, nullptr); }; #elif defined(STORMKIT_OS_LINUX) const auto make_wayland_surface = [&window, &instance] { @@ -76,7 +73,7 @@ namespace stormkit::gpu { .display = handles->display, .surface = handles->surface }; - return vk_call(vkCreateWaylandSurfaceKHR, instance.native_handle(), &create_info, nullptr); + return vk::call_checked(vkCreateWaylandSurfaceKHR, instance, &create_info, nullptr); }; const auto make_xcb_surface = [&window, &instance] { struct Handles { @@ -93,11 +90,11 @@ namespace stormkit::gpu { .connection = handles->connection, .window = handles->window }; - return vk_call(vkCreateXcbSurfaceKHR, instance.native_handle(), &create_info, nullptr); + return vk::call_checked(vkCreateXcbSurfaceKHR, instance, &create_info, nullptr); }; const auto create_surface = - [&window, &make_wayland_surface, &make_xcb_surface] noexcept -> FunctionRef()> { + [&window, &make_wayland_surface, &make_xcb_surface] noexcept -> FunctionRef()> { const auto is_wayland = window.wm() == wsi::WM::WAYLAND; if (is_wayland) return make_wayland_surface; @@ -106,22 +103,22 @@ namespace stormkit::gpu { }(); #elif defined(STORMKIT_OS_IOS) - const auto create_surface = [this, &window, &instance] noexcept { + const auto create_surface = [this, &window, &m_instance] noexcept { const auto create_info = VkIOSSurfaceCreateInfoMVK { .sType = VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK, .pNext = nullptr, .flags = 0, .pView = window->native_handle() }; - CHECK_VK_ERROR(vkCreateIOSSurfaceMVK(instance, &create_info, &m_surface)); + CHECK_VK_ERROR(vkCreateIOSSurfaceMVK(m_instance, &create_info, &m_surface)); }; #else const auto create_surface = [] static noexcept {}; assertWithMessage(true, "This platform WSI is not supported !"); #endif - m_vk_handle = { [vk_instance = m_vk_instance](auto handle) noexcept { - vkDestroySurfaceKHR(vk_instance, handle, nullptr); - } }; - return create_surface().transform(core::monadic::set(m_vk_handle)).transform_error(core::monadic::narrow()); + + m_vk_handle = Try(create_surface()); + + Return {}; } } // namespace stormkit::gpu diff --git a/src/gpu/execution/command_buffer.cpp b/src/gpu/execution/command_buffer.cpp index 2b2041a0f..3ebbe1cf7 100644 --- a/src/gpu/execution/command_buffer.cpp +++ b/src/gpu/execution/command_buffer.cpp @@ -25,6 +25,8 @@ using namespace std::literals; namespace stdr = std::ranges; namespace stdv = std::views; +namespace cmonadic = stormkit::core::monadic; + namespace stormkit::gpu { namespace { constexpr auto @@ -67,505 +69,1388 @@ namespace stormkit::gpu { { VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, { VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT } }, { VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, { VK_ACCESS_MEMORY_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT } }, }); - } // namespace - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::begin(bool one_time_submit, InheritanceInfo inheritance_info_variant) noexcept - -> Expected> { - EXPECTS(m_state == State::INITIAL); - - auto rendering_color_attachments = std::vector {}; - auto vk_rendering_inheritance_info = zeroed(); - vk_rendering_inheritance_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO; - - const auto vk_inheritance_info = - [&inheritance_info_variant, &rendering_color_attachments, &vk_rendering_inheritance_info] noexcept { - auto info = zeroed(); - info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; - - if (is(inheritance_info_variant)) { - const auto& inheritance_info = as(inheritance_info_variant); - info.renderPass = to_vk(*inheritance_info.render_pass); - info.subpass = inheritance_info.subpass; - info.framebuffer = to_vk(*inheritance_info.framebuffer); - } else if (is(inheritance_info_variant)) { - info.pNext = &vk_rendering_inheritance_info; - - const auto& inheritance_info = as(inheritance_info_variant); - - rendering_color_attachments = inheritance_info.color_attachments - | stdv::transform(gpu::monadic::to_vk()) - | stdr::to(); - vk_rendering_inheritance_info.viewMask = inheritance_info.view_mask; - vk_rendering_inheritance_info.colorAttachmentCount = as(stdr::size(inheritance_info.color_attachments)); - vk_rendering_inheritance_info.pColorAttachmentFormats = stdr::data(rendering_color_attachments); - - if (inheritance_info.depth_attachment) - vk_rendering_inheritance_info - .depthAttachmentFormat = gpu::to_vk(*inheritance_info.depth_attachment); - if (inheritance_info.stencil_attachment) - vk_rendering_inheritance_info - .stencilAttachmentFormat = gpu::to_vk(*inheritance_info.stencil_attachment); - - vk_rendering_inheritance_info - .rasterizationSamples = gpu::to_vk(inheritance_info.rasterization_samples); - } - return info; - }(); - - const auto flags = [this, one_time_submit, &inheritance_info_variant] noexcept -> VkCommandBufferUsageFlags { - auto flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - - if (!one_time_submit) flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; - if (m_level == CommandBufferLevel::SECONDARY) { - if (is(inheritance_info_variant) - or is(inheritance_info_variant)) - flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; - } - - return flags; - }(); - - const auto begin_info = VkCommandBufferBeginInfo { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, - .pNext = nullptr, - .flags = flags, - .pInheritanceInfo = &vk_inheritance_info, - }; + struct CommandBufferAPI { + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto reset(CommandBufferType& cmb) noexcept -> Expected { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); - return vk_call(m_vk_device_table->vkBeginCommandBuffer, m_vk_handle, &begin_info) - .transform([this, &self = *this] noexcept { - m_state = State::RECORDING; - return as_ref_mut(self); - }) - .transform_error(monadic::from_vk()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::begin_rendering(const RenderingInfo& info, bool secondary) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - auto to_vk_attachment = [](const auto& attachment) static noexcept { - auto attachment_info = VkRenderingAttachmentInfo { - .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - .pNext = nullptr, - .imageView = to_vk(attachment.image_view), - .imageLayout = to_vk(attachment.layout), - .resolveMode = {}, - .resolveImageView = nullptr, - .resolveImageLayout = {}, - .loadOp = to_vk(attachment.load_op), - .storeOp = to_vk(attachment.store_op), - .clearValue = {}, - }; - - if (attachment.resolve) { - auto& resolve = *attachment.resolve; - - attachment_info.resolveMode = to_vk(resolve.mode); - attachment_info.resolveImageView = to_vk(resolve.image_view); - attachment_info.resolveImageLayout = to_vk(resolve.layout); - } - if (attachment.clear_value) { - attachment_info - .clearValue = std::visit(Overloaded { - [](const ClearColor& clear_color) static noexcept -> decltype(auto) { - return VkClearValue { - .color = VkClearColorValue { .float32 = { clear_color.color.r, - clear_color.color.b, - clear_color.color.g, - clear_color.color.a } }, - }; - }, - [](const ClearDepthStencil& clear_depth_stencil) static noexcept -> decltype(auto) { - return VkClearValue { - .depthStencil = VkClearDepthStencilValue { .depth = clear_depth_stencil - .depth, - .stencil = clear_depth_stencil - .stencil }, - }; - } }, - *attachment.clear_value); - } - - return attachment_info; - }; + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + Try(vk::call_checked(m_vk_device_table->vkResetCommandBuffer, m_vk_handle, 0)); + state = State::INITIAL; + + Return {}; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto begin(CommandBufferType& cmb, bool one_time_submit, InheritanceInfo inheritance_info_variant) noexcept + -> Expected { + auto& state = cmb.state(); + EXPECTS(state == State::INITIAL); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + auto rendering_color_attachments = std::vector {}; + // auto vk_rendering_inheritance_info = zeroed(); + auto vk_rendering_inheritance_info = VkCommandBufferInheritanceRenderingInfo { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO + }; + + const auto vk_inheritance_info = + [&inheritance_info_variant, &rendering_color_attachments, &vk_rendering_inheritance_info] noexcept { + // auto info = zeroed(); + auto info = VkCommandBufferInheritanceInfo { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO }; + + if (is(inheritance_info_variant)) { + const auto& inheritance_info = as(inheritance_info_variant); + info.renderPass = vk::to_vk(*inheritance_info.render_pass); + info.subpass = inheritance_info.subpass; + info.framebuffer = vk::to_vk(*inheritance_info.framebuffer); + } else if (is(inheritance_info_variant)) { + info.pNext = &vk_rendering_inheritance_info; + + const auto& inheritance_info = as(inheritance_info_variant); + + rendering_color_attachments = inheritance_info.color_attachments + | stdv::transform(gpu::vk::monadic::to_vk()) + | stdr::to(); + vk_rendering_inheritance_info.viewMask = inheritance_info.view_mask; + vk_rendering_inheritance_info + .colorAttachmentCount = as(stdr::size(inheritance_info.color_attachments)); + vk_rendering_inheritance_info.pColorAttachmentFormats = stdr::data(rendering_color_attachments); + + if (inheritance_info.depth_attachment) + vk_rendering_inheritance_info + .depthAttachmentFormat = gpu::vk::to_vk(*inheritance_info.depth_attachment); + if (inheritance_info.stencil_attachment) + vk_rendering_inheritance_info + .stencilAttachmentFormat = gpu::vk::to_vk(*inheritance_info.stencil_attachment); + + vk_rendering_inheritance_info + .rasterizationSamples = gpu::vk::to_vk(inheritance_info.rasterization_samples); + } + return info; + }(); + + const auto flags = [this, one_time_submit, &inheritance_info_variant] noexcept -> VkCommandBufferUsageFlags { + auto flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + + if (!one_time_submit) flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; + if (m_level == CommandBufferLevel::SECONDARY) { + if (is(inheritance_info_variant) + or is(inheritance_info_variant)) + flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; + } + + return flags; + }(); + + const auto begin_info = VkCommandBufferBeginInfo { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + .pNext = nullptr, + .flags = flags, + .pInheritanceInfo = &vk_inheritance_info, + }; + + Try(vk::call_checked(m_vk_device_table->vkBeginCommandBuffer, m_vk_handle, &begin_info)); + state = State::RECORDING; + + Return {}; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto end(CommandBufferType& cmb) noexcept -> Expected { + auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + Try(vk::call_checked(device_table.vkEndCommandBuffer, cmb)); + state = State::EXECUTABLE; + + Return {}; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto begin_debug_region(const CommandBufferType& cmb, + std::string_view&& name, + const fcolor_rgb& color) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + if (not vkCmdBeginDebugUtilsLabelEXT) [[unlikely]] + return; + + const auto info = VkDebugUtilsLabelEXT { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, + .pNext = nullptr, + .pLabelName = stdr::data(name), + .color = { color.r, color.g, color.b, 1.f } + }; + + vk::call(vkCmdBeginDebugUtilsLabelEXT, cmb, &info); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto insert_debug_label(const CommandBufferType& cmb, + std::string_view&& name, + const fcolor_rgb& color) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + if (not vkCmdInsertDebugUtilsLabelEXT) [[unlikely]] + return; + + const auto info = VkDebugUtilsLabelEXT { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, + .pNext = nullptr, + .pLabelName = stdr::data(name), + .color = { color.r, color.g, color.b, 1.f } + }; + + vk::call(vkCmdInsertDebugUtilsLabelEXT, cmb, &info); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto end_debug_region(const CommandBufferType& cmb) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + if (not vkCmdEndDebugUtilsLabelEXT) [[unlikely]] + return; + + vk::call(vkCmdEndDebugUtilsLabelEXT, cmb); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto begin_rendering(const CommandBufferType& cmb, const RenderingInfo& info, bool secondary) noexcept + -> void { + EXPECTS(m_state == State::RECORDING); + + auto to_vk_attachment = [](const auto& attachment) static noexcept { + auto attachment_info = VkRenderingAttachmentInfo { + .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, + .pNext = nullptr, + .imageView = vk::to_vk(attachment.image_view), + .imageLayout = vk::to_vk(attachment.layout), + .resolveMode = {}, + .resolveImageView = nullptr, + .resolveImageLayout = {}, + .loadOp = vk::to_vk(attachment.load_op), + .storeOp = vk::to_vk(attachment.store_op), + .clearValue = {}, + }; + + if (attachment.resolve) { + auto& resolve = *attachment.resolve; + + attachment_info.resolveMode = vk::to_vk(resolve.mode); + attachment_info.resolveImageView = vk::to_vk(resolve.image_view); + attachment_info.resolveImageLayout = vk::to_vk(resolve.layout); + } + if (attachment.clear_value) { + attachment_info.clearValue = std:: + visit(Overloaded { + [](const ClearColor& clear_color) static noexcept -> decltype(auto) { + return VkClearValue { + .color = VkClearColorValue { .float32 = { clear_color.color.r, + clear_color.color.b, + clear_color.color.g, + clear_color.color.a } }, + }; + }, + [](const ClearDepthStencil& clear_depth_stencil) static noexcept -> decltype(auto) { + return VkClearValue { + .depthStencil = VkClearDepthStencilValue { .depth = clear_depth_stencil.depth, + .stencil = clear_depth_stencil.stencil }, + }; + } }, + *attachment.clear_value); + } + + return attachment_info; + }; + + const auto color_attachments = transform(info.color_attachments, to_vk_attachment); + const auto depth_attachment = info.depth_attachment ? to_vk_attachment(*info.depth_attachment) + : VkRenderingAttachmentInfo {}; + const auto stencil_attachment = info.stencil_attachment ? to_vk_attachment(*info.stencil_attachment) + : VkRenderingAttachmentInfo {}; + + const auto rendering_info = VkRenderingInfo { + .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, + .pNext = nullptr, + .flags = as((secondary) ? VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT : 0), + .renderArea = vk::to_vk(info.render_area), + .layerCount = info.layer_count, + .viewMask = info.view_mask, + .colorAttachmentCount = as(stdr::size(color_attachments)), + .pColorAttachments = stdr::data(color_attachments), + .pDepthAttachment = info.depth_attachment ? &depth_attachment : nullptr, + .pStencilAttachment = info.stencil_attachment ? &stencil_attachment : nullptr, + }; + + vk::call(device_table.vkCmdBeginRenderingKHR, cmb, &rendering_info); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto begin_render_pass(const CommandBufferType& cmb, + view::RenderPass&& render_pass, + view::FrameBuffer&& framebuffer, + std::span&& clear_values, + bool secondary_commandbuffers) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto + vk_clear_values = transform(clear_values, + cmonadic::either( + [](const ClearColor& clear_color) static noexcept -> decltype(auto) { + return VkClearValue { + .color = VkClearColorValue { .float32 = { clear_color.color.r, + clear_color.color.b, + clear_color.color.g, + clear_color.color.a } }, + }; + }, + [](const ClearDepthStencil& clear_depth_stencil) static noexcept + -> decltype(auto) { + return VkClearValue { + .depthStencil = VkClearDepthStencilValue { .depth = clear_depth_stencil + .depth, + .stencil = clear_depth_stencil + .stencil }, + }; + })); + + const auto begin_info = VkRenderPassBeginInfo { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + .pNext = nullptr, + .renderPass = vk::to_vk(render_pass), + .framebuffer = vk::to_vk(framebuffer), + .renderArea = VkRect2D { .offset = { 0, 0 }, + .extent = { framebuffer.extent().width, framebuffer.extent().height } }, + .clearValueCount = as(stdr::size(vk_clear_values)), + .pClearValues = stdr::data(vk_clear_values), + }; + + const auto subpass_content = secondary_commandbuffers ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS + : VK_SUBPASS_CONTENTS_INLINE; + + vk::call(device_table.vkCmdBeginRenderPass, cmb, &begin_info, subpass_content); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto next_subpass(const CommandBufferType& cmb) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdNextSubpass, cmb, VK_SUBPASS_CONTENTS_INLINE); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto end_render_pass(const CommandBufferType& cmb) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdEndRenderPass, cmb); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto end_rendering(const CommandBufferType& cmb) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdEndRendering, cmb); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto bind_pipeline(const CommandBufferType& cmb, view::Pipeline&& pipeline) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto bind_point = (pipeline.type() == Pipeline::Type::RASTER) ? VK_PIPELINE_BIND_POINT_GRAPHICS + : VK_PIPELINE_BIND_POINT_COMPUTE; + + vk::call(device_table.vkCmdBindPipeline, cmb, bind_point, pipeline); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto set_viewport(const CommandBufferType& cmb, u32 first_viewport, std::span&& viewports) noexcept + -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto vk_viewports = transform(viewports, vk::monadic::to_vk()); + + vk::call(device_table.vkCmdSetViewport, cmb, first_viewport, stdr::size(vk_viewports), stdr::data(vk_viewports)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto set_scissor(const CommandBufferType& cmb, u32 first_scissor, std::span&& scissors) noexcept + -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto vk_scissors = transform(scissors, vk::monadic::to_vk()); + + vk::call(device_table.vkCmdSetScissor, cmb, first_scissor, stdr::size(vk_scissors), stdr::data(vk_scissors)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto set_line_width(const CommandBufferType& cmb, f32 width) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdSetLineWidth, cmb, width); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto set_depth_bias(const CommandBufferType& cmb, f32 constant_factor, f32 clamp, f32 slope_factor) noexcept + -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdSetDepthBias, cmb, constant_factor, clamp, slope_factor); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto set_blend_constants(const CommandBufferType& cmb, std::span&& constants) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + f32 data[] = { constants[0], constants[1], constants[2], constants[3] }; + + vk::call(device_table.vkCmdSetBlendConstants, cmb, data); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto set_depth_bounds(const CommandBufferType& cmb, f32 min, f32 max) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdSetDepthBounds, cmb, min, max); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto set_stencil_compare_mask(const CommandBufferType& cmb, StencilFaceFlag face, u32 mask) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdSetStencilCompareMask, cmb, vk::to_vk(face), mask); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto set_stencil_write_mask(const CommandBufferType& cmb, StencilFaceFlag face, u32 mask) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdSetStencilWriteMask, cmb, vk::to_vk(face), mask); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto set_stencil_reference(const CommandBufferType& cmb, StencilFaceFlag face, u32 reference) noexcept + -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdSetStencilReference, cmb, vk::to_vk(face), reference); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto dispatch(const CommandBufferType& cmb, u32 group_count_x, u32 group_count_y, u32 group_count_z) noexcept + -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdDispatch, cmb, group_count_x, group_count_y, group_count_z); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto draw(const CommandBufferType& cmb, + u32 vertex_count, + u32 instance_count, + u32 first_vertex, + u32 first_instance) noexcept -> void { + EXPECTS(vertex_count > 0); + + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdDraw, cmb, vertex_count, instance_count, first_vertex, first_instance); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto draw_indexed(const CommandBufferType& cmb, + u32 index_count, + u32 instance_count, + u32 first_index, + i32 vertex_offset, + u32 first_instance) noexcept -> void { + EXPECTS(index_count > 0); + + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdDrawIndexed, + cmb, + index_count, + instance_count, + first_index, + vertex_offset, + first_instance); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto draw_indirect(const CommandBufferType& cmb, + view::Buffer&& buffer, + usize offset, + u32 draw_count, + u32 stride) noexcept -> void { + EXPECTS(draw_count > 0); + + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdDrawIndirect, cmb, buffer, offset, draw_count, stride); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto draw_indexed_indirect(const CommandBufferType& cmb, + view::Buffer&& buffer, + usize offset, + u32 draw_count, + u32 stride) noexcept -> void { + EXPECTS(draw_count > 0); + + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdDrawIndexedIndirect, cmb, buffer, offset, draw_count, stride); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto bind_vertex_buffers(const CommandBufferType& cmb, + std::span&& buffers, + std::span&& offsets) noexcept -> void { + EXPECTS(not std::empty(buffers)); + EXPECTS(std::size(buffers) == std::size(offsets)); + + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto vk_buffers = transform(buffers, vk::monadic::to_vk()); + + vk::call(device_table.vkCmdBindVertexBuffers, + cmb, + 0, + stdr::size(vk_buffers), + stdr::data(vk_buffers), + stdr::data(offsets)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto bind_index_buffer(const CommandBufferType& cmb, + view::Buffer&& buffer, + u64 offset, + bool large_indices) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdBindIndexBuffer, + cmb, + buffer, + offset, + (large_indices) ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto bind_descriptor_sets(const CommandBufferType& cmb, + view::Pipeline&& pipeline, + view::PipelineLayout&& layout, + std::span&& descriptor_sets, + std::span&& dynamic_offsets) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto bind_point = (pipeline.type() == Pipeline::Type::RASTER) ? VK_PIPELINE_BIND_POINT_GRAPHICS + : VK_PIPELINE_BIND_POINT_COMPUTE; + + const auto vk_descriptor_sets = transform(descriptor_sets, vk::monadic::to_vk()); + + vk::call(device_table.vkCmdBindDescriptorSets, + cmb, + bind_point, + layout, + 0, + stdr::size(vk_descriptor_sets), + stdr::data(vk_descriptor_sets), + stdr::size(dynamic_offsets), + stdr::data(dynamic_offsets)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto copy_buffer(const CommandBufferType& cmb, + view::Buffer&& src, + view::Buffer&& dst, + usize size, + u64 src_offset, + u64 dst_offset) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto vk_copy_buffers = into_array_of({ .srcOffset = src_offset, + .dstOffset = dst_offset, + .size = size }); + + vk::call(device_table.vkCmdCopyBuffer, cmb, src, dst, stdr::size(vk_copy_buffers), stdr::data(vk_copy_buffers)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto copy_buffer_to_image(const CommandBufferType& cmb, + view::Buffer&& src, + view::Image&& dst, + std::span&& buffer_image_copies) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto DEFAULT_COPY = into_array_of({ + 0, + 0, + 0, + {}, + { 0, 0, 0 }, + dst.extent() + }); + + if (stdr::empty(buffer_image_copies)) buffer_image_copies = DEFAULT_COPY; + + const auto vk_copy_regions = transform(buffer_image_copies, [](const auto& buffer_image_copy) static noexcept { + const auto image_subresource = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(buffer_image_copy.subresource_layers.aspect_mask), + .mipLevel = buffer_image_copy.subresource_layers.mip_level, + .baseArrayLayer = buffer_image_copy.subresource_layers.base_array_layer, + .layerCount = buffer_image_copy.subresource_layers.layer_count, + }; + + return VkBufferImageCopy { .bufferOffset = buffer_image_copy.buffer_offset, + .bufferRowLength = buffer_image_copy.buffer_row_length, + .bufferImageHeight = buffer_image_copy.buffer_image_height, + .imageSubresource = image_subresource, + .imageOffset = vk::to_vk(buffer_image_copy.offset), + .imageExtent = vk::to_vk(buffer_image_copy.extent) }; + }); + + vk::call(device_table.vkCmdCopyBufferToImage, + cmb, + src, + dst, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + stdr::size(vk_copy_regions), + stdr::data(vk_copy_regions)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto copy_image_to_buffer(const CommandBufferType& cmb, + view::Image&& src, + view::Buffer&& dst, + std::span&& buffer_image_copies) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto DEFAULT_COPY = into_array({ + BufferImageCopy { 0, 0, 0, {}, { 0, 0, 0 }, src.extent() } + }); + + if (stdr::empty(buffer_image_copies)) buffer_image_copies = DEFAULT_COPY; + + const auto vk_copy_regions = transform(buffer_image_copies, [](const auto& buffer_image_copy) static noexcept { + const auto image_subresource = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(buffer_image_copy.subresource_layers.aspect_mask), + .mipLevel = buffer_image_copy.subresource_layers.mip_level, + .baseArrayLayer = buffer_image_copy.subresource_layers.base_array_layer, + .layerCount = buffer_image_copy.subresource_layers.layer_count, + }; + + return VkBufferImageCopy { .bufferOffset = buffer_image_copy.buffer_offset, + .bufferRowLength = buffer_image_copy.buffer_row_length, + .bufferImageHeight = buffer_image_copy.buffer_image_height, + .imageSubresource = image_subresource, + .imageOffset = vk::to_vk(buffer_image_copy.offset), + .imageExtent = vk::to_vk(buffer_image_copy.extent) }; + }); + + vk::call(device_table.vkCmdCopyImageToBuffer, + cmb, + src, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + dst, + stdr::size(vk_copy_regions), + stdr::data(vk_copy_regions)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto copy_image(const CommandBufferType& cmb, + view::Image&& src, + view::Image&& dst, + ImageLayout src_layout, + ImageLayout dst_layout, + const ImageSubresourceLayers& src_subresource_layers, + const ImageSubresourceLayers& dst_subresource_layers, + const math::uextent3& extent) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto vk_src_subresource_layers = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(src_subresource_layers.aspect_mask), + .mipLevel = src_subresource_layers.mip_level, + .baseArrayLayer = src_subresource_layers.base_array_layer, + .layerCount = src_subresource_layers.layer_count + }; + + const auto vk_dst_subresource_layers = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(dst_subresource_layers.aspect_mask), + .mipLevel = dst_subresource_layers.mip_level, + .baseArrayLayer = dst_subresource_layers.base_array_layer, + .layerCount = dst_subresource_layers.layer_count + }; + + const auto vk_regions = into_array({ + VkImageCopy { .srcSubresource = vk_src_subresource_layers, + .srcOffset = { 0, 0, 0 }, + .dstSubresource = vk_dst_subresource_layers, + .dstOffset = { 0, 0, 0 }, + .extent = vk::to_vk(extent) } + }); + + vk::call(device_table.vkCmdCopyImage, + cmb, + src, + vk::to_vk(src_layout), + dst, + vk::to_vk(dst_layout), + stdr::size(vk_regions), + stdr::data(vk_regions)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto resolve_image(const CommandBufferType& cmb, + view::Image&& src, + view::Image&& dst, + ImageLayout src_layout, + ImageLayout dst_layout, + const ImageSubresourceLayers& src_subresource_layers, + const ImageSubresourceLayers& dst_subresource_layers) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto vk_extent = vk::to_vk(dst.extent()); + + const auto vk_src_subresource_layers = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(src_subresource_layers.aspect_mask), + .mipLevel = src_subresource_layers.mip_level, + .baseArrayLayer = src_subresource_layers.base_array_layer, + .layerCount = src_subresource_layers.layer_count + }; + + const auto vk_dst_subresource_layers = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(dst_subresource_layers.aspect_mask), + .mipLevel = dst_subresource_layers.mip_level, + .baseArrayLayer = dst_subresource_layers.base_array_layer, + .layerCount = dst_subresource_layers.layer_count + }; + + const auto vk_regions = into_array({ + VkImageResolve { .srcSubresource = vk_src_subresource_layers, + .srcOffset = { 0, 0, 0 }, + .dstSubresource = vk_dst_subresource_layers, + .dstOffset = { 0, 0, 0 }, + .extent = vk_extent } + }); + + vk::call(device_table.vkCmdResolveImage, + cmb, + src, + vk::to_vk(src_layout), + dst, + vk::to_vk(dst_layout), + stdr::size(vk_regions), + stdr::data(vk_regions)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto blit_image(const CommandBufferType& cmb, + view::Image&& src, + view::Image&& dst, + ImageLayout src_layout, + ImageLayout dst_layout, + std::span&& regions, + Filter filter) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto vk_regions = transform(regions, [](const auto& region) static noexcept { + const auto vk_src_subresource_layers = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(region.src.aspect_mask), + .mipLevel = region.src.mip_level, + .baseArrayLayer = region.src.base_array_layer, + .layerCount = region.src.layer_count + }; + + const auto vk_dst_subresource_layers = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(region.dst.aspect_mask), + .mipLevel = region.dst.mip_level, + .baseArrayLayer = region.dst.base_array_layer, + .layerCount = region.dst.layer_count + }; + + return VkImageBlit { + .srcSubresource = vk_src_subresource_layers, + .srcOffsets = { vk::to_vk(region.src_offset.position), + vk::to_vk(region.src_offset.extent) }, + .dstSubresource = vk_dst_subresource_layers, + .dstOffsets = { vk::to_vk(region.dst_offset.position), + vk::to_vk(region.dst_offset.extent) }, + }; + }); + + vk::call(device_table.vkCmdBlitImage, + cmb, + vk::to_vk(src), + vk::to_vk(src_layout), + vk::to_vk(dst), + vk::to_vk(dst_layout), + stdr::size(vk_regions), + stdr::data(vk_regions), + vk::to_vk(filter)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto transition_image_layout(const CommandBufferType& cmb, + view::Image&& image, + ImageLayout src_layout, + ImageLayout dst_layout, + const ImageSubresourceRange& subresource_range) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto vk_src_layout = vk::to_vk(src_layout); + const auto vk_dst_layout = vk::to_vk(dst_layout); + + const auto& src_access = OLD_LAYOUT_ACCESS_MAP.find(vk_src_layout); + const auto& dst_access = NEW_LAYOUT_ACCESS_MAP.find(vk_dst_layout); + + const auto src_stage = src_access->second.second; + const auto dst_stage = dst_access->second.second; + + const auto vk_subresource_range = VkImageSubresourceRange { + .aspectMask = vk::to_vk(subresource_range.aspect_mask), + .baseMipLevel = subresource_range.base_mip_level, + .levelCount = subresource_range.level_count, + .baseArrayLayer = subresource_range.base_array_layer, + .layerCount = subresource_range.layer_count, + }; + + const auto barriers = into_array({ + VkImageMemoryBarrier { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = src_access->second.first, + .dstAccessMask = dst_access->second.first, + .oldLayout = vk_src_layout, + .newLayout = vk_dst_layout, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = vk::to_vk(image), + .subresourceRange = vk_subresource_range + + }, + }); + + vk::call(device_table.vkCmdPipelineBarrier, + cmb, + src_stage, + dst_stage, + 0, + 0, + nullptr, + 0, + nullptr, + stdr::size(barriers), + stdr::data(barriers)); + } - const auto color_attachments = info.color_attachments | stdv::transform(to_vk_attachment) | stdr::to(); - const auto depth_attachment = info.depth_attachment ? to_vk_attachment(*info.depth_attachment) - : VkRenderingAttachmentInfo {}; - const auto stencil_attachment = info.stencil_attachment ? to_vk_attachment(*info.stencil_attachment) - : VkRenderingAttachmentInfo {}; - - const auto rendering_info = VkRenderingInfo { - .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, - .pNext = nullptr, - .flags = as((secondary) ? VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT : 0), - .renderArea = to_vk(info.render_area), - .layerCount = info.layer_count, - .viewMask = info.view_mask, - .colorAttachmentCount = as(stdr::size(color_attachments)), - .pColorAttachments = stdr::data(color_attachments), - .pDepthAttachment = info.depth_attachment ? &depth_attachment : nullptr, - .pStencilAttachment = info.stencil_attachment ? &stencil_attachment : nullptr, + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto pipeline_barrier(const CommandBufferType& cmb, + PipelineStageFlag src_mask, + PipelineStageFlag dst_mask, + DependencyFlag dependency, + std::span&& memory_barriers, + std::span&& buffer_memory_barriers, + std::span&& image_memory_barriers) noexcept -> void { + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto vk_memory_barriers = transform(memory_barriers, + [](const auto& barrier) static noexcept -> decltype(auto) { + return VkMemoryBarrier { + .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = vk::to_vk(barrier.src), + .dstAccessMask = vk::to_vk(barrier.dst), + }; + }); + const auto vk_buffer_memory_barriers = transform(buffer_memory_barriers, + [](const auto& barrier) static noexcept -> decltype(auto) { + return VkBufferMemoryBarrier { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = vk::to_vk(barrier.src), + .dstAccessMask = vk::to_vk(barrier.dst), + .srcQueueFamilyIndex = barrier.src_queue_family_index, + .dstQueueFamilyIndex = barrier.dst_queue_family_index, + .buffer = vk::to_vk(barrier.buffer), + .offset = barrier.offset, + .size = barrier.size + }; + }); + const auto + vk_image_memory_barriers = transform(image_memory_barriers, + [](const auto& barrier) static noexcept -> decltype(auto) { + const auto vk_subresource_range = VkImageSubresourceRange { + .aspectMask = vk::to_vk(barrier.range + .aspect_mask), + .baseMipLevel = barrier.range.base_mip_level, + .levelCount = barrier.range.level_count, + .baseArrayLayer = barrier.range.base_array_layer, + .layerCount = barrier.range.layer_count + }; + + return VkImageMemoryBarrier { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = vk::to_vk(barrier.src), + .dstAccessMask = vk::to_vk(barrier.dst), + .oldLayout = vk::to_vk(barrier.old_layout), + .newLayout = vk::to_vk(barrier.new_layout), + .srcQueueFamilyIndex = barrier.src_queue_family_index, + .dstQueueFamilyIndex = barrier.dst_queue_family_index, + .image = vk::to_vk(barrier.image), + .subresourceRange = vk_subresource_range + }; + }); + + vk::call(device_table.vkCmdPipelineBarrier, + cmb, + vk::to_vk(src_mask), + vk::to_vk(dst_mask), + vk::to_vk(dependency), + stdr::size(vk_memory_barriers), + stdr::data(vk_memory_barriers), + stdr::size(vk_buffer_memory_barriers), + stdr::data(vk_buffer_memory_barriers), + stdr::size(vk_image_memory_barriers), + stdr::data(vk_image_memory_barriers)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto push_constants(const CommandBufferType& cmb, + view::PipelineLayout&& pipeline_layout, + ShaderStageFlag stage, + std::span&& data, + u32 offset) noexcept -> void { + EXPECTS(not std::empty(data)); + + const auto& state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdPushConstants, + cmb, + vk::to_vk(pipeline_layout), + vk::to_vk(stage), + offset, + stdr::size(data), + stdr::data(data)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto execute_sub_command_buffers(const CommandBufferType& cmb, + std::span&& commandbuffers) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + constexpr auto expects_secondary = [](auto&& cmb) noexcept -> decltype(auto) { + EXPECTS(cmb.level() == CommandBufferLevel::SECONDARY); + return cmb; + }; + + const auto vk_command_buffers = transform(commandbuffers, cmonadic::map(expects_secondary, vk::monadic::to_vk())); + vk::call(device_table.vkCmdExecuteCommands, cmb, stdr::size(vk_command_buffers), stdr::data(vk_command_buffers)); + } }; + } // namespace - vk_call(m_vk_device_table->vkCmdBeginRenderingKHR, m_vk_handle, &rendering_info); - return *this; + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::reset() noexcept -> Expected { + return CommandBufferAPI::reset(*this); } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::begin_render_pass(const RenderPass& render_pass, - const FrameBuffer& framebuffer, - std::span clear_values, - bool secondary_commandbuffers) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - const auto vk_clear_values = clear_values - | stdv::transform(core::monadic::either( - [](const ClearColor& clear_color) static noexcept -> decltype(auto) { - return VkClearValue { - .color = VkClearColorValue { .float32 = { clear_color.color.r, - clear_color.color.b, - clear_color.color.g, - clear_color.color.a } }, - }; - }, - [](const ClearDepthStencil& clear_depth_stencil) static noexcept -> decltype(auto) { - return VkClearValue { - .depthStencil = VkClearDepthStencilValue { .depth = clear_depth_stencil.depth, - .stencil = clear_depth_stencil - .stencil }, - }; - })) - | stdr::to(); - - const auto begin_info = VkRenderPassBeginInfo { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .pNext = nullptr, - .renderPass = to_vk(render_pass), - .framebuffer = to_vk(framebuffer), - .renderArea = VkRect2D { .offset = { 0, 0 }, .extent = { framebuffer.extent().width, framebuffer.extent().height } }, - .clearValueCount = as(stdr::size(vk_clear_values)), - .pClearValues = stdr::data(vk_clear_values), - }; + auto CommandBuffer::begin(bool one_time_submit, InheritanceInfo inheritance_info_variant) noexcept -> Expected { + return CommandBufferAPI::begin(*this, one_time_submit, std::move(inheritance_info_variant)); + } - const auto subpass_content = secondary_commandbuffers ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS - : VK_SUBPASS_CONTENTS_INLINE; + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::end() noexcept -> Expected { + return CommandBufferAPI::end(*this); + } - vk_call(m_vk_device_table->vkCmdBeginRenderPass, m_vk_handle, &begin_info, subpass_content); + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::insert_debug_label(std::string_view name, const fcolor_rgb& color) const noexcept + -> const CommandBuffer& { + CommandBufferAPI::insert_debug_label(*this, std::move(name), color); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::set_viewport(u32 first_viewport, std::span viewports) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - const auto vk_viewports = viewports | stdv::transform(monadic::to_vk()) | stdr::to(); - - vk_call(m_vk_device_table->vkCmdSetViewport, - m_vk_handle, - first_viewport, - stdr::size(vk_viewports), - stdr::data(vk_viewports)); + auto CommandBuffer::end_debug_region() const noexcept -> const CommandBuffer& { + CommandBufferAPI::end_debug_region(*this); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::set_scissor(u32 first_scissor, std::span scissors) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); + auto CommandBuffer::begin_rendering(const RenderingInfo& info, bool secondary) const noexcept -> const CommandBuffer& { + CommandBufferAPI::begin_rendering(*this, info, secondary); + return *this; + } - const auto vk_scissors = scissors | stdv::transform(monadic::to_vk()) | stdr::to(); + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::begin_render_pass(view::RenderPass render_pass, + view::FrameBuffer framebuffer, + std::span clear_values, + bool secondary_commandbuffers) const noexcept -> const CommandBuffer& { + CommandBufferAPI::begin_render_pass(*this, + std::move(render_pass), + std::move(framebuffer), + std::move(clear_values), + secondary_commandbuffers); + return *this; + } - vk_call(m_vk_device_table->vkCmdSetScissor, m_vk_handle, first_scissor, stdr::size(vk_scissors), stdr::data(vk_scissors)); + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::next_subpass() const noexcept -> const CommandBuffer& { + CommandBufferAPI::next_subpass(*this); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::bind_vertex_buffers(std::span> buffers, std::span offsets) noexcept - -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - EXPECTS(not std::empty(buffers)); - EXPECTS(std::size(buffers) == std::size(offsets)); + auto CommandBuffer::end_render_pass() const noexcept -> const CommandBuffer& { + CommandBufferAPI::end_render_pass(*this); + return *this; + } - const auto vk_buffers = buffers | stdv::transform(monadic::to_vk()) | stdr::to(); + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::bind_pipeline(view::Pipeline pipeline) const noexcept -> const CommandBuffer& { + CommandBufferAPI::bind_pipeline(*this, std::move(pipeline)); + return *this; + } - vk_call(m_vk_device_table->vkCmdBindVertexBuffers, - m_vk_handle, - 0, - stdr::size(vk_buffers), - stdr::data(vk_buffers), - stdr::data(offsets)); + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::set_viewport(u32 first_viewport, std::span viewports) const noexcept + -> const CommandBuffer& { + CommandBufferAPI::set_viewport(*this, first_viewport, std::move(viewports)); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::bind_descriptor_sets(const Pipeline& pipeline, - const PipelineLayout& layout, - std::span> descriptor_sets, - std::span dynamic_offsets) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); + auto CommandBuffer::set_scissor(u32 first_scissor, std::span scissors) const noexcept -> const CommandBuffer& { + CommandBufferAPI::set_scissor(*this, first_scissor, std::move(scissors)); + return *this; + } - const auto bind_point = (pipeline.type() == Pipeline::Type::RASTER) ? VK_PIPELINE_BIND_POINT_GRAPHICS - : VK_PIPELINE_BIND_POINT_COMPUTE; + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::set_line_width(f32 width) const noexcept -> const CommandBuffer& { + CommandBufferAPI::set_line_width(*this, width); + return *this; + } - const auto vk_descriptor_sets = descriptor_sets | stdv::transform(monadic::to_vk()) | stdr::to(); + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::set_depth_bias(f32 constant_factor, f32 clamp, f32 slope_factor) const noexcept -> const CommandBuffer& { + CommandBufferAPI::set_depth_bias(*this, constant_factor, clamp, slope_factor); + return *this; + } - vk_call(m_vk_device_table->vkCmdBindDescriptorSets, - m_vk_handle, - bind_point, - to_vk(layout), - 0, - stdr::size(vk_descriptor_sets), - stdr::data(vk_descriptor_sets), - stdr::size(dynamic_offsets), - stdr::data(dynamic_offsets)); + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::set_blend_constants(std::span constants) const noexcept -> const CommandBuffer& { + CommandBufferAPI::set_blend_constants(*this, std::move(constants)); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::copy_buffer(const Buffer& src, const Buffer& dst, usize size, u64 src_offset, u64 dst_offset) noexcept - -> CommandBuffer& { - const auto vk_copy_buffers = std::array { - VkBufferCopy { .srcOffset = src_offset, .dstOffset = dst_offset, .size = size } - }; + auto CommandBuffer::set_depth_bounds(u32 min, u32 max) const noexcept -> const CommandBuffer& { + CommandBufferAPI::set_depth_bounds(*this, min, max); + return *this; + } - vk_call(m_vk_device_table->vkCmdCopyBuffer, - m_vk_handle, - to_vk(src), - to_vk(dst), - stdr::size(vk_copy_buffers), - stdr::data(vk_copy_buffers)); + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::set_stencil_compare_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBuffer& { + CommandBufferAPI::set_stencil_compare_mask(*this, face, mask); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::copy_buffer_to_image(const Buffer& src, - const Image& dst, - std::span buffer_image_copies) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); + auto CommandBuffer::set_stencil_write_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBuffer& { + CommandBufferAPI::set_stencil_write_mask(*this, face, mask); + return *this; + } - const auto DEFAULT_COPY = std::array { - BufferImageCopy { 0, 0, 0, {}, { 0, 0, 0 }, dst.extent() } - }; + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::set_stencil_reference(StencilFaceFlag face, u32 reference) const noexcept -> const CommandBuffer& { + CommandBufferAPI::set_stencil_reference(*this, face, reference); + return *this; + } - if (stdr::empty(buffer_image_copies)) buffer_image_copies = DEFAULT_COPY; + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::dispatch(u32 group_count_x, u32 group_count_y, u32 group_count_z) const noexcept -> void { + CommandBufferAPI::dispatch(*this, group_count_x, group_count_y, group_count_z); + return *this; + } - const auto vk_copy_regions = buffer_image_copies - | stdv::transform([](auto&& buffer_image_copy) noexcept { - const auto image_subresource = VkImageSubresourceLayers { - .aspectMask = to_vk(buffer_image_copy.subresource_layers - .aspect_mask), - .mipLevel = buffer_image_copy.subresource_layers.mip_level, - .baseArrayLayer = buffer_image_copy.subresource_layers.base_array_layer, - .layerCount = buffer_image_copy.subresource_layers.layer_count, - }; + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::draw(u32 vertex_count, u32 instance_count, u32 first_vertex, u32 first_instance) const noexcept -> void { + CommandBufferAPI::draw(*this, vertex_count, instance_count, first_vertex, first_instance); + return *this; + } - return VkBufferImageCopy { .bufferOffset = buffer_image_copy.buffer_offset, - .bufferRowLength = buffer_image_copy.buffer_row_length, - .bufferImageHeight = buffer_image_copy.buffer_image_height, - .imageSubresource = image_subresource, - .imageOffset = to_vk(buffer_image_copy.offset), - .imageExtent = to_vk(buffer_image_copy.extent) }; - }) - | stdr::to(); + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::draw_indexed(u32 index_count, u32 instance_count, u32 first_index, i32 vertex_offset, u32 first_instance) + const noexcept -> void { + CommandBufferAPI::draw_indexed(*this, index_count, instance_count, first_index, vertex_offset, first_instance); + return *this; + } - vk_call(m_vk_device_table->vkCmdCopyBufferToImage, - m_vk_handle, - to_vk(src), - to_vk(dst), - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - stdr::size(vk_copy_regions), - stdr::data(vk_copy_regions)); + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::draw_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept -> void { + CommandBufferAPI::draw_indirect(*this, std::move(buffer), offset, draw_count, stride); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::copy_image_to_buffer(const Image& src, - const Buffer& dst, - std::span buffer_image_copies) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); + auto CommandBuffer::draw_indexed_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept + -> void { + CommandBufferAPI::draw_indexed_indirect(*this, std::move(buffer), offset, draw_count, stride); + return *this; + } - const auto DEFAULT_COPY = std::array { - BufferImageCopy { 0, 0, 0, {}, { 0, 0, 0 }, src.extent() } - }; + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::bind_vertex_buffers(std::span buffers, std::span offsets) const noexcept { + CommandBufferAPI::bind_vertex_buffers(*this, std::move(buffers), std::move(offsets)); + return *this; + } - if (stdr::empty(buffer_image_copies)) buffer_image_copies = DEFAULT_COPY; + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::bind_descriptor_sets(view::Pipeline pipeline, + view::PipelineLayout layout, + std::span descriptor_sets, + std::span dynamic_offsets) const noexcept -> const CommandBuffer& { + CommandBufferAPI::bind_descriptor_sets(*this, + std::move(pipeline), + std::move(layout), + std::move(descriptor_sets), + std::move(dynamic_offsets)); + return *this; + } - const auto vk_copy_regions = buffer_image_copies - | stdv::transform([](auto&& buffer_image_copy) noexcept { - const auto image_subresource = VkImageSubresourceLayers { - .aspectMask = to_vk(buffer_image_copy.subresource_layers - .aspect_mask), - .mipLevel = buffer_image_copy.subresource_layers.mip_level, - .baseArrayLayer = buffer_image_copy.subresource_layers.base_array_layer, - .layerCount = buffer_image_copy.subresource_layers.layer_count, - }; + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::copy_buffer(view::Buffer src, view::Buffer dst, usize size, u64 src_offset, u64 dst_offset) const noexcept + -> const CommandBuffer& { + CommandBufferAPI::copy_buffer(*this, std::move(src), std::move(dst), size, src_offset, dst_offset); + return *this; + } - return VkBufferImageCopy { .bufferOffset = buffer_image_copy.buffer_offset, - .bufferRowLength = buffer_image_copy.buffer_row_length, - .bufferImageHeight = buffer_image_copy.buffer_image_height, - .imageSubresource = image_subresource, - .imageOffset = to_vk(buffer_image_copy.offset), - .imageExtent = to_vk(buffer_image_copy.extent) }; - }) - | stdr::to(); + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::copy_buffer_to_image(view::Buffer src, + view::Image dst, + std::span& buffer_image_copies) const noexcept + -> const CommandBuffer& { + CommandBufferAPI::copy_buffer_to_image(*this, std::move(src), std::move(dst), std::move(buffer_image_copies)); + return *this; + } - vk_call(m_vk_device_table->vkCmdCopyImageToBuffer, - m_vk_handle, - to_vk(src), - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - to_vk(dst), - stdr::size(vk_copy_regions), - stdr::data(vk_copy_regions)); + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::copy_image_to_buffer(view::Image src, + view::Buffer dst, + std::span buffer_image_copies) const noexcept + -> const CommandBuffer& { + CommandBufferAPI::copy_image_to_buffer(*this, std::move(src), std::move(dst), std::move(buffer_image_copies)); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::copy_image(const Image& src, - const Image& dst, + auto CommandBuffer::copy_image(view::Image src, + view::Image dst, ImageLayout src_layout, ImageLayout dst_layout, const ImageSubresourceLayers& src_subresource_layers, const ImageSubresourceLayers& dst_subresource_layers, - const math::uextent3& extent) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - const auto vk_src_subresource_layers = VkImageSubresourceLayers { - .aspectMask = to_vk(src_subresource_layers.aspect_mask), - .mipLevel = src_subresource_layers.mip_level, - .baseArrayLayer = src_subresource_layers.base_array_layer, - .layerCount = src_subresource_layers.layer_count - }; - - const auto vk_dst_subresource_layers = VkImageSubresourceLayers { - .aspectMask = to_vk(dst_subresource_layers.aspect_mask), - .mipLevel = dst_subresource_layers.mip_level, - .baseArrayLayer = dst_subresource_layers.base_array_layer, - .layerCount = dst_subresource_layers.layer_count - }; - - const auto vk_regions = std::array { - VkImageCopy { .srcSubresource = vk_src_subresource_layers, - .srcOffset = { 0, 0, 0 }, - .dstSubresource = vk_dst_subresource_layers, - .dstOffset = { 0, 0, 0 }, - .extent = to_vk(extent) } - }; - - vk_call(m_vk_device_table->vkCmdCopyImage, - m_vk_handle, - to_vk(src), - to_vk(src_layout), - to_vk(dst), - to_vk(dst_layout), - stdr::size(vk_regions), - stdr::data(vk_regions)); + const math::uextent3& extent) const noexcept -> const CommandBuffer& { + CommandBufferAPI::copy_image(*this, + std::move(src), + std::move(dst), + src_layout, + dst_layout, + src_subresource_layers, + dst_subresource_layers, + extent); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::resolve_image(const Image& src, - const Image& dst, + auto CommandBuffer::resolve_image(view::Image src, + view::Image dst, ImageLayout src_layout, ImageLayout dst_layout, const ImageSubresourceLayers& src_subresource_layers, - const ImageSubresourceLayers& dst_subresource_layers) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - const auto vk_extent = to_vk(dst.extent()); - - const auto vk_src_subresource_layers = VkImageSubresourceLayers { - .aspectMask = to_vk(src_subresource_layers.aspect_mask), - .mipLevel = src_subresource_layers.mip_level, - .baseArrayLayer = src_subresource_layers.base_array_layer, - .layerCount = src_subresource_layers.layer_count - }; - - const auto vk_dst_subresource_layers = VkImageSubresourceLayers { - .aspectMask = to_vk(dst_subresource_layers.aspect_mask), - .mipLevel = dst_subresource_layers.mip_level, - .baseArrayLayer = dst_subresource_layers.base_array_layer, - .layerCount = dst_subresource_layers.layer_count - }; - - const auto vk_regions = std::array { - VkImageResolve { .srcSubresource = vk_src_subresource_layers, - .srcOffset = { 0, 0, 0 }, - .dstSubresource = vk_dst_subresource_layers, - .dstOffset = { 0, 0, 0 }, - .extent = vk_extent } - }; - - vk_call(m_vk_device_table->vkCmdResolveImage, - m_vk_handle, - to_vk(src), - to_vk(src_layout), - to_vk(dst), - to_vk(dst_layout), - stdr::size(vk_regions), - stdr::data(vk_regions)); + const ImageSubresourceLayers& dst_subresource_layers) const noexcept + -> const CommandBuffer& { + CommandBufferAPI::resolve_image(*this, + std::move(src), + std::move(dst), + src_layout, + dst_layout, + src_subresource_layers, + dst_subresource_layers); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::blit_image(const Image& src, - const Image& dst, + auto CommandBuffer::blit_image(view::Image src, + view::Image dst, ImageLayout src_layout, ImageLayout dst_layout, std::span regions, - Filter filter) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - const auto vk_regions = regions - | stdv::transform([](auto&& region) noexcept { - const auto vk_src_subresource_layers = VkImageSubresourceLayers { - .aspectMask = to_vk(region.src.aspect_mask), - .mipLevel = region.src.mip_level, - .baseArrayLayer = region.src.base_array_layer, - .layerCount = region.src.layer_count - }; - - const auto vk_dst_subresource_layers = VkImageSubresourceLayers { - .aspectMask = to_vk(region.dst.aspect_mask), - .mipLevel = region.dst.mip_level, - .baseArrayLayer = region.dst.base_array_layer, - .layerCount = region.dst.layer_count - }; - - return VkImageBlit { - .srcSubresource = vk_src_subresource_layers, - .srcOffsets = { to_vk(region.src_offset.position), - to_vk(region.src_offset.extent) }, - .dstSubresource = vk_dst_subresource_layers, - .dstOffsets = { to_vk(region.dst_offset.position), - to_vk(region.dst_offset.extent) }, - }; - }) - | stdr::to(); - - vk_call(m_vk_device_table->vkCmdBlitImage, - m_vk_handle, - to_vk(src), - to_vk(src_layout), - to_vk(dst), - to_vk(dst_layout), - stdr::size(vk_regions), - stdr::data(vk_regions), - to_vk(filter)); + Filter filter) const noexcept -> const CommandBuffer& { + CommandBufferAPI::blit_image(*this, std::move(src), std::move(dst), src_layout, dst_layout, regions, filter); return *this; } @@ -574,53 +1459,9 @@ namespace stormkit::gpu { auto CommandBuffer::transition_image_layout(const Image& image, ImageLayout src_layout, ImageLayout dst_layout, - const ImageSubresourceRange& subresource_range) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - const auto vk_src_layout = to_vk(src_layout); - const auto vk_dst_layout = to_vk(dst_layout); - - const auto& src_access = OLD_LAYOUT_ACCESS_MAP.find(vk_src_layout); - const auto& dst_access = NEW_LAYOUT_ACCESS_MAP.find(vk_dst_layout); - - const auto src_stage = src_access->second.second; - const auto dst_stage = dst_access->second.second; - - const auto vk_subresource_range = VkImageSubresourceRange { - .aspectMask = to_vk(subresource_range.aspect_mask), - .baseMipLevel = subresource_range.base_mip_level, - .levelCount = subresource_range.level_count, - .baseArrayLayer = subresource_range.base_array_layer, - .layerCount = subresource_range.layer_count, - }; - - const auto barriers = std::array { - VkImageMemoryBarrier { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = src_access->second.first, - .dstAccessMask = dst_access->second.first, - .oldLayout = vk_src_layout, - .newLayout = vk_dst_layout, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .image = to_vk(image), - .subresourceRange = vk_subresource_range - - }, - }; - - vk_call(m_vk_device_table->vkCmdPipelineBarrier, - m_vk_handle, - src_stage, - dst_stage, - 0, - 0, - nullptr, - 0, - nullptr, - stdr::size(barriers), - stdr::data(barriers)); + const ImageSubresourceRange& subresource_range) const noexcept + -> const CommandBuffer& { + CommandBufferAPI::transition_image_layout(*this, std::move(image), src_layout, dst_layout, subresource_range); return *this; } @@ -631,112 +1472,380 @@ namespace stormkit::gpu { DependencyFlag dependency, std::span memory_barriers, std::span buffer_memory_barriers, - std::span image_memory_barriers) noexcept -> CommandBuffer& { - const auto vk_memory_barriers = memory_barriers - | stdv::transform([](auto&& barrier) noexcept -> decltype(auto) { - return VkMemoryBarrier { - .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = to_vk(barrier.src), - .dstAccessMask = to_vk(barrier.dst), - }; - }) - | stdr::to(); - - const auto vk_buffer_memory_barriers = buffer_memory_barriers - | stdv::transform([](auto&& barrier) noexcept -> decltype(auto) { - return VkBufferMemoryBarrier { - .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = to_vk(barrier.src), - .dstAccessMask = to_vk(barrier.dst), - .srcQueueFamilyIndex = barrier.src_queue_family_index, - .dstQueueFamilyIndex = barrier.dst_queue_family_index, - .buffer = to_vk(barrier.buffer), - .offset = barrier.offset, - .size = barrier.size - }; - }) - | stdr::to(); - - const auto vk_image_memory_barriers = image_memory_barriers - | stdv::transform([](auto&& barrier) noexcept -> decltype(auto) { - const auto vk_subresource_range = VkImageSubresourceRange { - .aspectMask = to_vk(barrier.range.aspect_mask), - .baseMipLevel = barrier.range.base_mip_level, - .levelCount = barrier.range.level_count, - .baseArrayLayer = barrier.range.base_array_layer, - .layerCount = barrier.range.layer_count - }; - - return VkImageMemoryBarrier { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = to_vk(barrier.src), - .dstAccessMask = to_vk(barrier.dst), - .oldLayout = to_vk(barrier.old_layout), - .newLayout = to_vk(barrier.new_layout), - .srcQueueFamilyIndex = barrier.src_queue_family_index, - .dstQueueFamilyIndex = barrier.dst_queue_family_index, - .image = to_vk(barrier.image), - .subresourceRange = vk_subresource_range - }; - }) - | stdr::to(); - - vk_call(m_vk_device_table->vkCmdPipelineBarrier, - m_vk_handle, - to_vk(src_mask), - to_vk(dst_mask), - to_vk(dependency), - stdr::size(vk_memory_barriers), - stdr::data(vk_memory_barriers), - stdr::size(vk_buffer_memory_barriers), - stdr::data(vk_buffer_memory_barriers), - stdr::size(vk_image_memory_barriers), - stdr::data(vk_image_memory_barriers)); + std::span image_memory_barriers) const noexcept + -> const CommandBuffer& { + CommandBufferAPI::pipeline_barrier(*this, + src_mask, + dst_mask, + dependency, + std::move(memory_barriers), + std::move(buffer_memory_barriers), + std::move(image_memory_barriers)); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::push_constants(const PipelineLayout& pipeline_layout, - ShaderStageFlag stage, - std::span data, - u32 offset) noexcept -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - EXPECTS(not std::empty(data)); - - vk_call(m_vk_device_table->vkCmdPushConstants, - m_vk_handle, - to_vk(pipeline_layout), - to_vk(stage), - offset, - stdr::size(data), - stdr::data(data)); + auto CommandBuffer::push_constants(const view::PipelineLayout& pipeline_layout, + ShaderStageFlag stage, + std::span data, + u32 offset) const noexcept -> const CommandBuffer& { + CommandBufferAPI::push_constants(*this, std::move(pipeline_layout), stage, std::move(data), offset); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::execute_sub_command_buffers(std::span> commandbuffers) noexcept - -> CommandBuffer& { - EXPECTS(m_state == State::RECORDING); - - constexpr auto EXPECTS_secondary = [](auto&& cmb) noexcept -> decltype(auto) { - EXPECTS(cmb.level() == CommandBufferLevel::SECONDARY); - return cmb; - }; - - const auto vk_command_buffers = commandbuffers - | stdv::transform(core::monadic::unref()) - | stdv::transform(core::monadic::map(EXPECTS_secondary, monadic::to_vk())) - | stdr::to(); - - vk_call(m_vk_device_table->vkCmdExecuteCommands, - m_vk_handle, - stdr::size(vk_command_buffers), - stdr::data(vk_command_buffers)); + auto CommandBuffer::execute_sub_command_buffers(std::span command_buffers) const noexcept + -> CommandBuffer { + CommandBufferAPI::execute_sub_command_buffers(*this, std::move(command_buffers)); return *this; } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::do_init(PrivateTag, + view::CommandPool pool, + CommandBufferLevel level, + VkCommandBuffer&& handle, + Deleter&& deleter) const noexcept -> Expected { + m_pool = pool; + m_level = level; + + m_vk_handle = handle; + m_deleter = std::move(deleter); + } + + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::reset() const noexcept -> Expected { + return CommandBufferAPI::reset(*this); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::begin(bool one_time_submit, InheritanceInfo inheritance_info_variant) const noexcept + -> Expected { + return CommandBufferAPI::begin(*this, one_time_submit, std::move(inheritance_info_variant)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::end() const noexcept -> Expected { + return CommandBufferAPI::end(*this); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::insert_debug_label(std::string_view name, const fcolor_rgb& color) const noexcept + -> const CommandBuffer& { + CommandBufferAPI::insert_debug_label(*this, std::move(name), color); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::end_debug_region() const noexcept -> const CommandBuffer& { + CommandBufferAPI::end_debug_region(*this); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::begin_rendering(const RenderingInfo& info, bool secondary) const noexcept -> const CommandBuffer& { + CommandBufferAPI::begin_rendering(*this, info, secondary); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::begin_render_pass(const RenderPass& render_pass, + const FrameBuffer& framebuffer, + std::span clear_values, + bool secondary_commandbuffers) const noexcept -> const CommandBuffer& { + CommandBufferAPI::begin_render_pass(*this, + std::move(render_pass), + std::move(framebuffer), + std::move(clear_values), + secondary_commandbuffers); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::next_subpass() const noexcept -> const CommandBuffer& { + CommandBufferAPI::next_subpass(*this); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::end_render_pass() const noexcept -> const CommandBuffer& { + CommandBufferAPI::end_render_pass(*this); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::bind_pipeline(view::Pipeline pipeline) const noexcept -> const CommandBuffer& { + CommandBufferAPI::bind_pipeline(*this, std::move(pipeline)); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::set_viewport(u32 first_viewport, std::span viewports) const noexcept + -> const CommandBuffer& { + CommandBufferAPI::set_viewport(*this, first_viewport, std::move(viewports)); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::set_scissor(u32 first_scissor, std::span scissors) const noexcept + -> const CommandBuffer& { + CommandBufferAPI::set_scissor(*this, first_scissor, std::move(scissors)); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::set_line_width(f32 width) const noexcept -> const CommandBuffer& { + CommandBufferAPI::set_line_width(*this, width); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::set_depth_bias(f32 constant_factor, f32 clamp, f32 slope_factor) const noexcept + -> const CommandBuffer& { + CommandBufferAPI::set_depth_bias(*this, constant_factor, clamp, slope_factor); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::set_blend_constants(std::span constants) const noexcept -> const CommandBuffer& { + CommandBufferAPI::set_blend_constants(*this, std::move(constants)); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::set_depth_bounds(u32 min, u32 max) const noexcept -> const CommandBuffer& { + CommandBufferAPI::set_depth_bounds(*this, min, max); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::set_stencil_compare_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBuffer& { + CommandBufferAPI::set_stencil_compare_mask(*this, face, mask); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::set_stencil_write_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBuffer& { + CommandBufferAPI::set_stencil_write_mask(*this, face, mask); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::set_stencil_reference(StencilFaceFlag face, u32 reference) const noexcept -> const CommandBuffer& { + CommandBufferAPI::set_stencil_reference(*this, face, reference); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::dispatch(u32 group_count_x, u32 group_count_y, u32 group_count_z) const noexcept -> void { + CommandBufferAPI::dispatch(*this, group_count_x, group_count_y, group_count_z); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::draw(u32 vertex_count, u32 instance_count, u32 first_vertex, u32 first_instance) const noexcept + -> void { + CommandBufferAPI::draw(*this, vertex_count, instance_count, first_vertex, first_instance); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::draw_indexed(u32 index_count, + u32 instance_count, + u32 first_index, + i32 vertex_offset, + u32 first_instance) const noexcept -> void { + CommandBufferAPI::draw_indexed(*this, index_count, instance_count, first_index, vertex_offset, first_instance); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::draw_indirect(const Buffer& buffer, usize offset, u32 draw_count, u32 stride) const noexcept -> void { + CommandBufferAPI::draw_indirect(*this, std::move(buffer), offset, draw_count, stride); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::draw_indexed_indirect(const Buffer& buffer, usize offset, u32 draw_count, u32 stride) const noexcept + -> void { + CommandBufferAPI::draw_indexed_indirect(*this, std::move(buffer), offset, draw_count, stride); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::bind_vertex_buffers(std::span buffers, std::span offsets) const noexcept { + CommandBufferAPI::bind_vertex_buffers(*this, std::move(buffers), std::move(offsets)); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::bind_descriptor_sets(const Pipeline& pipeline, + const PipelineLayout& layout, + std::span descriptor_sets, + std::span dynamic_offsets) const noexcept -> const CommandBuffer& { + CommandBufferAPI::bind_descriptor_sets(*this, + std::move(pipeline), + std::move(layout), + std::move(descriptor_sets), + std::move(dynamic_offsets)); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::copy_buffer(const Buffer& src, const Buffer& dst, usize size, u64 src_offset, u64 dst_offset) + const noexcept -> const CommandBuffer& { + CommandBufferAPI::copy_buffer(*this, src, dst, size, src_offset, dst_offset); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::copy_buffer_to_image(const Buffer& src, + const Image& dst, + std::span& buffer_image_copies) const noexcept + -> const CommandBuffer& { + CommandBufferAPI::copy_buffer_to_image(*this, std::move(src), std::move(dst), std::move(buffer_image_copies)); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::copy_image_to_buffer(const Image& src, + const Buffer& dst, + std::span buffer_image_copies) const noexcept + -> const CommandBuffer& { + CommandBufferAPI::copy_image_to_buffer(*this, std::move(src), std::move(dst), std::move(buffer_image_copies)); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::copy_image(const Image& src, + const Image& dst, + ImageLayout src_layout, + ImageLayout dst_layout, + const ImageSubresourceLayers& src_subresource_layers, + const ImageSubresourceLayers& dst_subresource_layers, + const math::uextent3& extent) const noexcept -> const CommandBuffer& { + CommandBufferAPI::copy_image(*this, + std::move(src), + std::move(dst), + src_layout, + dst_layout, + src_subresource_layers, + dst_subresource_layers, + extent); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::resolve_image(const Image& src, + const Image& dst, + ImageLayout src_layout, + ImageLayout dst_layout, + const ImageSubresourceLayers& src_subresource_layers, + const ImageSubresourceLayers& dst_subresource_layers) const noexcept + -> const CommandBuffer& { + CommandBufferAPI::resolve_image(*this, + std::move(src), + std::move(dst), + src_layout, + dst_layout, + src_subresource_layers, + dst_subresource_layers); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::blit_image(const Image& src, + const Image& dst, + ImageLayout src_layout, + ImageLayout dst_layout, + std::span regions, + Filter filter) const noexcept -> const CommandBuffer& { + CommandBufferAPI::blit_image(*this, std::move(src), std::move(dst), src_layout, dst_layout, regions, filter); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::transition_image_layout(const Image& image, + ImageLayout src_layout, + ImageLayout dst_layout, + const ImageSubresourceRange& subresource_range) const noexcept + -> const CommandBuffer& { + CommandBufferAPI::transition_image_layout(*this, image, src_layout, dst_layout, subresource_range); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::pipeline_barrier(PipelineStageFlag src_mask, + PipelineStageFlag dst_mask, + DependencyFlag dependency, + std::span memory_barriers, + std::span buffer_memory_barriers, + std::span image_memory_barriers) const noexcept + -> const CommandBuffer& { + CommandBufferAPI::pipeline_barrier(*this, + src_mask, + dst_mask, + dependency, + std::move(memory_barriers), + std::move(buffer_memory_barriers), + std::move(image_memory_barriers)); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::push_constants(const PipelineLayout& pipeline_layout, + ShaderStageFlag stage, + std::span data, + u32 offset) const noexcept -> const CommandBuffer& { + CommandBufferAPI::push_constants(*this, pipeline_layout, stage, data, offset); + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::execute_sub_command_buffers(std::span command_buffers) const noexcept + -> const CommandBuffer& { + CommandBufferAPI::execute_sub_command_buffers(*this, command_buffers); + return *this; + } + } // namespace view } // namespace stormkit::gpu diff --git a/src/gpu/execution/command_pool.cpp b/src/gpu/execution/command_pool.cpp index c7cf87061..8de7b61cf 100644 --- a/src/gpu/execution/command_pool.cpp +++ b/src/gpu/execution/command_pool.cpp @@ -20,108 +20,82 @@ namespace stdr = std::ranges; namespace stdv = std::views; namespace stormkit::gpu { - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandPool::create_command_buffers(usize count, CommandBufferLevel level) const noexcept - -> Expected> { - return create_vk_command_buffers(count, level) - .transform([this, &level](auto&& command_buffers) noexcept { - return command_buffers - | stdv::as_rvalue - | stdv::transform([this, &level](VkCommandBuffer&& cmb) noexcept -> decltype(auto) { - return CommandBuffer::create(m_vk_device, - m_vk_handle, - m_vk_device_table, - level, - std::move(cmb), - CommandPool::delete_vk_command_buffers); - }) - | stdr::to(); - }) - .transform_error(monadic::from_vk()); - } + namespace { + struct CommandPoolAPI { + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto create_vk_command_buffers(const CommandPoolType& pool, usize count, CommandBufferLevel level) + const noexcept -> Expected> { + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto allocate_info = VkCommandBufferAllocateInfo { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .pNext = nullptr, + .commandPool = pool, + .level = vk::to_vk(level), + .commandBufferCount = as(count) + }; + + return vk::allocate_checked(count, + device_table.vkAllocateCommandBuffers, + device, + &allocate_info); + } + + ///////////////////////////////////// + ///////////////////////////////////// + static auto delete_vk_command_buffers(Device device, + CommandPool command_pool, + VkCommandBuffer command_buffer) noexcept -> void { + vk::call(device_table.vkFreeCommandBuffers, device, command_pool, 1, &command_buffer); + } + }; + } // namespace ///////////////////////////////////// ///////////////////////////////////// - auto CommandPool::allocate_command_buffers(usize count, CommandBufferLevel level) const noexcept - -> Expected>> { - return create_vk_command_buffers(count, level) - .transform([this, &level](auto&& command_buffers) noexcept { - return command_buffers - | stdv::as_rvalue - | stdv::transform([this, &level](VkCommandBuffer&& cmb) noexcept -> decltype(auto) { - return CommandBuffer::allocate(m_vk_device, - m_vk_handle, - m_vk_device_table, - level, - std::move(cmb), - CommandPool::delete_vk_command_buffers); - }) - | stdr::to(); - }) - .transform_error(monadic::from_vk()); - } + auto CommandPool::do_init() noexcept -> Expected { + const auto& device = device(); + const auto& device_table = device.device_table(); - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandPool::create_vk_command_buffers(usize count, CommandBufferLevel level) const noexcept - -> VulkanExpected> { - // auto out = std::vector {}; - // const auto reuse_count = stdr::empty(m_reusable_command_buffers) - // ? 0 - // : math::abs(stdr::size(m_reusable_command_buffers) - count); - // auto create_count = count - reuse_count; - - { - // auto lock = std::unique_lock { m_reuse_mutex }; - // auto erase_end = std::ranges::end(m_reusable_command_buffers); - // auto erase_begin = std::ranges::end(m_reusable_command_buffers) - reuse_count; - // - // std::ranges::for_each(m_reusable_command_buffers | std::views::reverse | - // std::views::take(reuse_count), - // [&out](VkCommandBuffer&& cmb) { - // out.emplace_back(std::move(cmb)); - // }); - // - // m_reusable_command_buffers.erase(erase_begin, erase_end); - } - // out.reserve(count); - - // if (create_count > 0) { - const auto allocate_info = VkCommandBufferAllocateInfo { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, - .pNext = nullptr, - .commandPool = m_vk_handle, - .level = to_vk(level), - .commandBufferCount = as(count) + const auto create_info = VkCommandPoolCreateInfo { + .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .pNext = nullptr, + .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT | VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, + .queueFamilyIndex = 0, }; - return vk_allocate(count, m_vk_device_table->vkAllocateCommandBuffers, m_vk_device, &allocate_info); + m_vk_handle = Try(vk::call_checked(device_table.vkCreateCommandPool, device, &create_info, nullptr)); + Return {}; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandPool::delete_vk_command_buffers(VkDevice device, - VkCommandPool command_pool, - const VolkDeviceTable& device_table, - VkCommandBuffer command_buffer) noexcept -> void { - vk_call(device_table.vkFreeCommandBuffers, device, command_pool, 1, &command_buffer); - // auto lock = std::unique_lock { m_reuse_mutex }; - // m_reusable_command_buffers.emplace_back(std::move(cmb)); + auto CommandPool::create_vk_command_buffers(usize count, CommandBufferLevel level) const noexcept + -> Expected> { + return CommandPoolAPI::create_vk_command_buffers(*this, count, level); } ///////////////////////////////////// ///////////////////////////////////// - auto CommandPool::do_init() noexcept -> Expected { - const auto create_info = VkCommandPoolCreateInfo { - .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, - .pNext = nullptr, - .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT | VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, - .queueFamilyIndex = 0, - }; - - return vk_call(m_vk_device_table->vkCreateCommandPool, m_vk_device, &create_info, nullptr) - .transform(core::monadic::set(m_vk_handle)) - .transform_error(monadic::from_vk()); + auto CommandPool::delete_vk_command_buffers(Device device, CommandPool pool, VkCommandBuffer cmb) noexcept -> void { + return CommandPoolAPI::create_vk_command_buffers(std::move(device), std::move(pool), cmb); } + + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandPool::create_vk_command_buffers(usize count, CommandBufferLevel level) const noexcept + -> Expected> { + return CommandPoolAPI::create_vk_command_buffers(*this, count, level); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandPool::delete_vk_command_buffers(Device device, CommandPool pool, VkCommandBuffer cmb) noexcept -> void { + return CommandPoolAPI::create_vk_command_buffers(std::move(device), std::move(pool), cmb); + } + } // namespace view } // namespace stormkit::gpu diff --git a/src/gpu/execution/frame_buffer.cpp b/src/gpu/execution/frame_buffer.cpp new file mode 100644 index 000000000..8e6d3260d --- /dev/null +++ b/src/gpu/execution/frame_buffer.cpp @@ -0,0 +1,50 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +module stormkit.gpu.execution; + +import std; + +import stormkit.core; + +import stormkit.gpu.core; + +namespace stdr = std::ranges; +namespace stdv = std::views; + +using namespace std::literals; + +namespace stormkit::gpu { + ///////////////////////////////////// + ///////////////////////////////////// + auto FrameBuffer::do_init(view::RenderPass&& render_pass, + const math::uextent2&, + std::vector attachments) noexcept -> Expected { + m_extent = extent; + m_attachments = std::move(attachments); + const auto vk_attachments = transform(m_attachments, , vk::monadic::to_vk()); + + const auto create_info = VkFramebufferCreateInfo { + .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .renderPass = vk::to_vk(render_pass), + .attachmentCount = as(std::ranges::size(vk_attachments)), + .pAttachments = std::ranges::data(vk_attachments), + .width = m_extent.width, + .height = m_extent.height, + .layers = 1, + }; + + const auto& device = device(); + const auto& device_table = device.device_table(); + + m_vk_handle = Try(vk::call_checked(device_table.vkCreateFramebuffer, device, &create_info, nullptr)); + Return {}; + } +} // namespace stormkit::gpu diff --git a/src/gpu/execution/pipeline.cpp b/src/gpu/execution/pipeline.cpp index ceb22aa07..dfca33d64 100644 --- a/src/gpu/execution/pipeline.cpp +++ b/src/gpu/execution/pipeline.cpp @@ -37,7 +37,7 @@ namespace stormkit::gpu { return VkVertexInputBindingDescription { .binding = binding_description.binding, .stride = binding_description.stride, - .inputRate = to_vk(binding_description.input_rate) + .inputRate = vk::to_vk(binding_description.input_rate) }; }) @@ -48,7 +48,7 @@ namespace stormkit::gpu { return VkVertexInputAttributeDescription { .location = input_attribute_description.location, .binding = input_attribute_description.binding, - .format = to_vk(input_attribute_description.format), + .format = vk::to_vk(input_attribute_description.format), .offset = input_attribute_description.offset }; }) @@ -68,13 +68,13 @@ namespace stormkit::gpu { .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, .pNext = nullptr, .flags = 0, - .topology = to_vk(state.input_assembly_state.topology), + .topology = vk::to_vk(state.input_assembly_state.topology), .primitiveRestartEnable = state.input_assembly_state.primitive_restart_enable }; - const auto viewports = state.viewport_state.viewports | stdv::transform(monadic::to_vk()) | stdr::to(); + const auto viewports = state.viewport_state.viewports | stdv::transform(vk::monadic::to_vk()) | stdr::to(); - const auto scissors = state.viewport_state.scissors | stdv::transform(monadic::to_vk()) | stdr::to(); + const auto scissors = state.viewport_state.scissors | stdv::transform(vk::monadic::to_vk()) | stdr::to(); const auto viewport_state = VkPipelineViewportStateCreateInfo { .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, @@ -92,9 +92,9 @@ namespace stormkit::gpu { .flags = 0, .depthClampEnable = state.rasterization_state.depth_clamp_enable, .rasterizerDiscardEnable = state.rasterization_state.rasterizer_discard_enable, - .polygonMode = to_vk(state.rasterization_state.polygon_mode), - .cullMode = to_vk(state.rasterization_state.cull_mode), - .frontFace = to_vk(state.rasterization_state.front_face), + .polygonMode = vk::to_vk(state.rasterization_state.polygon_mode), + .cullMode = vk::to_vk(state.rasterization_state.cull_mode), + .frontFace = vk::to_vk(state.rasterization_state.front_face), .depthBiasEnable = state.rasterization_state.depth_bias_enable, .depthBiasConstantFactor = state.rasterization_state.depth_bias_constant_factor, .depthBiasClamp = state.rasterization_state.depth_bias_clamp, @@ -106,7 +106,7 @@ namespace stormkit::gpu { .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, .pNext = nullptr, .flags = 0, - .rasterizationSamples = to_vk(state.multisample_state.rasterization_samples), + .rasterizationSamples = vk::to_vk(state.multisample_state.rasterization_samples), .sampleShadingEnable = state.multisample_state.sample_shading_enable, .minSampleShading = state.multisample_state.min_sample_shading, .pSampleMask = nullptr, @@ -118,13 +118,13 @@ namespace stormkit::gpu { | stdv::transform([](auto&& attachment) static noexcept { return VkPipelineColorBlendAttachmentState { .blendEnable = attachment.blend_enable, - .srcColorBlendFactor = to_vk(attachment.src_color_blend_factor), - .dstColorBlendFactor = to_vk(attachment.dst_color_blend_factor), - .colorBlendOp = to_vk(attachment.color_blend_operation), - .srcAlphaBlendFactor = to_vk(attachment.src_alpha_blend_factor), - .dstAlphaBlendFactor = to_vk(attachment.dst_alpha_blend_factor), - .alphaBlendOp = to_vk(attachment.alpha_blend_operation), - .colorWriteMask = to_vk(attachment.color_write_mask) + .srcColorBlendFactor = vk::to_vk(attachment.src_color_blend_factor), + .dstColorBlendFactor = vk::to_vk(attachment.dst_color_blend_factor), + .colorBlendOp = vk::to_vk(attachment.color_blend_operation), + .srcAlphaBlendFactor = vk::to_vk(attachment.src_alpha_blend_factor), + .dstAlphaBlendFactor = vk::to_vk(attachment.dst_alpha_blend_factor), + .alphaBlendOp = vk::to_vk(attachment.alpha_blend_operation), + .colorWriteMask = vk::to_vk(attachment.color_write_mask) }; }) | stdr::to(); @@ -134,7 +134,7 @@ namespace stormkit::gpu { .pNext = nullptr, .flags = 0, .logicOpEnable = state.color_blend_state.logic_operation_enable, - .logicOp = to_vk(state.color_blend_state.logic_operation), + .logicOp = vk::to_vk(state.color_blend_state.logic_operation), .attachmentCount = as(stdr::size(blend_attachments)), .pAttachments = stdr::data(blend_attachments), .blendConstants = { state.color_blend_state.blend_constants[0], @@ -143,7 +143,7 @@ namespace stormkit::gpu { state.color_blend_state.blend_constants[3] }, }; - const auto states = state.dynamic_state | stdv::transform(monadic::to_vk()) | stdr::to(); + const auto states = state.dynamic_state | stdv::transform(vk::monadic::to_vk()) | stdr::to(); const auto dynamic_state = VkPipelineDynamicStateCreateInfo { .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, @@ -168,8 +168,8 @@ namespace stormkit::gpu { .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, .pNext = nullptr, .flags = 0, - .stage = to_vk(shader.type()), - .module = to_vk(shader), + .stage = vk::to_vk(shader.type()), + .module = vk::to_vk(shader), .pName = stdr::data(name), .pSpecializationInfo = nullptr, }; @@ -182,7 +182,7 @@ namespace stormkit::gpu { .flags = 0, .depthTestEnable = state.depth_stencil_state.depth_test_enable, .depthWriteEnable = state.depth_stencil_state.depth_write_enable, - .depthCompareOp = to_vk(state.depth_stencil_state.depth_compare_op), + .depthCompareOp = vk::to_vk(state.depth_stencil_state.depth_compare_op), .depthBoundsTestEnable = state.depth_stencil_state.depth_bounds_test_enable, .stencilTestEnable = false, .front = {}, @@ -196,7 +196,7 @@ namespace stormkit::gpu { if (not rendering_info) return std::make_pair(std::vector {}, std::move(info)); auto formats = rendering_info->color_attachment_formats - | stdv::transform(monadic::to_vk()) + | stdv::transform(vk::monadic::to_vk()) | stdr::to(); info = VkPipelineRenderingCreateInfo { @@ -210,10 +210,10 @@ namespace stormkit::gpu { }; if (rendering_info->depth_attachment_format) - info.depthAttachmentFormat = to_vk(*rendering_info->depth_attachment_format); + info.depthAttachmentFormat = vk::to_vk(*rendering_info->depth_attachment_format); if (rendering_info->stencil_attachment_format) - info.stencilAttachmentFormat = to_vk(*rendering_info->stencil_attachment_format); + info.stencilAttachmentFormat = vk::to_vk(*rendering_info->stencil_attachment_format); return std::make_pair(std::move(formats), std::move(info)); }(); @@ -233,23 +233,22 @@ namespace stormkit::gpu { .pDepthStencilState = &depth_stencil, .pColorBlendState = &color_blending, .pDynamicState = &dynamic_state, - .layout = to_vk(layout), - .renderPass = render_pass ? to_vk(render_pass) : nullptr, + .layout = vk::to_vk(layout), + .renderPass = render_pass ? vk::to_vk(render_pass) : nullptr, .subpass = 0, .basePipelineHandle = nullptr, .basePipelineIndex = -1, }; using namespace core::monadic; - const auto vk_pipeline_cache = core::either(pipeline_cache, monadic::to_vk(), init(nullptr)); - - return vk_call(m_vk_device_table->vkCreateGraphicsPipelines, - m_vk_device, - vk_pipeline_cache, - 1, - &create_info, - nullptr) - .transform(set(m_vk_handle)) - .transform_error(monadic::from_vk()); + const auto vk_pipeline_cache = core::either(pipeline_cache, vk::monadic::to_vk(), init(nullptr)); + + return vk::call_checked(m_vk_device_table->vkCreateGraphicsPipelines, + m_vk_device, + vk_pipeline_cache, + 1, + &create_info, + nullptr) + .transform(set(m_vk_handle)); } } // namespace stormkit::gpu diff --git a/src/gpu/execution/pipeline_cache.cpp b/src/gpu/execution/pipeline_cache.cpp index 6e509004f..a666e6ea3 100644 --- a/src/gpu/execution/pipeline_cache.cpp +++ b/src/gpu/execution/pipeline_cache.cpp @@ -21,6 +21,8 @@ import stormkit.gpu.core; namespace stdr = std::ranges; +using namespace stormkit::literals; + LOGGER("stormkit.gpu") namespace stormkit::gpu { @@ -65,8 +67,10 @@ namespace stormkit::gpu { .pInitialData = nullptr, }; - m_vk_handle = Try(vk_call(m_vk_device_table->vkCreatePipelineCache, m_vk_device, &create_info, nullptr) - .transform_error(monadic::from_vk()) + m_vk_handle = Try(vk::call_checked(m_vk_device_table->vkCreatePipelineCache, + m_vk_device, + &create_info, + nullptr) .transform_error(result_to_load_error)); Return {}; @@ -129,8 +133,10 @@ namespace stormkit::gpu { .pInitialData = stdr::data(data), }; - m_vk_handle = Try(vk_call(m_vk_device_table->vkCreatePipelineCache, m_vk_device, &create_info, nullptr) - .transform_error(monadic::from_vk()) + m_vk_handle = Try(vk::call_checked(m_vk_device_table->vkCreatePipelineCache, + m_vk_device, + &create_info, + nullptr) .transform_error(result_to_load_error)); Return {}; @@ -139,9 +145,23 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// auto PipelineCache::save_cache() noexcept -> LoadSaveExpected { - auto data = Try((vk_enumerate(m_vk_device_table->vkGetPipelineCacheData, m_vk_device, m_vk_handle) - .transform_error(monadic::from_vk()) - .transform_error(result_to_load_error))); + auto size = 0_usize; + { + const auto + result = vk::call_checked(m_vk_device_table->vkGetPipelineCacheData, m_vk_device, m_vk_handle, &size, nullptr); + if (not result) Return std::unexpected { result_to_load_error(result.error()) }; + } + auto data = std::vector {}; + data.resize(size, 0_b); + { + const auto result = vk::call_checked(m_vk_device_table->vkGetPipelineCacheData, + m_vk_device, + m_vk_handle, + &size, + stdr::data(data)); + if (not result) Return std::unexpected { result_to_load_error(result.error()) }; + } + m_serialized.guard.data_size = stdr::size(data); m_serialized.guard.data_hash = 0u; diff --git a/src/gpu/execution/queue.cpp b/src/gpu/execution/queue.cpp index 06984cdce..155d950e4 100644 --- a/src/gpu/execution/queue.cpp +++ b/src/gpu/execution/queue.cpp @@ -5,6 +5,7 @@ module; #include +#include #include @@ -20,149 +21,224 @@ using namespace std::literals; namespace stdr = std::ranges; namespace stdv = std::views; +namespace stdp = std::pmr; namespace stormkit::gpu { + namespace { + struct QueueAPI { + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto wait_idle(const QueueType& queue) noexcept -> Expected { + const auto& device = queue.device(); + const auto& device_table = queue.device_table(); + + return vk::call_checked(device_table->vkQueueWaitIdle, queue); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto submit(const QueueType& queue, + std::span&& submit_infos, + std::optional&& fence) noexcept -> Expected { + struct SubmitInfoRange { + std::span wait_semaphores; + std::span wait_dst_stages; + std::span command_buffers; + std::span signal_semaphores; + }; + + const auto bytes_count = [&submit_infos] noexcept { + auto _wait_semaphores_count = 0uz; + auto _wait_dst_stages_count = 0uz; + auto _command_buffers_count = 0uz; + auto _signal_semaphores_count = 0uz; + + for (auto&& submit_info : submit_infos) { + _wait_semaphores_count = stdr::size(submit_info.wait_semaphores); + _wait_dst_stages_count = stdr::size(submit_info.wait_dst_stages); + _command_buffers_count = stdr::size(submit_info.command_buffers); + _signal_semaphores_count = stdr::size(submit_info.signal_semaphores); + } + return _wait_semaphores_count * sizeof(VkSemaphore) + + _wait_dst_stages_count * sizeof(VkPipelineStageFlags) + + _command_buffers_count * sizeof(VkCommandBuffer) + + _signal_semaphores_count * sizeof(VkSemaphore) + + stdr::size(submit_infos) * sizeof(SubmitInfoRange); + }(); + + auto memory_resource = stdp::monotonic_buffer_resource { bytes_count }; + + auto wait_semaphores_buf = stdp::vector> { &memory_resource }; + wait_semaphores_buf.reserve(stdr::size(submit_infos)); + auto wait_dst_stages_buf = stdp::vector> { &memory_resource }; + wait_dst_stages_buf.reserve(stdr::size(submit_infos)); + auto command_buffers_buf = stdp::vector> { &memory_resource }; + command_buffers_buf.reserve(stdr::size(submit_infos)); + auto signal_semaphores_buf = stdp::vector> { &memory_resource }; + signal_semaphores_buf.reserve(stdr::size(submit_infos)); + + const auto submit_ranges = [&] noexcept { + auto vec = stdp::vector { &memory_resource }; + vec.reserve(stdr::size(submit_infos)); + for (auto&& submit_info : submit_infos) { + auto& wait_semaphores = wait_semaphores_buf.emplace_back(std::from_range, + submit_info.wait_semaphores + | stdv::transform(vk::monadic::to_vk())); + + auto& + wait_dst_stages = wait_dst_stages_buf + .emplace_back(std::from_range, + submit_info.wait_dst_stages + | stdv::transform(vk::monadic::to_vk())); + + auto& command_buffers = command_buffers_buf.emplace_back(std::from_range, + submit_info.command_buffers + | stdv::transform(vk::monadic::to_vk())); + + auto& signal_semaphores = signal_semaphores_buf.emplace_back(std::from_range, + submit_info.signal_semaphores + | stdv::transform(vk::monadic::to_vk())); + + vec.emplace_back(SubmitInfoRange { + .wait_semaphores = wait_semaphores, + .wait_dst_stages = wait_dst_stages, + .command_buffers = command_buffers, + .signal_semaphores = signal_semaphores, + }); + } + return vec; + }(); + + const auto vk_submit_infos = submit_ranges + | stdv::transform([](auto&& submit_range) noexcept { + EXPECTS(stdr::size(submit_range.wait_semaphores) + == stdr::size(submit_range.wait_dst_stages)); + + return VkSubmitInfo { + .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .pNext = nullptr, + .waitSemaphoreCount = as(stdr::size(submit_range.wait_semaphores)), + .pWaitSemaphores = stdr::data(submit_range.wait_semaphores), + .pWaitDstStageMask = stdr::data(submit_range.wait_dst_stages), + .commandBufferCount = as(stdr::size(submit_range.command_buffers)), + .pCommandBuffers = stdr::data(submit_range.command_buffers), + .signalSemaphoreCount = as(stdr::size(submit_range + .signal_semaphores)), + .pSignalSemaphores = stdr::data(submit_range.signal_semaphores), + }; + }) + | stdr::to(); + + const auto vk_fence = core::either(fence, vk::monadic::to_vk(), core::monadic::init(nullptr)); + + const auto& device = queue.device(); + const auto& device_table = device.device_table(); + return vk::call_checked(device_table.vkQueueSubmit, + queue, + stdr::size(vk_submit_infos), + stdr::data(vk_submit_infos), + vk_fence); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto present(const QueueType& queue, + std::span swapchains, + std::span wait_semaphores, + std::span image_indices) noexcept -> Expected { + EXPECTS(stdr::size(wait_semaphores) >= 1); + EXPECTS(stdr::size(image_indices) >= 1); + + const auto swapchains_count = stdr::size(swapchains); + const auto wait_semaphores_count = stdr::size(wait_semaphores); + + const auto bytes_count = swapchains_count * sizeof(VkSwapchainKHR) + wait_semaphores_count * sizeof(VkSemaphore); + auto memory_resource = stdp::monotonic_buffer_resource { bytes_count }; + + const auto vk_swapchains = stdp::vector { std::from_range, + swapchains | stdv::transform(vk::monadic::to_vk()), + &memory_resource }; + const auto vk_semaphores = stdp::vector { std::from_range, + wait_semaphores | stdv::transform(vk::monadic::to_vk()), + &memory_resource }; + + const auto present_info = VkPresentInfoKHR { + .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, + .pNext = nullptr, + .waitSemaphoreCount = as(stdr::size(vk_semaphores)), + .pWaitSemaphores = stdr::data(vk_semaphores), + .swapchainCount = as(stdr::size(vk_swapchains)), + .pSwapchains = stdr::data(vk_swapchains), + .pImageIndices = stdr::data(image_indices), + .pResults = nullptr, + }; + + const auto& device = queue.device(); + const auto& device_table = device.device_table(); + const auto + result = Try((vk::call_checked(device_table + .vkQueuePresentKHR, + queue, + &present_info))); + Return vk::from_vk(result); + } + }; + } // namespace ///////////////////////////////////// ///////////////////////////////////// - auto Queue::submit(std::span submit_infos, OptionalRef fence) const noexcept - -> Expected { - struct SubmitInfoRange { - std::span wait_semaphores; - std::span wait_dst_stages; - std::span command_buffers; - std::span signal_semaphores; - }; + auto Queue::wait_idle() const noexcept -> Expected { + return QueueAPI::wait_idle(*this); + } - const auto bytes_count = [&submit_infos] noexcept { - auto _wait_semaphores_count = 0uz; - auto _wait_dst_stages_count = 0uz; - auto _command_buffers_count = 0uz; - auto _signal_semaphores_count = 0uz; - - for (auto&& submit_info : submit_infos) { - _wait_semaphores_count = stdr::size(submit_info.wait_semaphores); - _wait_dst_stages_count = stdr::size(submit_info.wait_dst_stages); - _command_buffers_count = stdr::size(submit_info.command_buffers); - _signal_semaphores_count = stdr::size(submit_info.signal_semaphores); - } - return _wait_semaphores_count * sizeof(VkSemaphore) - + _wait_dst_stages_count * sizeof(VkPipelineStageFlags) - + _command_buffers_count * sizeof(VkCommandBuffer) - + _signal_semaphores_count * sizeof(VkSemaphore) - + stdr::size(submit_infos) * sizeof(SubmitInfoRange); - }(); - - namespace stdp = std::pmr; - - auto memory_resource = stdp::monotonic_buffer_resource { bytes_count }; - - auto wait_semaphores_buf = stdp::vector> { &memory_resource }; - wait_semaphores_buf.reserve(stdr::size(submit_infos)); - auto wait_dst_stages_buf = stdp::vector> { &memory_resource }; - wait_dst_stages_buf.reserve(stdr::size(submit_infos)); - auto command_buffers_buf = stdp::vector> { &memory_resource }; - command_buffers_buf.reserve(stdr::size(submit_infos)); - auto signal_semaphores_buf = stdp::vector> { &memory_resource }; - signal_semaphores_buf.reserve(stdr::size(submit_infos)); - - const auto submit_ranges = [&] noexcept { - auto vec = stdp::vector { &memory_resource }; - vec.reserve(stdr::size(submit_infos)); - for (auto&& submit_info : submit_infos) { - auto& wait_semaphores = wait_semaphores_buf - .emplace_back(std::from_range, - submit_info.wait_semaphores | stdv::transform(monadic::to_vk())); - - auto& wait_dst_stages = wait_dst_stages_buf - .emplace_back(std::from_range, - submit_info.wait_dst_stages - | stdv::transform(monadic::to_vk())); - - auto& command_buffers = command_buffers_buf - .emplace_back(std::from_range, - submit_info.command_buffers | stdv::transform(monadic::to_vk())); - - auto& signal_semaphores = signal_semaphores_buf - .emplace_back(std::from_range, - submit_info.signal_semaphores | stdv::transform(monadic::to_vk())); - - vec.emplace_back(SubmitInfoRange { - .wait_semaphores = wait_semaphores, - .wait_dst_stages = wait_dst_stages, - .command_buffers = command_buffers, - .signal_semaphores = signal_semaphores, - }); - } - return vec; - }(); - - const auto vk_submit_infos = submit_ranges - | stdv::transform([](auto&& submit_range) noexcept { - EXPECTS(stdr::size(submit_range.wait_semaphores) - == stdr::size(submit_range.wait_dst_stages)); - - return VkSubmitInfo { - .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, - .pNext = nullptr, - .waitSemaphoreCount = as(stdr::size(submit_range.wait_semaphores)), - .pWaitSemaphores = stdr::data(submit_range.wait_semaphores), - .pWaitDstStageMask = stdr::data(submit_range.wait_dst_stages), - .commandBufferCount = as(stdr::size(submit_range.command_buffers)), - .pCommandBuffers = stdr::data(submit_range.command_buffers), - .signalSemaphoreCount = as(stdr::size(submit_range.signal_semaphores)), - .pSignalSemaphores = stdr::data(submit_range.signal_semaphores), - }; - }) - | stdr::to(); - - const auto vk_fence = core::either(fence, monadic::to_vk(), core::monadic::init(nullptr)); - - return vk_call(m_vk_device_table->vkQueueSubmit, - m_vk_handle, - stdr::size(vk_submit_infos), - stdr::data(vk_submit_infos), - vk_fence) - .transform_error(monadic::from_vk()); + ///////////////////////////////////// + ///////////////////////////////////// + auto Queue::present(std::span swapchains, + std::span wait_semaphores, + std::span image_indices) const noexcept -> Expected { + return QueueAPI::present(*this, std::move(swapchains), std::move(wait_semaphores), std::move(image_indices)); } ///////////////////////////////////// ///////////////////////////////////// - auto Queue::present(std::span> swapchains, - std::span> wait_semaphores, - std::span image_indices) const noexcept -> Expected { - EXPECTS(stdr::size(wait_semaphores) >= 1); - EXPECTS(stdr::size(image_indices) >= 1); - - const auto swapchains_count = stdr::size(swapchains); - const auto wait_semaphores_count = stdr::size(wait_semaphores); - - namespace stdp = std::pmr; - - const auto bytes_count = swapchains_count * sizeof(VkSwapchainKHR) + wait_semaphores_count * sizeof(VkSemaphore); - auto memory_resource = stdp::monotonic_buffer_resource { bytes_count }; - - const auto vk_swapchains = stdp::vector { std::from_range, - swapchains | stdv::transform(monadic::to_vk()), - &memory_resource }; - const auto vk_semaphores = stdp::vector { std::from_range, - wait_semaphores | stdv::transform(monadic::to_vk()), - &memory_resource }; - - const auto present_info = VkPresentInfoKHR { - .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, - .pNext = nullptr, - .waitSemaphoreCount = as(stdr::size(vk_semaphores)), - .pWaitSemaphores = stdr::data(vk_semaphores), - .swapchainCount = as(stdr::size(vk_swapchains)), - .pSwapchains = stdr::data(vk_swapchains), - .pImageIndices = stdr::data(image_indices), - .pResults = nullptr, - }; + auto Queue::submit(std::span submit_infos, std::optional fence) const noexcept + -> Expected { + return QueueAPI::submit(*this, std::move(submit_infos), std::move(fence)); + } - const auto possible_results = into_array_of(VK_SUCCESS, VK_ERROR_OUT_OF_DATE_KHR, VK_SUBOPTIMAL_KHR); - return vk_call(m_vk_device_table->vkQueuePresentKHR, as_view(possible_results), m_vk_handle, &present_info) - .transform(monadic::from_vk()) - .transform_error(monadic::from_vk()); + ///////////////////////////////////// + ///////////////////////////////////// + auto Queue::do_init(const Device::QueueEntry& entry) -> void { + m_entry = entry; + + const auto& device = this->device(); + const auto& device_table = device.device_table(); + m_vk_handle = vk::call(device_table.vkGetDeviceQueue, device, m_entry.id, 0); } + + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + auto Queue::wait_idle() const noexcept -> Expected { + return QueueAPI::wait_idle(*this); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto Queue::present(std::span swapchains, + std::span wait_semaphores, + std::span image_indices) const noexcept -> Expected { + return QueueAPI::present(*this, std::move(swapchains), std::move(wait_semaphores), std::move(image_indices)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto Queue::submit(std::span submit_infos, std::optional fence) const noexcept + -> Expected { + return QueueAPI::submit(*this, std::move(submit_infos), std::move(fence)); + } + } // namespace view } // namespace stormkit::gpu diff --git a/src/gpu/execution/render_pass.cpp b/src/gpu/execution/render_pass.cpp index 64e69976a..7e792b497 100644 --- a/src/gpu/execution/render_pass.cpp +++ b/src/gpu/execution/render_pass.cpp @@ -23,7 +23,7 @@ namespace stormkit::gpu { return [](auto&& attachment_ref) noexcept -> VkAttachmentReference { return VkAttachmentReference { .attachment = attachment_ref.attachment_id, - .layout = to_vk(attachment_ref.layout), + .layout = vk::to_vk(attachment_ref.layout), }; }; } @@ -31,22 +31,22 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto RenderPass::do_init() noexcept -> Expected { - const auto attachments = m_description.attachments - | stdv::transform([](auto&& attachment) static noexcept { - return VkAttachmentDescription { - .flags = 0, - .format = to_vk(attachment.format), - .samples = to_vk(attachment.samples), - .loadOp = to_vk(attachment.load_op), - .storeOp = to_vk(attachment.store_op), - .stencilLoadOp = to_vk(attachment.stencil_load_op), - .stencilStoreOp = to_vk(attachment.stencil_store_op), - .initialLayout = to_vk(attachment.source_layout), - .finalLayout = to_vk(attachment.destination_layout), - }; - }) - | stdr::to(); + auto RenderPass::do_init(PrivateTag, const RenderPassDescription& description) noexcept -> Expected { + m_description = description; + + const auto attachments = transform(m_description.attachments, [](auto&& attachment) static noexcept { + return VkAttachmentDescription { + .flags = 0, + .format = vk::to_vk(attachment.format), + .samples = vk::to_vk(attachment.samples), + .loadOp = vk::to_vk(attachment.load_op), + .storeOp = vk::to_vk(attachment.store_op), + .stencilLoadOp = vk::to_vk(attachment.stencil_load_op), + .stencilStoreOp = vk::to_vk(attachment.stencil_store_op), + .initialLayout = vk::to_vk(attachment.source_layout), + .finalLayout = vk::to_vk(attachment.destination_layout), + }; + }); auto color_attachment_refs = std::vector> {}; auto depth_attachment_ref = std::optional {}; @@ -60,17 +60,15 @@ namespace stormkit::gpu { subpasses_deps.reserve(stdr::size(m_description.subpasses)); for (const auto& subpass : m_description.subpasses) { - auto& color_attachment_ref = color_attachment_refs.emplace_back(subpass.color_attachment_refs - | stdv::transform(monadic::vk_ref()) - | stdr::to()); - auto& resolve_attachment_ref = resolve_attachment_refs.emplace_back(subpass.resolve_attachment_refs - | stdv::transform(monadic::vk_ref()) - | stdr::to()); + auto& color_attachment_ref = color_attachment_refs.emplace_back(transform(subpass.color_attachment_refs, + monadic::vk_ref()); + auto& resolve_attachment_ref = resolve_attachment_refs.emplace_back(transform(subpass.resolve_attachment_refs, + monadic::vk_ref()); if (subpass.depth_attachment_ref) depth_attachment_ref = monadic::vk_ref()(*subpass.depth_attachment_ref); subpasses.emplace_back(VkSubpassDescription { .flags = 0, - .pipelineBindPoint = to_vk(subpass.bind_point), + .pipelineBindPoint = vk::to_vk(subpass.bind_point), .inputAttachmentCount = 0, .pInputAttachments = nullptr, .colorAttachmentCount = as(stdr::size(color_attachment_ref)), @@ -104,9 +102,11 @@ namespace stormkit::gpu { .pDependencies = stdr::data(subpasses_deps), }; - return vk_call(m_vk_device_table->vkCreateRenderPass, m_vk_device, &create_info, nullptr) - .transform(core::monadic::set(m_vk_handle)) - .transform_error(monadic::from_vk()); + const auto& device = device(); + const auto& device_table = device.device_table(); + + m_vk_handle = Try(vk::call_checked(device_table.vkCreateRenderPass, device, &create_info, nullptr)); + Return {}; } ///////////////////////////////////// diff --git a/src/gpu/execution/swapchain.cpp b/src/gpu/execution/swapchain.cpp index f3966a648..448e41db0 100644 --- a/src/gpu/execution/swapchain.cpp +++ b/src/gpu/execution/swapchain.cpp @@ -13,160 +13,161 @@ import stormkit.core; import stormkit.gpu.core; import stormkit.gpu.resource; -namespace stormkit::gpu { - namespace { - ///////////////////////////////////// - ///////////////////////////////////// - auto choose_swap_surface_format(std::span formats) noexcept -> VkSurfaceFormatKHR { - for (const auto& format : formats) { - if (format.format == VK_FORMAT_B8G8R8A8_UNORM && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) - return format; - } - - return formats[0]; +namespace stormkit::gpu { namespace { + ///////////////////////////////////// + ///////////////////////////////////// + auto choose_swap_surface_format(std::span formats) noexcept -> VkSurfaceFormatKHR { + for (const auto& format : formats) { + if (format.format == VK_FORMAT_B8G8R8A8_UNORM && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) + return format; } - ///////////////////////////////////// - ///////////////////////////////////// - auto choose_swap_present_mode(std::span present_modes) noexcept -> VkPresentModeKHR { - auto present_mode_ = VK_PRESENT_MODE_FIFO_KHR; + return formats[0]; + } - for (const auto& present_mode : present_modes) { - if (present_mode == VK_PRESENT_MODE_IMMEDIATE_KHR) return present_mode; - else if (present_mode == VK_PRESENT_MODE_MAILBOX_KHR) - return present_mode; - } + ///////////////////////////////////// + ///////////////////////////////////// + auto choose_swap_present_mode(std::span present_modes) noexcept -> VkPresentModeKHR { + auto present_mode_ = VK_PRESENT_MODE_FIFO_KHR; - return present_mode_; + for (const auto& present_mode : present_modes) { + if (present_mode == VK_PRESENT_MODE_IMMEDIATE_KHR) return present_mode; + else if (present_mode == VK_PRESENT_MODE_MAILBOX_KHR) + return present_mode; } - ///////////////////////////////////// - ///////////////////////////////////// - auto choose_swap_extent(const VkSurfaceCapabilitiesKHR& capabilities, const math::uextent2& extent) noexcept - -> VkExtent2D { - static constexpr auto int_max = std::numeric_limits::max(); - - if (capabilities.currentExtent.width != int_max && capabilities.currentExtent.height != int_max) - return capabilities.currentExtent; - - auto actual_extent = to_vk(extent); - actual_extent.width = std::max(capabilities.minImageExtent.width, - std::min(capabilities.maxImageExtent.width, actual_extent.width)); - actual_extent.height = std::max(capabilities.minImageExtent.height, - std::min(capabilities.maxImageExtent.height, actual_extent.height)); + return present_mode_; + } - return actual_extent; - } + ///////////////////////////////////// + ///////////////////////////////////// + auto choose_swap_extent(const VkSurfaceCapabilitiesKHR& capabilities, const math::uextent2& extent) noexcept -> VkExtent2D { + static constexpr auto int_max = std::numeric_limits::max(); - ///////////////////////////////////// - ///////////////////////////////////// - auto choose_image_count(const VkSurfaceCapabilitiesKHR& capabilities) noexcept -> u32 { - auto image_count = capabilities.minImageCount + 1; + if (capabilities.currentExtent.width != int_max && capabilities.currentExtent.height != int_max) + return capabilities.currentExtent; - if (capabilities.maxImageCount > 0 && image_count > capabilities.maxImageCount) - image_count = capabilities.maxImageCount; + auto actual_extent = vk::to_vk(extent); + actual_extent + .width = std::max(capabilities.minImageExtent.width, std::min(capabilities.maxImageExtent.width, actual_extent.width)); + actual_extent.height = std::max(capabilities.minImageExtent.height, + std::min(capabilities.maxImageExtent.height, actual_extent.height)); - return image_count; - } - } // namespace + return actual_extent; + } ///////////////////////////////////// ///////////////////////////////////// - auto SwapChain::do_init(const Device& device, - const Surface& surface, - const math::uextent2& extent, - VkSwapchainKHR old_swapchain) noexcept -> Expected { - const auto& physical_device = device.physical_device(); - - return vk_call(vkGetPhysicalDeviceSurfaceCapabilitiesKHR, - physical_device.native_handle(), - surface.native_handle()) - .and_then([&physical_device, &surface](auto&& capabilities) noexcept { - return vk_enumerate(vkGetPhysicalDeviceSurfaceFormatsKHR, - physical_device.native_handle(), - surface.native_handle()) - .transform(core::monadic::as_tuple(std::move(capabilities))); - }) - .and_then(core::monadic::unpack_tuple_to([&physical_device, &surface](auto&& capabilities, auto&& formats) noexcept { - return vk_enumerate(vkGetPhysicalDeviceSurfacePresentModesKHR, - physical_device.native_handle(), - surface.native_handle()) - .transform(core::monadic::as_tuple(std::move(capabilities), std::move(formats))); - })) - .and_then(core::monadic::unpack_tuple_to([this, &surface, &extent, &old_swapchain](auto&& capabilities, - auto&& formats, - auto&& present_modes) noexcept { - const auto format = choose_swap_surface_format(formats); - const auto present_mode = choose_swap_present_mode(present_modes); - const auto swapchain_extent = choose_swap_extent(capabilities, extent.to<2uz>()); - const auto image_count = choose_image_count(capabilities); - const auto image_sharing_mode = VK_SHARING_MODE_EXCLUSIVE; - const auto image_usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; - - m_extent = extent; - m_pixel_format = from_vk(format.format); - - const auto create_info = VkSwapchainCreateInfoKHR { - .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, - .pNext = nullptr, - .flags = 0, - .surface = surface.native_handle(), - .minImageCount = image_count, - .imageFormat = format.format, - .imageColorSpace = format.colorSpace, - .imageExtent = swapchain_extent, - .imageArrayLayers = 1, - .imageUsage = image_usage, - .imageSharingMode = image_sharing_mode, - .queueFamilyIndexCount = 0, - .pQueueFamilyIndices = nullptr, - .preTransform = capabilities.currentTransform, - .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, - .presentMode = present_mode, - .clipped = true, - .oldSwapchain = old_swapchain - }; - - ENSURES(m_vk_device_table->vkCreateSwapchainKHR != nullptr); - ENSURES(m_vk_device != nullptr); - - return vk_call(m_vk_device_table->vkCreateSwapchainKHR, m_vk_device, &create_info, nullptr); - })) - .transform(core::monadic::set(m_vk_handle)) - .and_then([this] noexcept { - return vk_enumerate(m_vk_device_table->vkGetSwapchainImagesKHR, m_vk_device, m_vk_handle); - }) - .transform([this, &device](auto&& vk_images) noexcept { - m_image_count = as(std::ranges::size(vk_images)); - m_images = vk_images - | std::views::transform([this, &device](auto&& image) noexcept { - const auto create_info = Image::CreateInfo { - .extent = { m_extent.width, m_extent.height, 1_u32 }, - .format = m_pixel_format - }; - return Image::create(device, create_info, std::move(image)); - }) - | std::ranges::to(); - }) - .transform_error(monadic::from_vk()); + auto choose_image_count(const VkSurfaceCapabilitiesKHR& capabilities) noexcept -> u32 { + auto image_count = capabilities.minImageCount + 1; + + if (capabilities.maxImageCount > 0 && image_count > capabilities.maxImageCount) image_count = capabilities.maxImageCount; + + return image_count; } + struct SwapChainAPI { + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto acquire_next_image(const SwapChainType& swapchain, + std::chrono::nanoseconds wait, + view::Semaphore&& image_available) const noexcept -> Expected { + const auto& device = device(); + const auto& device_table = device.device_table(); + + auto id = u32 { 0 }; + Try(vk::call_checked(device_table->vkAcquireNextImageKHR, + device, + swapchain, + wait.count(), + image_available, + nullptr, + &id)); + Return SwapChain::NextImage { .result = vk::from_vk(result), .id = id }; + }; + } +}; } // namespace + +///////////////////////////////////// +///////////////////////////////////// +auto SwapChain::do_init(view::Surface&& surface, const math::uextent2& extent, VkSwapchainKHR old_swapchain) noexcept + -> Expected { + const auto& device = device(); + const auto& device_table = device.device_table(); + const auto& physical_device = device.physical_device(); + + const auto capabilities = Try(vk::call_checked(vkGetPhysicalDeviceSurfaceCapabilitiesKHR, + physical_device, + surface)); + const auto + formats = Try(vk::enumerate_checked(vkGetPhysicalDeviceSurfaceFormatsKHR, physical_device, surface)); + const auto present_modes = Try(vk::enumerate_checked(vkGetPhysicalDeviceSurfacePresentModesKHR, + physical_device, + surface)); + + const auto format = choose_swap_surface_format(formats); + const auto present_mode = choose_swap_present_mode(present_modes); + const auto swapchain_extent = choose_swap_extent(capabilities, extent.to<2uz>()); + const auto image_count = choose_image_count(capabilities); + const auto image_sharing_mode = VK_SHARING_MODE_EXCLUSIVE; + const auto image_usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + + m_extent = extent; + m_pixel_format = vk::from_vk(format.format); + + const auto create_info = VkSwapchainCreateInfoKHR { + .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, + .pNext = nullptr, + .flags = 0, + .surface = surface, + .minImageCount = image_count, + .imageFormat = format.format, + .imageColorSpace = format.colorSpace, + .imageExtent = swapchain_extent, + .imageArrayLayers = 1, + .imageUsage = image_usage, + .imageSharingMode = image_sharing_mode, + .queueFamilyIndexCount = 0, + .pQueueFamilyIndices = nullptr, + .preTransform = capabilities.currentTransform, + .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, + .presentMode = present_mode, + .clipped = true, + .oldSwapchain = old_swapchain + }; + + ENSURES(device_table.vkCreateSwapchainKHR != nullptr); + ENSURES(device_table.vkGetSwapchainImagesKHR != nullptr); + + m_vk_handle = Try(vk::call_checked(device_table.vkCreateSwapchainKHR, device, &create_info, nullptr)); + const auto vk_images = Try(vk::enumerate_checked(device_table.vkGetSwapchainImagesKHR, device, m_vk_handle)); + + m_image_count = as(stdr::size(vk_images)); + m_images = transform(vk_images, [this, &device](auto image) noexcept { + const auto create_info = Image::CreateInfo { + .extent = { m_extent.width, m_extent.height, 1_u32 }, + .format = m_pixel_format + }; + return Image::from_existing(device, create_info, image); + }); + + Return {}; +} + +///////////////////////////////////// +///////////////////////////////////// +auto SwapChain::acquire_next_image(std::chrono::nanoseconds wait, view::Semaphore image_available) const noexcept + -> Expected { + return SwapChainAPI::acquire_next_image(*this, std::move(wait), std::move(image_available)) +} + +namespace view { ///////////////////////////////////// ///////////////////////////////////// - auto SwapChain::acquire_next_image(std::chrono::nanoseconds wait, const Semaphore& image_available) const noexcept + auto SwapChain::acquire_next_image(std::chrono::nanoseconds wait, Semaphore image_available) const noexcept -> Expected { - static constexpr auto POSSIBLE_RESULTS = std::array { VK_SUCCESS, VK_ERROR_OUT_OF_DATE_KHR, VK_SUBOPTIMAL_KHR }; - - auto id = u32 { 0 }; - return vk_call(m_vk_device_table->vkAcquireNextImageKHR, - as_view(POSSIBLE_RESULTS), - m_vk_device, - m_vk_handle, - wait.count(), - image_available.native_handle(), - nullptr, - &id) - .transform([&id](auto&& result) { return NextImage { .result = from_vk(result), .id = id }; }) - .transform_error(monadic::from_vk()); + return SwapChainAPI::acquire_next_image(*this, std::move(wait), std::move(image_available)) } +} // namespace view } // namespace stormkit::gpu diff --git a/src/gpu/resource/buffer.cpp b/src/gpu/resource/buffer.cpp index b090e84ab..ca4be7b4e 100644 --- a/src/gpu/resource/buffer.cpp +++ b/src/gpu/resource/buffer.cpp @@ -4,6 +4,9 @@ module; +#include +#include + #include module stormkit.gpu.resource; @@ -15,53 +18,143 @@ import stormkit.core; import stormkit.gpu.core; namespace stormkit::gpu { + struct BufferAPI { + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto map(BufferType& buffer, ioffset offset) noexcept -> Expected { + EXPECTS(buffer.allocation() and buffer.native_handle()); + EXPECTS(offset < as(buffer.size())); + + const auto& device = buffer.device(); + const auto& allocator = device.allocator(); + const auto& allocation = buffer.allocation(); + + auto ptr = Try(vk::call_checked(vmaMapMemory, allocator, allocation)); + + buffer.m_mapped_pointer = std::bit_cast(ptr); + buffer.m_mapped_pointer += offset; + return buffer.m_mapped_pointer; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto flush(const BufferType& buffer, ioffset offset, usize size) noexcept -> Expected { + EXPECTS(buffer.allocation() and buffer.native_handle()); + EXPECTS(offset <= as(buffer.size())); + EXPECTS(size <= buffer.size()); + + const auto& device = buffer.device(); + const auto& allocator = device.allocator(); + const auto& allocation = buffer.allocation(); + + return vk::call_checked(vmaFlushAllocation, allocator, allocation, offset, size); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto unmap(BufferType& buffer) noexcept -> void { + EXPECTS(buffer.allocation() and buffer.native_handle()); + // expects(buffer.is_persistently_mapped(), "unmapping persistent buffer !"); + + const auto& device = buffer.device(); + const auto& allocator = device.allocator(); + const auto& allocation = buffer.allocation(); + + vk::call(vmaUnmapMemory, allocator, allocation); + + buffer.m_mapped_pointer = nullptr; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto upload(BufferType& buffer, std::span data, ioffset offset) noexcept -> Expected { + EXPECTS(stdr::size(data) <= buffer.size()); + + if (buffer.is_persistently_mapped()) { + stdr::copy(data, buffer.m_mapped_pointer); + Return {}; + } + + auto gpu_data = Try(buffer.map(offset, stdr::size(data))); + stdr::copy(data, stdr::begin(gpu_data)); + buffer.unmap(); + + Return {}; + } + }; + + ///////////////////////////////////// + ///////////////////////////////////// + auto Buffer::map(ioffset offset) noexcept -> Expected { + return BufferAPI::map(*this, offset); + } + ///////////////////////////////////// ///////////////////////////////////// - auto Buffer::do_init(MemoryPropertyFlag memory_properties) noexcept -> Expected { - const auto create_info = VkBufferCreateInfo { + auto Buffer::flush(ioffset offset, usize size) noexcept -> Expected { + return BufferAPI::flush(*this, offset, size); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto Buffer::unmap() noexcept -> void { + return BufferAPI::unmap(*this); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto Buffer::upload(std::span data, ioffset offset) noexcept -> Expected { + return BufferAPI::upload(*this, std::move(data), offset); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto Buffer::do_init(PrivateTag, const CreateInfo& _create_info) noexcept -> Expected { + m_usages = _create_info.usages; + m_size = _create_info.size; + m_memory_properties = _create_info.properties; + m_is_persistently_mapped = _create_info.persistently_mapped; + + const auto& device = this->device(); + const auto& device_table = device.device_table(); + const auto create_info = VkBufferCreateInfo { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .pNext = nullptr, .flags = 0, .size = m_size, - .usage = to_vk(m_usages), + .usage = vk::to_vk(m_usages), .sharingMode = VK_SHARING_MODE_EXCLUSIVE, .queueFamilyIndexCount = 0, .pQueueFamilyIndices = nullptr, }; - return vk_call(m_vk_device_table->vkCreateBuffer, m_vk_device, &create_info, nullptr) - .transform(core::monadic::set(m_vk_handle)) - .and_then([this, &memory_properties] noexcept -> VulkanExpected { - const auto create_info = VmaAllocationCreateInfo { - .flags = 0, - .usage = VMA_MEMORY_USAGE_UNKNOWN, - .requiredFlags = to_vk(memory_properties), - .preferredFlags = 0, - .memoryTypeBits = 0, - .pool = nullptr, - .pUserData = nullptr, - .priority = 0 - }; - - auto out = VulkanExpected { std::in_place, nullptr }; - auto result = vmaAllocateMemoryForBuffer(m_vma_allocator, m_vk_handle, &create_info, &*out, nullptr); - if (result != VK_SUCCESS) out = std::unexpected { result }; - else { - m_vma_allocation = { [vma_allocator = m_vma_allocator](VmaAllocation handle) noexcept { - if (handle) { vmaFreeMemory(vma_allocator, handle); } - } }; - } - - return out; - }) - .transform(core::monadic::set(m_vma_allocation)) - .and_then([this] noexcept { return vk_call(vmaBindBufferMemory, m_vma_allocator, m_vma_allocation, m_vk_handle); }) - .transform_error(monadic::from_vk()) - .and_then([this] noexcept -> Expected { - if (m_is_persistently_mapped) return map(0u); - - return {}; - }) - .transform(core::monadic::discard()); + m_vk_handle = Try(vk::call_checked(device_table.vkCreateBuffer, device, &create_info, nullptr)); + + const auto vma_create_info = VmaAllocationCreateInfo { + .flags = 0, + .usage = VMA_MEMORY_USAGE_UNKNOWN, + .requiredFlags = vk::to_vk(m_memory_properties), + .preferredFlags = 0, + .memoryTypeBits = 0, + .pool = nullptr, + .pUserData = nullptr, + .priority = 0 + }; + const auto allocator = device.allocator(); + auto out = VmaAllocation { VK_NULL_HANDLE }; + Try(vk::call_checked(vmaAllocateMemoryForBuffer, allocator, m_vk_handle, &vma_create_info, &out, nullptr)); + m_vma_allocation = { [allocator](VmaAllocation handle) noexcept { + if (handle) { vmaFreeMemory(allocator, handle); } + } }; + m_vma_allocation = std::move(out); + Try(vk::call_checked(vmaBindBufferMemory, allocator, m_vma_allocation, m_vk_handle)); + + if (m_is_persistently_mapped) Try(map(0u)); + + Return {}; } ///////////////////////////////////// @@ -79,4 +172,30 @@ namespace stormkit::gpu { return 0; } + + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + auto Buffer::map(ioffset offset) noexcept -> Expected { + return BufferAPI::map(*this, offset); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto Buffer::flush(ioffset offset, usize size) noexcept -> Expected { + return BufferAPI::flush(*this, offset, size); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto Buffer::unmap() noexcept -> void { + return BufferAPI::unmap(*this); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto Buffer::upload(std::span data, ioffset offset) noexcept -> Expected { + return BufferAPI::upload(*this, std::move(data), offset); + } + } // namespace view } // namespace stormkit::gpu diff --git a/src/gpu/resource/image.cpp b/src/gpu/resource/image.cpp index 554026e9c..ebb25a093 100644 --- a/src/gpu/resource/image.cpp +++ b/src/gpu/resource/image.cpp @@ -4,6 +4,8 @@ module; +#include + #include module stormkit.gpu.resource; @@ -80,33 +82,63 @@ namespace stormkit::gpu { // } } // namespace - auto Image::do_init(const VkImageCreateInfo& create_info, MemoryPropertyFlag memory_properties) noexcept -> Expected { - return vk_call(m_vk_device_table->vkCreateImage, m_vk_device, &create_info, nullptr) - .transform(core::monadic::set(m_vk_handle)) - .and_then([this, memory_properties] noexcept -> VulkanExpected { - const auto create_info = VmaAllocationCreateInfo { - .flags = 0, - .usage = VMA_MEMORY_USAGE_UNKNOWN, - .requiredFlags = to_vk(memory_properties), - .preferredFlags = 0, - .memoryTypeBits = 0, - .pool = nullptr, - .pUserData = nullptr, - .priority = 0 - }; - - auto out = VulkanExpected { std::in_place, nullptr }; - auto result = vmaAllocateMemoryForImage(m_vma_allocator, m_vk_handle, &create_info, &*out, nullptr); - if (result != VK_SUCCESS) out = std::unexpected { result }; - else { - m_vma_allocation = { [vma_allocator = m_vma_allocator](auto handle) noexcept { - vmaFreeMemory(vma_allocator, handle); - } }; - } - return out; - }) - .transform(core::monadic::set(m_vma_allocation)) - .and_then([this] noexcept { return vk_call(vmaBindImageMemory, m_vma_allocator, m_vma_allocation, m_vk_handle); }) - .transform_error(monadic::from_vk()); + ///////////////////////////////////// + ///////////////////////////////////// + auto Image::do_init(PrivateTag, const CreateInfo& _create_info) noexcept -> Expected { + m_extent = _create_info.extent; + m_format = _create_info.format; + m_layers = _create_info.layers; + m_faces = 1; + m_mip_levels = _create_info.mip_levels; + m_type = _create_info.type; + m_flags = _create_info.flags; + m_samples = _create_info.samples; + m_usages = _create_info.usages; + + if (core::check_flag_bit(m_flags, gpu::ImageCreateFlag::CUBE_COMPATIBLE)) m_faces = 6u; + const auto create_info = VkImageCreateInfo { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .pNext = nullptr, + .flags = vk::to_vk(m_flags), + .imageType = vk::to_vk(m_type), + .format = vk::to_vk(m_format), + .extent = { m_extent.width, m_extent.height, m_extent.depth }, + .mipLevels = m_mip_levels, + .arrayLayers = m_layers * m_faces, + .samples = vk::to_vk(m_samples), + .tiling = vk::to_vk(_create_info.tiling), + .usage = vk::to_vk(m_usages), + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .queueFamilyIndexCount = 0, // TODO CHECK IF VALID VALUE + .pQueueFamilyIndices = nullptr, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + }; + + const auto& device = this->device(); + + m_vk_handle = Try(vk::call_checked(device.device_table().vkCreateImage, device, &create_info, nullptr)); + + const auto vma_create_info = VmaAllocationCreateInfo { + .flags = 0, + .usage = VMA_MEMORY_USAGE_UNKNOWN, + .requiredFlags = vk::to_vk(_create_info.properties), + .preferredFlags = 0, + .memoryTypeBits = 0, + .pool = nullptr, + .pUserData = nullptr, + .priority = 0 + }; + + const auto allocator = device.allocator(); + auto out = VmaAllocation { VK_NULL_HANDLE }; + Try(vk::call_checked(vmaAllocateMemoryForImage, allocator, m_vk_handle, &vma_create_info, &out, nullptr)); + m_vma_allocation = { [allocator](VmaAllocation handle) noexcept { + if (handle != VK_NULL_HANDLE) vk::call(vmaFreeMemory, allocator, handle); + } }; + m_vma_allocation = std::move(out); + + Try(vk::call_checked(vmaBindImageMemory, allocator, m_vma_allocation, m_vk_handle)); + + Return {}; } } // namespace stormkit::gpu diff --git a/src/gpu/resource/image_view.cpp b/src/gpu/resource/image_view.cpp new file mode 100644 index 000000000..fce96904f --- /dev/null +++ b/src/gpu/resource/image_view.cpp @@ -0,0 +1,57 @@ + +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +module stormkit.gpu.resource; + +import std; + +import stormkit.core; + +import stormkit.gpu.core; + +namespace stormkit::gpu { + ///////////////////////////////////// + ///////////////////////////////////// + auto ImageView::do_init(PrivateTag, + view::Image image, + ImageViewType type, + const ImageSubresourceRange& subresource_range) noexcept -> Expected { + m_type = type; + m_subresource_range = subresource_range; + + const auto vk_subresource_range = VkImageSubresourceRange { + .aspectMask = vk::to_vk(m_subresource_range.aspect_mask), + .baseMipLevel = m_subresource_range.base_mip_level, + .levelCount = m_subresource_range.level_count, + .baseArrayLayer = m_subresource_range.base_array_layer, + .layerCount = m_subresource_range.layer_count, + }; + + const auto create_info = VkImageViewCreateInfo { + .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .image = image, + .viewType = vk::to_vk(m_type), + .format = vk::to_vk(image.format()), + .components = { .r = VK_COMPONENT_SWIZZLE_R, + .g = VK_COMPONENT_SWIZZLE_G, + .b = VK_COMPONENT_SWIZZLE_B, + .a = VK_COMPONENT_SWIZZLE_A }, + .subresourceRange = vk_subresource_range, + }; + + const auto& device = this->device(); + + m_vk_handle = Try(vk::call_checked(device.device_table().vkCreateImageView, device, &create_info, nullptr)); + Return {}; + } +} // namespace stormkit::gpu diff --git a/src/gpu/resource/sampler.cpp b/src/gpu/resource/sampler.cpp new file mode 100644 index 000000000..c4d0bc1ed --- /dev/null +++ b/src/gpu/resource/sampler.cpp @@ -0,0 +1,50 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +module stormkit.gpu.resource; + +import std; + +import stormkit.core; + +import stormkit.gpu.core; + +namespace stormkit::gpu { + ///////////////////////////////////// + ///////////////////////////////////// + auto Sampler::do_init(PrivateTag, const Settings& settings) noexcept -> Expected { + m_settings = settings; + const auto create_info = VkSamplerCreateInfo { + .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .magFilter = vk::to_vk(m_settings.mag_filter), + .minFilter = vk::to_vk(m_settings.min_filter), + .mipmapMode = vk::to_vk(m_settings.mipmap_mode), + .addressModeU = vk::to_vk(m_settings.address_mode_u), + .addressModeV = vk::to_vk(m_settings.address_mode_v), + .addressModeW = vk::to_vk(m_settings.address_mode_w), + .mipLodBias = m_settings.mip_lod_bias, + .anisotropyEnable = m_settings.enable_anisotropy, + .maxAnisotropy = m_settings.max_anisotropy, + .compareEnable = m_settings.compare_enable, + .compareOp = vk::to_vk(m_settings.compare_operation), + .minLod = m_settings.min_lod, + .maxLod = m_settings.max_lod, + .borderColor = vk::to_vk(m_settings.border_color), + .unnormalizedCoordinates = m_settings.unnormalized_coordinates + }; + const auto& device = this->device(); + + m_vk_handle = Try(vk::call_checked(device.device_table().vkCreateSampler, device, &create_info, nullptr)); + Return {}; + } + +} // namespace stormkit::gpu diff --git a/src/gpu/resource/shader.cpp b/src/gpu/resource/shader.cpp index 4b049fbd7..8aadfcd1e 100644 --- a/src/gpu/resource/shader.cpp +++ b/src/gpu/resource/shader.cpp @@ -4,6 +4,8 @@ module; +#include + #include module stormkit.gpu.resource; @@ -16,6 +18,28 @@ import stormkit.gpu.core; ; namespace stormkit::gpu { + ///////////////////////////////////// + ///////////////////////////////////// + auto Shader::do_init(PrivateTag, std::vector data, ShaderStageFlag type) -> Expected { + m_source = std::move(data); + m_type = type; + + const auto create_info = VkShaderModuleCreateInfo { + .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .codeSize = stdr::size(m_source) * sizeof(SpirvID), + .pCode = stdr::data(m_source) + }; + + const auto& device = this->device(); + m_vk_handle = Try(vk::call_checked(device.device_table().vkCreateShaderModule, + device, + &create_info, + nullptr)); + Return {}; + } + ///////////////////////////////////// ///////////////////////////////////// auto Shader::reflect() noexcept -> void { diff --git a/src/wsi/linux/wayland/window.cpp b/src/wsi/linux/wayland/window.cpp index 7ed949f25..4892a862d 100644 --- a/src/wsi/linux/wayland/window.cpp +++ b/src/wsi/linux/wayland/window.cpp @@ -197,7 +197,7 @@ namespace stormkit::wsi::linux::wayland { auto Window::clear(const ucolor_rgb& color) noexcept -> void { const auto value = (255 << 24) + (color.r << 16) + (color.g << 8) + (color.b); - auto view = std::span { std::bit_cast(m_shm_buffer.get().begin()), m_shm_buffer->size() / sizeof(i32) }; + auto view = std::span { std::bit_cast(m_shm_buffer.value().begin()), m_shm_buffer->size() / sizeof(i32) }; stdr::fill(view, value); const auto [width, height] = extent().to(); @@ -208,7 +208,7 @@ namespace stormkit::wsi::linux::wayland { ///////////////////////////////////// ///////////////////////////////////// auto Window::fill_framebuffer(std::span colors) noexcept -> void { - auto view = std::span { std::bit_cast(m_shm_buffer.get().begin()), m_shm_buffer->size() / sizeof(i32) }; + auto view = std::span { std::bit_cast(m_shm_buffer.value().begin()), m_shm_buffer->size() / sizeof(i32) }; stdr::copy(colors | stdv::transform([](const auto& color) static noexcept { return (255 << 24) + (color.r << 16) + (color.g << 8) + (color.b); }), @@ -606,7 +606,7 @@ namespace stormkit::wsi::linux::wayland { auto old_pixel_buffer = DeferInit {}; const auto [width, height] = extent.to(); - if (not m_shm_buffer or stdr::size(m_shm_buffer.get()) < size) { + if (not m_shm_buffer or stdr::size(m_shm_buffer.value()) < size) { old_shm_buffer = std::move(m_shm_buffer); old_shm_pool = std::move(m_shm_pool); old_pixel_buffer = std::move(m_pixel_buffer); From 0048e531b2f848fdf9887e4ee4fb9c4a05151da9 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 16 Mar 2026 14:44:23 +0100 Subject: [PATCH 165/194] (core) add some concepts and rename some other --- include/stormkit/core/as_casts_macro.hpp | 8 +- include/stormkit/core/format_macro.hpp | 8 +- modules/stormkit/core/functional/utils.cppm | 15 +- modules/stormkit/core/meta/concepts.cppm | 159 +++--- modules/stormkit/core/meta/type_query.cppm | 45 +- modules/stormkit/core/typesafe/boolean.cppm | 4 +- modules/stormkit/core/typesafe/byte.cppm | 8 +- modules/stormkit/core/typesafe/ref.cppm | 501 ++++++++++++------ modules/stormkit/core/typesafe/safecasts.cppm | 16 +- modules/stormkit/core/utils/color.cppm | 8 +- .../stormkit/core/utils/numeric_range.cppm | 2 +- src/wsi/common/window_base.cppm | 2 +- 12 files changed, 505 insertions(+), 271 deletions(-) diff --git a/include/stormkit/core/as_casts_macro.hpp b/include/stormkit/core/as_casts_macro.hpp index f9cab0eb2..616f42274 100644 --- a/include/stormkit/core/as_casts_macro.hpp +++ b/include/stormkit/core/as_casts_macro.hpp @@ -8,13 +8,13 @@ #include #define ASCASTER_STRICT_DECLARE(_To, _From) \ - template To, stormkit::meta::IsStrict<_From> From> \ + template To, stormkit::meta::SameAs<_From> From> \ struct stormkit::casts::AsCaster { \ static constexpr auto operator()(const From& from, const std::source_location& location) noexcept -> To; \ }; #define ASCASTER_STRICT_DEFINE(_To, _From) \ - template To, stormkit::meta::IsStrict<_From> From> \ + template To, stormkit::meta::SameAs<_From> From> \ STORMKIT_FORCE_INLINE constexpr auto \ stormkit::casts::AsCaster::operator()(const From& from, \ [[maybe_unused]] const std::source_location& location) noexcept -> To @@ -40,13 +40,13 @@ ASCASTER_DEFINE(_To, _From) #define NARROWCASTER_STRICT_DECLARE(_To, _From) \ - template To, stormkit::meta::IsStrict<_From> From> \ + template To, stormkit::meta::SameAs<_From> From> \ struct stormkit::casts::NarrowCaster { \ static constexpr auto operator()(const From& from, const std::source_location& location) noexcept -> To; \ }; #define NARROWCASTER_STRICT_DEFINE(_To, _From) \ - template To, stormkit::meta::IsStrict<_From> From> \ + template To, stormkit::meta::SameAs<_From> From> \ STORMKIT_FORCE_INLINE constexpr auto \ stormkit::casts::NarrowCaster::operator()(const From& from, \ [[maybe_unused]] const std::source_location& location) noexcept -> To diff --git a/include/stormkit/core/format_macro.hpp b/include/stormkit/core/format_macro.hpp index 778dca433..28d5783c5 100644 --- a/include/stormkit/core/format_macro.hpp +++ b/include/stormkit/core/format_macro.hpp @@ -14,7 +14,7 @@ constexpr auto parse(ParseContext& ctx) noexcept -> decltype(ctx.begin()); \ \ template \ - requires(stormkit::meta::IsStrict>) \ + requires(stormkit::meta::SameAs>) \ auto format(U&& data, FormatContext& ctx) const noexcept -> decltype(ctx.out()); \ }; @@ -26,21 +26,21 @@ #define FORMATTER_DEFINE_FORMAT(_From) \ template<_From T, typename CharT> \ template \ - requires(stormkit::meta::IsStrict>) \ + requires(stormkit::meta::SameAs>) \ inline auto std::formatter::format(U&& data, FormatContext& ctx) const noexcept -> decltype(ctx.out()) #define FORMATTER_INHERIT_DECLARE(_Parent, _From) \ template<_From T, typename CharT> \ struct std::formatter: std::formatter<_Parent, CharT> { \ template \ - requires(stormkit::meta::IsStrict>) \ + requires(stormkit::meta::SameAs>) \ auto format(U&& data, FormatContext& ctx) const noexcept -> decltype(ctx.out()); \ }; #define FORMATTER_INHERIT_DEFINE_FORMAT(_From) \ template<_From T, typename CharT> \ template \ - requires(stormkit::meta::IsStrict>) \ + requires(stormkit::meta::SameAs>) \ inline auto std::formatter::format(U&& data, FormatContext& ctx) const noexcept -> decltype(ctx.out()) #define FORMATTER_INHERIT_DEFINE_FORMAT_AS_STRING(_Parent, _From) \ diff --git a/modules/stormkit/core/functional/utils.cppm b/modules/stormkit/core/functional/utils.cppm index 1987426ea..fac519139 100644 --- a/modules/stormkit/core/functional/utils.cppm +++ b/modules/stormkit/core/functional/utils.cppm @@ -11,6 +11,7 @@ export module stormkit.core:functional.utils; import std; import :meta; +import :typesafe.ref; namespace stormkit { inline namespace core { namespace details { struct EitherFunc { @@ -19,15 +20,15 @@ namespace stormkit { inline namespace core { namespace details { -> decltype(false_()); template - using ForwardArg = meta::ForwardLike>>; + using ForwardArg = meta::ForwardLike>>; template [[nodiscard]] static constexpr auto operator()(T value, - std::invocable&> auto&& true_, + std::invocable&> auto&& true_, std::invocable auto&& false_) noexcept -> decltype(false_()); - template + template requires(meta::IsConvertibleTo) [[nodiscard]] static constexpr auto operator()(T&& value, @@ -68,21 +69,21 @@ namespace stormkit { inline namespace core { template STORMKIT_FORCE_INLINE constexpr auto EitherFunc::operator()(T value, - std::invocable&> auto&& true_, + std::invocable&> auto&& true_, std::invocable auto&& false_) noexcept -> decltype(false_()) { - if (static_cast(value)) return true_(*value); + if (static_cast(value)) return true_(unref(value)); return false_(); } ///////////////////////////////////// ///////////////////////////////////// - template + template requires(meta::IsConvertibleTo) STORMKIT_FORCE_INLINE constexpr auto EitherFunc::operator()(T&& value, std::invocable> auto&& true_, std::invocable auto&& false_) noexcept -> decltype(false_()) { - if (static_cast(value)) return true_(std::forward_like(*value)); + if (static_cast(value)) return true_(std::forward_like(unref(value))); return false_(); } } // namespace details diff --git a/modules/stormkit/core/meta/concepts.cppm b/modules/stormkit/core/meta/concepts.cppm index 8f6a8ecf5..40d78a6f7 100644 --- a/modules/stormkit/core/meta/concepts.cppm +++ b/modules/stormkit/core/meta/concepts.cppm @@ -37,12 +37,6 @@ namespace stormkit { inline namespace core { namespace meta::details { }}} // namespace stormkit::core::meta::details export namespace stormkit { inline namespace core { namespace meta { - template - concept IsStrict = std::same_as; - - template - concept Same = std::same_as; - template concept SameAs = std::same_as; @@ -64,6 +58,36 @@ export namespace stormkit { inline namespace core { namespace meta { template concept... C> concept AnyOf = (C or ...); + template + concept IsBooleanTestable = details::IsBooleanTestable && requires(T&& t) { + { not std::forward(t) } -> details::IsBooleanTestable; + }; + + template class T> + concept IsSpecializationOf = requires(S&& s) { + { details::is_specialization_of_helper(std::forward(s)) } -> SameAs; + }; + + template typename T> + concept IsSpecializationOfNTTP_TV = requires(S&& s) { + { details::is_specialization_of_helper_nttp_tv(std::forward(s)) } -> SameAs; + }; + + template typename T> + concept IsSpecializationOfNTTP_TTV = requires(S&& s) { + { details::is_specialization_of_helper_nttp_ttv(std::forward(s)) } -> SameAs; + }; + + template typename T> + concept IsSpecializationOfNTTP_TTVTs = requires(S&& s) { + { details::is_specialization_of_helper_nttp_ttvts(std::forward(s)) } -> SameAs; + }; + + template class T> + concept IsSpecializationWithNTTPOf = requires(S&& s) { + { details::is_specialization_of_with_nttp_helper(std::forward(s)) } -> SameAs; + }; + template concept ConvertibleTo = std::convertible_to; @@ -74,7 +98,7 @@ export namespace stormkit { inline namespace core { namespace meta { concept HasStdHashSpecialization = requires(T&& a) { std::hash> {}(std::forward(a)); }; template - concept IsCanonical = IsStrict, std::remove_cvref_t>; + concept IsCanonical = SameAs, std::remove_cvref_t>; template concept PlainIs = Is, std::remove_cvref_t>; @@ -92,7 +116,7 @@ export namespace stormkit { inline namespace core { namespace meta { concept SameAsAnyOf = (SameAs or ...); template - concept IsByte = IsStrict; + concept IsByte = SameAs; template concept IsByteSized = sizeof(T) == sizeof(std::byte); @@ -104,27 +128,22 @@ export namespace stormkit { inline namespace core { namespace meta { concept IsStringLike = std::convertible_to; template - concept IsRawPointer = std::is_pointer_v; + concept IsOptionalType = IsSpecializationOf; template - concept IsNonOwningPointer = IsRawPointer or (requires { - typename T::element_type; - } and requires(T a) { - { a.operator->() } -> std::convertible_to; - { a.operator*() }; - { static_cast(a) }; - }); + concept IsExpectedType = IsSpecializationOf; template - concept IsOwningPointer = IsNonOwningPointer and requires(T a) { - { a.reset() }; - }; + concept IsVariantType = IsSpecializationOf; template - concept IsPointer = IsNonOwningPointer or IsOwningPointer; + concept IsMdspanType = IsSpecializationOf; template - concept IsNotPointer = not IsPointer; + concept IsArrayType = IsSpecializationWithNTTPOf; + + template + concept IsStdReferenceWrapper = IsSpecializationOf; template concept IsLValueReference = std::is_lvalue_reference_v; @@ -141,6 +160,32 @@ export namespace stormkit { inline namespace core { namespace meta { template concept IsReferenceTo = IsReference and Is, U>; + template + concept IsRawPointer = std::is_pointer_v; + + template + concept IsNonOwningPointer = IsRawPointer or (requires { + typename std::pointer_traits::element_type; + } and requires(T a) { + { a.operator->() } -> std::convertible_to; + { a.operator*() }; + { a == nullptr } -> IsBooleanTestable; + }) or IsStdReferenceWrapper; + + template + concept IsOwningPointer = IsNonOwningPointer and requires(T a) { + { a.reset() }; + }; + + template + concept IsPointer = IsNonOwningPointer or IsOwningPointer; + + template + concept IsNotPointer = not IsPointer; + + template + concept IsPointerOf = IsPointer and SameAs; + template concept IsMovedOwningPointer = IsOwningPointer and IsRValueReference; @@ -155,7 +200,23 @@ export namespace stormkit { inline namespace core { namespace meta { concept IsIndirection = IsLValueReference or IsPointer; template - concept AreIndirections = ((IsLValueReference or IsPointer) && ...); + concept AreIndirections = ((IsLValueReference or IsPointer) and ...); + + template + concept IsContainer = requires(T& val) { + typename T::value_type; + { val.operator*() } -> IsReferenceTo; + { val.operator->() } -> IsReferenceTo; + }; + + template + concept IsContainerOf = IsContainer and SameAs; + + template + concept IsContainerOrPointer = IsContainer or IsPointer; + + template + concept IsContainerOrPointerOf = IsContainerOf or IsPointerOf; template concept IsPolymorphic = std::is_polymorphic_v; @@ -188,7 +249,7 @@ export namespace stormkit { inline namespace core { namespace meta { concept IsEnumeration = std::is_enum_v and IsNotByte; template - concept IsIntegral = (std::integral and not IsStrict and not IsByte) + concept IsIntegral = (std::integral and not SameAs and not IsByte) or Is>> or Is>> #if defined(STORMKIT_COMPILER_MSVC) @@ -214,58 +275,6 @@ export namespace stormkit { inline namespace core { namespace meta { template concept IsPreIncrementable = requires(T& a) { a.operator--(); }; - template - concept IsBooleanTestable = details::IsBooleanTestable && requires(T&& t) { - { not std::forward(t) } -> details::IsBooleanTestable; - }; - - template - concept IsContainedSemantics = requires(T& val) { - typename T::value_type; - { val.operator*() } -> IsReferenceTo; - { val.operator->() } -> IsReferenceTo; - }; - - template class T> - concept IsSpecializationOf = requires(S&& s) { - { details::is_specialization_of_helper(std::forward(s)) } -> IsStrict; - }; - - template typename T> - concept IsSpecializationOfNTTP_TV = requires(S&& s) { - { details::is_specialization_of_helper_nttp_tv(std::forward(s)) } -> IsStrict; - }; - - template typename T> - concept IsSpecializationOfNTTP_TTV = requires(S&& s) { - { details::is_specialization_of_helper_nttp_ttv(std::forward(s)) } -> IsStrict; - }; - - template typename T> - concept IsSpecializationOfNTTP_TTVTs = requires(S&& s) { - { details::is_specialization_of_helper_nttp_ttvts(std::forward(s)) } -> IsStrict; - }; - - template class T> - concept IsSpecializationWithNTTPOf = requires(S&& s) { - { details::is_specialization_of_with_nttp_helper(std::forward(s)) } -> IsStrict; - }; - - template - concept IsOptionalType = IsSpecializationOf; - - template - concept IsExpectedType = IsSpecializationOf; - - template - concept IsVariantType = IsSpecializationOf; - - template - concept IsMdspanType = IsSpecializationOf; - - template - concept IsArrayType = IsSpecializationWithNTTPOf; - template concept IsPredicate = std::predicate; diff --git a/modules/stormkit/core/meta/type_query.cppm b/modules/stormkit/core/meta/type_query.cppm index 6cf8d8288..034cbd62f 100644 --- a/modules/stormkit/core/meta/type_query.cppm +++ b/modules/stormkit/core/meta/type_query.cppm @@ -49,19 +49,43 @@ namespace stormkit { inline namespace core { namespace meta { }; template - struct PointedType { - using Type = RemoveReferencesType; + struct PointerType; + + template + struct PointerType { + using Type = typename std::pointer_traits::pointer; }; - template - struct PointedType { - using Type = UnderlyingType::Type; + template + struct PointerType> { + using Type = std::reference_wrapper::type*; }; + template + struct PointedType; + template struct PointedType { using Type = typename std::pointer_traits::element_type; }; + + template + struct PointedType> { + using Type = std::reference_wrapper::type; + }; + + template + struct ContainedType; + + template + struct ContainedType { + using Type = typename T::value_type; + }; + + template + struct ContainedType { + using Type = typename T::value_type; + }; } // namespace details export { @@ -69,15 +93,16 @@ namespace stormkit { inline namespace core { namespace meta { using UnderlyingType = details::UnderlyingType::Type; template - using ElementType = typename std::pointer_traits::element_type; + using PointerType = details::PointerType::Type; template - using PointerType = typename std::pointer_traits::pointer; + using PointedType = details::PointedType::Type; - // clang-format off template - using PointedType = details::PointedType::Type; - // clang-format on + using ContainedType = details::ContainedType::Type; + + template + using ContainedOrPointedType = If, ContainedType, PointedType>; template using IteratorType = stdr::iterator_t; diff --git a/modules/stormkit/core/typesafe/boolean.cppm b/modules/stormkit/core/typesafe/boolean.cppm index 81b51fe7e..051d421bb 100644 --- a/modules/stormkit/core/typesafe/boolean.cppm +++ b/modules/stormkit/core/typesafe/boolean.cppm @@ -41,7 +41,7 @@ export { }} // namespace stormkit::core - FORMATTER_INHERIT_DECLARE(bool, stormkit::meta::IsStrict) + FORMATTER_INHERIT_DECLARE(bool, stormkit::meta::SameAs) } //////////////////////////////////////////////////////////////////// @@ -106,6 +106,6 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// -FORMATTER_INHERIT_DEFINE_FORMAT(stormkit::meta::IsStrict) { +FORMATTER_INHERIT_DEFINE_FORMAT(stormkit::meta::SameAs) { return formatter::format(static_cast(data), ctx); } diff --git a/modules/stormkit/core/typesafe/byte.cppm b/modules/stormkit/core/typesafe/byte.cppm index ad7fb4d94..789295044 100644 --- a/modules/stormkit/core/typesafe/byte.cppm +++ b/modules/stormkit/core/typesafe/byte.cppm @@ -90,7 +90,7 @@ export namespace stormkit { inline namespace core { constexpr auto bytes_as(std::span bytes) noexcept -> const T&; template - requires(meta::SameAs>, byte>) + requires(meta::SameAs, byte>) [[nodiscard]] constexpr auto bytes_as_span(const Range& bytes) noexcept -> std::span; @@ -104,7 +104,7 @@ export namespace stormkit { inline namespace core { constexpr auto bytes_mut_as(std::span bytes) noexcept -> T&; template - requires(meta::SameAs, byte> and not meta::IsConst) + requires(meta::SameAs, byte> and not meta::IsConst) [[nodiscard]] constexpr auto bytes_mut_as_span(Range& range) noexcept -> std::span; @@ -257,7 +257,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - requires(meta::SameAs>, byte>) + requires(meta::SameAs>, byte>) STORMKIT_FORCE_INLINE constexpr auto bytes_as_span(const Range& bytes) noexcept -> std::span { return std::span { std::bit_cast(stdr::data(bytes)), stdr::size(bytes) / sizeof(T) }; @@ -289,7 +289,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - requires(meta::SameAs, byte> and not meta::IsConst) + requires(meta::SameAs, byte> and not meta::IsConst) STORMKIT_FORCE_INLINE constexpr auto bytes_mut_as_span(Range& bytes) noexcept -> std::span { return std::span { std::bit_cast(stdr::data(bytes)), stdr::size(bytes) / sizeof(T) }; diff --git a/modules/stormkit/core/typesafe/ref.cppm b/modules/stormkit/core/typesafe/ref.cppm index 406ecd5a5..583e1d575 100644 --- a/modules/stormkit/core/typesafe/ref.cppm +++ b/modules/stormkit/core/typesafe/ref.cppm @@ -23,11 +23,6 @@ import :hash; export { namespace stormkit { inline namespace core { - namespace meta { - template - concept ContainedOrPointerOf = (IsContainedSemantics or IsPointer) and SameAs>; - } - template using ptr = T*; template @@ -39,6 +34,9 @@ export { template using OptionalRef = Ref; + inline constexpr struct Raw { + } RAW; + template class Ref { public: @@ -158,120 +156,203 @@ export { PointerType m_value; - template - friend constexpr auto as_ref(const U&) noexcept -> Ref>; + template + friend constexpr auto as_ref_raw(const U&) noexcept -> Ref; - template - requires meta::IsNotConst> - friend constexpr auto as_ref_mut(U&) noexcept -> Ref>; + template + requires(not meta::IsConst) + friend constexpr auto as_ref_mut_raw(U&) noexcept -> Ref; - template - friend constexpr auto as_ref_like(U&) noexcept -> Ref, meta::PointedType>>; + template + friend constexpr auto as_ref_like_raw(U&) noexcept -> Ref; - template - friend constexpr auto as_opt_ref(const U&) noexcept -> OptionalRef>; + template + friend constexpr auto as_optref_raw(const U&) noexcept -> OptionalRef; - template - requires meta::IsNotConst> - friend constexpr auto as_opt_ref_mut(U&) noexcept -> OptionalRef>; + template + requires(not meta::IsConst) + friend constexpr auto as_optref_mut_raw(U&) noexcept -> OptionalRef; - template - friend constexpr auto as_opt_ref_like(U&) noexcept - -> OptionalRef, meta::PointedType>>; + template + friend constexpr auto as_optref_like_raw(U&) noexcept -> OptionalRef; }; - template + template + [[nodiscard]] + constexpr auto as_ref_raw(const T& value) noexcept -> Ref; + + template + requires(not meta::IsContainerOrPointer) + [[nodiscard]] + constexpr auto as_ref(const T& value) noexcept -> Ref; + + template + [[nodiscard]] + constexpr auto as_ref(const T& value) noexcept -> Ref>; + + template + [[nodiscard]] + constexpr auto as_ref(const T& value) noexcept -> Ref>; + + template + [[nodiscard]] + constexpr auto as_ref_mut_raw(const T& value) noexcept -> Ref; + + template + requires(not meta::IsContainerOrPointer and not meta::IsConst) + [[nodiscard]] + constexpr auto as_ref_mut(T& value) noexcept -> Ref; + + template + requires(not meta::IsConst>) + [[nodiscard]] + constexpr auto as_ref_mut(T& value) noexcept -> Ref>; + + template + requires(not meta::IsConst>) [[nodiscard]] - constexpr auto as_ref(const T& value STORMKIT_LIFETIMEBOUND) noexcept -> Ref>; + constexpr auto as_ref_mut(T& value) noexcept -> Ref>; - template - requires meta::IsNotConst> + template + [[nodiscard]] + constexpr auto as_ref_mut_like(const T& value) noexcept -> Ref; + + template [[nodiscard]] - constexpr auto as_ref_mut(T& value STORMKIT_LIFETIMEBOUND) noexcept -> Ref>; + constexpr auto as_ref_like_raw(T& value) noexcept -> Ref; - template + template + requires(not meta::IsContainerOrPointer) [[nodiscard]] - constexpr auto as_ref_like(T& value STORMKIT_LIFETIMEBOUND) noexcept - -> Ref, meta::PointedType>>; + constexpr auto as_ref_like(T& value) noexcept -> Ref; - template + template [[nodiscard]] - constexpr auto as_opt_ref(const T& value STORMKIT_LIFETIMEBOUND) noexcept -> OptionalRef>; + constexpr auto as_ref_like(T& value) noexcept -> Ref>; - template - requires meta::IsNotConst> + template [[nodiscard]] - constexpr auto as_opt_ref_mut(T& value STORMKIT_LIFETIMEBOUND) noexcept -> OptionalRef>; + constexpr auto as_ref_like(T& value) noexcept -> Ref>; - template + template [[nodiscard]] - constexpr auto as_opt_ref_like(T& value STORMKIT_LIFETIMEBOUND) noexcept - -> OptionalRef, meta::PointedType>>; + constexpr auto as_optref_raw(const T& value) noexcept -> OptionalRef; template + requires(not meta::IsContainerOrPointer) + [[nodiscard]] + constexpr auto as_optref(const T& value) noexcept -> OptionalRef; + + template + [[nodiscard]] + constexpr auto as_optref(const T& value) noexcept -> OptionalRef>; + + template + [[nodiscard]] + constexpr auto as_optref(const T& value) noexcept -> OptionalRef>; + + template + requires(not meta::IsConst) + [[nodiscard]] + constexpr auto as_optref_mut_raw(T& value) noexcept -> OptionalRef; + + template + requires(not meta::IsContainerOrPointer and not meta::IsConst) + [[nodiscard]] + constexpr auto as_optref_mut(T& value) noexcept -> OptionalRef; + + template + requires(not meta::IsConst>) [[nodiscard]] - constexpr auto unref(const Ref& value STORMKIT_LIFETIMEBOUND) noexcept -> const T&; + constexpr auto as_optref_mut(T& value) noexcept -> OptionalRef>; - template + template + requires(not meta::IsConst>) [[nodiscard]] - constexpr auto unref_mut(const Ref& value STORMKIT_LIFETIMEBOUND) noexcept -> T&; + constexpr auto as_optref_mut(T& value) noexcept -> OptionalRef>; - template typename Out = std::array, bool RAW = false, typename... Args> + template + [[nodiscard]] + constexpr auto as_optref_like_raw(T& value) noexcept -> OptionalRef; + + template + requires(not meta::IsContainerOrPointer) + [[nodiscard]] + constexpr auto as_optref_like(T& value) noexcept -> OptionalRef; + + template + [[nodiscard]] + constexpr auto as_optref_like(T& value) noexcept -> OptionalRef>; + + template + [[nodiscard]] + constexpr auto as_optref_like(T& value) noexcept -> OptionalRef>; + + template + [[nodiscard]] + constexpr auto unref(const T& value) noexcept -> const meta::PointedType&; + + template + requires(not meta::IsConst>) + [[nodiscard]] + constexpr auto unref_mut(T& value) noexcept -> meta::PointedType&; + + template typename Out = std::array, typename... Args> requires(not std::ranges::range and ...) [[nodiscard]] constexpr auto as_refs(Args&&... args) noexcept -> decltype(auto); - template typename Out = std::vector, bool RAW = false, typename... Args> + template typename Out = std::vector, typename... Args> requires(not std::ranges::range and ...) [[nodiscard]] constexpr auto to_refs(Args&&... args) noexcept -> decltype(auto); - template typename Out = std::array, bool RAW = false, typename... Args> + template typename Out = std::array, typename... Args> requires(not std::ranges::range and ...) [[nodiscard]] constexpr auto as_ref_muts(Args&&... args) noexcept -> decltype(auto); - template typename Out = std::vector, bool RAW = false, typename... Args> + template typename Out = std::vector, typename... Args> requires(not std::ranges::range and ...) [[nodiscard]] constexpr auto to_ref_muts(Args&&... args) noexcept -> decltype(auto); - template class Out = std::vector, bool RAW = false, std::ranges::range T> + template class Out = std::vector, std::ranges::range T> requires(std::ranges::range>) [[nodiscard]] constexpr auto to_refs(const T& range) noexcept -> decltype(auto); - template class Out = std::vector, bool RAW = false, std::ranges::range T> + template class Out = std::vector, std::ranges::range T> requires(std::ranges::range>) [[nodiscard]] constexpr auto to_mut_refs(T& range) noexcept -> decltype(auto); - template typename Out = std::array, bool RAW = false, typename... Args> + template typename Out = std::array, typename... Args> requires(not std::ranges::range and ...) [[nodiscard]] - constexpr auto as_opt_refs(Args&&... args) noexcept -> decltype(auto); + constexpr auto as_optrefs(Args&&... args) noexcept -> decltype(auto); - template typename Out = std::vector, bool RAW = false, typename... Args> + template typename Out = std::vector, typename... Args> requires(not std::ranges::range and ...) [[nodiscard]] constexpr auto to_opt_refs(Args&&... args) noexcept -> decltype(auto); - template typename Out = std::array, bool RAW = false, typename... Args> + template typename Out = std::array, typename... Args> requires(not std::ranges::range and ...) [[nodiscard]] - constexpr auto as_opt_ref_muts(Args&&... args) noexcept -> decltype(auto); + constexpr auto as_optref_muts(Args&&... args) noexcept -> decltype(auto); - template typename Out = std::vector, bool RAW = false, typename... Args> + template typename Out = std::vector, typename... Args> requires(not std::ranges::range and ...) [[nodiscard]] constexpr auto to_opt_ref_muts(Args&&... args) noexcept -> decltype(auto); - template class Out = std::vector, bool RAW = false, std::ranges::range T> + template class Out = std::vector, std::ranges::range T> requires(std::ranges::range>) [[nodiscard]] constexpr auto to_opt_refs(const T& range) noexcept -> decltype(auto); - template class Out = std::vector, bool RAW = false, std::ranges::range T> + template class Out = std::vector, std::ranges::range T> requires(std::ranges::range>) [[nodiscard]] constexpr auto to_mut_opt_refs(T& range) noexcept -> decltype(auto); @@ -372,7 +453,7 @@ namespace stormkit { inline namespace core { template U, bool OptionalU> requires(not(meta::IsConst and not meta::IsConst)) constexpr auto Ref::operator=(Ref&& other) noexcept -> decltype(auto) { - if constexpr (meta::IsStrict and Optional == OptionalU) + if constexpr (meta::SameAs and Optional == OptionalU) if (&other == this) return *this; m_value = std::exchange(other.m_value, nullptr); @@ -622,243 +703,361 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template + template + STORMKIT_FORCE_INLINE + constexpr auto as_ref_raw(const T& value) noexcept -> Ref { + return { std::addressof(value) }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(not meta::IsContainerOrPointer) + STORMKIT_FORCE_INLINE + constexpr auto as_ref(const T& value) noexcept -> Ref { + return as_ref_raw(value); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template STORMKIT_FORCE_INLINE constexpr auto as_ref(const T& value) noexcept -> Ref> { - using OutRef = Ref>; + EXPECTS(value != nullptr); + return as_ref(unref(value)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto as_ref(const T& value) noexcept -> Ref> { + EXPECTS(value.operator bool()); + return as_ref(value.value()); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(not meta::IsConst) + STORMKIT_FORCE_INLINE + constexpr auto as_ref_mut_raw(T& value) noexcept -> Ref { + return { std::addressof(value) }; + } - if constexpr (not RAW and meta::IsPointer) { - EXPECTS(value != nullptr); - return OutRef { std::addressof(*value) }; - } else if constexpr (not RAW and meta::IsContainedSemantics) { - EXPECTS(value.operator bool()); - return OutRef { &(value.operator*()) }; - } else { - return OutRef { std::addressof(value) }; - } + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(not meta::IsContainerOrPointer and not meta::IsConst) + STORMKIT_FORCE_INLINE + constexpr auto as_ref_mut(T& value) noexcept -> Ref { + return as_ref_mut_raw(value); } ///////////////////////////////////// ///////////////////////////////////// - template - requires meta::IsNotConst> + template + requires(not meta::IsConst>) STORMKIT_FORCE_INLINE constexpr auto as_ref_mut(T& value) noexcept -> Ref> { - using OutRef = Ref>; + EXPECTS(value != nullptr); + return as_ref_mut(unref_mut(value)); + } - if constexpr (not RAW and meta::IsPointer) { - EXPECTS(value != nullptr); - return OutRef { std::addressof(*value) }; - } else if constexpr (not RAW and meta::IsContainedSemantics) { - EXPECTS(value.operator bool()); - return OutRef { &(value.operator*()) }; - } else { - return OutRef { std::addressof(value) }; - } + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(not meta::IsConst>) + STORMKIT_FORCE_INLINE + constexpr auto as_ref_mut(T& value) noexcept -> Ref> { + if constexpr (requires { value.has_value(); }) EXPECTS(value.has_value()); + return as_ref_mut(value.value()); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto as_ref_like_raw(T& value) noexcept -> Ref { + return { std::addressof(value) }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(not meta::IsContainerOrPointer) + STORMKIT_FORCE_INLINE + constexpr auto as_ref_like(T& value, Raw) noexcept -> Ref { + return as_ref_like_raw(value); } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr auto as_ref_like(T& value) noexcept -> Ref, meta::PointedType>> { - using OutRef = Ref, meta::PointedType>>; + constexpr auto as_ref_like(T& value) noexcept -> Ref> { + EXPECTS(value != nullptr); + if (meta::IsConst>) return as_ref_like(unref(value)); + else + return as_ref_like(unref_mut(value)); + } - if constexpr (not RAW and meta::IsPointer) { - EXPECTS(value != nullptr); - return OutRef { std::addressof(*value) }; - } else if constexpr (not RAW and meta::IsContainedSemantics) { - EXPECTS(value.operator bool()); - return OutRef { &(value.operator*()) }; - } else { - return OutRef { std::addressof(value) }; - } + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto as_ref_like(T& value) noexcept -> Ref> { + if constexpr (requires { value.has_value(); }) EXPECTS(value.has_value()); + return as_ref_like(value.value()); } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr auto as_opt_ref(const T& value) noexcept -> OptionalRef> { - using OutRef = OptionalRef>; + constexpr auto as_optref_raw(const T& value) noexcept -> OptionalRef { + return { std::addressof(value) }; + } - if constexpr (not RAW and meta::IsPointer) { - return OutRef { std::addressof(*value) }; - } else if constexpr (not RAW and meta::IsContainedSemantics) { - return OutRef { &(value.operator*()) }; - } else { - return OutRef { std::addressof(value) }; - } + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(not meta::IsContainerOrPointer) + STORMKIT_FORCE_INLINE + constexpr auto as_optref(const T& value) noexcept -> OptionalRef { + return as_optref_raw(value); } ///////////////////////////////////// ///////////////////////////////////// - template - requires meta::IsNotConst> + template STORMKIT_FORCE_INLINE - constexpr auto as_opt_ref_mut(T& value) noexcept -> OptionalRef> { - using OutRef = OptionalRef>; + constexpr auto as_optref(const T& value) noexcept -> OptionalRef> { + EXPECTS(value != nullptr); + return as_optref(unref(value)); + } - if constexpr (not RAW and meta::IsPointer) { - return OutRef { std::addressof(*value) }; - } else if constexpr (not RAW and meta::IsContainedSemantics) { - return OutRef { &(value.operator*()) }; - } else { - return OutRef { std::addressof(value) }; - } + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto as_optref(const T& value) noexcept -> OptionalRef> { + EXPECTS(value.operator bool()); + return as_optref(value.value()); } ///////////////////////////////////// ///////////////////////////////////// - template + template + requires(not meta::IsConst) STORMKIT_FORCE_INLINE - constexpr auto as_opt_ref_like(T& value) noexcept -> OptionalRef, meta::PointedType>> { - using OutRef = OptionalRef, meta::PointedType>>; - if constexpr (not RAW and meta::IsPointer) { - return OutRef { std::addressof(*value) }; - } else if constexpr (not RAW and meta::IsContainedSemantics) { - return OutRef { &(value.operator*()) }; - } else { - return OutRef { std::addressof(value) }; - } + constexpr auto as_optref_mut_raw(T& value) noexcept -> OptionalRef { + return { std::addressof(value) }; } ///////////////////////////////////// ///////////////////////////////////// template - STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto unref(const Ref& value) noexcept -> const T& { + requires(not meta::IsContainerOrPointer and not meta::IsConst) + STORMKIT_FORCE_INLINE + constexpr auto as_optref_mut(T& value) noexcept -> OptionalRef { + return as_optref_mut(value); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(not meta::IsConst>) + STORMKIT_FORCE_INLINE + constexpr auto as_optref_mut(T& value) noexcept -> OptionalRef> { + EXPECTS(value != nullptr); + return as_optref_mut(unref_mut(value)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(not meta::IsConst>) + STORMKIT_FORCE_INLINE + constexpr auto as_optref_mut(T& value) noexcept -> OptionalRef> { + if constexpr (requires { value.has_value(); }) EXPECTS(value.has_value()); + return as_optref_mut(value.value()); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto as_optref_like_raw(T& value) noexcept -> OptionalRef { + return { std::addressof(value) }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(not meta::IsContainerOrPointer) + STORMKIT_FORCE_INLINE + constexpr auto as_optref_like(T& value) noexcept -> OptionalRef { + return as_optref_like_raw(value); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto as_optref_like(T& value) noexcept -> OptionalRef> { + EXPECTS(value != nullptr); + if (meta::IsConst>) return as_optref_like(unref(value)); + else + return as_optref_like(unref_mut(value)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto as_optref_like(T& value) noexcept -> OptionalRef> { + if constexpr (requires { value.has_value(); }) EXPECTS(value.has_value()); + return as_optref_like(value.value()); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto unref(const T& value) noexcept -> const meta::PointedType& { return *value; } ///////////////////////////////////// ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto unref_mut(const Ref& value) noexcept -> T& { + template + requires(not meta::IsConst>) + STORMKIT_FORCE_INLINE + constexpr auto unref_mut(T& value) noexcept -> meta::PointedType& { return *value; } ///////////////////////////////////// ///////////////////////////////////// - template typename Out, bool RAW, typename... Args> + template typename Out, typename... Args> requires(not std::ranges::range and ...) STORMKIT_FORCE_INLINE constexpr auto as_refs(Args&&... args) noexcept -> decltype(auto) { - return Out { as_ref(std::forward(args))... }; + return Out { as_ref(std::forward(args))... }; } ///////////////////////////////////// ///////////////////////////////////// - template typename Out, bool RAW, typename... Args> + template typename Out, typename... Args> requires(not std::ranges::range and ...) STORMKIT_FORCE_INLINE constexpr auto to_refs(Args&&... args) noexcept -> decltype(auto) { - return Out { { as_ref(std::forward(args))... } }; + return Out { { as_ref(std::forward(args))... } }; } ///////////////////////////////////// ///////////////////////////////////// - template typename Out, bool RAW, typename... Args> + template typename Out, typename... Args> requires(not std::ranges::range and ...) STORMKIT_FORCE_INLINE constexpr auto as_ref_muts(Args&&... args) noexcept -> decltype(auto) { - return Out { { as_ref_mut(std::forward(args))... } }; + return Out { { as_ref_mut(std::forward(args))... } }; } ///////////////////////////////////// ///////////////////////////////////// - template typename Out, bool RAW, typename... Args> + template typename Out, typename... Args> requires(not std::ranges::range and ...) STORMKIT_FORCE_INLINE constexpr auto to_ref_muts(Args&&... args) noexcept -> decltype(auto) { - return Out { { as_ref_mut(std::forward(args))... } }; + return Out { { as_ref_mut(std::forward(args))... } }; } ///////////////////////////////////// ///////////////////////////////////// - template class Out, bool RAW, std::ranges::range T> + template class Out, std::ranges::range T> requires(std::ranges::range>) STORMKIT_FORCE_INLINE constexpr auto to_refs(const T& range) noexcept -> decltype(auto) { return range | std::views::transform([](U&& val) static noexcept -> decltype(auto) { - return as_ref(std::forward(val)); + return as_ref(std::forward(val)); }) | std::ranges::to(); } ///////////////////////////////////// ///////////////////////////////////// - template class Out, bool RAW, std::ranges::range T> + template class Out, std::ranges::range T> requires(std::ranges::range>) STORMKIT_FORCE_INLINE constexpr auto to_mut_refs(T& range) noexcept -> decltype(auto) { return range | std::views::transform([](U&& val) static noexcept -> decltype(auto) { - return as_ref_mut(std::forward(val)); + return as_ref_mut(std::forward(val)); }) | std::ranges::to(); } ///////////////////////////////////// ///////////////////////////////////// - template typename Out, bool RAW, typename... Args> + template typename Out, typename... Args> requires(not std::ranges::range and ...) STORMKIT_FORCE_INLINE - constexpr auto as_opt_refs(Args&&... args) noexcept -> decltype(auto) { - return Out { as_opt_ref(std::forward(args))... }; + constexpr auto as_optrefs(Args&&... args) noexcept -> decltype(auto) { + return Out { as_optref(std::forward(args))... }; } ///////////////////////////////////// ///////////////////////////////////// - template typename Out, bool RAW, typename... Args> + template typename Out, typename... Args> requires(not std::ranges::range and ...) STORMKIT_FORCE_INLINE constexpr auto to_opt_refs(Args&&... args) noexcept -> decltype(auto) { - return Out { { as_opt_ref(std::forward(args))... } }; + return Out { { as_optref(std::forward(args))... } }; } ///////////////////////////////////// ///////////////////////////////////// - template typename Out, bool RAW, typename... Args> + template typename Out, typename... Args> requires(not std::ranges::range and ...) STORMKIT_FORCE_INLINE - constexpr auto as_opt_ref_muts(Args&&... args) noexcept -> decltype(auto) { - return Out { { as_opt_ref_mut(std::forward(args))... } }; + constexpr auto as_optref_muts(Args&&... args) noexcept -> decltype(auto) { + return Out { { as_optref_mut(std::forward(args))... } }; } ///////////////////////////////////// ///////////////////////////////////// - template typename Out, bool RAW, typename... Args> + template typename Out, typename... Args> requires(not std::ranges::range and ...) STORMKIT_FORCE_INLINE constexpr auto to_opt_ref_muts(Args&&... args) noexcept -> decltype(auto) { - return Out { { as_opt_ref_mut(std::forward(args))... } }; + return Out { { as_optref_mut(std::forward(args))... } }; } ///////////////////////////////////// ///////////////////////////////////// - template class Out, bool RAW, std::ranges::range T> + template class Out, std::ranges::range T> requires(std::ranges::range>) STORMKIT_FORCE_INLINE constexpr auto to_opt_refs(const T& range) noexcept -> decltype(auto) { return range | std::views::transform([](U&& val) static noexcept -> decltype(auto) { - return as_opt_ref(std::forward(val)); + return as_optref(std::forward(val)); }) | std::ranges::to(); } ///////////////////////////////////// ///////////////////////////////////// - template class Out, bool RAW, std::ranges::range T> + template class Out, std::ranges::range T> requires(std::ranges::range>) STORMKIT_FORCE_INLINE constexpr auto to_mut_opt_refs(T& range) noexcept -> decltype(auto) { return range | std::views::transform([](U&& val) static noexcept -> decltype(auto) { - return as_opt_ref_mut(std::forward(val)); + return as_optref_mut(std::forward(val)); }) | std::ranges::to(); } diff --git a/modules/stormkit/core/typesafe/safecasts.cppm b/modules/stormkit/core/typesafe/safecasts.cppm index c2d86f0d7..35cab148e 100644 --- a/modules/stormkit/core/typesafe/safecasts.cppm +++ b/modules/stormkit/core/typesafe/safecasts.cppm @@ -194,22 +194,22 @@ export { /// ENUMERATION /// //////////////////////////////////////////////////////////////////// template - requires(meta::Same) + requires(meta::SameAs) [[nodiscard]] constexpr auto is_impl(T first, U second) noexcept -> bool; template - requires(meta::Same) + requires(meta::SameAs) [[nodiscard]] constexpr auto as_impl(U value, const std::source_location&) noexcept -> meta::UnderlyingType; template - requires(meta::Same, U>) + requires(meta::SameAs, U>) [[nodiscard]] constexpr auto as_impl(U value, const std::source_location&) noexcept -> T; template - requires(meta::Same>) + requires(meta::SameAs>) [[nodiscard]] constexpr auto as_impl(U value, const std::source_location&) noexcept -> T; @@ -447,7 +447,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - requires(meta::Same) + requires(meta::SameAs) STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto is_impl(T first, U second) noexcept -> bool { return first == second; @@ -456,7 +456,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - requires(meta::Same) + requires(meta::SameAs) STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto as_impl(U value, const std::source_location&) noexcept -> meta::UnderlyingType { // TODO WHEN REFLEXION IS IMPLEMENTED, CHECK IF `value` IS A VALID ENUMERATION VALUE @@ -466,7 +466,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - requires(meta::Same, U>) + requires(meta::SameAs, U>) STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto as_impl(U value, const std::source_location&) noexcept -> T { // TODO WHEN REFLEXION IS IMPLEMENTED, CHECK IF `value` IS A VALID ENUMERATION VALUE @@ -476,7 +476,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - requires(meta::Same>) + requires(meta::SameAs>) STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto as_impl(U value, const std::source_location&) noexcept -> T { return narrow>(value); diff --git a/modules/stormkit/core/utils/color.cppm b/modules/stormkit/core/utils/color.cppm index 47acd3eb0..6ec042e6f 100644 --- a/modules/stormkit/core/utils/color.cppm +++ b/modules/stormkit/core/utils/color.cppm @@ -19,7 +19,7 @@ import :meta; export namespace stormkit { inline namespace core { namespace meta { template - concept ColorComponentStorageType = IsStrict or IsStrict; + concept ColorComponentStorageType = SameAs or SameAs; } enum class ColorLayout { @@ -376,7 +376,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template constexpr auto to_storage(const color& in) noexcept -> stormkit::color { - if constexpr (meta::IsStrict) return in; + if constexpr (meta::SameAs) return in; else { using OutColor = color; auto out = OutColor {}; @@ -420,7 +420,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template constexpr auto ColorComponent::max() noexcept -> T { - if constexpr (meta::IsStrict) return 1.f; + if constexpr (meta::SameAs) return 1.f; else return 255u; } @@ -429,7 +429,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template constexpr auto as_impl(ColorComponent component) noexcept -> ColorComponent { - if constexpr (meta::IsStrict) return ColorComponent { as(component.value) / 255.f }; + if constexpr (meta::SameAs) return ColorComponent { as(component.value) / 255.f }; else return ColorComponent { as(component.value) * 255.f }; } diff --git a/modules/stormkit/core/utils/numeric_range.cppm b/modules/stormkit/core/utils/numeric_range.cppm index 082e8f477..3a5e57ff6 100644 --- a/modules/stormkit/core/utils/numeric_range.cppm +++ b/modules/stormkit/core/utils/numeric_range.cppm @@ -244,7 +244,7 @@ namespace stormkit { inline namespace core { Type m_step; }; - constexpr explicit Range(meta::IsStrict auto&& range) : m_range { std::forward(range) } {} + constexpr explicit Range(meta::SameAs auto&& range) : m_range { std::forward(range) } {} constexpr auto begin() const noexcept -> Iterator { return { m_range.begin, m_range.step }; } diff --git a/src/wsi/common/window_base.cppm b/src/wsi/common/window_base.cppm index e2fe21f49..89e7d26a5 100644 --- a/src/wsi/common/window_base.cppm +++ b/src/wsi/common/window_base.cppm @@ -151,7 +151,7 @@ namespace stormkit::wsi::common { ///////////////////////////////////// STORMKIT_FORCE_INLINE inline auto WindowBase::set_current_monitor(const Monitor& monitor) noexcept -> void { - m_state.current_monitor = as_opt_ref(monitor); + m_state.current_monitor = as_optref(monitor); } ///////////////////////////////////// From a15e111d92bfcb694654df43350abb1e21d4102d Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 16 Mar 2026 19:30:02 +0100 Subject: [PATCH 166/194] (gpu) add views for all gpu object --- examples/gpu/common/app.cppm | 16 +- examples/gpu/imgui/src/main.cpp | 90 +- examples/gpu/textured_cube/src/main.cpp | 220 +- examples/gpu/triangle/src/main.cpp | 127 +- modules/stormkit/gpu/core/base.cppm | 307 ++- modules/stormkit/gpu/core/device.cppm | 8 +- modules/stormkit/gpu/core/instance.cppm | 4 +- .../stormkit/gpu/core/physical_device.cppm | 210 +- modules/stormkit/gpu/core/sync.cppm | 8 +- .../gpu/execution/command_buffer.cppm | 312 +-- .../stormkit/gpu/execution/descriptors.cppm | 708 +++-- modules/stormkit/gpu/execution/pipeline.cppm | 263 +- .../gpu/execution/raster_pipeline.cppm | 6 +- .../stormkit/gpu/execution/render_pass.cppm | 6 +- modules/stormkit/gpu/execution/swapchain.cppm | 7 +- modules/stormkit/gpu/resource/buffer.cppm | 28 +- modules/stormkit/gpu/resource/image.cppm | 12 +- modules/stormkit/gpu/resource/shader.cppm | 4 +- src/gpu/core/device.cpp | 9 +- src/gpu/core/instance.cpp | 2 +- src/gpu/core/physical_device.cpp | 116 +- src/gpu/execution/command_buffer.cpp | 2271 +++++++++-------- src/gpu/execution/command_pool.cpp | 26 +- src/gpu/execution/descriptor_pool.cpp | 116 + src/gpu/execution/descriptor_set.cpp | 117 + src/gpu/execution/descriptor_set_layout.cpp | 54 + src/gpu/execution/frame_buffer.cpp | 14 +- src/gpu/execution/pipeline.cpp | 465 ++-- src/gpu/execution/pipeline_cache.cpp | 146 +- src/gpu/execution/pipeline_layout.cpp | 56 + src/gpu/execution/queue.cpp | 18 +- src/gpu/execution/render_pass.cpp | 12 +- src/gpu/execution/swapchain.cpp | 279 +- 33 files changed, 3253 insertions(+), 2784 deletions(-) create mode 100644 src/gpu/execution/descriptor_pool.cpp create mode 100644 src/gpu/execution/descriptor_set.cpp create mode 100644 src/gpu/execution/descriptor_set_layout.cpp create mode 100644 src/gpu/execution/pipeline_layout.cpp diff --git a/examples/gpu/common/app.cppm b/examples/gpu/common/app.cppm index 4b9c46894..39713cc88 100644 --- a/examples/gpu/common/app.cppm +++ b/examples/gpu/common/app.cppm @@ -68,15 +68,15 @@ export namespace base { } protected: - DeferInit m_window; - DeferInit m_instance; - DeferInit m_debug_callback; - DeferInit m_surface; + DeferInit m_window; + DeferInit m_instance; + DeferInit m_debug_callback; + DeferInit m_surface; DeferInit m_physical_device; - DeferInit m_device; - DeferInit m_swapchain; - DeferInit m_raster_queue; - DeferInit m_command_pool; + DeferInit m_device; + DeferInit m_swapchain; + DeferInit m_raster_queue; + DeferInit m_command_pool; private: auto init_window(std::string_view example_name) noexcept -> void { diff --git a/examples/gpu/imgui/src/main.cpp b/examples/gpu/imgui/src/main.cpp index cb012c652..9018fdd70 100644 --- a/examples/gpu/imgui/src/main.cpp +++ b/examples/gpu/imgui/src/main.cpp @@ -36,7 +36,7 @@ struct SwapchainImageResource { }; namespace { - constexpr auto BUFFERING_COUNT = 2; + constexpr auto BUFFERING_COUNT = 2_u32; constexpr auto POOL_SIZES = std::array { gpu::DescriptorPool::Size { .type = gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, .descriptor_count = BUFFERING_COUNT } }; @@ -52,7 +52,7 @@ class Application: public base::Application { auto init_resources() -> void { // initialilze descriptor pool m_descriptor_pool = TryAssert(gpu::DescriptorPool::create(m_device, POOL_SIZES, BUFFERING_COUNT), - "Failed to create descriptor pool"); + "Failed to create descriptor pool!"); // create present engine resources m_submission_resources = init_by>([&](auto& out) noexcept { @@ -61,13 +61,13 @@ class Application: public base::Application { out.push_back({ .in_flight = TryAssert(gpu::Fence::create_signaled(m_device), "Failed to create swapchain image " - "in flight fence"), + "in flight fence!"), .image_available = TryAssert(gpu::Semaphore::create(m_device), "Failed to create " - "present wait semaphore"), + "present wait semaphore!"), .render_cmb = TryAssert(m_command_pool->create_command_buffer(), "Failed to create transition " - "command buffers"), + "command buffers!"), }); } }); @@ -77,40 +77,39 @@ class Application: public base::Application { const auto image_count = stdr::size(images); auto transition_cmbs = TryAssert(m_command_pool->create_command_buffers(image_count), - "Failed to create transition command buffers"); + "Failed to create transition command buffers!"); m_image_resources.reserve(stdr::size(images)); auto image_index = 0u; for (const auto& swap_image : images) { - auto view = TryAssert(gpu::ImageView::create(m_device, swap_image), "Failed to create swapchain image view"); + auto view = TryAssert(gpu::ImageView::create(m_device, swap_image), "Failed to create swapchain image view!"); m_image_resources .push_back({ .image = as_ref(swap_image), .view = std::move(view), .render_finished = TryAssert(gpu::Semaphore::create(m_device), "Failed to create render " - "signal semaphore") }); + "signal semaphore!") }); auto& transition_cmb = transition_cmbs[image_index]; - TryDiscardAssert(transition_cmb.begin(true), "Failed to begin texture transition command buffer"); - - transition_cmb.begin_debug_region(std::format("transition image {}", image_index)) - .transition_image_layout(swap_image, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::PRESENT_SRC) - .end_debug_region(); - - TryDiscardAssert(transition_cmb.end(), - "Failed to begin texture transition command " - "buffer"); + TryDiscardAssert((transition_cmb.record([&](auto cmb) noexcept { + cmb.begin_debug_region(std::format("Transition image {}", image_index)) + .transition_image_layout(swap_image, + gpu::ImageLayout::UNDEFINED, + gpu::ImageLayout::PRESENT_SRC) + .end_debug_region(); + })), + std::format("Failed to record transition cmb {}!", image_index)); ++image_index; } - const auto fence = TryAssert(gpu::Fence::create(m_device), "Failed to create transition fence"); + const auto fence = TryAssert(gpu::Fence::create(m_device), "Failed to create transition fence!"); - const auto cmbs = to_refs(transition_cmbs); + const auto cmbs = to_views(transition_cmbs); - TryAssert(m_raster_queue->submit({ .command_buffers = cmbs }, as_ref(fence)), - "Failed to submit texture transition command buffers"); + TryAssert(m_raster_queue->submit({ .command_buffers = cmbs }, fence), + "Failed to submit texture transition command buffers!"); // wait for transition to be done TryAssert(fence.wait(), ""); @@ -213,11 +212,11 @@ class Application: public base::Application { const auto& wait = submission_resource.image_available; auto& in_flight = submission_resource.in_flight; - TryAssert(in_flight.wait(), "Failed to wait in_flight fence"); - TryAssert(in_flight.reset(), "Failed to reset in_flight fence"); + TryAssert(in_flight.wait(), "Failed to wait in_flight fence!"); + TryAssert(in_flight.reset(), "Failed to reset in_flight fence!"); const auto&& [_, image_index] = TryAssert(m_swapchain->acquire_next_image(100ms, wait), - "Failed to acquire next swapchain image"); + "Failed to acquire next swapchain image!"); const auto& swapchain_image_resource = m_image_resources[image_index]; const auto& signal = swapchain_image_resource.render_finished; @@ -234,30 +233,31 @@ class Application: public base::Application { // render in it auto& render_cmb = submission_resource.render_cmb; - TryDiscardAssert(render_cmb.reset(), "Failed to reset render command buffer"); - TryDiscardAssert(render_cmb.begin(), "Failed to begin render command buffer"); - - render_cmb - .transition_image_layout(swapchain_image_resource.image, - gpu::ImageLayout::PRESENT_SRC, - gpu::ImageLayout::ATTACHMENT_OPTIMAL) - .begin_debug_region("Render imgui") - .begin_rendering(rendering_info); - - ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), render_cmb.native_handle()); - - render_cmb.end_rendering() - .end_debug_region() - .transition_image_layout(swapchain_image_resource.image, - gpu::ImageLayout::ATTACHMENT_OPTIMAL, - gpu::ImageLayout::PRESENT_SRC); - - TryDiscardAssert(render_cmb.end(), "Failed to end render command buffer"); - TryDiscardAssert(render_cmb.submit(m_raster_queue, as_refs(wait), PIPELINE_FLAGS, as_refs(signal), as_ref(in_flight)), + TryAssert(render_cmb.reset(), std::format("Failed to reset render cmb {}!", image_index)); + TryDiscardAssert((render_cmb.record([&](auto cmb) noexcept { + cmb + .transition_image_layout(gpu::as_view(swapchain_image_resource.image), + gpu::ImageLayout::PRESENT_SRC, + gpu::ImageLayout::ATTACHMENT_OPTIMAL) + .begin_debug_region("Render imgui") + .begin_rendering(rendering_info); + + ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmb); + + cmb + .end_rendering() // + .end_debug_region() + .transition_image_layout(gpu::as_view(swapchain_image_resource.image), + gpu::ImageLayout::ATTACHMENT_OPTIMAL, + gpu::ImageLayout::PRESENT_SRC); + })), + std::format("Failed to record render cmb {}!", image_index)); + + TryDiscardAssert(render_cmb.submit(m_raster_queue, gpu::as_views(wait), PIPELINE_FLAGS, gpu::as_views(signal), in_flight), "Failed to submit render command buffer"); // present it - TryDiscardAssert(m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)), + TryDiscardAssert(m_raster_queue->present(gpu::as_views(m_swapchain), gpu::as_views(signal), as_view(image_index)), "Failed to present swapchain image"); if (++m_current_frame >= BUFFERING_COUNT) m_current_frame = 0; diff --git a/examples/gpu/textured_cube/src/main.cpp b/examples/gpu/textured_cube/src/main.cpp index f75fc2a05..131682f3d 100644 --- a/examples/gpu/textured_cube/src/main.cpp +++ b/examples/gpu/textured_cube/src/main.cpp @@ -125,7 +125,7 @@ namespace { }; constexpr auto VERTICES_SIZE = sizeof(Vertex) * stdr::size(VERTICES); - constexpr auto BUFFERING_COUNT = 2; + constexpr auto BUFFERING_COUNT = 2_u32; constexpr auto POOL_SIZES = to_array({ { .type = gpu::DescriptorType::UNIFORM_BUFFER, @@ -145,14 +145,14 @@ class Application: public base::Application { public: auto init_example() { m_descriptor_pool = TryAssert(gpu::DescriptorPool::create(m_device, POOL_SIZES, BUFFERING_COUNT * 2), - "Failed to create descriptor pool"); + "Failed to create descriptor pool!"); // load shaders m_vertex_shader = TryAssert(gpu::Shader::load_from_file(m_device, SHADER, gpu::ShaderStageFlag::VERTEX), - std::format("Failed to load vertex shader {}", SHADER.string())); + std::format("Failed to load vertex shader {}!", SHADER.string())); m_fragment_shader = TryAssert(gpu::Shader::load_from_file(m_device, SHADER, gpu::ShaderStageFlag::FRAGMENT), - std::format("Failed to load fragment shader {}", SHADER.string())); + std::format("Failed to load fragment shader {}!", SHADER.string())); m_descriptor_set_layout = TryAssert(gpu::DescriptorSetLayout:: create(m_device, @@ -162,11 +162,13 @@ class Application: public base::Application { gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, gpu::ShaderStageFlag::FRAGMENT, 1 })), - "Failed to create descriptor set layout"); + "Failed to create descriptor set layout!"); - m_pipeline_layout = TryAssert(gpu::PipelineLayout::create(m_device, - { .descriptor_set_layouts = to_refs(m_descriptor_set_layout) }), - "Failed to create pipeline layout"); + m_pipeline_layout = TryAssert(gpu::PipelineLayout:: + create(m_device, + gpu::RasterPipelineLayout { + .descriptor_set_layouts = gpu::to_views(m_descriptor_set_layout) }), + "Failed to create pipeline layout!"); // initialize render pass const auto depth_format = [this] { const auto formats_properties = m_physical_device->formats_properties(); @@ -185,7 +187,7 @@ class Application: public base::Application { } } - ensures(false, "No supported depth format found !"); + ensures(false, "No supported depth format found!"); std::unreachable(); }(); @@ -222,7 +224,7 @@ class Application: public base::Application { .src_alpha_blend_factor = gpu::BlendFactor::SRC_ALPHA, .dst_alpha_blend_factor = gpu::BlendFactor::ONE_MINUS_SRC_ALPHA, .alpha_blend_operation = gpu::BlendOperation::ADD, }, }, }, - .shader_state = to_refs(m_vertex_shader, m_fragment_shader), + .shader_state = to_views(m_vertex_shader, m_fragment_shader), .vertex_input_state = { .binding_descriptions = into_dyn_array(Vertex::binding_description()), .input_attribute_descriptions = to_dyn_array(Vertex::attribute_descriptions()), @@ -239,11 +241,11 @@ class Application: public base::Application { }; m_pipeline = TryAssert(gpu::Pipeline::create(m_device, state, m_pipeline_layout, rendering_info), - "Failed to create raster pipeline"); + "Failed to create raster pipeline!"); // load texture auto image = image::Image {}; - TryAssert(image.load_from_file(TEXTURE), std::format("Failed to load texture file {}", TEXTURE.string())); + TryAssert(image.load_from_file(TEXTURE), std::format("Failed to load texture file {}!", TEXTURE.string())); m_texture = TryAssert(gpu::Image::create(m_device, gpu::Image::CreateInfo { @@ -251,64 +253,68 @@ class Application: public base::Application { .format = gpu::PixelFormat::RGBA8_UNORM, .usages = gpu::ImageUsageFlag::SAMPLED | gpu::ImageUsageFlag::TRANSFER_DST, .properties = gpu::MemoryPropertyFlag::DEVICE_LOCAL }), - "Failed to allocate texture"); + "Failed to allocate texture!"); { - auto cpy_fence = TryAssert(gpu::Fence::create(m_device), "Failed to create copy texture buffer fence"); + auto cpy_fence = TryAssert(gpu::Fence::create(m_device), "Failed to create copy texture buffer fence!"); auto staging_buffer = TryAssert(gpu::Buffer::create(m_device, gpu::Buffer::CreateInfo { .usages = gpu::BufferUsageFlag::TRANSFER_SRC, .size = image.size() }), - "Failed to allocate gpu texture staging buffer"); - TryAssert(staging_buffer.upload(image.data()), "Failed to upload texture data to staging buffer"); - - const auto copy = std::array { - gpu::BufferImageCopy { - .buffer_offset = 0, - .buffer_row_length = 0, - .buffer_image_height = 0, - .subresource_layers = {}, - .offset = {}, - .extent = image.extent() } - }; - auto copy_cmb = TryAssert(m_command_pool->create_command_buffer(), "Failed to allocate copy texture buffer"); - - TryAssert(copy_cmb.begin(), "Failed to begin texture upload command buffer"); - - copy_cmb.begin_debug_region("Upload texture data") - .transition_image_layout(m_texture, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::TRANSFER_DST_OPTIMAL) - .copy_buffer_to_image(staging_buffer, m_texture, as_view(copy)) - .transition_image_layout(m_texture, - gpu::ImageLayout::TRANSFER_DST_OPTIMAL, - gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL) - .end_debug_region(); + "Failed to allocate gpu texture staging buffer!"); + TryAssert(staging_buffer.upload(image.data()), "Failed to upload texture data to staging buffer!"); - TryDiscardAssert(copy_cmb.end(), "Failed to end texture upload command buffer"); - TryDiscardAssert(copy_cmb.submit(m_raster_queue, {}, {}, {}, as_ref(cpy_fence)), - "Failed to submit texture upload command buffer"); - - TryDiscardAssert(cpy_fence.wait(), "Failed to create texture view"); + auto copy_cmb = TryAssert(m_command_pool->create_command_buffer(), "Failed to allocate copy texture buffer"); + TryDiscardAssert((copy_cmb.record([&](auto cmb) noexcept { + const auto copy = std::array { + gpu::BufferImageCopy { + .buffer_offset = 0, + .buffer_row_length = 0, + .buffer_image_height = 0, + .subresource_layers = {}, + .offset = {}, + .extent = image.extent() } + }; + + cmb.begin_debug_region("Upload texture data") + .transition_image_layout(m_texture, + gpu::ImageLayout::UNDEFINED, + gpu::ImageLayout::TRANSFER_DST_OPTIMAL) + .copy_buffer_to_image(staging_buffer, m_texture, as_view(copy)) + .end_debug_region() + .begin_debug_region("Transition texture data") + .transition_image_layout(m_texture, + gpu::ImageLayout::TRANSFER_DST_OPTIMAL, + gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL) + .end_debug_region(); + })), + "Failed to record texture upload and transition cmb!"); + + TryDiscardAssert(copy_cmb.submit(m_raster_queue, {}, {}, {}, cpy_fence), + "Failed to submit texture upload command buffer!"); + + TryDiscardAssert(cpy_fence.wait(), "Failed to create texture view!"); } - m_texture_view = TryAssert(gpu::ImageView::create(m_device, m_texture), "Failed to create texture view"); - m_sampler = TryAssert(gpu::Sampler::create(m_device, gpu::Sampler::Settings {}), "Failed to create sampler"); + m_texture_view = TryAssert(gpu::ImageView::create(m_device, m_texture), "Failed to create texture view!"); + m_sampler = TryAssert(gpu::Sampler::create(m_device, gpu::Sampler::Settings {}), "Failed to create sampler!"); m_submission_resources = std::vector {}; m_submission_resources.reserve(BUFFERING_COUNT); for (auto _ : range(BUFFERING_COUNT)) { m_submission_resources - .push_back({ .in_flight = TryAssert(gpu::Fence::create_signaled(m_device), "Failed to create swapchain image"), - .image_available = TryAssert(gpu::Semaphore::create(m_device), "Failed to create present image"), - .render_cmb = TryAssert(m_command_pool->create_command_buffer(), "Failed to create buffers"), + .push_back({ .in_flight = TryAssert(gpu::Fence::create_signaled(m_device), "Failed to create swapchain image!"), + .image_available = TryAssert(gpu::Semaphore::create(m_device), "Failed to create present image!"), + .render_cmb = TryAssert(m_command_pool->create_command_buffer(), "Failed to create buffers!"), .viewer_buffer = TryAssert(gpu::Buffer::create(m_device, gpu::Buffer::CreateInfo { .usages = gpu::BufferUsageFlag::UNIFORM, .size = sizeof(ViewerData), .persistently_mapped = true, }), - "Failed to allocate gpu viewer buffer"), + "Failed to allocate gpu viewer buffer!"), .descriptor_set = TryAssert(m_descriptor_pool->create_descriptor_set(m_descriptor_set_layout), - "Failed to create descriptor set") }); + "Failed to create descriptor set!") }); auto& res = m_submission_resources.back(); const auto sets = std::array { gpu::BufferDescriptor { @@ -320,8 +326,8 @@ class Application: public base::Application { gpu::ImageDescriptor { .binding = 1, .layout = gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL, - .image_view = as_ref(m_texture_view), - .sampler = as_ref(m_sampler), + .image_view = gpu::as_view(m_texture_view), + .sampler = gpu::as_view(m_sampler), } }; res.descriptor_set.update(sets); @@ -331,58 +337,61 @@ class Application: public base::Application { const auto image_count = stdr::size(images); auto transition_cmbs = TryAssert(m_command_pool->create_command_buffers(image_count), - "Failed to create transition command buffers"); + "Failed to create transition command buffers!"); m_image_resources = std::vector {}; m_image_resources.reserve(stdr::size(images)); auto image_index = 0u; for (const auto& swap_image : images) { - auto view = TryAssert(gpu::ImageView::create(m_device, swap_image), "Failed to create swapchain image view"); + auto view = TryAssert(gpu::ImageView::create(m_device, swap_image), "Failed to create swapchain image view!"); auto depth_image = TryAssert(gpu::Image::create(m_device, gpu::Image::CreateInfo { .extent = swap_image.extent(), .format = depth_format, .usages = gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT, .properties = gpu::MemoryPropertyFlag::DEVICE_LOCAL }), - "Failed to create depth image"); + "Failed to create depth image!"); auto depth_view = TryAssert(gpu::ImageView::create(m_device, depth_image, gpu::ImageViewType::T2D, gpu::ImageSubresourceRange { .aspect_mask = depth_aspect_flag }), - "Failed to create depth image view"); + "Failed to create depth image view!"); m_image_resources .push_back({ .image = as_ref(swap_image), .view = std::move(view), .depth_image = std::move(depth_image), .depth_view = std::move(depth_view), - .render_finished = TryAssert(gpu::Semaphore::create(m_device), "Failed to create render") }); + .render_finished = TryAssert(gpu::Semaphore::create(m_device), "Failed to create render!") }); const auto& resources = m_image_resources.back(); auto& transition_cmb = transition_cmbs[image_index]; - TryDiscardAssert(transition_cmb.begin(true), "Failed to begin texture transition command buffer"); - - transition_cmb.begin_debug_region(std::format("transition image {}", image_index)) - .transition_image_layout(swap_image, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::PRESENT_SRC) - .transition_image_layout(resources.depth_image, - gpu::ImageLayout::UNDEFINED, - gpu::ImageLayout::ATTACHMENT_OPTIMAL, - { .aspect_mask = depth_aspect_flag }) - .end_debug_region(); - - TryDiscardAssert(transition_cmb.end(), "Failed to begin texture transition command buffer"); + TryDiscardAssert((transition_cmb.record([&](auto cmb) noexcept { + cmb.begin_debug_region(std::format("Transition image {}", image_index)) + .transition_image_layout(swap_image, + gpu::ImageLayout::UNDEFINED, + gpu::ImageLayout::PRESENT_SRC) + .end_debug_region() + .begin_debug_region(std::format("Transition depth image {}", image_index)) + .transition_image_layout(resources.depth_image, + gpu::ImageLayout::UNDEFINED, + gpu::ImageLayout::ATTACHMENT_OPTIMAL, + { .aspect_mask = depth_aspect_flag }) + .end_debug_region(); + })), + std::format("Failed to record transition cmb {}!", image_index)); ++image_index; } - const auto fence = TryAssert(gpu::Fence::create(m_device), "Failed to create transition fence"); + const auto fence = TryAssert(gpu::Fence::create(m_device), "Failed to create transition fence!"); - const auto cmbs = to_refs(transition_cmbs); - TryDiscardAssert(m_raster_queue->submit({ .command_buffers = cmbs }, as_ref(fence)), - "Failed to submit texture transition command buffers"); + const auto cmbs = to_views(transition_cmbs); + TryDiscardAssert(m_raster_queue->submit({ .command_buffers = cmbs }, fence), + "Failed to submit texture transition command buffers!"); // setup vertex buffer m_vertex_buffer = TryAssert(gpu::Buffer::create(m_device, @@ -391,18 +400,18 @@ class Application: public base::Application { | gpu::BufferUsageFlag::TRANSFER_DST, .size = VERTICES_SIZE, .properties = gpu::MemoryPropertyFlag::DEVICE_LOCAL }), - "Failed to allocate gpu vertex buffer"); + "Failed to allocate gpu vertex buffer!"); { auto staging_buffer = TryAssert(gpu::Buffer::create(m_device, gpu::Buffer::CreateInfo { .usages = gpu::BufferUsageFlag::TRANSFER_SRC, .size = VERTICES_SIZE }), - "Failed to allocate gpu vertex staging buffer"); + "Failed to allocate gpu vertex staging buffer!"); - TryAssert(staging_buffer.upload(VERTICES), "Failed to upload vertex data to staging buffer"); + TryAssert(staging_buffer.upload(VERTICES), "Failed to upload vertex data to staging buffer!"); - auto cpy_fence = TryAssert(gpu::Fence::create(m_device), "Failed to create copy vertex buffer fence"); + auto cpy_fence = TryAssert(gpu::Fence::create(m_device), "Failed to create copy vertex buffer fence!"); auto copy_cmb = TryAssert(m_command_pool->create_command_buffer(), "Failed to allocate copy vertex buffer"); TryAssert(copy_cmb.begin(), "Failed to begin vertices upload command buffer"); @@ -412,9 +421,9 @@ class Application: public base::Application { .end_debug_region(); TryDiscardAssert(copy_cmb.end(), "Failed to begin vertices upload command buffer"); - TryDiscardAssert(copy_cmb.submit(m_raster_queue, {}, {}, {}, as_ref(cpy_fence)), - "Failed to submit vertices upload command buffer"); - TryAssert(cpy_fence.wait(), "Failed to acquire next swapchain image"); + TryDiscardAssert(copy_cmb.submit(m_raster_queue, {}, {}, {}, cpy_fence), + "Failed to submit vertices upload command buffer!"); + TryAssert(cpy_fence.wait(), "Failed to acquire next swapchain image!"); } TryAssert(fence.wait(), ""); @@ -442,11 +451,11 @@ class Application: public base::Application { const auto& wait = submission_resource.image_available; auto& in_flight = submission_resource.in_flight; - TryAssert(in_flight.wait(), "Failed to wait in_flight fence"); - TryAssert(in_flight.reset(), "Failed to reset in_flight fence"); + TryAssert(in_flight.wait(), "Failed to wait in_flight fence!"); + TryAssert(in_flight.reset(), "Failed to reset in_flight fence!"); const auto&& [_, image_index] = TryAssert(m_swapchain->acquire_next_image(100ms, wait), - "Failed to acquire next swapchain image"); + "Failed to acquire next swapchain image!"); const auto& swapchain_image_resource = m_image_resources[image_index]; const auto& signal = swapchain_image_resource.render_finished; @@ -457,7 +466,7 @@ class Application: public base::Application { .model = math::rotate(math::fmat4::identity(), time * math::angle::radians(90.f), math::fvec3 { 0.f, 1.f, 0.f }); auto& viewer_buffer = submission_resource.viewer_buffer; - TryAssert(viewer_buffer.upload(viewer_data), "Failed to upload texture to gpu"); + TryAssert(viewer_buffer.upload(viewer_data), "Failed to upload texture to gpu!"); const auto rendering_info = gpu::RenderingInfo { .render_area = { .x = 0, .y = 0, .width = window_extent.to().width, .height = window_extent.to().height }, @@ -473,32 +482,31 @@ class Application: public base::Application { auto& render_cmb = submission_resource.render_cmb; const auto& descriptor_set = submission_resource.descriptor_set; - TryDiscardAssert(render_cmb.reset(), "Failed to reset render command buffer"); - TryDiscardAssert(render_cmb.begin(), "Failed to begin render command buffer"); - - render_cmb - .transition_image_layout(swapchain_image_resource.image, - gpu::ImageLayout::PRESENT_SRC, - gpu::ImageLayout::ATTACHMENT_OPTIMAL) - .begin_debug_region("Render textured cube") - .begin_rendering(rendering_info) - .bind_pipeline(m_pipeline) - .bind_vertex_buffers(to_refs(m_vertex_buffer), OFFSETS) - .bind_descriptor_sets(m_pipeline, m_pipeline_layout, as_refs(descriptor_set), {}) - .draw(stdr::size(VERTICES)) - .end_rendering() - .end_debug_region() - .transition_image_layout(swapchain_image_resource.image, - gpu::ImageLayout::ATTACHMENT_OPTIMAL, - gpu::ImageLayout::PRESENT_SRC); - - TryDiscardAssert(render_cmb.end(), "Failed to end render command buffer"); - TryDiscardAssert(render_cmb.submit(m_raster_queue, as_refs(wait), PIPELINE_FLAGS, as_refs(signal), as_ref(in_flight)), - "Failed to submit render command buffer"); + TryAssert(render_cmb.reset(), std::format("Failed to reset render cmb {}!", image_index)); + TryDiscardAssert((render_cmb.record([&](auto cmb) noexcept { + cmb + .transition_image_layout(gpu::as_view(swapchain_image_resource.image), + gpu::ImageLayout::PRESENT_SRC, + gpu::ImageLayout::ATTACHMENT_OPTIMAL) + .begin_debug_region("Render cube") + .begin_rendering(rendering_info) + .bind_pipeline(m_pipeline) + .bind_vertex_buffers(gpu::as_views(m_vertex_buffer), OFFSETS) + .bind_descriptor_sets(m_pipeline, m_pipeline_layout, gpu::as_views(descriptor_set), {}) + .draw(stdr::size(VERTICES)) + .end_rendering() + .end_debug_region() + .transition_image_layout(gpu::as_view(swapchain_image_resource.image), + gpu::ImageLayout::ATTACHMENT_OPTIMAL, + gpu::ImageLayout::PRESENT_SRC); + })), + std::format("Failed to record render cmb {}!", image_index)); + TryDiscardAssert(render_cmb.submit(m_raster_queue, gpu::as_views(wait), PIPELINE_FLAGS, gpu::as_views(signal), in_flight), + "Failed to submit render command buffer!"); // present it - TryAssert(m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)), - "Failed to present swapchain image"); + TryAssert(m_raster_queue->present(gpu::as_views(m_swapchain), gpu::as_views(signal), as_view(image_index)), + "Failed to present swapchain image!"); if (++m_current_frame >= BUFFERING_COUNT) m_current_frame = 0; } diff --git a/examples/gpu/triangle/src/main.cpp b/examples/gpu/triangle/src/main.cpp index 3dd2bb2b2..60b5e50d3 100644 --- a/examples/gpu/triangle/src/main.cpp +++ b/examples/gpu/triangle/src/main.cpp @@ -35,7 +35,7 @@ struct SwapchainImageResource { }; namespace { - constexpr auto BUFFERING_COUNT = 2; + constexpr auto BUFFERING_COUNT = 2_u32; const auto SHADER = stdfs::path { SHADER_DIR } / "triangle.spv"; } // namespace @@ -44,12 +44,13 @@ class Application: public base::Application { auto init_example() { // load shaders m_vertex_shader = TryAssert(gpu::Shader::load_from_file(m_device, SHADER, gpu::ShaderStageFlag::VERTEX), - std::format("Failed to load vertex shader {}", SHADER.string())); + std::format("Failed to load vertex shader {}!", SHADER.string())); m_fragment_shader = TryAssert(gpu::Shader::load_from_file(m_device, SHADER, gpu::ShaderStageFlag::FRAGMENT), - std::format("Failed to load fragment shader {}", SHADER.string())); + std::format("Failed to load fragment shader {}!", SHADER.string())); - m_pipeline_layout = TryAssert(gpu::PipelineLayout::create(m_device, {}), "Failed to create pipeline layout"); + m_pipeline_layout = TryAssert(gpu::PipelineLayout::create(m_device, gpu::RasterPipelineLayout {}), + "Failed to create pipeline layoutu!"); const auto window_extent = m_window->extent(); @@ -64,26 +65,33 @@ class Application: public base::Application { .extent = window_extent, }; + static_assert(meta::SameAs); + static_assert(meta::SameAs>); + static_assert(meta::SameAs>); + static_assert(meta::SameAs>); + const auto state = gpu::RasterPipelineState { - .input_assembly_state = { .topology = gpu::PrimitiveTopology::TRIANGLE_LIST, }, - .viewport_state = { .viewports = { window_viewport }, - .scissors = { scissor }, }, - .color_blend_state - = { .attachments = { { .blend_enable = true, - .src_color_blend_factor = gpu::BlendFactor::SRC_ALPHA, - .dst_color_blend_factor = gpu::BlendFactor::ONE_MINUS_SRC_ALPHA, - .src_alpha_blend_factor = gpu::BlendFactor::SRC_ALPHA, - .dst_alpha_blend_factor = gpu::BlendFactor::ONE_MINUS_SRC_ALPHA, - .alpha_blend_operation = gpu::BlendOperation::ADD, }, }, }, - .shader_state = to_refs(m_vertex_shader, m_fragment_shader), - }; + .input_assembly_state = { .topology = gpu::PrimitiveTopology::TRIANGLE_LIST, }, + .viewport_state = { .viewports = { window_viewport }, + .scissors = { scissor }, }, + .color_blend_state + = { .attachments = { { .blend_enable = true, + .src_color_blend_factor = gpu::BlendFactor::SRC_ALPHA, + .dst_color_blend_factor = gpu::BlendFactor::ONE_MINUS_SRC_ALPHA, + .src_alpha_blend_factor = gpu::BlendFactor::SRC_ALPHA, + .dst_alpha_blend_factor = gpu::BlendFactor::ONE_MINUS_SRC_ALPHA, + .alpha_blend_operation = gpu::BlendOperation::ADD, }, }, }, + .shader_state = gpu::to_views(m_vertex_shader, m_fragment_shader), + }; const auto rendering_info = gpu::RasterPipelineRenderingInfo { .color_attachment_formats = { m_swapchain->pixel_format() } }; m_pipeline = TryAssert(gpu::Pipeline::create(m_device, state, m_pipeline_layout, rendering_info), - "Failed to create raster pipeline"); + "Failed to create raster pipeline!"); // create present engine resources m_submission_resources = init_by>([&](auto& out) noexcept { @@ -92,13 +100,13 @@ class Application: public base::Application { out.push_back({ .in_flight = TryAssert(gpu::Fence::create_signaled(m_device), "Failed to create swapchain image " - "in flight fence"), + "in flight fence!"), .image_available = TryAssert(gpu::Semaphore::create(m_device), "Failed to create " - "present wait semaphore"), + "present wait semaphore!"), .render_cmb = TryAssert(m_command_pool->create_command_buffer(), "Failed to create transition " - "command buffers"), + "command buffers!"), }); } }); @@ -108,40 +116,39 @@ class Application: public base::Application { const auto image_count = stdr::size(images); auto transition_cmbs = TryAssert(m_command_pool->create_command_buffers(image_count), - "Failed to create transition command buffers"); + "Failed to create transition command buffers!"); m_image_resources.reserve(stdr::size(images)); auto image_index = 0u; for (const auto& swap_image : images) { - auto view = TryAssert(gpu::ImageView::create(m_device, swap_image), "Failed to create swapchain image view"); + auto view = TryAssert(gpu::ImageView::create(m_device, swap_image), "Failed to create swapchain image view!"); m_image_resources .push_back({ .image = swap_image, .view = std::move(view), .render_finished = TryAssert(gpu::Semaphore::create(m_device), "Failed to create render " - "signal semaphore") }); + "signal semaphore!") }); auto& transition_cmb = transition_cmbs[image_index]; - TryDiscardAssert(transition_cmb.begin(true), "Failed to begin texture transition command buffer"); - - transition_cmb.begin_debug_region(std::format("transition image {}", image_index)) - .transition_image_layout(swap_image, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::PRESENT_SRC) - .end_debug_region(); - - TryDiscardAssert(transition_cmb.end(), - "Failed to begin texture transition command " - "buffer"); + TryDiscardAssert((transition_cmb.record([&](auto cmb) noexcept { + cmb.begin_debug_region(std::format("Transition image {}", image_index)) + .transition_image_layout(swap_image, + gpu::ImageLayout::UNDEFINED, + gpu::ImageLayout::PRESENT_SRC) + .end_debug_region(); + })), + std::format("Failed to record transition cmb {}!", image_index)); ++image_index; } - const auto fence = TryAssert(gpu::Fence::create(m_device), "Failed to create transition fence"); + const auto fence = TryAssert(gpu::Fence::create(m_device), "Failed to create transition fence!"); - const auto cmbs = to_refs(transition_cmbs); + const auto cmbs = gpu::to_views(transition_cmbs); - TryAssert(m_raster_queue->submit({ .command_buffers = cmbs }, as_ref(fence)), - "Failed to submit texture transition command buffers"); + TryAssert(m_raster_queue->submit({ .command_buffers = cmbs }, fence), + "Failed to submit texture transition command buffers!"); // wait for transition to be done TryAssert(fence.wait(), ""); @@ -156,11 +163,11 @@ class Application: public base::Application { const auto& wait = submission_resource.image_available; auto& in_flight = submission_resource.in_flight; - TryAssert(in_flight.wait(), "Failed to wait in_flight fence"); - TryAssert(in_flight.reset(), "Failed to reset in_flight fence"); + TryAssert(in_flight.wait(), "Failed to wait in_flight fence!"); + TryAssert(in_flight.reset(), "Failed to reset in_flight fence!"); const auto&& [_, image_index] = TryAssert(m_swapchain->acquire_next_image(100ms, wait), - "Failed to acquire next swapchain image"); + "Failed to acquire next swapchain image!"); const auto& swapchain_image_resource = m_image_resources[image_index]; const auto& signal = swapchain_image_resource.render_finished; @@ -177,30 +184,30 @@ class Application: public base::Application { // render in it auto& render_cmb = submission_resource.render_cmb; - TryDiscardAssert(render_cmb.reset(), "Failed to reset render command buffer"); - TryDiscardAssert(render_cmb.begin(), "Failed to begin render command buffer"); - - render_cmb - .transition_image_layout(swapchain_image_resource.image, - gpu::ImageLayout::PRESENT_SRC, - gpu::ImageLayout::ATTACHMENT_OPTIMAL) - .begin_debug_region("Render triangle") - .begin_rendering(rendering_info) - .bind_pipeline(m_pipeline) - .draw(3) - .end_rendering() - .end_debug_region() - .transition_image_layout(swapchain_image_resource.image, - gpu::ImageLayout::ATTACHMENT_OPTIMAL, - gpu::ImageLayout::PRESENT_SRC); - - TryDiscardAssert(render_cmb.end(), "Failed to end render command buffer"); - TryDiscardAssert(render_cmb.submit(m_raster_queue, as_refs(wait), PIPELINE_FLAGS, as_refs(signal), as_ref(in_flight)), + TryAssert(render_cmb.reset(), std::format("Failed to reset render cmb {}!", image_index)); + TryDiscardAssert((render_cmb.record([&](auto cmb) noexcept { + cmb + .transition_image_layout(gpu::as_view(swapchain_image_resource.image), + gpu::ImageLayout::PRESENT_SRC, + gpu::ImageLayout::ATTACHMENT_OPTIMAL) + .begin_debug_region("Render triangle") + .begin_rendering(rendering_info) + .bind_pipeline(m_pipeline) + .draw(3) + .end_rendering() + .end_debug_region() + .transition_image_layout(gpu::as_view(swapchain_image_resource.image), + gpu::ImageLayout::ATTACHMENT_OPTIMAL, + gpu::ImageLayout::PRESENT_SRC); + })), + std::format("Failed to record render cmb {}!", image_index)); + + TryDiscardAssert(render_cmb.submit(m_raster_queue, gpu::as_views(wait), PIPELINE_FLAGS, gpu::as_views(signal), in_flight), "Failed to submit render command buffer"); // present it - TryDiscardAssert(m_raster_queue->present(as_refs(m_swapchain), as_refs(signal), as_view(image_index)), - "Failed to present swapchain image"); + TryDiscardAssert(m_raster_queue->present(gpu::as_views(m_swapchain), gpu::as_views(signal), as_view(image_index)), + "Failed to present swapchain image!"); if (++m_current_frame >= BUFFERING_COUNT) m_current_frame = 0; } diff --git a/modules/stormkit/gpu/core/base.cppm b/modules/stormkit/gpu/core/base.cppm index da9ff7c8e..b626f687c 100644 --- a/modules/stormkit/gpu/core/base.cppm +++ b/modules/stormkit/gpu/core/base.cppm @@ -19,6 +19,9 @@ import stormkit.core; import :structs; import :vulkan; +namespace stdr = std::ranges; +namespace stdv = std::views; + namespace cmeta = stormkit::core::meta; export namespace stormkit::gpu { @@ -30,18 +33,19 @@ export namespace stormkit::gpu { struct ObjectInfo; template - concept HasRequiresInfo = requires(ObjectInfo value) { value; }; + concept HasRequiresInfo = requires(ObjectInfo> value) { value; }; template concept CreateAllocateDisabled = HasRequiresInfo and requires() { - { ObjectInfo::DISABLE_CREATE_ALLOCATE } -> cmeta::IsBooleanTestable; - } and ObjectInfo::DISABLE_CREATE_ALLOCATE; + { ObjectInfo>::DISABLE_CREATE_ALLOCATE } -> cmeta::IsBooleanTestable; + } and ObjectInfo>::DISABLE_CREATE_ALLOCATE; template - concept IsOwnedByOther = HasRequiresInfo and requires(T) { typename ObjectInfo::OwnedBy; }; + concept IsOwnedByOther = HasRequiresInfo and requires(T) { typename ObjectInfo>::OwnedBy; }; template - concept IsOwned = HasRequiresInfo; + concept IsOwned = HasRequiresInfo + and std::derived_from, Owned>::Of>>; } // namespace meta template @@ -49,10 +53,10 @@ export namespace stormkit::gpu { namespace meta { template - concept IsView = not IsOwned and requires(const T& value) { - typename T::ElementType; - typename T::ViewType; - { value.native_handle() } -> cmeta::Is; + concept IsView = not IsOwned> and requires(T value) { + typename cmeta::CanonicalType::ElementType; + typename cmeta::CanonicalType::ViewType; + { value.native_handle() } -> cmeta::Is::ElementType>; }; template @@ -60,11 +64,11 @@ export namespace stormkit::gpu { template concept DoInitReturnExpected = requires(T& foo, Args&&... args) { - { foo.do_init(T::PRIVATE, std::forward(args)...) } -> cmeta::SameAs>; + { foo.do_init(cmeta::CanonicalType::PRIVATE, std::forward(args)...) } -> cmeta::SameAs>; }; template concept DoInitReturnVoid = requires(T& foo, Args&&... args) { - { foo.do_init(T::PRIVATE, std::forward(args)...) } -> cmeta::SameAs; + { foo.do_init(cmeta::CanonicalType::PRIVATE, std::forward(args)...) } -> cmeta::SameAs; }; } // namespace meta @@ -79,7 +83,7 @@ export namespace stormkit::gpu { using ViewType = ObjectInfo::ViewType; View(const T& of) noexcept; - template U> + template U> View(const U& of) noexcept; ~View() noexcept; @@ -105,6 +109,7 @@ export namespace stormkit::gpu { using ElementType = ObjectInfo::ElementType; using DeleterType = ObjectInfo::DeleterType; using ViewType = ObjectInfo::ViewType; + ~Owned() noexcept; Owned(const Owned&) = delete; @@ -113,14 +118,52 @@ export namespace stormkit::gpu { Owned(Owned&&) noexcept; auto operator=(Owned&&) noexcept -> Owned&; + template + requires(meta::IsOwnedByOther and meta::DoInitReturnExpected) + [[nodiscard]] + static auto create(Owner&& owner, Args&&... args) noexcept -> Expected + requires(not meta::CreateAllocateDisabled); + + template + requires(meta::IsOwnedByOther and meta::DoInitReturnVoid) + [[nodiscard]] + static auto create(Owner&& owner, Args&&... args) noexcept -> T + requires(not meta::CreateAllocateDisabled); + + template + requires(not meta::IsOwnedByOther and meta::DoInitReturnExpected) + [[nodiscard]] + static auto create(Args&&... args) noexcept -> Expected + requires(not meta::CreateAllocateDisabled); + template + requires(not meta::IsOwnedByOther and meta::DoInitReturnVoid) [[nodiscard]] - static auto create(Args&&... args) noexcept -> decltype(auto) + static auto create(Args&&... args) noexcept -> T + requires(not meta::CreateAllocateDisabled); + + template + requires(meta::IsOwnedByOther and meta::DoInitReturnExpected) + [[nodiscard]] + static auto allocate(Owner&& owner, Args&&... args) noexcept -> Expected> + requires(not meta::CreateAllocateDisabled); + + template + requires(meta::IsOwnedByOther and meta::DoInitReturnVoid) + [[nodiscard]] + static auto allocate(Owner&& owner, Args&&... args) noexcept -> Heap requires(not meta::CreateAllocateDisabled); template + requires(not meta::IsOwnedByOther and meta::DoInitReturnExpected) [[nodiscard]] - static auto allocate(Args&&... args) noexcept -> decltype(auto) + static auto allocate(Args&&... args) noexcept -> Expected> + requires(not meta::CreateAllocateDisabled); + + template + requires(not meta::IsOwnedByOther and meta::DoInitReturnVoid) + [[nodiscard]] + static auto allocate(Args&&... args) noexcept -> Heap requires(not meta::CreateAllocateDisabled); [[nodiscard]] @@ -139,19 +182,30 @@ export namespace stormkit::gpu { }; template - auto to_view(T value) noexcept -> T; + auto as_view(T&& value) noexcept -> T; template - auto to_view(const T& value) noexcept -> typename T::ViewType; + auto as_view(const T& value) noexcept -> typename meta::ObjectInfo>::ViewType; + + template + auto as_view(const T& value) noexcept -> typename meta::ObjectInfo>>::ViewType; - template U> - auto to_view(const U& value) noexcept -> typename T::ViewType; + template + auto as_view(const T& value) noexcept -> typename meta::ObjectInfo>>::ViewType; template class Out = std::array, typename... Args> - auto to_views(const Args&... args) noexcept -> decltype(auto); + requires(not stdr::range and ...) + auto as_views(Args&&... args) noexcept -> decltype(auto); template class Out = std::vector, typename... Args> - auto to_views(const Args&... args) noexcept -> decltype(auto); + requires(not stdr::range and ...) + auto to_views(Args&&... args) noexcept -> decltype(auto); + + template class Out = std::vector, stdr::range Range> + auto to_views(const Range& range) noexcept -> decltype(auto); + + template + auto format_as(const T& object, FormatContext& ctx) noexcept -> decltype(ctx.out()); } // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// @@ -164,7 +218,7 @@ namespace stormkit::gpu { template STORMKIT_FORCE_INLINE inline Owned::Owned(DeleterType&& deleter_ptr) noexcept - : m_deleter_ptr { std::move(deleter_ptr) } { + : m_vk_handle { VK_NULL_HANDLE }, m_deleter_ptr { std::move(deleter_ptr) } { } ///////////////////////////////////// @@ -182,8 +236,9 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline Owned::Owned(Owned&& other) noexcept - : m_vk_handle { std::exchange(other.m_vk_handle, VK_NULL_HANDLE) }, m_deleter_ptr { std::move(other.m_deleter_ptr) } { + inline Owned::Owned(Owned&& other) noexcept + : m_vk_handle { std::exchange(other.m_vk_handle, VK_NULL_HANDLE) }, + m_deleter_ptr { std::exchange(other.m_deleter_ptr, {}) } { } ///////////////////////////////////// @@ -195,7 +250,7 @@ namespace stormkit::gpu { return *this; m_vk_handle = std::exchange(other.m_vk_handle, VK_NULL_HANDLE); - m_deleter_ptr = std::move(other.m_deleter_ptr); + m_deleter_ptr = std::exchange(other.m_deleter_ptr, {}); return *this; } @@ -217,82 +272,116 @@ namespace stormkit::gpu { return native_handle(); } + ///////////////////////////////////// + ///////////////////////////////////// + template + template + requires(meta::IsOwnedByOther and meta::DoInitReturnExpected) + STORMKIT_FORCE_INLINE + inline auto Owned::create(Owner&& owner, Args&&... args) noexcept -> Expected + requires(not meta::CreateAllocateDisabled) + { + auto out = T { PRIVATE, std::forward(owner) }; + Try(out.do_init(PRIVATE, std::forward(args)...)); + Return out; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + template + requires(meta::IsOwnedByOther and meta::DoInitReturnVoid) + STORMKIT_FORCE_INLINE + inline auto Owned::create(Owner&& owner, Args&&... args) noexcept -> T + requires(not meta::CreateAllocateDisabled) + { + auto out = T { PRIVATE, std::forward(owner) }; + out.do_init(PRIVATE, std::forward(args)...); + return out; + } + ///////////////////////////////////// ///////////////////////////////////// template template + requires(not meta::IsOwnedByOther and meta::DoInitReturnExpected) STORMKIT_FORCE_INLINE - inline auto Owned::create(Args&&... args) noexcept -> decltype(auto) + inline auto Owned::create(Args&&... args) noexcept -> Expected requires(not meta::CreateAllocateDisabled) { - if constexpr (meta::IsOwnedByOther) { - auto out = T { PRIVATE, std::forward(args...[0]) }; - return [](auto&& out, auto&&, Args2&&... args2) static noexcept -> decltype(auto) { - if constexpr (meta::DoInitReturnExpected) { - auto out_expected = Expected { std::in_place, std::move(out) }; - if (auto result = out.do_init(PRIVATE, std::forward(args2)...); not result) - out_expected = std::unexpected { std::move(result).error() }; - - return out_expected; - } else if constexpr (meta::DoInitReturnVoid) { - out.do_init(PRIVATE, std::forward(args2)...); - return out; - } - }(std::move(out), std::forward(args)...); - } else { - auto out = T { PRIVATE }; - if constexpr (meta::DoInitReturnExpected) { - auto out_expected = Expected { std::in_place, std::move(out) }; - if (auto result = out.do_init(PRIVATE, std::forward(args)...); not result) - out_expected = std::unexpected { std::move(result).error() }; - - return out_expected; - } else if constexpr (meta::DoInitReturnVoid) { - out.do_init(PRIVATE, std::forward(args)...); - return out; - } - } + auto out = T { PRIVATE }; + Try(out.do_init(PRIVATE, std::forward(args)...)); + Return out; + } - std::unreachable(); + ///////////////////////////////////// + ///////////////////////////////////// + template + template + requires(not meta::IsOwnedByOther and meta::DoInitReturnVoid) + STORMKIT_FORCE_INLINE + inline auto Owned::create(Args&&... args) noexcept -> T + requires(not meta::CreateAllocateDisabled) + { + auto out = T { PRIVATE }; + out.do_init(PRIVATE, std::forward(args)...); + return out; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + template + requires(meta::IsOwnedByOther and meta::DoInitReturnExpected) + STORMKIT_FORCE_INLINE + inline auto Owned::allocate(Owner&& owner, Args&&... args) noexcept -> Expected> + requires(not meta::CreateAllocateDisabled) + { + auto out = core::allocate_unsafe(PRIVATE, std::forward(owner)); + Try(out->do_init(PRIVATE, std::forward(args)...)); + Return out; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + template + requires(meta::IsOwnedByOther and meta::DoInitReturnVoid) + STORMKIT_FORCE_INLINE + inline auto Owned::allocate(Owner&& owner, Args&&... args) noexcept -> Heap + requires(not meta::CreateAllocateDisabled) + { + auto out = core::allocate_unsafe(PRIVATE, std::forward(owner)); + out->do_init(PRIVATE, std::forward(args)...); + return out; } ///////////////////////////////////// ///////////////////////////////////// template template + requires(not meta::IsOwnedByOther and meta::DoInitReturnExpected) STORMKIT_FORCE_INLINE - inline auto Owned::allocate(Args&&... args) noexcept -> decltype(auto) + inline auto Owned::allocate(Args&&... args) noexcept -> Expected> requires(not meta::CreateAllocateDisabled) { - if constexpr (meta::IsOwnedByOther) { - auto out = core::allocate_unsafe(PRIVATE, std::forward(args...[0])); - return [](auto&& out, auto&&, Args2&&... args2) static noexcept -> Expected> { - if constexpr (meta::DoInitReturnExpected) { - auto out_expected = Expected> { std::in_place, std::move(out) }; - if (auto result = out->do_init(PRIVATE, std::forward(args2)...); not result) - out_expected = std::unexpected { std::move(result).error() }; - - return out_expected; - } else if constexpr (meta::DoInitReturnVoid) { - out->do_init(PRIVATE, std::forward(args2)...); - return out; - } - }(std::move(out), std::forward(args)...); - } else { - auto out = core::allocate_unsafe(PRIVATE); - if constexpr (meta::DoInitReturnExpected) { - auto out_expected = Expected> { std::in_place, std::move(out) }; - if (auto result = out.do_init(PRIVATE, std::forward(args)...); not result) - out_expected = std::unexpected { std::move(result).error() }; - - return out_expected; - } else if constexpr (meta::DoInitReturnVoid) { - out->do_init(PRIVATE, std::forward(args)...); - return out; - } - } + auto out = core::allocate_unsafe(PRIVATE); + Try(out->do_init(PRIVATE, std::forward(args)...)); + Return out; + } - std::unreachable(); + ///////////////////////////////////// + ///////////////////////////////////// + template + template + requires(not meta::IsOwnedByOther and meta::DoInitReturnVoid) + STORMKIT_FORCE_INLINE + inline auto Owned::allocate(Args&&... args) noexcept -> Heap + requires(not meta::CreateAllocateDisabled) + { + auto out = core::allocate_unsafe(PRIVATE); + out->do_init(PRIVATE, std::forward(args)...); + return out; } ///////////////////////////////////// @@ -307,7 +396,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - template U> + template U> STORMKIT_FORCE_INLINE inline View::View(const U& object) noexcept : m_vk_handle { object->native_handle() } { @@ -365,7 +454,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto to_view(T&& value) noexcept -> T { + inline auto as_view(T&& value) noexcept -> T { return std::forward(value); } @@ -373,31 +462,61 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto to_view(const T& value) noexcept -> typename T::ViewType { - return typename T::ViewType { value }; + inline auto as_view(const T& value) noexcept -> typename meta::ObjectInfo>::ViewType { + return typename meta::ObjectInfo::ViewType { value }; } ///////////////////////////////////// ///////////////////////////////////// - template U> + template STORMKIT_FORCE_INLINE - inline auto to_view(const U& value) noexcept -> typename T::ViewType { - return to_view(*value); + inline auto as_view(const T& value) noexcept -> + typename meta::ObjectInfo>>::ViewType { + return as_view(unref(value)); } ///////////////////////////////////// ///////////////////////////////////// - template class Out = std::array, typename... Args> + template STORMKIT_FORCE_INLINE - inline auto to_views(Args&&... args) noexcept -> decltype(auto) { - return Out { to_view(std::forward(args))... }; + inline auto as_view(const T& value) noexcept -> + typename meta::ObjectInfo>>::ViewType { + return as_view(value.value()); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template class Out, typename... Args> + requires(not stdr::range and ...) + STORMKIT_FORCE_INLINE + inline auto as_views(Args&&... args) noexcept -> decltype(auto) { + return Out { gpu::as_view(std::forward(args))... }; } ///////////////////////////////////// ///////////////////////////////////// template class Out = std::vector, typename... Args> + requires(not stdr::range and ...) + STORMKIT_FORCE_INLINE + inline auto to_views(Args&&... args) noexcept -> decltype(auto) { + return Out { gpu::as_view(std::forward(args))... }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template class Out, stdr::range Range> + STORMKIT_FORCE_INLINE + inline auto to_views(const Range& range) noexcept -> decltype(auto) { + return range + | stdv::transform([](T&& val) static noexcept { return gpu::as_view(std::forward(val)); }) + | stdr::to(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto to_views(const Args&... args) noexcept -> decltype(auto) { - return Out { to_view(std::forward(args))... }; + inline auto format_as(const T& object, FormatContext& ctx) noexcept -> decltype(ctx.out()) { + return format_as(as_view(object), ctx); } } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/core/device.cppm b/modules/stormkit/gpu/core/device.cppm index e1dc849bd..a6c785d15 100644 --- a/modules/stormkit/gpu/core/device.cppm +++ b/modules/stormkit/gpu/core/device.cppm @@ -111,7 +111,7 @@ export namespace stormkit::gpu { class STORMKIT_GPU_API Device: public PhysicalDeviceObject { public: Device(const gpu::Device& of) noexcept; - template T> + template T> Device(const T& of) noexcept; ~Device() noexcept; @@ -163,7 +163,7 @@ export namespace stormkit::gpu { using ViewType = ObjectInfo::ViewType; DeviceObject(const T& child) noexcept; - template U> + template U> DeviceObject(const U& child) noexcept; ~DeviceObject() noexcept; @@ -298,7 +298,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - template T> + template T> STORMKIT_FORCE_INLINE inline Device::Device(const T& of) noexcept : PhysicalDeviceObject { of }, @@ -375,7 +375,7 @@ namespace stormkit::gpu { /////////////////////////////////// /////////////////////////////////// template - template U> + template U> STORMKIT_FORCE_INLINE inline DeviceObject::DeviceObject(const U& child) noexcept : PhysicalDeviceObject { child }, m_device { child->device() } { diff --git a/modules/stormkit/gpu/core/instance.cppm b/modules/stormkit/gpu/core/instance.cppm index c004ab7f6..52023664b 100644 --- a/modules/stormkit/gpu/core/instance.cppm +++ b/modules/stormkit/gpu/core/instance.cppm @@ -80,7 +80,7 @@ export namespace stormkit::gpu { using ViewType = ObjectInfo::ViewType; InstanceObject(const T& child) noexcept; - template U> + template U> InstanceObject(const U& child) noexcept; ~InstanceObject() noexcept; @@ -150,7 +150,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - template U> + template U> STORMKIT_FORCE_INLINE inline InstanceObject::InstanceObject(const U& child) noexcept : View { child }, m_instance { child->instance() } { diff --git a/modules/stormkit/gpu/core/physical_device.cppm b/modules/stormkit/gpu/core/physical_device.cppm index 1add27cab..3dc8bb23e 100644 --- a/modules/stormkit/gpu/core/physical_device.cppm +++ b/modules/stormkit/gpu/core/physical_device.cppm @@ -64,38 +64,40 @@ export namespace stormkit::gpu { [[nodiscard]] auto capabilities() const noexcept -> const RenderCapabilities&; [[nodiscard]] - auto memory_types() const noexcept -> const std::vector&; - + auto memory_types() const noexcept -> std::span; [[nodiscard]] - auto queue_families() const noexcept -> const std::vector&; - + auto queue_families() const noexcept -> std::span; [[nodiscard]] - auto extensions() const noexcept -> const std::vector&; - + auto extensions() const noexcept -> std::span; [[nodiscard]] - auto formats_properties() const noexcept -> const std::vector>&; + auto formats_properties() const noexcept -> std::span>; // clang-format off // private: // clang-format on - explicit PhysicalDevice(PrivateTag, view::Instance) noexcept; - auto do_init(PrivateTag, VkPhysicalDevice) noexcept -> void; + PhysicalDevice(PrivateTag, view::Instance&&) noexcept; + auto do_init(PrivateTag, VkPhysicalDevice&&) noexcept -> void; private: - mutable PhysicalDeviceInfo m_device_info; - mutable RenderCapabilities m_capabilities; - mutable std::vector m_memory_types; + struct Data { + PhysicalDeviceInfo device_info; + RenderCapabilities capabilities; + }; + + Heap m_data; + std::vector m_memory_types; + std::vector m_queue_families; + std::vector m_extensions; + std::vector> m_format_properties; - mutable std::vector m_queue_families; - mutable std::vector m_extensions; - mutable std::vector> m_format_properties; + friend class view::PhysicalDevice; }; namespace view { class STORMKIT_GPU_API PhysicalDevice: public InstanceObject { public: PhysicalDevice(const gpu::PhysicalDevice& of) noexcept; - template T> + template T> PhysicalDevice(const T& of) noexcept; ~PhysicalDevice() noexcept; @@ -117,25 +119,21 @@ export namespace stormkit::gpu { [[nodiscard]] auto capabilities() const noexcept -> const RenderCapabilities&; [[nodiscard]] - auto memory_types() const noexcept -> const std::vector&; - + auto memory_types() const noexcept -> std::span; [[nodiscard]] - auto queue_families() const noexcept -> const std::vector&; - + auto queue_families() const noexcept -> std::span; [[nodiscard]] - auto extensions() const noexcept -> const std::vector&; - + auto extensions() const noexcept -> std::span; [[nodiscard]] - auto formats_properties() const noexcept -> const std::vector>&; + auto formats_properties() const noexcept -> std::span>; private: - mutable PhysicalDeviceInfo m_device_info; - mutable RenderCapabilities m_capabilities; - mutable std::vector m_memory_types; + Ref m_data; + std::span m_memory_types; - mutable std::vector m_queue_families; - mutable std::vector m_extensions; - mutable std::vector> m_format_properties; + std::span m_queue_families; + std::span m_extensions; + std::span> m_format_properties; }; template @@ -146,7 +144,7 @@ export namespace stormkit::gpu { using ViewType = ObjectInfo::ViewType; PhysicalDeviceObject(const T& child) noexcept; - template U> + template U> PhysicalDeviceObject(const U& child) noexcept; ~PhysicalDeviceObject() noexcept; @@ -196,9 +194,6 @@ export namespace stormkit::gpu { template auto format_as(view::PhysicalDevice physical_device, FormatContext& ctx) noexcept -> decltype(ctx.out()); - - template - auto format_as(const PhysicalDevice& physical_device, FormatContext& ctx) noexcept -> decltype(ctx.out()); } // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// @@ -209,7 +204,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline PhysicalDevice::PhysicalDevice(PrivateTag, view::Instance instance) noexcept + inline PhysicalDevice::PhysicalDevice(PrivateTag, view::Instance&& instance) noexcept : OwnedByInstance { std::move(instance), monadic::noop() } { } @@ -221,18 +216,53 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline PhysicalDevice::PhysicalDevice(PhysicalDevice&& other) noexcept = default; + inline PhysicalDevice::PhysicalDevice(PhysicalDevice&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto PhysicalDevice::operator=(PhysicalDevice&&) noexcept -> PhysicalDevice& = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::operator=(PhysicalDevice&& other) noexcept -> PhysicalDevice& = default; + inline auto PhysicalDevice::info() const noexcept -> const PhysicalDeviceInfo& { + return m_data->device_info; + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::do_init(PrivateTag, VkPhysicalDevice physical_device) noexcept -> void { - m_vk_handle = physical_device; + inline auto PhysicalDevice::capabilities() const noexcept -> const RenderCapabilities& { + return m_data->capabilities; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto PhysicalDevice::memory_types() const noexcept -> std::span { + return m_memory_types; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto PhysicalDevice::queue_families() const noexcept -> std::span { + return m_queue_families; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto PhysicalDevice::extensions() const noexcept -> std::span { + return m_extensions; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto PhysicalDevice::formats_properties() const noexcept -> std::span> { + return m_format_properties; } namespace view { @@ -240,15 +270,25 @@ namespace stormkit::gpu { ///////////////////////////////////// STORMKIT_FORCE_INLINE inline PhysicalDevice::PhysicalDevice(const gpu::PhysicalDevice& of) noexcept - : InstanceObject { of } { + : InstanceObject { of }, + m_data { as_ref(of.m_data) }, + m_memory_types { of.m_memory_types }, + m_queue_families { of.m_queue_families }, + m_extensions { of.m_extensions }, + m_format_properties { of.m_format_properties } { } ///////////////////////////////////// ///////////////////////////////////// - template T> + template T> STORMKIT_FORCE_INLINE inline PhysicalDevice::PhysicalDevice(const T& of) noexcept - : InstanceObject { of } { + : InstanceObject { of }, + m_data { as_ref(of->m_data) }, + m_memory_types { of->m_memory_types }, + m_queue_families { of->m_queue_families }, + m_extensions { of->m_extensions }, + m_format_properties { of->m_format_properties } { } ///////////////////////////////////// @@ -264,7 +304,20 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::operator=(const PhysicalDevice&) noexcept -> PhysicalDevice& = default; + inline auto PhysicalDevice::operator=(const PhysicalDevice& other) noexcept -> PhysicalDevice& { + if (&other == this) [[unlikely]] + return *this; + + m_data = as_ref(other.m_data); + m_memory_types = other.m_memory_types; + m_queue_families = other.m_queue_families; + m_extensions = other.m_extensions; + m_format_properties = other.m_format_properties; + + InstanceObject::operator=(other); + + return *this; + } ///////////////////////////////////// ///////////////////////////////////// @@ -276,6 +329,49 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto PhysicalDevice::operator=(PhysicalDevice&&) noexcept -> PhysicalDevice& = default; + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto PhysicalDevice::info() const noexcept -> const PhysicalDeviceInfo& { + return m_data->device_info; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto PhysicalDevice::capabilities() const noexcept -> const RenderCapabilities& { + return m_data->capabilities; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto PhysicalDevice::memory_types() const noexcept -> std::span { + return m_memory_types; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto PhysicalDevice::queue_families() const noexcept -> std::span { + return m_queue_families; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto PhysicalDevice::extensions() const noexcept -> std::span { + return m_extensions; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto PhysicalDevice::formats_properties() const noexcept + -> std::span> { + return m_format_properties; + } + ///////////////////////////////////// ///////////////////////////////////// template @@ -287,7 +383,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - template U> + template U> STORMKIT_FORCE_INLINE inline PhysicalDeviceObject::PhysicalDeviceObject(const U& child) noexcept : InstanceObject { child }, m_physical_device { child->physical_device() } { @@ -337,7 +433,7 @@ namespace stormkit::gpu { template STORMKIT_FORCE_INLINE inline OwnedByPhysicalDevice::OwnedByPhysicalDevice(view::PhysicalDevice&& physical_device, - DeleterType&& deleter_ptr) noexcept + DeleterType&& deleter_ptr) noexcept : Parent { clone(physical_device.instance()), std::move(deleter_ptr) }, m_physical_device { std::move(physical_device) } { } @@ -357,8 +453,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto OwnedByPhysicalDevice::operator=(OwnedByPhysicalDevice&&) noexcept - -> OwnedByPhysicalDevice& = default; + inline auto OwnedByPhysicalDevice::operator=(OwnedByPhysicalDevice&&) noexcept -> OwnedByPhysicalDevice& = default; ///////////////////////////////////// ///////////////////////////////////// @@ -371,29 +466,10 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - inline auto format_as(const view::PhysicalDevice& physical_device, FormatContext& ctx) noexcept -> decltype(ctx.out()) { - const auto& info = physical_device.info(); - return std::format_to(ctx.out(), - "[name: {}, vendor: {}, id: {}, vulkan: {}.{}.{}, driver version: " - "{}.{}.{}]", - info.device_name, - info.vendor_name, - info.device_id, - info.api_major_version, - info.api_minor_version, - info.api_patch_version, - info.driver_major_version, - info.driver_minor_version, - info.driver_patch_version); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - inline auto format_as(const PhysicalDevice& physical_device, FormatContext& ctx) noexcept -> decltype(ctx.out()) { + inline auto format_as(view::PhysicalDevice physical_device, FormatContext& ctx) noexcept -> decltype(ctx.out()) { const auto& info = physical_device.info(); return std::format_to(ctx.out(), - "[name: {}, vendor: {}, id: {}, vulkan: {}.{}.{}, driver version: " + "PhysicalDevice[name: {}, vendor: {}, id: {}, vulkan: {}.{}.{}, driver version: " "{}.{}.{}]", info.device_name, info.vendor_name, diff --git a/modules/stormkit/gpu/core/sync.cppm b/modules/stormkit/gpu/core/sync.cppm index 3f7c82a7b..506d71b11 100644 --- a/modules/stormkit/gpu/core/sync.cppm +++ b/modules/stormkit/gpu/core/sync.cppm @@ -185,14 +185,14 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto Device::wait_for_fence(view::Fence fence, const std::chrono::milliseconds& timeout) const noexcept -> Expected { - return wait_for_fences(to_views(std::move(fence)), true, timeout); + return wait_for_fences(as_views(std::move(fence)), true, timeout); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE inline auto Device::reset_fence(view::Fence fence) const noexcept -> Expected { - return reset_fences(to_views(std::move(fence))); + return reset_fences(as_views(std::move(fence))); } namespace view { @@ -201,14 +201,14 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto Device::wait_for_fence(view::Fence fence, const std::chrono::milliseconds& timeout) const noexcept -> Expected { - return wait_for_fences(to_views(std::move(fence)), true, timeout); + return wait_for_fences(as_views(std::move(fence)), true, timeout); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE inline auto Device::reset_fence(view::Fence fence) const noexcept -> Expected { - return reset_fences(to_views(std::move(fence))); + return reset_fences(as_views(std::move(fence))); } } // namespace view } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/execution/command_buffer.cppm b/modules/stormkit/gpu/execution/command_buffer.cppm index 6cb91c1fc..8a8ef429a 100644 --- a/modules/stormkit/gpu/execution/command_buffer.cppm +++ b/modules/stormkit/gpu/execution/command_buffer.cppm @@ -6,6 +6,7 @@ module; #include #include +#include #include #include @@ -60,8 +61,7 @@ export namespace stormkit::gpu { using OwnedBy = Device; static constexpr auto DISABLE_CREATE_ALLOCATE = true; - - static constexpr auto DEBUG_TYPE = DebugObjectType::COMMAND_BUFFER; + static constexpr auto DEBUG_TYPE = DebugObjectType::COMMAND_BUFFER; }; template<> @@ -113,21 +113,21 @@ export namespace stormkit::gpu { // private: // clang-format on Queue(PrivateTag, view::Device&& device) noexcept; - auto do_init(const Device::QueueEntry&) -> void; + auto do_init(PrivateTag, const Device::QueueEntry&) -> void; private: Device::QueueEntry m_entry; }; namespace view { - class Queue: DeviceObject { + class Queue: public DeviceObject { public: - using ObjectInfo = typename meta::ObjectInfo; + using ObjectInfo = typename meta::ObjectInfo; using ElementType = ObjectInfo::ElementType; using ViewType = ObjectInfo::ViewType; Queue(const gpu::Queue& of) noexcept; - template T> + template T> Queue(const T& of) noexcept; ~Queue() noexcept; @@ -152,6 +152,9 @@ export namespace stormkit::gpu { [[nodiscard]] auto entry() const noexcept -> const gpu::Device::QueueEntry&; + + private: + gpu::Device::QueueEntry m_entry; }; } // namespace view @@ -207,7 +210,7 @@ export namespace stormkit::gpu { EXECUTABLE, }; - using RecordClosure = FunctionRef(CommandBuffer&)>; + using RecordClosure = FunctionRef; using Deleter = std::function; ~CommandBuffer() noexcept; @@ -243,17 +246,17 @@ export namespace stormkit::gpu { std::span clear_values = std::array { ClearValue { ClearColor { .color = colors::SILVER } } }, bool secondary_commandbuffers = false) const noexcept -> const CommandBuffer&; - auto next_sub_pass() const noexcept -> const CommandBuffer&; + auto next_subpass() const noexcept -> const CommandBuffer&; auto end_render_pass() const noexcept -> const CommandBuffer&; auto end_rendering() const noexcept -> const CommandBuffer&; - auto bind_pipeline(const Pipeline& pipeline) const noexcept -> const CommandBuffer&; + auto bind_pipeline(view::Pipeline pipeline) const noexcept -> const CommandBuffer&; auto set_viewport(u32 first_viewport, std::span viewports) const noexcept -> const CommandBuffer&; auto set_scissor(u32 first_scissor, std::span scissors) const noexcept -> const CommandBuffer&; auto set_line_width(f32 width) const noexcept -> const CommandBuffer&; auto set_depth_bias(f32 constant_factor, f32 clamp, f32 slope_factor) const noexcept -> const CommandBuffer&; auto set_blend_constants(std::span constants) const noexcept -> const CommandBuffer&; - auto set_depth_bounds(f32 min, f32 max) noexcept -> CommandBuffer&; + auto set_depth_bounds(f32 min, f32 max) const noexcept -> const CommandBuffer&; auto set_stencil_compare_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBuffer&; auto set_stencil_write_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBuffer&; auto set_stencil_reference(StencilFaceFlag face, u32 reference) const noexcept -> const CommandBuffer&; @@ -266,7 +269,7 @@ export namespace stormkit::gpu { u32 instance_count = 1u, u32 first_index = 0u, i32 vertex_offset = 0, - u32 first_instance = 0u) noexcept -> CommandBuffer&; + u32 first_instance = 0u) const noexcept -> const CommandBuffer&; auto draw_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept -> const CommandBuffer&; auto draw_indexed_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept -> const CommandBuffer&; @@ -329,20 +332,20 @@ export namespace stormkit::gpu { u32 offset = 0u) const noexcept -> const CommandBuffer&; auto submit(view::Queue queue, - std::span wait_semaphores = {}, + std::span wait_semaphores = {}, std::span wait_dst_stages = {}, - std::span signal_semaphores = {}, + std::span signal_semaphores = {}, std::optional fence = std::nullopt) const noexcept -> Expected; - CommandBuffer(PrivateTag, view::Device&&); - auto do_init(PrivateTag, view::CommandPool&&, CommandBufferLevel, VkCommandBuffer&&, Deleter&&) noexcept - -> Expected; + // clang-format off + // private: + // clang-format on + CommandBuffer(PrivateTag, view::Device&&) noexcept; + auto do_init(PrivateTag, CommandBufferLevel, VkCommandBuffer&&, Deleter&&) noexcept -> void; private: - static auto create(view::Device, view::CommandPool, CommandBufferLevel, VkCommandBuffer&&, Deleter&&) noexcept - -> CommandBuffer; - static auto allocate(view::Device, view::CommandPool, CommandBufferLevel, VkCommandBuffer&&, Deleter&&) noexcept - -> Heap; + static auto create(view::Device&&, CommandBufferLevel, VkCommandBuffer&&, Deleter&&) noexcept -> CommandBuffer; + static auto allocate(view::Device&&, CommandBufferLevel, VkCommandBuffer&&, Deleter&&) noexcept -> Heap; CommandBufferLevel m_level = CommandBufferLevel::PRIMARY; @@ -350,14 +353,16 @@ export namespace stormkit::gpu { State m_state = State::INITIAL; + friend struct CommandBufferAPI; friend class CommandPool; + friend class view::CommandPool; }; namespace view { - class STORMKIT_GPU_API CommandBuffer: public OwnedByDevice { + class STORMKIT_GPU_API CommandBuffer: public DeviceObject { public: CommandBuffer(const gpu::CommandBuffer& of) noexcept; - template T> + template T> CommandBuffer(const T& of) noexcept; ~CommandBuffer() noexcept; @@ -368,19 +373,10 @@ export namespace stormkit::gpu { auto operator=(CommandBuffer&&) noexcept -> CommandBuffer&; [[nodiscard]] - auto state() const noexcept -> State; + auto state() const noexcept -> gpu::CommandBuffer::State; [[nodiscard]] auto level() const noexcept -> CommandBufferLevel; - auto record(RecordClosure record_closure, - bool one_time_submit = false, - InheritanceInfo inheritance_info = std::monostate {}) noexcept -> Expected; - - auto reset() noexcept -> Expected; - auto begin(bool one_time_submit = false, InheritanceInfo inheritance_info = std::monostate {}) noexcept - -> Expected; - auto end() noexcept -> Expected; - auto begin_debug_region(std::string_view name, const fcolor_rgb& color = colors::WHITE) const noexcept -> const CommandBuffer&; auto insert_debug_label(std::string_view name, const fcolor_rgb& color = colors::WHITE) const noexcept @@ -394,17 +390,17 @@ export namespace stormkit::gpu { std::span clear_values = std::array { ClearValue { ClearColor { .color = colors::SILVER } } }, bool secondary_commandbuffers = false) const noexcept -> const CommandBuffer&; - auto next_sub_pass() const noexcept -> const CommandBuffer&; + auto next_subpass() const noexcept -> const CommandBuffer&; auto end_render_pass() const noexcept -> const CommandBuffer&; auto end_rendering() const noexcept -> const CommandBuffer&; - auto bind_pipeline(const Pipeline& pipeline) const noexcept -> const CommandBuffer&; + auto bind_pipeline(view::Pipeline pipeline) const noexcept -> const CommandBuffer&; auto set_viewport(u32 first_viewport, std::span viewports) const noexcept -> const CommandBuffer&; auto set_scissor(u32 first_scissor, std::span scissors) const noexcept -> const CommandBuffer&; auto set_line_width(f32 width) const noexcept -> const CommandBuffer&; auto set_depth_bias(f32 constant_factor, f32 clamp, f32 slope_factor) const noexcept -> const CommandBuffer&; auto set_blend_constants(std::span constants) const noexcept -> const CommandBuffer&; - auto set_depth_bounds(f32 min, f32 max) noexcept -> CommandBuffer&; + auto set_depth_bounds(f32 min, f32 max) const noexcept -> const CommandBuffer&; auto set_stencil_compare_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBuffer&; auto set_stencil_write_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBuffer&; auto set_stencil_reference(StencilFaceFlag face, u32 reference) const noexcept -> const CommandBuffer&; @@ -432,8 +428,8 @@ export namespace stormkit::gpu { std::span descriptor_sets, std::span dynamic_offsets = {}) const noexcept -> const CommandBuffer&; - auto copy_buffer(view::Buffer src, view::Buffer dst, usize size, u64 src_offset = 0u, u64 dst_offset = 0u) noexcept - -> const CommandBuffer&; + auto copy_buffer(view::Buffer src, view::Buffer dst, usize size, u64 src_offset = 0u, u64 dst_offset = 0u) + const noexcept -> const CommandBuffer&; auto copy_buffer_to_image(view::Buffer src, view::Image dst, std::span buffer_image_copies = {}) const noexcept @@ -487,13 +483,14 @@ export namespace stormkit::gpu { u32 offset = 0u) const noexcept -> const CommandBuffer&; auto submit(view::Queue queue, - std::span wait_semaphores = {}, + std::span wait_semaphores = {}, std::span wait_dst_stages = {}, - std::span signal_semaphores = {}, + std::span signal_semaphores = {}, std::optional fence = std::nullopt) const noexcept -> Expected; private: - CommandBufferLevel m_level = CommandBufferLevel::PRIMARY; + gpu::CommandBuffer::State m_state; + CommandBufferLevel m_level; }; } // namespace view @@ -509,25 +506,13 @@ export namespace stormkit::gpu { auto create_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept -> Expected; - - template class Out = std::array> - auto create_command_buffers(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>; - - template class Out = std::vector> auto create_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>; + -> Expected>; auto allocate_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept -> Expected>; - - template class Out = std::array> - auto allocate_command_buffers(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>; - - template class Out = std::vector> auto allocate_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>>; + -> Expected>>; // clang-format off // private: @@ -538,17 +523,17 @@ export namespace stormkit::gpu { private: auto create_vk_command_buffers(usize, CommandBufferLevel) const noexcept -> Expected>; - static auto delete_vk_command_buffers(Device, CommandPool, VkCommandBuffer) noexcept -> void; + static auto delete_vk_command_buffers(view::Device, view::CommandPool, VkCommandBuffer) noexcept -> void; }; namespace view { - class CommandPool: DeviceObject { + class CommandPool: public DeviceObject { public: - using ObjectInfo = typename meta::ObjectInfo; + using ObjectInfo = typename meta::ObjectInfo; using ElementType = ObjectInfo::ElementType; using ViewType = ObjectInfo::ViewType; - using DeviceObject::DeviceObject(); + using DeviceObject::DeviceObject; ~CommandPool() noexcept; CommandPool(const CommandPool&) noexcept; @@ -558,26 +543,14 @@ export namespace stormkit::gpu { auto operator=(CommandPool&&) noexcept -> CommandPool&; auto create_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected; - - template class Out = std::array> - auto create_command_buffers(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>; - - template class Out = std::vector> + -> Expected; auto create_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>; + -> Expected>; auto allocate_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>; - - template class Out = std::array> - auto allocate_command_buffers(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>; - - template class Out = std::vector> + -> Expected>; auto allocate_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>>; + -> Expected>>; private: auto create_vk_command_buffers(usize, CommandBufferLevel) const noexcept -> Expected>; @@ -639,7 +612,7 @@ namespace stormkit::gpu { /////////////////////////////////// /////////////////////////////////// - template T> + template T> STORMKIT_FORCE_INLINE inline Queue::Queue(const T& of) noexcept : DeviceObject { of }, m_entry { of->entry() } { @@ -660,16 +633,6 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto Queue::operator=(const Queue&) noexcept -> Queue& = default; - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Queue::Queue(const Queue&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Queue::operator=(const Queue&) noexcept -> Queue& = default; - ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE @@ -683,7 +646,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Queue::submit(const SubmitInfo& submit_info, std::optional fence) const noexcept + inline auto Queue::submit(const gpu::Queue::SubmitInfo& submit_info, std::optional fence) const noexcept -> Expected { return submit({ &submit_info, 1 }, std::move(fence)); } @@ -706,26 +669,24 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::create(view::Device device, - view::CommandPool pool, + inline auto CommandBuffer::create(view::Device&& device, CommandBufferLevel level, VkCommandBuffer&& cmb, - Deleter deleter) noexcept -> CommandBuffer { - auto out = CommandBuffer { PrivateTag, std::move(device) }; - out.do_init(std::move(pool), level, std::move(cmb), std::move(deleter)); + Deleter&& deleter) noexcept -> CommandBuffer { + auto out = CommandBuffer { PRIVATE, std::move(device) }; + out.do_init(PRIVATE, level, std::move(cmb), std::move(deleter)); return out; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::create(view::Device device, - view::CommandPool pool, - CommandBufferLevel level, - VkCommandBuffer&& cmb, - Deleter deleter) noexcept -> CommandBuffer { - auto out = Heap { PrivateTag, std::move(device) }; - out->do_init(std::move(pool), level, std::move(cmb), std::move(deleter)); + inline auto CommandBuffer::allocate(view::Device&& device, + CommandBufferLevel level, + VkCommandBuffer&& cmb, + Deleter&& deleter) noexcept -> Heap { + auto out = core::allocate_unsafe(PRIVATE, std::move(device)); + out->do_init(PRIVATE, level, std::move(cmb), std::move(deleter)); return out; } @@ -752,12 +713,13 @@ namespace stormkit::gpu { std::span wait_dst_stages, std::span signal_semaphores, std::optional fence) const noexcept -> Expected { - auto cmbs = to_views(*this); - auto submit_infos = into_array(SubmitInfo { - .wait_semaphores = wait_semaphores, - .wait_dst_stages = wait_dst_stages, - .command_buffers = cmbs, - .signal_semaphores = signal_semaphores }); + auto cmbs = as_views(*this); + auto submit_infos = std::array { + Queue::SubmitInfo { .wait_semaphores = wait_semaphores, + .wait_dst_stages = wait_dst_stages, + .command_buffers = cmbs, + .signal_semaphores = signal_semaphores } + }; return queue.submit(submit_infos, std::move(fence)); } @@ -776,6 +738,18 @@ namespace stormkit::gpu { return m_level; } + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto CommandBuffer::record(RecordClosure record_closure, + bool one_time_submit, + InheritanceInfo inheritance_info) noexcept -> Expected { + Try(begin(one_time_submit, std::move(inheritance_info))); + record_closure(*this); + Try(end()); + Return {}; + } + namespace view { ///////////////////////////////////// ///////////////////////////////////// @@ -786,7 +760,7 @@ namespace stormkit::gpu { /////////////////////////////////// /////////////////////////////////// - template T> + template T> STORMKIT_FORCE_INLINE inline CommandBuffer::CommandBuffer(const T& of) noexcept : DeviceObject { of }, m_state { of->state() }, m_level { of->level() } { @@ -825,12 +799,13 @@ namespace stormkit::gpu { std::span wait_dst_stages, std::span signal_semaphores, std::optional fence) const noexcept -> Expected { - auto cmbs = to_views(*this); - auto submit_infos = into_array(SubmitInfo { - .wait_semaphores = wait_semaphores, - .wait_dst_stages = wait_dst_stages, - .command_buffers = cmbs, - .signal_semaphores = signal_semaphores }); + auto cmbs = as_views(*this); + auto submit_infos = std::array { + gpu::Queue::SubmitInfo { .wait_semaphores = wait_semaphores, + .wait_dst_stages = wait_dst_stages, + .command_buffers = cmbs, + .signal_semaphores = signal_semaphores } + }; return queue.submit(submit_infos, std::move(fence)); } @@ -838,7 +813,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::state() const noexcept -> State { + inline auto CommandBuffer::state() const noexcept -> gpu::CommandBuffer::State { return m_state; } @@ -876,32 +851,17 @@ namespace stormkit::gpu { ///////////////////////////////////// STORMKIT_FORCE_INLINE inline auto CommandPool::create_command_buffer(CommandBufferLevel level) const noexcept -> Expected { - auto cmbs = Try(create_command_buffers(1, level)); - Return std::move(cmbs.front()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - template class Out = std::array> - inline auto CommandPool::create_command_buffers(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected> { - Return Try(create_vk_command_buffers(count, level)) - | stdv::transform([this, &count, &level](auto vk_handle) static noexcept { - return CommandBuffer::create(device(), *this, level, std::move(vk_handle), delete_vk_command_buffers); - }) - | stdr::to(); + auto vk_handle = Try(create_vk_command_buffers(1, level)).front(); + Return CommandBuffer::create(auto(device()), level, std::move(vk_handle), delete_vk_command_buffers); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - template class Out = std::vector> - inline auto CommandPool::create_command_buffers(usize count, - CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected> { - Return transform(Try(create_vk_command_buffers(count, level)), [this, &count, &level](auto vk_handle) static noexcept { - return CommandBuffer::create(device(), *this, level, std::move(vk_handle), delete_vk_command_buffers); + inline auto CommandPool::create_command_buffers(usize count, CommandBufferLevel level) const noexcept + -> Expected> { + Return transform(Try(create_vk_command_buffers(count, level)), [this, &level](auto vk_handle) noexcept { + return CommandBuffer::create(auto(device()), level, std::move(vk_handle), delete_vk_command_buffers); }); } @@ -909,32 +869,17 @@ namespace stormkit::gpu { ///////////////////////////////////// STORMKIT_FORCE_INLINE inline auto CommandPool::allocate_command_buffer(CommandBufferLevel level) const noexcept -> Expected> { - auto cmbs = Try(allocate_command_buffers(1, level)); - Return std::move(cmbs.front()); + auto vk_handle = Try(create_vk_command_buffers(1, level)).front(); + Return CommandBuffer::allocate(auto(device()), level, std::move(vk_handle), delete_vk_command_buffers); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - template class Out = std::array> - inline auto CommandPool::allocate_command_buffers(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected, COUNT>> { - Return Try(create_vk_command_buffers(count, level)) - | stdv::transform([this, &count, &level](auto vk_handle) static noexcept { - return CommandBuffer::allocate(device(), *this, level, std::move(vk_handle), delete_vk_command_buffers); - }) - | stdr::to(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - template class Out = std::vector> - inline auto CommandPool::allocate_command_buffers(usize count, - CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected> { - Return transform(Try(create_vk_command_buffers(count, level)), [this, &count, &level](auto vk_handle) static noexcept { - return CommandBuffer::allocate(device(), *this, level, std::move(vk_handle), delete_vk_command_buffers); + inline auto CommandPool::allocate_command_buffers(usize count, CommandBufferLevel level) const noexcept + -> Expected>> { + Return transform(Try(create_vk_command_buffers(count, level)), [this, &level](auto vk_handle) noexcept { + return CommandBuffer::allocate(auto(device()), level, std::move(vk_handle), delete_vk_command_buffers); }); } @@ -968,34 +913,18 @@ namespace stormkit::gpu { ///////////////////////////////////// STORMKIT_FORCE_INLINE inline auto CommandPool::create_command_buffer(CommandBufferLevel level) const noexcept -> Expected { - auto cmbs = Try(create_command_buffers(1, level)); - Return std::move(cmbs.front()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - template class Out = std::array> - inline auto CommandPool::create_command_buffers(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected> { - Return Try(create_vk_command_buffers(count, level)) - | stdv::transform([this, &count, &level](auto vk_handle) static noexcept { - return gpu::CommandBuffer::create(device(), *this, level, std::move(vk_handle), delete_vk_command_buffers); - }) - | stdr::to(); + auto vk_handle = Try(create_vk_command_buffers(1, level)).front(); + Return gpu::CommandBuffer::create(auto(device()), level, std::move(vk_handle), delete_vk_command_buffers); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - template class Out = std::vector> - inline auto CommandPool::create_command_buffers(usize count, - CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected> { - Return - transform(Try(create_vk_command_buffers(count, level)), [this, &count, &level](auto vk_handle) static noexcept { - return gpu::CommandBuffer::create(device(), *this, level, std::move(vk_handle), delete_vk_command_buffers); - }); + inline auto CommandPool::create_command_buffers(usize count, CommandBufferLevel level) const noexcept + -> Expected> { + Return transform(Try(create_vk_command_buffers(count, level)), [this, &level](auto vk_handle) noexcept { + return gpu::CommandBuffer::create(auto(device()), level, std::move(vk_handle), delete_vk_command_buffers); + }); } ///////////////////////////////////// @@ -1003,34 +932,19 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto CommandPool::allocate_command_buffer(CommandBufferLevel level) const noexcept -> Expected> { - auto cmbs = Try(allocate_command_buffers(1, level)); - Return std::move(cmbs.front()); + auto vk_handle = Try(create_vk_command_buffers(1, level)).front(); + Return gpu::CommandBuffer::allocate(auto(device()), level, std::move(vk_handle), delete_vk_command_buffers); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - template class Out = std::array> - inline auto CommandPool::allocate_command_buffers(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected, COUNT>> { - Return Try(create_vk_command_buffers(count, level)) - | stdv::transform([this, &count, &level](auto vk_handle) static noexcept { - return gpu::CommandBuffer::allocate(device(), *this, level, std::move(vk_handle), delete_vk_command_buffers); - }) - | stdr::to(); + inline auto CommandPool::allocate_command_buffers(usize count, CommandBufferLevel level) const noexcept + -> Expected>> { + Return transform(Try(create_vk_command_buffers(count, level)), [this, &level](auto vk_handle) noexcept { + return gpu::CommandBuffer::allocate(auto(device()), level, std::move(vk_handle), delete_vk_command_buffers); + }); } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - template class Out = std::vector> - inline auto CommandPool::allocate_command_buffers(usize count, - CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected> { - Return - transform(Try(create_vk_command_buffers(count, level)), [this, &count, &level](auto vk_handle) static noexcept { - return gpu::CommandBuffer::allocate(device(), *this, level, std::move(vk_handle), delete_vk_command_buffers); - }); - } } // namespace view } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/execution/descriptors.cppm b/modules/stormkit/gpu/execution/descriptors.cppm index 9d84ceb22..2a9bda525 100644 --- a/modules/stormkit/gpu/execution/descriptors.cppm +++ b/modules/stormkit/gpu/execution/descriptors.cppm @@ -6,6 +6,7 @@ module; #include #include +#include #include #include @@ -21,34 +22,77 @@ import stormkit.gpu.resource; namespace stdr = std::ranges; namespace stdv = std::views; +namespace cmonadic = stormkit::core::monadic; +namespace cmeta = stormkit::core::meta; + export namespace stormkit::gpu { + class DescriptorSet; + class DescriptorSetLayout; + class DescriptorPool; + + namespace view { + class DescriptorSet; + class DescriptorSetLayout; + class DescriptorPool; + } // namespace view + + namespace meta { + template<> + struct ObjectInfo { + using Of = DescriptorSet; + using ElementType = VkDescriptorSet; + using DeleterType = decltype(cmonadic::noop()); + using ViewType = view::DescriptorSet; + using OwnedBy = Device; + + static constexpr auto DISABLE_CREATE_ALLOCATE = true; + static constexpr auto DEBUG_TYPE = DebugObjectType::DESCRIPTOR_SET; + }; + + template<> + struct ObjectInfo { + using Of = DescriptorSetLayout; + using ElementType = VkDescriptorSetLayout; + using DeleterType = PFN_vkDestroyDescriptorSetLayout VolkDeviceTable::*; + using ViewType = view::DescriptorSetLayout; + using OwnedBy = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::DESCRIPTOR_SET_LAYOUT; + }; + + template<> + struct ObjectInfo { + using Of = DescriptorPool; + using ElementType = VkDescriptorPool; + using DeleterType = PFN_vkDestroyDescriptorPool VolkDeviceTable::*; + using ViewType = view::DescriptorPool; + using OwnedBy = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::DESCRIPTOR_POOL; + }; + } // namespace meta + struct BufferDescriptor { DescriptorType type = DescriptorType::UNIFORM_BUFFER; u32 binding; - view::Buffer buffer; + view::Buffer buffer; std::optional range = std::nullopt; u32 offset = 0; }; struct ImageDescriptor { - DescriptorType type = DescriptorType::COMBINED_IMAGE_SAMPLER; - u32 binding; - ImageLayout layout; - Ref image_view; - Ref sampler; + DescriptorType type = DescriptorType::COMBINED_IMAGE_SAMPLER; + u32 binding; + ImageLayout layout; + view::ImageView image_view; + view::Sampler sampler; }; using Descriptor = std::variant; - class DescriptorPool; - - class STORMKIT_GPU_API DescriptorSet { - struct PrivateFuncTag {}; - - using Deleter = std::function; + class STORMKIT_GPU_API DescriptorSet: public OwnedByDevice { public: - static constexpr auto DEBUG_TYPE = DebugObjectType::DESCRIPTOR_SET; - + using Deleter = std::function; ~DescriptorSet() noexcept; DescriptorSet(const DescriptorSet&) = delete; @@ -57,24 +101,22 @@ export namespace stormkit::gpu { DescriptorSet(DescriptorSet&&) noexcept; auto operator=(DescriptorSet&&) noexcept -> DescriptorSet&; - auto update(std::span descriptors) -> void; - - [[nodiscard]] - auto types() const noexcept -> const std::vector&; - - [[nodiscard]] - auto native_handle() const noexcept -> VkDescriptorSet; + auto update(std::span descriptors) const noexcept -> void; - DescriptorSet(VkDevice, const VolkDeviceTable&, VkDescriptorSet&&, Deleter&&, PrivateFuncTag) noexcept; + // clang-format off + // private: + // clang-format on + DescriptorSet(PrivateTag, view::Device&&) noexcept; private: - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; + auto do_init(VkDescriptorSet&&, Deleter&&) noexcept -> void; - VkDescriptorSet m_vk_handle; + static auto create(view::Device&&, VkDescriptorSet&&, Deleter&&) noexcept -> DescriptorSet; + static auto allocate(view::Device&&, VkDescriptorSet&&, Deleter&&) noexcept -> Heap; Deleter m_deleter; friend class DescriptorPool; + friend class view::DescriptorPool; }; struct DescriptorSetLayoutBinding { @@ -84,16 +126,28 @@ export namespace stormkit::gpu { usize descriptor_count; }; - class STORMKIT_GPU_API DescriptorSetLayout { - struct PrivateFuncTag {}; + namespace view { + class DescriptorSet: public DeviceObject { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using ViewType = ObjectInfo::ViewType; - public: - static constexpr auto DEBUG_TYPE = DebugObjectType::DESCRIPTOR_SET_LAYOUT; + using DeviceObject::DeviceObject; + ~DescriptorSet() noexcept; - static auto create(const Device& device, std::vector bindings) noexcept - -> Expected; - static auto allocate(const Device& device, std::vector bindings) noexcept - -> Expected>; + DescriptorSet(const DescriptorSet&) noexcept; + auto operator=(const DescriptorSet&) noexcept -> DescriptorSet&; + + DescriptorSet(DescriptorSet&&) noexcept; + auto operator=(DescriptorSet&&) noexcept -> DescriptorSet&; + + auto update(std::span descriptors) const noexcept -> void; + }; + } // namespace view + + class STORMKIT_GPU_API DescriptorSetLayout: public OwnedByDevice { + public: ~DescriptorSetLayout() noexcept; DescriptorSetLayout(const DescriptorSetLayout&) = delete; @@ -103,43 +157,50 @@ export namespace stormkit::gpu { auto operator=(DescriptorSetLayout&&) noexcept -> DescriptorSetLayout&; [[nodiscard]] - auto hash() const noexcept -> hash64; - [[nodiscard]] - auto bindings() const noexcept -> const std::vector&; + auto bindings() const noexcept -> std::span; - [[nodiscard]] - auto native_handle() const noexcept -> VkDescriptorSetLayout; + // clang-format off + // private: + // clang-format on + DescriptorSetLayout(PrivateTag, view::Device&&) noexcept; + auto do_init(PrivateTag, std::vector&&) noexcept -> Expected; - [[nodiscard]] - auto operator==(const DescriptorSetLayout& second) const noexcept -> bool; + private: + std::vector m_bindings; + }; - DescriptorSetLayout(const Device&, std::vector&&, PrivateFuncTag) noexcept; + namespace view { + class DescriptorSetLayout: public DeviceObject { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using ViewType = ObjectInfo::ViewType; - private: - auto do_init() noexcept -> Expected; + DescriptorSetLayout(const gpu::DescriptorSetLayout& of) noexcept; + template T> + DescriptorSetLayout(const T& of) noexcept; + ~DescriptorSetLayout() noexcept; - std::vector m_bindings; + DescriptorSetLayout(const DescriptorSetLayout&) noexcept; + auto operator=(const DescriptorSetLayout&) noexcept -> DescriptorSetLayout&; - hash64 m_hash = 0; - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - vk::Owned m_vk_handle; - }; + DescriptorSetLayout(DescriptorSetLayout&&) noexcept; + auto operator=(DescriptorSetLayout&&) noexcept -> DescriptorSetLayout&; - class STORMKIT_GPU_API DescriptorPool { - struct PrivateFuncTag {}; + auto bindings() const noexcept -> std::span; - public: - static constexpr auto DEBUG_TYPE = DebugObjectType::DESCRIPTOR_POOL; + private: + std::span m_bindings; + }; + } // namespace view + class STORMKIT_GPU_API DescriptorPool: public OwnedByDevice { + public: struct Size { DescriptorType type; u32 descriptor_count; }; - static auto create(const Device& device, std::span sizes, u32 max_sets) noexcept -> Expected; - static auto allocate(const Device& device, std::span sizes, u32 max_sets) noexcept - -> Expected>; ~DescriptorPool() noexcept; DescriptorPool(const DescriptorPool&) = delete; @@ -148,32 +209,62 @@ export namespace stormkit::gpu { DescriptorPool(DescriptorPool&&) noexcept; auto operator=(DescriptorPool&&) noexcept -> DescriptorPool&; - auto create_descriptor_set(const DescriptorSetLayout& layout) const noexcept -> Expected; - auto create_descriptor_sets(usize count, const DescriptorSetLayout& layout) const noexcept + auto create_descriptor_set(view::DescriptorSetLayout layout) const noexcept -> Expected; + auto create_descriptor_sets(usize count, view::DescriptorSetLayout layout) const noexcept -> Expected>; - auto allocate_descriptor_set(const DescriptorSetLayout& layout) const noexcept -> Expected>; - auto allocate_descriptor_sets(usize count, const DescriptorSetLayout& layout) const noexcept + auto allocate_descriptor_set(view::DescriptorSetLayout layout) const noexcept -> Expected>; + auto allocate_descriptor_sets(usize count, view::DescriptorSetLayout layout) const noexcept -> Expected>>; - [[nodiscard]] - auto native_handle() const noexcept -> VkDescriptorPool; - - DescriptorPool(const Device&, PrivateFuncTag) noexcept; + // clang-format off + // private: + // clang-format on + DescriptorPool(PrivateTag, view::Device&&) noexcept; + auto do_init(PrivateTag, std::span&&, u32) noexcept -> Expected; private: - auto do_init(std::span, u32) noexcept -> Expected; + auto create_vk_descriptor_sets(usize, view::DescriptorSetLayout&&) const noexcept + -> Expected>; - auto create_vk_descriptor_sets(usize, const DescriptorSetLayout&) const -> Expected>; - static auto delete_vk_descriptor_set(VkDescriptorSet) -> void; + static auto delete_vk_descriptor_set(view::Device, view::DescriptorPool, VkDescriptorSet) noexcept -> void; - VkDevice m_vk_device = nullptr; - Ref m_vk_device_table; - vk::Owned m_vk_handle; + friend class view::DescriptorPool; }; + namespace view { + class DescriptorPool: public DeviceObject { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using ViewType = ObjectInfo::ViewType; + + using DeviceObject::DeviceObject; + ~DescriptorPool() noexcept; + + DescriptorPool(const DescriptorPool&) noexcept; + auto operator=(const DescriptorPool&) noexcept -> DescriptorPool&; + + DescriptorPool(DescriptorPool&&) noexcept; + auto operator=(DescriptorPool&&) noexcept -> DescriptorPool&; + + auto create_descriptor_set(DescriptorSetLayout layout) const noexcept -> Expected; + auto create_descriptor_sets(usize count, DescriptorSetLayout layout) const noexcept + -> Expected>; + + auto allocate_descriptor_set(DescriptorSetLayout layout) const noexcept -> Expected>; + auto allocate_descriptor_sets(usize count, DescriptorSetLayout layout) const noexcept + -> Expected>>; + + private: + auto create_vk_descriptor_sets(usize, DescriptorSetLayout&&) const noexcept -> Expected>; + + static auto delete_vk_descriptor_set(Device, DescriptorPool, VkDescriptorSet) noexcept -> void; + }; + } // namespace view + template - constexpr auto hasher(const DescriptorSetLayout& value) noexcept -> Ret; + constexpr auto hasher(view::DescriptorSetLayout value) noexcept -> Ret; template constexpr auto hasher(const DescriptorSetLayoutBinding& value) noexcept -> Ret; template @@ -192,153 +283,80 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorSet::DescriptorSet(VkDevice device, - const VolkDeviceTable& device_table, - VkDescriptorSet&& set, - Deleter&& deleter, - PrivateFuncTag) noexcept - : m_vk_device { device }, - m_vk_device_table { as_ref(device_table) }, - m_vk_handle { std::move(set) }, - m_deleter { std::move(deleter) } { - ensures(m_deleter.operator bool()); + inline DescriptorSet::DescriptorSet(PrivateTag, view::Device&& device) noexcept + : OwnedByDevice { std::move(device), cmonadic::noop() } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE inline DescriptorSet::~DescriptorSet() noexcept { - if (m_vk_handle) m_deleter(m_vk_handle); + if (m_vk_handle != VK_NULL_HANDLE) { + m_deleter(m_vk_handle); + m_vk_handle = VK_NULL_HANDLE; + } } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorSet::DescriptorSet(DescriptorSet&& other) noexcept - : m_vk_device { std::exchange(other.m_vk_device, nullptr) }, - m_vk_device_table { other.m_vk_device_table }, - m_vk_handle { std::exchange(other.m_vk_handle, nullptr) }, - m_deleter { std::move(other.m_deleter) } { - } + inline DescriptorSet::DescriptorSet(DescriptorSet&& other) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorSet::operator=(DescriptorSet&& other) noexcept -> DescriptorSet& { - if (&other == this) [[unlikely]] - return *this; - - m_vk_device = std::exchange(other.m_vk_device, nullptr); - m_vk_device_table = as_ref(other.m_vk_device_table); - m_vk_handle = std::exchange(other.m_vk_handle, nullptr); - m_deleter = std::move(other.m_deleter); - - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto DescriptorSet::update(std::span descriptors) -> void { - auto&& [_, _, _writes] = [this, &descriptors] noexcept -> decltype(auto) { - auto buffers = std::vector {}; - auto images = std::vector {}; - auto writes = std::vector {}; - buffers.reserve(std::size(descriptors)); - images.reserve(std::size(descriptors)); - writes.reserve(std::size(descriptors)); - - std::ranges::for_each(descriptors, - core::monadic::either( - [vk_handle = m_vk_handle, &buffers, &writes](const BufferDescriptor& descriptor) noexcept - -> decltype(auto) { - buffers.push_back(VkDescriptorBufferInfo { - .buffer = descriptor.buffer, - .offset = descriptor.offset, - .range = descriptor.range.value_or(VK_WHOLE_SIZE), - }); - const auto& buffer_descriptor = buffers.back(); - - writes.push_back(VkWriteDescriptorSet { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = vk_handle, - .dstBinding = descriptor.binding, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = vk::to_vk(descriptor.type), - .pImageInfo = nullptr, - .pBufferInfo = &buffer_descriptor, - .pTexelBufferView = nullptr, - }); - }, - [vk_handle = m_vk_handle, &images, &writes](const ImageDescriptor& descriptor) noexcept - -> decltype(auto) { - images.push_back(VkDescriptorImageInfo { - // .sampler = descriptor.sampler, - // .imageView = descriptor.image_view, - .sampler = descriptor.sampler->native_handle(), - .imageView = descriptor.image_view->native_handle(), - .imageLayout = narrow(descriptor.layout), - }); - const auto& image_descriptor = images.back(); - - writes.push_back(VkWriteDescriptorSet { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = vk_handle, - .dstBinding = descriptor.binding, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = vk::to_vk(descriptor.type), - .pImageInfo = &image_descriptor, - .pBufferInfo = nullptr, - .pTexelBufferView = nullptr, - }); - })); - - return std::tuple { std::move(buffers), std::move(images), std::move(writes) }; - }(); - - vk::call(m_vk_device_table->vkUpdateDescriptorSets, m_vk_device, stdr::size(_writes), stdr::data(_writes), 0, nullptr); - } + inline auto DescriptorSet::operator=(DescriptorSet&& other) noexcept -> DescriptorSet& = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorSet::native_handle() const noexcept -> VkDescriptorSet { - return m_vk_handle; + inline auto DescriptorSet::create(view::Device&& device, VkDescriptorSet&& handle, Deleter&& deleter) noexcept + -> DescriptorSet { + auto out = DescriptorSet { PRIVATE, std::move(device) }; + out.do_init(std::move(handle), std::move(deleter)); + return out; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorSetLayout::DescriptorSetLayout(const Device& device, - std::vector&& bindings, - PrivateFuncTag) noexcept - : m_bindings { std::move(bindings) }, - m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { { [vk_device_table = m_vk_device_table, vk_device = m_vk_device](VkDescriptorSetLayout handle) noexcept { - if (handle) vk_device_table->vkDestroyDescriptorSetLayout(vk_device, handle, nullptr); - } } } { + inline auto DescriptorSet::allocate(view::Device&& device, VkDescriptorSet&& handle, Deleter&& deleter) noexcept + -> Heap { + auto out = core::allocate_unsafe(PRIVATE, std::move(device)); + out->do_init(std::move(handle), std::move(deleter)); + return out; } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DescriptorSetLayout::create(const Device& device, std::vector bindings) noexcept - -> Expected { - auto layout = DescriptorSetLayout { device, std::move(bindings), PrivateFuncTag {} }; - return layout.do_init().transform(core::monadic::consume(layout)); - } + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline DescriptorSet::~DescriptorSet() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline DescriptorSet::DescriptorSet(const DescriptorSet&) noexcept = default; + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto DescriptorSet::operator=(const DescriptorSet&) noexcept -> DescriptorSet& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline DescriptorSet::DescriptorSet(DescriptorSet&&) noexcept = default; + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto DescriptorSet::operator=(DescriptorSet&&) noexcept -> DescriptorSet& = default; + } // namespace view - ////////////////////////////////////p/ + ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorSetLayout::allocate(const Device& device, std::vector bindings) noexcept - -> Expected> { - auto layout = allocate_unsafe(device, std::move(bindings), PrivateFuncTag {}); - return layout->do_init().transform(core::monadic::consume(layout)); + inline DescriptorSetLayout::DescriptorSetLayout(PrivateTag, view::Device&& device) noexcept + : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyDescriptorSetLayout } { } ///////////////////////////////////// @@ -359,89 +377,62 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorSetLayout::hash() const noexcept -> hash64 { - return m_hash; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DescriptorSetLayout::bindings() const noexcept -> const std::vector& { + inline auto DescriptorSetLayout::bindings() const noexcept -> std::span { return m_bindings; } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DescriptorSetLayout::native_handle() const noexcept -> VkDescriptorSetLayout { - return m_vk_handle; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DescriptorSetLayout::operator==(const DescriptorSetLayout& second) const noexcept -> bool { - return m_hash == second.hash(); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DescriptorSetLayout::do_init() noexcept -> Expected { - const auto vk_bindings = m_bindings - | std::views::transform([](const DescriptorSetLayoutBinding& binding) static noexcept { - return VkDescriptorSetLayoutBinding { - .binding = binding.binding, - .descriptorType = vk::to_vk(binding.type), - .descriptorCount = as(binding.descriptor_count), - .stageFlags = vk::to_vk(binding.stages), - .pImmutableSamplers = nullptr, - }; - }) - | std::ranges::to(); - - const auto create_info = VkDescriptorSetLayoutCreateInfo { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .bindingCount = as(std::ranges::size(vk_bindings)), - .pBindings = std::ranges::data(vk_bindings) - }; - - return vk::call_checked(m_vk_device_table->vkCreateDescriptorSetLayout, - m_vk_device, - &create_info, - nullptr) - .transform(core::monadic::set(m_vk_handle)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline DescriptorPool::DescriptorPool(const Device& device, PrivateFuncTag) noexcept - : m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { { [vk_device = m_vk_device, vk_device_table = m_vk_device_table](VkDescriptorPool handle) noexcept { - vk_device_table->vkDestroyDescriptorPool(vk_device, handle, nullptr); - } } } { - } + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline DescriptorSetLayout::DescriptorSetLayout(const gpu::DescriptorSetLayout& of) noexcept + : DeviceObject { of }, m_bindings { of.bindings() } { + } + + /////////////////////////////////// + /////////////////////////////////// + template T> + STORMKIT_FORCE_INLINE + inline DescriptorSetLayout::DescriptorSetLayout(const T& of) noexcept + : DeviceObject { of }, m_bindings { of->bindings() } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline DescriptorSetLayout::~DescriptorSetLayout() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline DescriptorSetLayout::DescriptorSetLayout(const DescriptorSetLayout&) noexcept = default; + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto DescriptorSetLayout::operator=(const DescriptorSetLayout&) noexcept -> DescriptorSetLayout& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline DescriptorSetLayout::DescriptorSetLayout(DescriptorSetLayout&&) noexcept = default; + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto DescriptorSetLayout::operator=(DescriptorSetLayout&&) noexcept -> DescriptorSetLayout& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto DescriptorSetLayout::bindings() const noexcept -> std::span { + return m_bindings; + } + } // namespace view ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorPool::create(const Device& device, std::span extents, u32 max_sets) noexcept - -> Expected { - auto pool = DescriptorPool { device, PrivateFuncTag {} }; - return pool.do_init(extents, max_sets).transform(core::monadic::consume(pool)); - } - - ////////////////////////////////////p/ - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DescriptorPool::allocate(const Device& device, std::span extents, u32 max_sets) noexcept - -> Expected> { - auto pool = allocate_unsafe(device, PrivateFuncTag {}); - return pool->do_init(extents, max_sets).transform(core::monadic::consume(pool)); + inline DescriptorPool::DescriptorPool(PrivateTag, view::Device&& device) noexcept + : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyDescriptorPool } { } ///////////////////////////////////// @@ -462,121 +453,128 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - auto DescriptorPool::create_descriptor_set(const DescriptorSetLayout& layout) const noexcept -> Expected { - return create_descriptor_sets(1, layout) - .transform([](std::vector&& sets) static noexcept { return std::move(sets.front()); }); + inline auto DescriptorPool::create_descriptor_set(view::DescriptorSetLayout layout) const noexcept + -> Expected { + auto vk_handle = Try(create_vk_descriptor_sets(1, std::move(layout))).front(); + Return DescriptorSet::create(auto(device()), + std::move(vk_handle), + bind_front(delete_vk_descriptor_set, device(), as_view(*this))); } ///////////////////////////////////// ///////////////////////////////////// - inline auto DescriptorPool::create_descriptor_sets(usize count, const DescriptorSetLayout& layout) const noexcept + STORMKIT_FORCE_INLINE + inline auto DescriptorPool::create_descriptor_sets(usize count, view::DescriptorSetLayout layout) const noexcept -> Expected> { - auto tag = DescriptorSet::PrivateFuncTag {}; - return create_vk_descriptor_sets(count, layout).transform([this, &tag](std::vector&& sets) noexcept { - return std::move(sets) - | stdv::as_rvalue - | stdv::transform([this, &tag](VkDescriptorSet&& set) noexcept -> decltype(auto) { - return DescriptorSet { m_vk_device, - *m_vk_device_table, - std::move(set), - DescriptorPool::delete_vk_descriptor_set, - tag }; - }) - | stdr::to(); + Return transform(Try(create_vk_descriptor_sets(count, std::move(layout))), [this](auto vk_handle) noexcept { + return DescriptorSet::create(auto(device()), + std::move(vk_handle), + bind_front(delete_vk_descriptor_set, device(), as_view(*this))); }); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - auto DescriptorPool::allocate_descriptor_set(const DescriptorSetLayout& layout) const noexcept + inline auto DescriptorPool::allocate_descriptor_set(view::DescriptorSetLayout layout) const noexcept -> Expected> { - return allocate_descriptor_sets(1, layout) - .transform([](std::vector>&& sets) static noexcept { return std::move(sets.front()); }); + auto vk_handle = Try(create_vk_descriptor_sets(1, std::move(layout))).front(); + Return DescriptorSet::allocate(auto(device()), + std::move(vk_handle), + bind_front(delete_vk_descriptor_set, device(), as_view(*this))); } ///////////////////////////////////// ///////////////////////////////////// - inline auto DescriptorPool::allocate_descriptor_sets(usize count, const DescriptorSetLayout& layout) const noexcept + STORMKIT_FORCE_INLINE + inline auto DescriptorPool::allocate_descriptor_sets(usize count, view::DescriptorSetLayout layout) const noexcept -> Expected>> { - auto tag = DescriptorSet::PrivateFuncTag {}; - return create_vk_descriptor_sets(count, layout).transform([this, &tag](std::vector&& sets) noexcept { - return std::move(sets) - | stdv::as_rvalue - | stdv::transform([this, &tag](VkDescriptorSet&& set) noexcept -> decltype(auto) { - return core::allocate_unsafe(m_vk_device, - *m_vk_device_table, - std::move(set), - DescriptorPool::delete_vk_descriptor_set, - tag); - }) - | stdr::to(); + Return transform(Try(create_vk_descriptor_sets(count, std::move(layout))), [this](auto vk_handle) noexcept { + return DescriptorSet::allocate(auto(device()), + std::move(vk_handle), + bind_front(delete_vk_descriptor_set, device(), as_view(*this))); }); } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DescriptorPool::native_handle() const noexcept -> VkDescriptorPool { - return m_vk_handle; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DescriptorPool::do_init(std::span sizes, u32 max_sets) noexcept -> Expected { - const auto pool_sizes = sizes - | std::views::transform([](const Size& size) static noexcept { - return VkDescriptorPoolSize { - .type = vk::to_vk(size.type), - .descriptorCount = size.descriptor_count, - }; - }) - | std::ranges::to(); - - const auto create_info = VkDescriptorPoolCreateInfo { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, - .pNext = nullptr, - .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, - .maxSets = max_sets, - .poolSizeCount = as(std::ranges::size(sizes)), - .pPoolSizes = std::ranges::data(pool_sizes), - }; - - return vk::call_checked(m_vk_device_table->vkCreateDescriptorPool, m_vk_device, &create_info, nullptr) - .transform(core::monadic::set(m_vk_handle)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto DescriptorPool::create_vk_descriptor_sets(usize count, const DescriptorSetLayout& layout) const - -> Expected> { - const auto vk_layout = vk::to_vk(layout); - const auto allocate_info = VkDescriptorSetAllocateInfo { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .pNext = nullptr, - .descriptorPool = m_vk_handle, - .descriptorSetCount = as(count), - .pSetLayouts = &vk_layout, - }; - - return vk::allocate_checked(count, - m_vk_device_table->vkAllocateDescriptorSets, - m_vk_device, - &allocate_info); - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto DescriptorPool::delete_vk_descriptor_set(VkDescriptorSet) -> void { - } + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline DescriptorPool::~DescriptorPool() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline DescriptorPool::DescriptorPool(const DescriptorPool&) noexcept = default; + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto DescriptorPool::operator=(const DescriptorPool&) noexcept -> DescriptorPool& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline DescriptorPool::DescriptorPool(DescriptorPool&&) noexcept = default; + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto DescriptorPool::operator=(DescriptorPool&&) noexcept -> DescriptorPool& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto DescriptorPool::create_descriptor_set(DescriptorSetLayout layout) const noexcept + -> Expected { + auto vk_handle = Try(create_vk_descriptor_sets(1, std::move(layout))).front(); + Return gpu::DescriptorSet::create(auto(device()), + std::move(vk_handle), + bind_front(delete_vk_descriptor_set, device(), as_view(*this))); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto DescriptorPool::create_descriptor_sets(usize count, DescriptorSetLayout layout) const noexcept + -> Expected> { + Return transform(Try(create_vk_descriptor_sets(count, std::move(layout))), [this](auto vk_handle) noexcept { + return gpu::DescriptorSet::create(auto(device()), + std::move(vk_handle), + bind_front(delete_vk_descriptor_set, device(), as_view(*this))); + }); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto DescriptorPool::allocate_descriptor_set(DescriptorSetLayout layout) const noexcept + -> Expected> { + auto vk_handle = Try(create_vk_descriptor_sets(1, std::move(layout))).front(); + Return gpu::DescriptorSet::allocate(auto(device()), + std::move(vk_handle), + bind_front(delete_vk_descriptor_set, device(), as_view(*this))); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto DescriptorPool::allocate_descriptor_sets(usize count, DescriptorSetLayout layout) const noexcept + -> Expected>> { + Return transform(Try(create_vk_descriptor_sets(count, std::move(layout))), [this](auto vk_handle) noexcept { + return gpu::DescriptorSet::allocate(auto(device()), + std::move(vk_handle), + bind_front(delete_vk_descriptor_set, device(), as_view(*this))); + }); + } + } // namespace view ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto hasher(const DescriptorSetLayout& value) noexcept -> Ret { - return as(value.hash()); + constexpr auto hasher(view::DescriptorSetLayout value) noexcept -> Ret { + auto out = Ret {}; + for (const auto binding : value.bindings()) out = hash_combine(out, binding); + return out; } ///////////////////////////////////// diff --git a/modules/stormkit/gpu/execution/pipeline.cppm b/modules/stormkit/gpu/execution/pipeline.cppm index 6896f06cb..f3ce0fba4 100644 --- a/modules/stormkit/gpu/execution/pipeline.cppm +++ b/modules/stormkit/gpu/execution/pipeline.cppm @@ -32,21 +32,22 @@ export namespace stormkit::gpu { class PipelineLayout; namespace view { - class PipelineCache; + using PipelineCache = DeviceObject; + using PipelineLayout = DeviceObject; class Pipeline; - class PipelineLayout; } // namespace view namespace meta { template<> struct ObjectInfo { using Of = PipelineCache; - using ElementType = VkFramebuffer; - using DeleterType = PFN_vkDestroyFramebuffer VolkDeviceTable::*; + using ElementType = VkPipelineCache; + using DeleterType = PFN_vkDestroyPipelineCache VolkDeviceTable::*; using ViewType = view::PipelineCache; using OwnedBy = Device; - static constexpr auto DEBUG_TYPE = DebugObjectType::PIPELINE_CACHE; + static constexpr auto DISABLE_CREATE_ALLOCATE = true; + static constexpr auto DEBUG_TYPE = DebugObjectType::PIPELINE_CACHE; }; template<> @@ -72,13 +73,15 @@ export namespace stormkit::gpu { }; } // namespace meta - class STORMKIT_GPU_API PipelineCache: public OwnedByDevice { + class STORMKIT_GPU_API PipelineCache: public OwnedByDevice { public: using LoadSaveError = DecoratedError>; template using LoadSaveExpected = core::Expected; - static auto load_from_file(const Device& device, stdfs::path cache_path) noexcept -> LoadSaveExpected; + static auto load_from_file(view::Device device, stdfs::path cache_path) noexcept -> LoadSaveExpected; + static auto allocate_load_from_file(view::Device device, stdfs::path cache_path) noexcept + -> LoadSaveExpected>; ~PipelineCache() noexcept; PipelineCache(const PipelineCache&) = delete; @@ -87,12 +90,15 @@ export namespace stormkit::gpu { PipelineCache(PipelineCache&&) noexcept; auto operator=(PipelineCache&&) noexcept -> PipelineCache&; + // clang-format off + // private: + // clang-format on PipelineCache(PrivateTag, view::Device&&) noexcept; auto do_init(PrivateTag, stdfs::path&&) noexcept -> LoadSaveExpected; private: - auto create_new_pipeline_cache(const Device&) noexcept -> LoadSaveExpected; - auto read_pipeline_cache(const Device&) noexcept -> LoadSaveExpected; + auto create_new_pipeline_cache() noexcept -> LoadSaveExpected; + auto read_pipeline_cache() noexcept -> LoadSaveExpected; auto save_cache() noexcept -> LoadSaveExpected; static constexpr auto MAGIC = u32 { 0xDEADBEEF }; @@ -119,11 +125,7 @@ export namespace stormkit::gpu { stdfs::path m_path; }; - namespace view { - using PipelineCache = DeviceObject; - } - - class STORMKIT_GPU_API PipelineLayout { + class STORMKIT_GPU_API PipelineLayout: public OwnedByDevice { public: ~PipelineLayout() noexcept; @@ -139,18 +141,14 @@ export namespace stormkit::gpu { // clang-format off // private: // clang-format on - PipelineLayout(view::Device&& device) noexcept; + PipelineLayout(PrivateTag, view::Device&& device) noexcept; auto do_init(PrivateTag, const RasterPipelineLayout&) noexcept -> Expected; private: RasterPipelineLayout m_layout; }; - namespace view { - using PipelineLayout = DeviceObject; - } - - class STORMKIT_GPU_API Pipeline { + class STORMKIT_GPU_API Pipeline: public OwnedByDevice { public: enum class Type { RASTER, @@ -177,19 +175,46 @@ export namespace stormkit::gpu { Pipeline(PrivateTag, view::Device&&) noexcept; auto do_init(PrivateTag, const RasterPipelineState&, - const PipelineLayout&, - std::optional, - std::optional) noexcept -> Expected; + view::PipelineLayout&&, + const RasterPipelineRenderingInfo&, + std::optional&& = std::nullopt) noexcept -> Expected; auto do_init(PrivateTag, const RasterPipelineState&, - const PipelineLayout&, - std::optional, - std::optional) noexcept -> Expected; + view::PipelineLayout&&, + view::RenderPass&&, + std::optional&& = std::nullopt) noexcept -> Expected; private: Type m_type; std::variant m_state; }; + + namespace view { + class STORMKIT_GPU_API Pipeline: public DeviceObject { + public: + using ObjectInfo = typename meta::ObjectInfo; + using ElementType = ObjectInfo::ElementType; + using ViewType = ObjectInfo::ViewType; + + Pipeline(const gpu::Pipeline& of) noexcept; + template T> + Pipeline(const T& of) noexcept; + ~Pipeline() noexcept; + + Pipeline(const Pipeline&) noexcept; + auto operator=(const Pipeline&) noexcept -> Pipeline&; + + Pipeline(Pipeline&&) noexcept; + auto operator=(Pipeline&&) noexcept -> Pipeline&; + + [[nodiscard]] + auto type() const noexcept -> gpu::Pipeline::Type; + + private: + gpu::Pipeline::Type m_type; + }; + } // namespace view + } // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// @@ -200,13 +225,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline PipelineCache::PipelineCache(const Device& device, stdfs::path path, PrivateFuncTag) noexcept - : m_path { std::move(path) }, - m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { - vk_device_table.vkDestroyPipelineCache(vk_device, handle, nullptr); - } } } { + inline PipelineCache::PipelineCache(PrivateTag, view::Device&& device) noexcept + : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyPipelineCache } { } ///////////////////////////////////// @@ -222,37 +242,28 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto PipelineCache::load_from_file(const Device& device, stdfs::path cache_path) noexcept + inline auto PipelineCache::load_from_file(view::Device device, stdfs::path cache_path) noexcept -> LoadSaveExpected { - auto cache = PipelineCache { device, std::move(cache_path), PrivateFuncTag {} }; - Try(cache.do_init(device)); + auto cache = PipelineCache { PRIVATE, std::move(device) }; + Try(cache.do_init(PRIVATE, std::move(cache_path))); Return cache; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto PipelineCache::native_handle() const noexcept -> VkPipelineCache { - return m_vk_handle; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PipelineCache::do_init(const Device& device) noexcept -> LoadSaveExpected { - Return read_pipeline_cache(device); + inline auto PipelineCache::allocate_load_from_file(view::Device device, stdfs::path cache_path) noexcept + -> LoadSaveExpected> { + auto cache = core::allocate_unsafe(PRIVATE, std::move(device)); + Try(cache->do_init(PRIVATE, std::move(cache_path))); + Return cache; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline PipelineLayout::PipelineLayout(const Device& device, const RasterPipelineLayout& layout, PrivateFuncTag) noexcept - : m_layout { layout }, - m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { - vk_device_table.vkDestroyPipelineLayout(vk_device, handle, nullptr); - } } } { + inline PipelineLayout::PipelineLayout(PrivateTag, view::Device&& device) noexcept + : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyPipelineLayout } { } ///////////////////////////////////// @@ -263,104 +274,18 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline PipelineLayout::PipelineLayout(PipelineLayout&& other) noexcept = default; + inline PipelineLayout::PipelineLayout(PipelineLayout&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto PipelineLayout::operator=(PipelineLayout&& other) noexcept -> PipelineLayout& = default; + inline auto PipelineLayout::operator=(PipelineLayout&&) noexcept -> PipelineLayout& = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto PipelineLayout::create(const Device& device, const RasterPipelineLayout& layout) noexcept - -> Expected { - auto pipeline_layout = PipelineLayout { device, layout, PrivateFuncTag {} }; - Try(pipeline_layout.do_init()); - Return pipeline_layout; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PipelineLayout::native_handle() const noexcept -> VkPipelineLayout { - return m_vk_handle; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PipelineLayout::do_init() noexcept -> Expected { - namespace stdv = std::views; - namespace stdr = std::ranges; - const auto set_layouts = m_layout.descriptor_set_layouts - | stdv::transform(core::monadic::unref()) - | stdv::transform(vk::monadic::to_vk()) - | stdr::to(); - - const auto push_constant_ranges = transform(m_layout.push_constant_ranges, [](auto&& push_constant_range) noexcept { - return VkPushConstantRange { - .stageFlags = vk::to_vk(push_constant_range.stages), - .offset = push_constant_range.offset, - .size = as(push_constant_range.size), - }; - }); - - const auto create_info = VkPipelineLayoutCreateInfo { - .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .setLayoutCount = as(stdr::size(set_layouts)), - .pSetLayouts = stdr::data(set_layouts), - .pushConstantRangeCount = as(stdr::size(push_constant_ranges)), - .pPushConstantRanges = stdr::data(push_constant_ranges), - }; - - m_vk_handle = Try(vk::call_checked(m_vk_device_table->vkCreatePipelineLayout, - m_vk_device, - &create_info, - nullptr)); - - Return {}; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Pipeline::Pipeline(const Device& device, const RasterPipelineState& state, PrivateFuncTag) noexcept - : m_type { Type::RASTER }, - m_state { state }, - m_vk_device { device.native_handle() }, - m_vk_device_table { as_ref(device.device_table()) }, - m_vk_handle { { [vk_device_table = *m_vk_device_table, vk_device = m_vk_device](auto handle) noexcept { - vk_device_table.vkDestroyPipeline(vk_device, handle, nullptr); - } } } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Pipeline::create(const Device& device, - const RasterPipelineState& state, - const PipelineLayout& layout, - const RenderPass& render_pass, - OptionalRef cache) noexcept -> Expected { - auto pipeline = Pipeline { device, state, PrivateFuncTag {} }; - Try(pipeline.do_init(layout, as_opt_ref(render_pass), std::nullopt, std::move(cache))); - Return pipeline; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Pipeline::create(const Device& device, - const RasterPipelineState& state, - const PipelineLayout& layout, - const RasterPipelineRenderingInfo& rendering_info, - OptionalRef cache) noexcept -> Expected { - auto pipeline = Pipeline { device, state, PrivateFuncTag {} }; - Try(pipeline.do_init(layout, std::nullopt, as_opt_ref(rendering_info), std::move(cache))); - Return pipeline; + inline Pipeline::Pipeline(PrivateTag, view::Device&& device) noexcept + : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyPipeline } { } ///////////////////////////////////// @@ -394,10 +319,52 @@ namespace stormkit::gpu { return as(m_state); } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Pipeline::native_handle() const noexcept -> VkPipeline { - return m_vk_handle; - } + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Pipeline::Pipeline(const gpu::Pipeline& of) noexcept + : DeviceObject { of }, m_type { of.type() } { + } + + /////////////////////////////////// + /////////////////////////////////// + template T> + STORMKIT_FORCE_INLINE + inline Pipeline::Pipeline(const T& of) noexcept + : DeviceObject { of }, m_type { of->type() } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Pipeline::~Pipeline() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Pipeline::Pipeline(const Pipeline& other) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Pipeline::operator=(const Pipeline& other) noexcept -> Pipeline& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline Pipeline::Pipeline(Pipeline&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Pipeline::operator=(Pipeline&&) noexcept -> Pipeline& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Pipeline::type() const noexcept -> gpu::Pipeline::Type { + return m_type; + } + } // namespace view } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/execution/raster_pipeline.cppm b/modules/stormkit/gpu/execution/raster_pipeline.cppm index 944ee1a36..e21c83edb 100644 --- a/modules/stormkit/gpu/execution/raster_pipeline.cppm +++ b/modules/stormkit/gpu/execution/raster_pipeline.cppm @@ -89,7 +89,7 @@ export namespace stormkit::gpu { }; using RasterPipelineDynamicState = std::vector; - using RasterPipelineShaderState = std::vector>; + using RasterPipelineShaderState = std::vector; struct RasterPipelineDepthStencilState { bool depth_test_enable = false; @@ -111,8 +111,8 @@ export namespace stormkit::gpu { }; struct RasterPipelineLayout { - std::vector> descriptor_set_layouts = {}; - std::vector push_constant_ranges = {}; + std::vector descriptor_set_layouts = {}; + std::vector push_constant_ranges = {}; }; struct RasterPipelineState { diff --git a/modules/stormkit/gpu/execution/render_pass.cppm b/modules/stormkit/gpu/execution/render_pass.cppm index e932aeb1f..22d4cc2e7 100644 --- a/modules/stormkit/gpu/execution/render_pass.cppm +++ b/modules/stormkit/gpu/execution/render_pass.cppm @@ -101,7 +101,7 @@ export namespace stormkit::gpu { using ViewType = ObjectInfo::ViewType; FrameBuffer(const gpu::FrameBuffer& of) noexcept; - template T> + template T> FrameBuffer(const T& of) noexcept; ~FrameBuffer() noexcept; @@ -205,7 +205,7 @@ export namespace stormkit::gpu { using ViewType = ObjectInfo::ViewType; // RenderPass(const gpu::RenderPass& of) noexcept; - // template T> + // template T> // RenderPass(const T& of) noexcept; using DeviceObject::DeviceObject; ~RenderPass() noexcept; @@ -310,7 +310,7 @@ namespace stormkit::gpu { /////////////////////////////////// /////////////////////////////////// - template T> + template T> STORMKIT_FORCE_INLINE inline FrameBuffer::FrameBuffer(const T& of) noexcept : DeviceObject { of }, m_extent { of->extent() }, m_attachments { of->attachments() } { diff --git a/modules/stormkit/gpu/execution/swapchain.cppm b/modules/stormkit/gpu/execution/swapchain.cppm index 61fe12653..a7f33c395 100644 --- a/modules/stormkit/gpu/execution/swapchain.cppm +++ b/modules/stormkit/gpu/execution/swapchain.cppm @@ -67,7 +67,8 @@ export namespace stormkit::gpu { // private: // clang-format on SwapChain(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, view::Surface&&, const math::uextent2&) noexcept -> Expected; + auto do_init(PrivateTag, view::Surface&&, const math::uextent2&, VkSwapchainKHR = VK_NULL_HANDLE) noexcept + -> Expected; private: math::uextent2 m_extent; @@ -85,7 +86,7 @@ export namespace stormkit::gpu { using ViewType = ObjectInfo::ViewType; SwapChain(const gpu::SwapChain& of) noexcept; - template T> + template T> SwapChain(const T& of) noexcept; ~SwapChain() noexcept; @@ -161,7 +162,7 @@ namespace stormkit::gpu { /////////////////////////////////// /////////////////////////////////// - template T> + template T> STORMKIT_FORCE_INLINE inline SwapChain::SwapChain(const T& of) noexcept : view::DeviceObject { of }, m_pixel_format { of->pixel_format() }, m_images { of->images() } { diff --git a/modules/stormkit/gpu/resource/buffer.cppm b/modules/stormkit/gpu/resource/buffer.cppm index c467ca084..7f759d861 100644 --- a/modules/stormkit/gpu/resource/buffer.cppm +++ b/modules/stormkit/gpu/resource/buffer.cppm @@ -80,6 +80,8 @@ export namespace stormkit::gpu { template auto map_as(ioffset offset) noexcept -> Expected>; + bool mapped() const noexcept; + template [[nodiscard]] auto data(this Self& self) noexcept -> cmeta::ForwardConst*; @@ -136,7 +138,7 @@ export namespace stormkit::gpu { using ViewType = ObjectInfo::ViewType; Buffer(const gpu::Buffer& of) noexcept; - template T> + template T> Buffer(const T& of) noexcept; ~Buffer() noexcept; @@ -161,6 +163,8 @@ export namespace stormkit::gpu { template auto map_as(ioffset offset) noexcept -> Expected>; + bool mapped() const noexcept; + template [[nodiscard]] auto data(this Self& self) noexcept -> cmeta::ForwardConst*; @@ -299,6 +303,13 @@ namespace stormkit::gpu { Return from_bytes_mut(ptr); } + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::mapped() const noexcept -> bool { + return m_mapped_pointer != nullptr; + } + ///////////////////////////////////// ///////////////////////////////////// template @@ -363,13 +374,14 @@ namespace stormkit::gpu { m_size { of.size() }, m_memory_properties { of.memory_properties() }, m_is_persistently_mapped { of.is_persistently_mapped() }, - m_mapped_pointer { std::bit_cast(of.data()) }, + m_mapped_pointer { nullptr }, m_vma_allocation { of.allocation() } { + if (of.is_persistently_mapped()) m_mapped_pointer = std::bit_cast(of.data()); } /////////////////////////////////// /////////////////////////////////// - template T> + template T> STORMKIT_FORCE_INLINE inline Buffer::Buffer(const T& of) noexcept : DeviceObject { of }, @@ -377,8 +389,9 @@ namespace stormkit::gpu { m_size { of->size() }, m_memory_properties { of->memory_properties() }, m_is_persistently_mapped { of->is_persistently_mapped() }, - m_mapped_pointer { std::bit_cast(of->data()) }, + m_mapped_pointer { nullptr }, m_vma_allocation { of->allocation() } { + if (of->is_persistently_mapped()) m_mapped_pointer = std::bit_cast(of->data()); } ///////////////////////////////////// @@ -454,6 +467,13 @@ namespace stormkit::gpu { Return from_bytes_mut(ptr); } + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto Buffer::mapped() const noexcept -> bool { + return m_mapped_pointer != nullptr; + } + ///////////////////////////////////// ///////////////////////////////////// template diff --git a/modules/stormkit/gpu/resource/image.cppm b/modules/stormkit/gpu/resource/image.cppm index 6c86e0faf..1fbb3a14e 100644 --- a/modules/stormkit/gpu/resource/image.cppm +++ b/modules/stormkit/gpu/resource/image.cppm @@ -123,7 +123,7 @@ export namespace stormkit::gpu { using ViewType = ObjectInfo::ViewType; Sampler(const gpu::Sampler& of) noexcept; - template T> + template T> Sampler(const T& of) noexcept; ~Sampler() noexcept; @@ -176,7 +176,7 @@ export namespace stormkit::gpu { using ViewType = ObjectInfo::ViewType; ImageView(const gpu::ImageView& of) noexcept; - template T> + template T> ImageView(const T& of) noexcept; ~ImageView() noexcept; @@ -272,7 +272,7 @@ export namespace stormkit::gpu { using ViewType = ObjectInfo::ViewType; Image(const gpu::Image& of) noexcept; - template T> + template T> Image(const T& of) noexcept; ~Image() noexcept; @@ -378,7 +378,7 @@ namespace stormkit::gpu { /////////////////////////////////// /////////////////////////////////// - template T> + template T> STORMKIT_FORCE_INLINE inline Sampler::Sampler(const T& of) noexcept : view::DeviceObject { of }, m_settings { of->settings() } { @@ -463,7 +463,7 @@ namespace stormkit::gpu { /////////////////////////////////// /////////////////////////////////// - template T> + template T> STORMKIT_FORCE_INLINE inline ImageView::ImageView(const T& of) noexcept : view::DeviceObject { of }, m_type { of.type() }, m_subresource_range { of.subresource_range() } { @@ -644,7 +644,7 @@ namespace stormkit::gpu { /////////////////////////////////// /////////////////////////////////// - template T> + template T> STORMKIT_FORCE_INLINE inline Image::Image(const T& of) noexcept : view::DeviceObject { of }, diff --git a/modules/stormkit/gpu/resource/shader.cppm b/modules/stormkit/gpu/resource/shader.cppm index 0ce3a31e8..1c6ca712b 100644 --- a/modules/stormkit/gpu/resource/shader.cppm +++ b/modules/stormkit/gpu/resource/shader.cppm @@ -104,7 +104,7 @@ export namespace stormkit::gpu { using ViewType = ObjectInfo::ViewType; Shader(const gpu::Shader& of) noexcept; - template T> + template T> Shader(const T& of) noexcept; ~Shader() noexcept; @@ -258,7 +258,7 @@ namespace stormkit::gpu { /////////////////////////////////// /////////////////////////////////// - template T> + template T> STORMKIT_FORCE_INLINE inline Shader::Shader(const T& of) noexcept : view::DeviceObject { of }, m_type { of->type() } { diff --git a/src/gpu/core/device.cpp b/src/gpu/core/device.cpp index d76237bc3..d50101080 100644 --- a/src/gpu/core/device.cpp +++ b/src/gpu/core/device.cpp @@ -232,7 +232,7 @@ namespace stormkit::gpu { const auto& device_table = device.device_table(); const auto _fences = transform(fences, vk::monadic::to_vk()); - Try(vk::call_checked(table.vkResetFences, device, stdr::size(_fences), stdr::data(_fences))); + Try(vk::call_checked(device_table.vkResetFences, device, stdr::size(_fences), stdr::data(_fences))); Return {}; } @@ -243,8 +243,7 @@ namespace stormkit::gpu { std::string_view name) noexcept -> Expected { if (not vkSetDebugUtilsObjectNameEXT) return {}; - const auto& handle = device.native_handle(); - const auto info = VkDebugUtilsObjectNameInfoEXT { + const auto info = VkDebugUtilsObjectNameInfoEXT { .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, .pNext = nullptr, .objectType = vk::to_vk(type), @@ -293,7 +292,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto Device::wait_for_fences(std::span fences, + auto Device::wait_for_fences(std::span fences, bool wait_all, const std::chrono::milliseconds& timeout) const noexcept -> Expected { return DeviceAPI::wait_for_fences(*this, std::move(fences), wait_all, timeout); @@ -301,7 +300,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto Device::reset_fences(std::span fences) const noexcept -> Expected { + auto Device::reset_fences(std::span fences) const noexcept -> Expected { return DeviceAPI::reset_fences(*this, std::move(fences)); } diff --git a/src/gpu/core/instance.cpp b/src/gpu/core/instance.cpp index 54ab3c7dc..8e2d11d5a 100644 --- a/src/gpu/core/instance.cpp +++ b/src/gpu/core/instance.cpp @@ -168,7 +168,7 @@ namespace stormkit::gpu { auto Instance::do_retrieve_physical_devices() noexcept -> Expected { m_physical_devices = transform(Try(vk::enumerate_checked(vkEnumeratePhysicalDevices, m_vk_handle)), [this](auto physical_device) noexcept { - return PhysicalDevice::create(*this, physical_device); + return PhysicalDevice::create(*this, std::move(physical_device)); }); Return {}; } diff --git a/src/gpu/core/physical_device.cpp b/src/gpu/core/physical_device.cpp index 7d768ef6e..28ba528f4 100644 --- a/src/gpu/core/physical_device.cpp +++ b/src/gpu/core/physical_device.cpp @@ -370,7 +370,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto score_physical_device(const view::PhysicalDevice& physical_device) noexcept -> u64 { + auto score_physical_device(view::PhysicalDevice physical_device) noexcept -> u64 { const auto support_raytracing = physical_device.check_extension_support(RAYTRACING_EXTENSIONS); auto score = u64 { 0u }; @@ -421,55 +421,18 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto PhysicalDevice::info() const noexcept -> const PhysicalDeviceInfo& { - if (stdr::empty(m_device_info.device_name)) m_device_info = PhysicalDeviceAPI::info(*this); - - return m_device_info; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto PhysicalDevice::capabilities() const noexcept -> const RenderCapabilities& { - if (m_capabilities.limits.max_image_dimension_2D == 0) [[unlikely]] - m_capabilities = PhysicalDeviceAPI::capabilities(*this); - - return m_capabilities; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto PhysicalDevice::memory_types() const noexcept -> const std::vector& { - if (stdr::empty(m_memory_types)) [[unlikely]] - m_memory_types = PhysicalDeviceAPI::memory_types(*this); - - return m_memory_types; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto PhysicalDevice::queue_families() const noexcept -> const std::vector& { - if (stdr::empty(m_queue_families)) [[unlikely]] - m_queue_families = PhysicalDeviceAPI::queue_families(*this); - - return m_queue_families; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto PhysicalDevice::extensions() const noexcept -> const std::vector& { - if (stdr::empty(m_extensions)) [[unlikely]] - m_extensions = PhysicalDeviceAPI::extensions(*this); - - return m_extensions; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto PhysicalDevice::formats_properties() const noexcept -> const std::vector>& { - if (stdr::empty(m_format_properties)) [[unlikely]] - m_format_properties = PhysicalDeviceAPI::formats_properties(*this); - - return m_format_properties; + auto PhysicalDevice::do_init(PrivateTag, VkPhysicalDevice&& physical_device) noexcept -> void { + m_vk_handle = std::move(physical_device); + + m_data = core::allocate_unsafe(Data { + .device_info = PhysicalDeviceAPI::info(*this), + .capabilities = PhysicalDeviceAPI::capabilities(*this), + }); + + m_memory_types = PhysicalDeviceAPI::memory_types(*this); + m_extensions = PhysicalDeviceAPI::extensions(*this); + m_queue_families = PhysicalDeviceAPI::queue_families(*this); + m_format_properties = PhysicalDeviceAPI::formats_properties(*this); } namespace view { @@ -490,58 +453,5 @@ namespace stormkit::gpu { auto PhysicalDevice::check_extension_support(std::span extensions) const noexcept -> bool { return PhysicalDeviceAPI::check_extension_support(*this, std::move(extensions)); } - - ///////////////////////////////////// - ///////////////////////////////////// - auto PhysicalDevice::info() const noexcept -> const PhysicalDeviceInfo& { - if (stdr::empty(m_device_info.device_name)) m_device_info = PhysicalDeviceAPI::info(*this); - - return m_device_info; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto PhysicalDevice::capabilities() const noexcept -> const RenderCapabilities& { - if (m_capabilities.limits.max_image_dimension_2D == 0) [[unlikely]] - m_capabilities = PhysicalDeviceAPI::capabilities(*this); - - return m_capabilities; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto PhysicalDevice::memory_types() const noexcept -> const std::vector& { - if (stdr::empty(m_memory_types)) [[unlikely]] - m_memory_types = PhysicalDeviceAPI::memory_types(*this); - - return m_memory_types; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto PhysicalDevice::queue_families() const noexcept -> const std::vector& { - if (stdr::empty(m_queue_families)) [[unlikely]] - m_queue_families = PhysicalDeviceAPI::queue_families(*this); - - return m_queue_families; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto PhysicalDevice::extensions() const noexcept -> const std::vector& { - if (stdr::empty(m_extensions)) [[unlikely]] - m_extensions = PhysicalDeviceAPI::extensions(*this); - - return m_extensions; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto PhysicalDevice::formats_properties() const noexcept -> const std::vector>& { - if (stdr::empty(m_format_properties)) [[unlikely]] - m_format_properties = PhysicalDeviceAPI::formats_properties(*this); - - return m_format_properties; - } } // namespace view } // namespace stormkit::gpu diff --git a/src/gpu/execution/command_buffer.cpp b/src/gpu/execution/command_buffer.cpp index 3ebbe1cf7..5b4efb93e 100644 --- a/src/gpu/execution/command_buffer.cpp +++ b/src/gpu/execution/command_buffer.cpp @@ -6,6 +6,7 @@ module; #include #include +#include #include @@ -69,1114 +70,1091 @@ namespace stormkit::gpu { { VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, { VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT } }, { VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, { VK_ACCESS_MEMORY_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT } }, }); + } // namespace - struct CommandBufferAPI { - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto reset(CommandBufferType& cmb) noexcept -> Expected { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - Try(vk::call_checked(m_vk_device_table->vkResetCommandBuffer, m_vk_handle, 0)); - state = State::INITIAL; - - Return {}; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto begin(CommandBufferType& cmb, bool one_time_submit, InheritanceInfo inheritance_info_variant) noexcept - -> Expected { - auto& state = cmb.state(); - EXPECTS(state == State::INITIAL); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - auto rendering_color_attachments = std::vector {}; - // auto vk_rendering_inheritance_info = zeroed(); - auto vk_rendering_inheritance_info = VkCommandBufferInheritanceRenderingInfo { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO - }; + struct CommandBufferAPI { + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto reset(CommandBufferType& cmb) noexcept -> Expected { + auto& state = cmb.m_state; - const auto vk_inheritance_info = - [&inheritance_info_variant, &rendering_color_attachments, &vk_rendering_inheritance_info] noexcept { - // auto info = zeroed(); - auto info = VkCommandBufferInheritanceInfo { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO }; - - if (is(inheritance_info_variant)) { - const auto& inheritance_info = as(inheritance_info_variant); - info.renderPass = vk::to_vk(*inheritance_info.render_pass); - info.subpass = inheritance_info.subpass; - info.framebuffer = vk::to_vk(*inheritance_info.framebuffer); - } else if (is(inheritance_info_variant)) { - info.pNext = &vk_rendering_inheritance_info; - - const auto& inheritance_info = as(inheritance_info_variant); - - rendering_color_attachments = inheritance_info.color_attachments - | stdv::transform(gpu::vk::monadic::to_vk()) - | stdr::to(); - vk_rendering_inheritance_info.viewMask = inheritance_info.view_mask; - vk_rendering_inheritance_info - .colorAttachmentCount = as(stdr::size(inheritance_info.color_attachments)); - vk_rendering_inheritance_info.pColorAttachmentFormats = stdr::data(rendering_color_attachments); + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); - if (inheritance_info.depth_attachment) - vk_rendering_inheritance_info - .depthAttachmentFormat = gpu::vk::to_vk(*inheritance_info.depth_attachment); - if (inheritance_info.stencil_attachment) - vk_rendering_inheritance_info - .stencilAttachmentFormat = gpu::vk::to_vk(*inheritance_info.stencil_attachment); + Try(vk::call_checked(device_table.vkResetCommandBuffer, cmb, 0)); + state = CommandBuffer::State::INITIAL; + Return {}; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto begin(CommandBufferType& cmb, bool one_time_submit, InheritanceInfo inheritance_info_variant) noexcept + -> Expected { + auto& state = cmb.m_state; + EXPECTS(state == CommandBuffer::State::INITIAL); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + auto rendering_color_attachments = std::vector {}; + auto vk_rendering_inheritance_info = init_by([](auto& info) noexcept { + info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO; + info.pNext = nullptr; + }); + + const auto vk_inheritance_info = + [&inheritance_info_variant, &rendering_color_attachments, &vk_rendering_inheritance_info] noexcept { + auto info = init_by([](auto& info) noexcept { + info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; + info.pNext = nullptr; + }); + + if (is(inheritance_info_variant)) { + const auto& inheritance_info = as(inheritance_info_variant); + info.renderPass = vk::to_vk(*inheritance_info.render_pass); + info.subpass = inheritance_info.subpass; + info.framebuffer = vk::to_vk(*inheritance_info.framebuffer); + } else if (is(inheritance_info_variant)) { + info.pNext = &vk_rendering_inheritance_info; + + const auto& inheritance_info = as(inheritance_info_variant); + + rendering_color_attachments = inheritance_info.color_attachments + | stdv::transform(gpu::vk::monadic::to_vk()) + | stdr::to(); + vk_rendering_inheritance_info.viewMask = inheritance_info.view_mask; + vk_rendering_inheritance_info + .colorAttachmentCount = as(stdr::size(inheritance_info.color_attachments)); + vk_rendering_inheritance_info.pColorAttachmentFormats = stdr::data(rendering_color_attachments); + + if (inheritance_info.depth_attachment) vk_rendering_inheritance_info - .rasterizationSamples = gpu::vk::to_vk(inheritance_info.rasterization_samples); - } - return info; - }(); - - const auto flags = [this, one_time_submit, &inheritance_info_variant] noexcept -> VkCommandBufferUsageFlags { - auto flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - - if (!one_time_submit) flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; - if (m_level == CommandBufferLevel::SECONDARY) { - if (is(inheritance_info_variant) - or is(inheritance_info_variant)) - flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; - } - - return flags; - }(); - - const auto begin_info = VkCommandBufferBeginInfo { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, - .pNext = nullptr, - .flags = flags, - .pInheritanceInfo = &vk_inheritance_info, - }; + .depthAttachmentFormat = gpu::vk::to_vk(*inheritance_info.depth_attachment); + if (inheritance_info.stencil_attachment) + vk_rendering_inheritance_info + .stencilAttachmentFormat = gpu::vk::to_vk(*inheritance_info.stencil_attachment); + + vk_rendering_inheritance_info + .rasterizationSamples = gpu::vk::to_vk(inheritance_info.rasterization_samples); + } + return info; + }(); + + const auto flags = [&cmb, one_time_submit, &inheritance_info_variant] noexcept -> VkCommandBufferUsageFlags { + auto flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + + if (!one_time_submit) flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; + if (cmb.level() == CommandBufferLevel::SECONDARY) { + if (is(inheritance_info_variant) + or is(inheritance_info_variant)) + flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; + } + + return flags; + }(); + + const auto begin_info = VkCommandBufferBeginInfo { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + .pNext = nullptr, + .flags = flags, + .pInheritanceInfo = &vk_inheritance_info, + }; + + Try(vk::call_checked(device_table.vkBeginCommandBuffer, cmb, &begin_info)); + state = CommandBuffer::State::RECORDING; + + Return {}; + } - Try(vk::call_checked(m_vk_device_table->vkBeginCommandBuffer, m_vk_handle, &begin_info)); - state = State::RECORDING; + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto end(CommandBufferType& cmb) noexcept -> Expected { + auto& state = cmb.m_state; + EXPECTS(state == CommandBuffer::State::RECORDING); - Return {}; - } + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto end(CommandBufferType& cmb) noexcept -> Expected { - auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); + Try(vk::call_checked(device_table.vkEndCommandBuffer, cmb)); + state = CommandBuffer::State::EXECUTABLE; - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); + Return {}; + } - Try(vk::call_checked(device_table.vkEndCommandBuffer, cmb)); - state = State::EXECUTABLE; + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto begin_debug_region(const CommandBufferType& cmb, std::string_view&& name, const fcolor_rgb& color) noexcept + -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); - Return {}; - } + if (not vkCmdBeginDebugUtilsLabelEXT) [[unlikely]] + return; - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto begin_debug_region(const CommandBufferType& cmb, - std::string_view&& name, - const fcolor_rgb& color) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); + const auto info = VkDebugUtilsLabelEXT { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, + .pNext = nullptr, + .pLabelName = stdr::data(name), + .color = { color.r, color.g, color.b, 1.f } + }; - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); + vk::call(vkCmdBeginDebugUtilsLabelEXT, cmb, &info); + } - if (not vkCmdBeginDebugUtilsLabelEXT) [[unlikely]] - return; + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto insert_debug_label(const CommandBufferType& cmb, std::string_view&& name, const fcolor_rgb& color) noexcept + -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); - const auto info = VkDebugUtilsLabelEXT { - .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, - .pNext = nullptr, - .pLabelName = stdr::data(name), - .color = { color.r, color.g, color.b, 1.f } - }; + if (not vkCmdInsertDebugUtilsLabelEXT) [[unlikely]] + return; - vk::call(vkCmdBeginDebugUtilsLabelEXT, cmb, &info); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto insert_debug_label(const CommandBufferType& cmb, - std::string_view&& name, - const fcolor_rgb& color) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - if (not vkCmdInsertDebugUtilsLabelEXT) [[unlikely]] - return; - - const auto info = VkDebugUtilsLabelEXT { - .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, - .pNext = nullptr, - .pLabelName = stdr::data(name), - .color = { color.r, color.g, color.b, 1.f } - }; + const auto info = VkDebugUtilsLabelEXT { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, + .pNext = nullptr, + .pLabelName = stdr::data(name), + .color = { color.r, color.g, color.b, 1.f } + }; - vk::call(vkCmdInsertDebugUtilsLabelEXT, cmb, &info); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto end_debug_region(const CommandBufferType& cmb) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - if (not vkCmdEndDebugUtilsLabelEXT) [[unlikely]] - return; - - vk::call(vkCmdEndDebugUtilsLabelEXT, cmb); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto begin_rendering(const CommandBufferType& cmb, const RenderingInfo& info, bool secondary) noexcept - -> void { - EXPECTS(m_state == State::RECORDING); - - auto to_vk_attachment = [](const auto& attachment) static noexcept { - auto attachment_info = VkRenderingAttachmentInfo { - .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - .pNext = nullptr, - .imageView = vk::to_vk(attachment.image_view), - .imageLayout = vk::to_vk(attachment.layout), - .resolveMode = {}, - .resolveImageView = nullptr, - .resolveImageLayout = {}, - .loadOp = vk::to_vk(attachment.load_op), - .storeOp = vk::to_vk(attachment.store_op), - .clearValue = {}, - }; - - if (attachment.resolve) { - auto& resolve = *attachment.resolve; - - attachment_info.resolveMode = vk::to_vk(resolve.mode); - attachment_info.resolveImageView = vk::to_vk(resolve.image_view); - attachment_info.resolveImageLayout = vk::to_vk(resolve.layout); - } - if (attachment.clear_value) { - attachment_info.clearValue = std:: - visit(Overloaded { - [](const ClearColor& clear_color) static noexcept -> decltype(auto) { - return VkClearValue { - .color = VkClearColorValue { .float32 = { clear_color.color.r, - clear_color.color.b, - clear_color.color.g, - clear_color.color.a } }, - }; - }, - [](const ClearDepthStencil& clear_depth_stencil) static noexcept -> decltype(auto) { - return VkClearValue { - .depthStencil = VkClearDepthStencilValue { .depth = clear_depth_stencil.depth, - .stencil = clear_depth_stencil.stencil }, - }; - } }, - *attachment.clear_value); - } - - return attachment_info; - }; + vk::call(vkCmdInsertDebugUtilsLabelEXT, cmb, &info); + } - const auto color_attachments = transform(info.color_attachments, to_vk_attachment); - const auto depth_attachment = info.depth_attachment ? to_vk_attachment(*info.depth_attachment) - : VkRenderingAttachmentInfo {}; - const auto stencil_attachment = info.stencil_attachment ? to_vk_attachment(*info.stencil_attachment) - : VkRenderingAttachmentInfo {}; - - const auto rendering_info = VkRenderingInfo { - .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, - .pNext = nullptr, - .flags = as((secondary) ? VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT : 0), - .renderArea = vk::to_vk(info.render_area), - .layerCount = info.layer_count, - .viewMask = info.view_mask, - .colorAttachmentCount = as(stdr::size(color_attachments)), - .pColorAttachments = stdr::data(color_attachments), - .pDepthAttachment = info.depth_attachment ? &depth_attachment : nullptr, - .pStencilAttachment = info.stencil_attachment ? &stencil_attachment : nullptr, - }; + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto end_debug_region(const CommandBufferType& cmb) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + if (not vkCmdEndDebugUtilsLabelEXT) [[unlikely]] + return; + + vk::call(vkCmdEndDebugUtilsLabelEXT, cmb); + } - vk::call(device_table.vkCmdBeginRenderingKHR, cmb, &rendering_info); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto begin_render_pass(const CommandBufferType& cmb, - view::RenderPass&& render_pass, - view::FrameBuffer&& framebuffer, - std::span&& clear_values, - bool secondary_commandbuffers) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto - vk_clear_values = transform(clear_values, - cmonadic::either( - [](const ClearColor& clear_color) static noexcept -> decltype(auto) { - return VkClearValue { - .color = VkClearColorValue { .float32 = { clear_color.color.r, - clear_color.color.b, - clear_color.color.g, - clear_color.color.a } }, - }; - }, - [](const ClearDepthStencil& clear_depth_stencil) static noexcept - -> decltype(auto) { - return VkClearValue { - .depthStencil = VkClearDepthStencilValue { .depth = clear_depth_stencil - .depth, - .stencil = clear_depth_stencil - .stencil }, - }; - })); - - const auto begin_info = VkRenderPassBeginInfo { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .pNext = nullptr, - .renderPass = vk::to_vk(render_pass), - .framebuffer = vk::to_vk(framebuffer), - .renderArea = VkRect2D { .offset = { 0, 0 }, - .extent = { framebuffer.extent().width, framebuffer.extent().height } }, - .clearValueCount = as(stdr::size(vk_clear_values)), - .pClearValues = stdr::data(vk_clear_values), + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto begin_rendering(const CommandBufferType& cmb, const RenderingInfo& info, bool secondary) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + auto to_vk_attachment = [](const auto& attachment) static noexcept { + auto attachment_info = VkRenderingAttachmentInfo { + .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, + .pNext = nullptr, + .imageView = vk::to_vk(attachment.image_view), + .imageLayout = vk::to_vk(attachment.layout), + .resolveMode = {}, + .resolveImageView = nullptr, + .resolveImageLayout = {}, + .loadOp = vk::to_vk(attachment.load_op), + .storeOp = vk::to_vk(attachment.store_op), + .clearValue = {}, }; - const auto subpass_content = secondary_commandbuffers ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS - : VK_SUBPASS_CONTENTS_INLINE; + if (attachment.resolve) { + auto& resolve = *attachment.resolve; + + attachment_info.resolveMode = vk::to_vk(resolve.mode); + attachment_info.resolveImageView = vk::to_vk(resolve.image_view); + attachment_info.resolveImageLayout = vk::to_vk(resolve.layout); + } + if (attachment.clear_value) { + attachment_info.clearValue = std:: + visit(Overloaded { + [](const ClearColor& clear_color) static noexcept -> decltype(auto) { + return VkClearValue { + .color = VkClearColorValue { .float32 = { clear_color.color.r, + clear_color.color.b, + clear_color.color.g, + clear_color.color.a } }, + }; + }, + [](const ClearDepthStencil& clear_depth_stencil) static noexcept -> decltype(auto) { + return VkClearValue { + .depthStencil = VkClearDepthStencilValue { .depth = clear_depth_stencil.depth, + .stencil = clear_depth_stencil.stencil }, + }; + } }, + *attachment.clear_value); + } + + return attachment_info; + }; + + const auto color_attachments = transform(info.color_attachments, to_vk_attachment); + const auto depth_attachment = info.depth_attachment ? to_vk_attachment(*info.depth_attachment) + : VkRenderingAttachmentInfo {}; + const auto stencil_attachment = info.stencil_attachment ? to_vk_attachment(*info.stencil_attachment) + : VkRenderingAttachmentInfo {}; + + const auto rendering_info = VkRenderingInfo { + .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, + .pNext = nullptr, + .flags = as((secondary) ? VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT : 0), + .renderArea = vk::to_vk(info.render_area), + .layerCount = info.layer_count, + .viewMask = info.view_mask, + .colorAttachmentCount = as(stdr::size(color_attachments)), + .pColorAttachments = stdr::data(color_attachments), + .pDepthAttachment = info.depth_attachment ? &depth_attachment : nullptr, + .pStencilAttachment = info.stencil_attachment ? &stencil_attachment : nullptr, + }; + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdBeginRenderingKHR, cmb, &rendering_info); + } - vk::call(device_table.vkCmdBeginRenderPass, cmb, &begin_info, subpass_content); - } + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto begin_render_pass(const CommandBufferType& cmb, + view::RenderPass&& render_pass, + view::FrameBuffer&& framebuffer, + std::span&& clear_values, + bool secondary_commandbuffers) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto + vk_clear_values = transform(clear_values, + cmonadic::either( + [](const ClearColor& clear_color) static noexcept -> decltype(auto) { + return VkClearValue { + .color = VkClearColorValue { .float32 = { clear_color.color.r, + clear_color.color.b, + clear_color.color.g, + clear_color.color.a } }, + }; + }, + [](const ClearDepthStencil& clear_depth_stencil) static noexcept -> decltype(auto) { + return VkClearValue { + .depthStencil = VkClearDepthStencilValue { .depth = clear_depth_stencil.depth, + .stencil = clear_depth_stencil + .stencil }, + }; + })); + + const auto begin_info = VkRenderPassBeginInfo { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + .pNext = nullptr, + .renderPass = vk::to_vk(render_pass), + .framebuffer = vk::to_vk(framebuffer), + .renderArea = VkRect2D { .offset = { 0, 0 }, + .extent = { framebuffer.extent().width, framebuffer.extent().height } }, + .clearValueCount = as(stdr::size(vk_clear_values)), + .pClearValues = stdr::data(vk_clear_values), + }; + + const auto subpass_content = secondary_commandbuffers ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS + : VK_SUBPASS_CONTENTS_INLINE; + + vk::call(device_table.vkCmdBeginRenderPass, cmb, &begin_info, subpass_content); + } - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto next_subpass(const CommandBufferType& cmb) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdNextSubpass, cmb, VK_SUBPASS_CONTENTS_INLINE); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto end_render_pass(const CommandBufferType& cmb) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdEndRenderPass, cmb); - } + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto next_subpass(const CommandBufferType& cmb) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto end_rendering(const CommandBufferType& cmb) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); - vk::call(device_table.vkCmdEndRendering, cmb); - } + vk::call(device_table.vkCmdNextSubpass, cmb, VK_SUBPASS_CONTENTS_INLINE); + } - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto bind_pipeline(const CommandBufferType& cmb, view::Pipeline&& pipeline) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto bind_point = (pipeline.type() == Pipeline::Type::RASTER) ? VK_PIPELINE_BIND_POINT_GRAPHICS - : VK_PIPELINE_BIND_POINT_COMPUTE; + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto end_render_pass(const CommandBufferType& cmb) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); - vk::call(device_table.vkCmdBindPipeline, cmb, bind_point, pipeline); - } + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); - ///////////////////////////////////// - ///////////////////////////////////// - template - auto set_viewport(const CommandBufferType& cmb, u32 first_viewport, std::span&& viewports) noexcept - -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto vk_viewports = transform(viewports, vk::monadic::to_vk()); + vk::call(device_table.vkCmdEndRenderPass, cmb); + } - vk::call(device_table.vkCmdSetViewport, cmb, first_viewport, stdr::size(vk_viewports), stdr::data(vk_viewports)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto set_scissor(const CommandBufferType& cmb, u32 first_scissor, std::span&& scissors) noexcept - -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto vk_scissors = transform(scissors, vk::monadic::to_vk()); - - vk::call(device_table.vkCmdSetScissor, cmb, first_scissor, stdr::size(vk_scissors), stdr::data(vk_scissors)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto set_line_width(const CommandBufferType& cmb, f32 width) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdSetLineWidth, cmb, width); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto set_depth_bias(const CommandBufferType& cmb, f32 constant_factor, f32 clamp, f32 slope_factor) noexcept - -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdSetDepthBias, cmb, constant_factor, clamp, slope_factor); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto set_blend_constants(const CommandBufferType& cmb, std::span&& constants) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - f32 data[] = { constants[0], constants[1], constants[2], constants[3] }; - - vk::call(device_table.vkCmdSetBlendConstants, cmb, data); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto set_depth_bounds(const CommandBufferType& cmb, f32 min, f32 max) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdSetDepthBounds, cmb, min, max); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto set_stencil_compare_mask(const CommandBufferType& cmb, StencilFaceFlag face, u32 mask) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdSetStencilCompareMask, cmb, vk::to_vk(face), mask); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto set_stencil_write_mask(const CommandBufferType& cmb, StencilFaceFlag face, u32 mask) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdSetStencilWriteMask, cmb, vk::to_vk(face), mask); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto set_stencil_reference(const CommandBufferType& cmb, StencilFaceFlag face, u32 reference) noexcept - -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdSetStencilReference, cmb, vk::to_vk(face), reference); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto dispatch(const CommandBufferType& cmb, u32 group_count_x, u32 group_count_y, u32 group_count_z) noexcept - -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdDispatch, cmb, group_count_x, group_count_y, group_count_z); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto draw(const CommandBufferType& cmb, - u32 vertex_count, - u32 instance_count, - u32 first_vertex, - u32 first_instance) noexcept -> void { - EXPECTS(vertex_count > 0); - - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdDraw, cmb, vertex_count, instance_count, first_vertex, first_instance); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto draw_indexed(const CommandBufferType& cmb, - u32 index_count, - u32 instance_count, - u32 first_index, - i32 vertex_offset, - u32 first_instance) noexcept -> void { - EXPECTS(index_count > 0); - - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdDrawIndexed, - cmb, - index_count, - instance_count, - first_index, - vertex_offset, - first_instance); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto draw_indirect(const CommandBufferType& cmb, - view::Buffer&& buffer, - usize offset, - u32 draw_count, - u32 stride) noexcept -> void { - EXPECTS(draw_count > 0); - - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdDrawIndirect, cmb, buffer, offset, draw_count, stride); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto draw_indexed_indirect(const CommandBufferType& cmb, - view::Buffer&& buffer, - usize offset, - u32 draw_count, - u32 stride) noexcept -> void { - EXPECTS(draw_count > 0); - - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdDrawIndexedIndirect, cmb, buffer, offset, draw_count, stride); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - auto bind_vertex_buffers(const CommandBufferType& cmb, - std::span&& buffers, - std::span&& offsets) noexcept -> void { - EXPECTS(not std::empty(buffers)); - EXPECTS(std::size(buffers) == std::size(offsets)); - - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto vk_buffers = transform(buffers, vk::monadic::to_vk()); - - vk::call(device_table.vkCmdBindVertexBuffers, - cmb, - 0, - stdr::size(vk_buffers), - stdr::data(vk_buffers), - stdr::data(offsets)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto bind_index_buffer(const CommandBufferType& cmb, + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto end_rendering(const CommandBufferType& cmb) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdEndRendering, cmb); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto bind_pipeline(const CommandBufferType& cmb, view::Pipeline&& pipeline) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto bind_point = (pipeline.type() == Pipeline::Type::RASTER) ? VK_PIPELINE_BIND_POINT_GRAPHICS + : VK_PIPELINE_BIND_POINT_COMPUTE; + + vk::call(device_table.vkCmdBindPipeline, cmb, bind_point, pipeline); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto set_viewport(const CommandBufferType& cmb, u32 first_viewport, std::span&& viewports) noexcept + -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto vk_viewports = transform(viewports, vk::monadic::to_vk()); + + vk::call(device_table.vkCmdSetViewport, cmb, first_viewport, stdr::size(vk_viewports), stdr::data(vk_viewports)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto set_scissor(const CommandBufferType& cmb, u32 first_scissor, std::span&& scissors) noexcept + -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto vk_scissors = transform(scissors, vk::monadic::to_vk()); + + vk::call(device_table.vkCmdSetScissor, cmb, first_scissor, stdr::size(vk_scissors), stdr::data(vk_scissors)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto set_line_width(const CommandBufferType& cmb, f32 width) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdSetLineWidth, cmb, width); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto set_depth_bias(const CommandBufferType& cmb, f32 constant_factor, f32 clamp, f32 slope_factor) noexcept + -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdSetDepthBias, cmb, constant_factor, clamp, slope_factor); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto set_blend_constants(const CommandBufferType& cmb, std::span&& constants) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + f32 data[] = { constants[0], constants[1], constants[2], constants[3] }; + + vk::call(device_table.vkCmdSetBlendConstants, cmb, data); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto set_depth_bounds(const CommandBufferType& cmb, f32 min, f32 max) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdSetDepthBounds, cmb, min, max); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto set_stencil_compare_mask(const CommandBufferType& cmb, StencilFaceFlag face, u32 mask) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdSetStencilCompareMask, cmb, vk::to_vk(face), mask); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto set_stencil_write_mask(const CommandBufferType& cmb, StencilFaceFlag face, u32 mask) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdSetStencilWriteMask, cmb, vk::to_vk(face), mask); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto set_stencil_reference(const CommandBufferType& cmb, StencilFaceFlag face, u32 reference) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdSetStencilReference, cmb, vk::to_vk(face), reference); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto dispatch(const CommandBufferType& cmb, u32 group_count_x, u32 group_count_y, u32 group_count_z) noexcept + -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdDispatch, cmb, group_count_x, group_count_y, group_count_z); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto draw(const CommandBufferType& cmb, + u32 vertex_count, + u32 instance_count, + u32 first_vertex, + u32 first_instance) noexcept -> void { + EXPECTS(vertex_count > 0); + + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdDraw, cmb, vertex_count, instance_count, first_vertex, first_instance); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto draw_indexed(const CommandBufferType& cmb, + u32 index_count, + u32 instance_count, + u32 first_index, + i32 vertex_offset, + u32 first_instance) noexcept -> void { + EXPECTS(index_count > 0); + + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdDrawIndexed, cmb, index_count, instance_count, first_index, vertex_offset, first_instance); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto draw_indirect(const CommandBufferType& cmb, + view::Buffer&& buffer, + usize offset, + u32 draw_count, + u32 stride) noexcept -> void { + EXPECTS(draw_count > 0); + + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdDrawIndirect, cmb, buffer, offset, draw_count, stride); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto draw_indexed_indirect(const CommandBufferType& cmb, view::Buffer&& buffer, - u64 offset, - bool large_indices) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdBindIndexBuffer, - cmb, - buffer, - offset, - (large_indices) ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto bind_descriptor_sets(const CommandBufferType& cmb, - view::Pipeline&& pipeline, - view::PipelineLayout&& layout, - std::span&& descriptor_sets, - std::span&& dynamic_offsets) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto bind_point = (pipeline.type() == Pipeline::Type::RASTER) ? VK_PIPELINE_BIND_POINT_GRAPHICS - : VK_PIPELINE_BIND_POINT_COMPUTE; - - const auto vk_descriptor_sets = transform(descriptor_sets, vk::monadic::to_vk()); - - vk::call(device_table.vkCmdBindDescriptorSets, - cmb, - bind_point, - layout, - 0, - stdr::size(vk_descriptor_sets), - stdr::data(vk_descriptor_sets), - stdr::size(dynamic_offsets), - stdr::data(dynamic_offsets)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto copy_buffer(const CommandBufferType& cmb, - view::Buffer&& src, - view::Buffer&& dst, - usize size, - u64 src_offset, - u64 dst_offset) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto vk_copy_buffers = into_array_of({ .srcOffset = src_offset, - .dstOffset = dst_offset, - .size = size }); - - vk::call(device_table.vkCmdCopyBuffer, cmb, src, dst, stdr::size(vk_copy_buffers), stdr::data(vk_copy_buffers)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto copy_buffer_to_image(const CommandBufferType& cmb, - view::Buffer&& src, - view::Image&& dst, - std::span&& buffer_image_copies) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto DEFAULT_COPY = into_array_of({ - 0, - 0, - 0, - {}, - { 0, 0, 0 }, - dst.extent() - }); - - if (stdr::empty(buffer_image_copies)) buffer_image_copies = DEFAULT_COPY; - - const auto vk_copy_regions = transform(buffer_image_copies, [](const auto& buffer_image_copy) static noexcept { - const auto image_subresource = VkImageSubresourceLayers { - .aspectMask = vk::to_vk(buffer_image_copy.subresource_layers.aspect_mask), - .mipLevel = buffer_image_copy.subresource_layers.mip_level, - .baseArrayLayer = buffer_image_copy.subresource_layers.base_array_layer, - .layerCount = buffer_image_copy.subresource_layers.layer_count, - }; - - return VkBufferImageCopy { .bufferOffset = buffer_image_copy.buffer_offset, - .bufferRowLength = buffer_image_copy.buffer_row_length, - .bufferImageHeight = buffer_image_copy.buffer_image_height, - .imageSubresource = image_subresource, - .imageOffset = vk::to_vk(buffer_image_copy.offset), - .imageExtent = vk::to_vk(buffer_image_copy.extent) }; - }); - - vk::call(device_table.vkCmdCopyBufferToImage, - cmb, - src, - dst, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - stdr::size(vk_copy_regions), - stdr::data(vk_copy_regions)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto copy_image_to_buffer(const CommandBufferType& cmb, - view::Image&& src, - view::Buffer&& dst, - std::span&& buffer_image_copies) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto DEFAULT_COPY = into_array({ - BufferImageCopy { 0, 0, 0, {}, { 0, 0, 0 }, src.extent() } - }); - - if (stdr::empty(buffer_image_copies)) buffer_image_copies = DEFAULT_COPY; - - const auto vk_copy_regions = transform(buffer_image_copies, [](const auto& buffer_image_copy) static noexcept { - const auto image_subresource = VkImageSubresourceLayers { - .aspectMask = vk::to_vk(buffer_image_copy.subresource_layers.aspect_mask), - .mipLevel = buffer_image_copy.subresource_layers.mip_level, - .baseArrayLayer = buffer_image_copy.subresource_layers.base_array_layer, - .layerCount = buffer_image_copy.subresource_layers.layer_count, - }; - - return VkBufferImageCopy { .bufferOffset = buffer_image_copy.buffer_offset, - .bufferRowLength = buffer_image_copy.buffer_row_length, - .bufferImageHeight = buffer_image_copy.buffer_image_height, - .imageSubresource = image_subresource, - .imageOffset = vk::to_vk(buffer_image_copy.offset), - .imageExtent = vk::to_vk(buffer_image_copy.extent) }; - }); - - vk::call(device_table.vkCmdCopyImageToBuffer, - cmb, - src, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - dst, - stdr::size(vk_copy_regions), - stdr::data(vk_copy_regions)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto copy_image(const CommandBufferType& cmb, - view::Image&& src, - view::Image&& dst, - ImageLayout src_layout, - ImageLayout dst_layout, - const ImageSubresourceLayers& src_subresource_layers, - const ImageSubresourceLayers& dst_subresource_layers, - const math::uextent3& extent) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); + usize offset, + u32 draw_count, + u32 stride) noexcept -> void { + EXPECTS(draw_count > 0); - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); - const auto vk_src_subresource_layers = VkImageSubresourceLayers { - .aspectMask = vk::to_vk(src_subresource_layers.aspect_mask), - .mipLevel = src_subresource_layers.mip_level, - .baseArrayLayer = src_subresource_layers.base_array_layer, - .layerCount = src_subresource_layers.layer_count + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdDrawIndexedIndirect, cmb, buffer, offset, draw_count, stride); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto bind_vertex_buffers(const CommandBufferType& cmb, + std::span&& buffers, + std::span&& offsets) noexcept -> void { + EXPECTS(not std::empty(buffers)); + EXPECTS(std::size(buffers) == std::size(offsets)); + + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto vk_buffers = transform(buffers, vk::monadic::to_vk()); + + vk::call(device_table.vkCmdBindVertexBuffers, + cmb, + 0, + stdr::size(vk_buffers), + stdr::data(vk_buffers), + stdr::data(offsets)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto bind_index_buffer(const CommandBufferType& cmb, + view::Buffer&& buffer, + u64 offset, + bool large_indices) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdBindIndexBuffer, + cmb, + buffer, + offset, + (large_indices) ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto bind_descriptor_sets(const CommandBufferType& cmb, + view::Pipeline&& pipeline, + view::PipelineLayout&& layout, + std::span&& descriptor_sets, + std::span&& dynamic_offsets) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto bind_point = (pipeline.type() == Pipeline::Type::RASTER) ? VK_PIPELINE_BIND_POINT_GRAPHICS + : VK_PIPELINE_BIND_POINT_COMPUTE; + + const auto vk_descriptor_sets = transform(descriptor_sets, vk::monadic::to_vk()); + + vk::call(device_table.vkCmdBindDescriptorSets, + cmb, + bind_point, + layout, + 0, + stdr::size(vk_descriptor_sets), + stdr::data(vk_descriptor_sets), + stdr::size(dynamic_offsets), + stdr::data(dynamic_offsets)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto copy_buffer(const CommandBufferType& cmb, + view::Buffer&& src, + view::Buffer&& dst, + usize size, + u64 src_offset, + u64 dst_offset) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto vk_copy_buffers = std::array { + VkBufferCopy { .srcOffset = src_offset, .dstOffset = dst_offset, .size = size } + }; + + vk::call(device_table.vkCmdCopyBuffer, cmb, src, dst, stdr::size(vk_copy_buffers), stdr::data(vk_copy_buffers)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto copy_buffer_to_image(const CommandBufferType& cmb, + view::Buffer&& src, + view::Image&& dst, + std::span&& buffer_image_copies) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto DEFAULT_COPY = std::array { + BufferImageCopy { 0, 0, 0, {}, { 0, 0, 0 }, dst.extent() } + }; + + if (stdr::empty(buffer_image_copies)) buffer_image_copies = DEFAULT_COPY; + + const auto vk_copy_regions = transform(buffer_image_copies, [](const auto& buffer_image_copy) static noexcept { + const auto image_subresource = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(buffer_image_copy.subresource_layers.aspect_mask), + .mipLevel = buffer_image_copy.subresource_layers.mip_level, + .baseArrayLayer = buffer_image_copy.subresource_layers.base_array_layer, + .layerCount = buffer_image_copy.subresource_layers.layer_count, }; - const auto vk_dst_subresource_layers = VkImageSubresourceLayers { - .aspectMask = vk::to_vk(dst_subresource_layers.aspect_mask), - .mipLevel = dst_subresource_layers.mip_level, - .baseArrayLayer = dst_subresource_layers.base_array_layer, - .layerCount = dst_subresource_layers.layer_count + return VkBufferImageCopy { .bufferOffset = buffer_image_copy.buffer_offset, + .bufferRowLength = buffer_image_copy.buffer_row_length, + .bufferImageHeight = buffer_image_copy.buffer_image_height, + .imageSubresource = image_subresource, + .imageOffset = vk::to_vk(buffer_image_copy.offset), + .imageExtent = vk::to_vk(buffer_image_copy.extent) }; + }); + + vk::call(device_table.vkCmdCopyBufferToImage, + cmb, + src, + dst, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + stdr::size(vk_copy_regions), + stdr::data(vk_copy_regions)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto copy_image_to_buffer(const CommandBufferType& cmb, + view::Image&& src, + view::Buffer&& dst, + std::span&& buffer_image_copies) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto DEFAULT_COPY = into_array({ + BufferImageCopy { 0, 0, 0, {}, { 0, 0, 0 }, src.extent() } + }); + + if (stdr::empty(buffer_image_copies)) buffer_image_copies = DEFAULT_COPY; + + const auto vk_copy_regions = transform(buffer_image_copies, [](const auto& buffer_image_copy) static noexcept { + const auto image_subresource = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(buffer_image_copy.subresource_layers.aspect_mask), + .mipLevel = buffer_image_copy.subresource_layers.mip_level, + .baseArrayLayer = buffer_image_copy.subresource_layers.base_array_layer, + .layerCount = buffer_image_copy.subresource_layers.layer_count, }; - const auto vk_regions = into_array({ - VkImageCopy { .srcSubresource = vk_src_subresource_layers, - .srcOffset = { 0, 0, 0 }, - .dstSubresource = vk_dst_subresource_layers, - .dstOffset = { 0, 0, 0 }, - .extent = vk::to_vk(extent) } - }); - - vk::call(device_table.vkCmdCopyImage, - cmb, - src, - vk::to_vk(src_layout), - dst, - vk::to_vk(dst_layout), - stdr::size(vk_regions), - stdr::data(vk_regions)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto resolve_image(const CommandBufferType& cmb, - view::Image&& src, - view::Image&& dst, - ImageLayout src_layout, - ImageLayout dst_layout, - const ImageSubresourceLayers& src_subresource_layers, - const ImageSubresourceLayers& dst_subresource_layers) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); + return VkBufferImageCopy { .bufferOffset = buffer_image_copy.buffer_offset, + .bufferRowLength = buffer_image_copy.buffer_row_length, + .bufferImageHeight = buffer_image_copy.buffer_image_height, + .imageSubresource = image_subresource, + .imageOffset = vk::to_vk(buffer_image_copy.offset), + .imageExtent = vk::to_vk(buffer_image_copy.extent) }; + }); + + vk::call(device_table.vkCmdCopyImageToBuffer, + cmb, + src, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + dst, + stdr::size(vk_copy_regions), + stdr::data(vk_copy_regions)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto copy_image(const CommandBufferType& cmb, + view::Image&& src, + view::Image&& dst, + ImageLayout src_layout, + ImageLayout dst_layout, + const ImageSubresourceLayers& src_subresource_layers, + const ImageSubresourceLayers& dst_subresource_layers, + const math::uextent3& extent) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto vk_src_subresource_layers = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(src_subresource_layers.aspect_mask), + .mipLevel = src_subresource_layers.mip_level, + .baseArrayLayer = src_subresource_layers.base_array_layer, + .layerCount = src_subresource_layers.layer_count + }; + + const auto vk_dst_subresource_layers = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(dst_subresource_layers.aspect_mask), + .mipLevel = dst_subresource_layers.mip_level, + .baseArrayLayer = dst_subresource_layers.base_array_layer, + .layerCount = dst_subresource_layers.layer_count + }; + + const auto vk_regions = into_array({ + VkImageCopy { .srcSubresource = vk_src_subresource_layers, + .srcOffset = { 0, 0, 0 }, + .dstSubresource = vk_dst_subresource_layers, + .dstOffset = { 0, 0, 0 }, + .extent = vk::to_vk(extent) } + }); + + vk::call(device_table.vkCmdCopyImage, + cmb, + src, + vk::to_vk(src_layout), + dst, + vk::to_vk(dst_layout), + stdr::size(vk_regions), + stdr::data(vk_regions)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto resolve_image(const CommandBufferType& cmb, + view::Image&& src, + view::Image&& dst, + ImageLayout src_layout, + ImageLayout dst_layout, + const ImageSubresourceLayers& src_subresource_layers, + const ImageSubresourceLayers& dst_subresource_layers) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto vk_extent = vk::to_vk(dst.extent()); + + const auto vk_src_subresource_layers = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(src_subresource_layers.aspect_mask), + .mipLevel = src_subresource_layers.mip_level, + .baseArrayLayer = src_subresource_layers.base_array_layer, + .layerCount = src_subresource_layers.layer_count + }; + + const auto vk_dst_subresource_layers = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(dst_subresource_layers.aspect_mask), + .mipLevel = dst_subresource_layers.mip_level, + .baseArrayLayer = dst_subresource_layers.base_array_layer, + .layerCount = dst_subresource_layers.layer_count + }; + + const auto vk_regions = into_array({ + VkImageResolve { .srcSubresource = vk_src_subresource_layers, + .srcOffset = { 0, 0, 0 }, + .dstSubresource = vk_dst_subresource_layers, + .dstOffset = { 0, 0, 0 }, + .extent = vk_extent } + }); + + vk::call(device_table.vkCmdResolveImage, + cmb, + src, + vk::to_vk(src_layout), + dst, + vk::to_vk(dst_layout), + stdr::size(vk_regions), + stdr::data(vk_regions)); + } - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto blit_image(const CommandBufferType& cmb, + view::Image&& src, + view::Image&& dst, + ImageLayout src_layout, + ImageLayout dst_layout, + std::span&& regions, + Filter filter) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); - const auto vk_extent = vk::to_vk(dst.extent()); + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + const auto vk_regions = transform(regions, [](const auto& region) static noexcept { const auto vk_src_subresource_layers = VkImageSubresourceLayers { - .aspectMask = vk::to_vk(src_subresource_layers.aspect_mask), - .mipLevel = src_subresource_layers.mip_level, - .baseArrayLayer = src_subresource_layers.base_array_layer, - .layerCount = src_subresource_layers.layer_count + .aspectMask = vk::to_vk(region.src.aspect_mask), + .mipLevel = region.src.mip_level, + .baseArrayLayer = region.src.base_array_layer, + .layerCount = region.src.layer_count }; const auto vk_dst_subresource_layers = VkImageSubresourceLayers { - .aspectMask = vk::to_vk(dst_subresource_layers.aspect_mask), - .mipLevel = dst_subresource_layers.mip_level, - .baseArrayLayer = dst_subresource_layers.base_array_layer, - .layerCount = dst_subresource_layers.layer_count + .aspectMask = vk::to_vk(region.dst.aspect_mask), + .mipLevel = region.dst.mip_level, + .baseArrayLayer = region.dst.base_array_layer, + .layerCount = region.dst.layer_count }; - const auto vk_regions = into_array({ - VkImageResolve { .srcSubresource = vk_src_subresource_layers, - .srcOffset = { 0, 0, 0 }, - .dstSubresource = vk_dst_subresource_layers, - .dstOffset = { 0, 0, 0 }, - .extent = vk_extent } - }); - - vk::call(device_table.vkCmdResolveImage, - cmb, - src, - vk::to_vk(src_layout), - dst, - vk::to_vk(dst_layout), - stdr::size(vk_regions), - stdr::data(vk_regions)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto blit_image(const CommandBufferType& cmb, - view::Image&& src, - view::Image&& dst, - ImageLayout src_layout, - ImageLayout dst_layout, - std::span&& regions, - Filter filter) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto vk_regions = transform(regions, [](const auto& region) static noexcept { - const auto vk_src_subresource_layers = VkImageSubresourceLayers { - .aspectMask = vk::to_vk(region.src.aspect_mask), - .mipLevel = region.src.mip_level, - .baseArrayLayer = region.src.base_array_layer, - .layerCount = region.src.layer_count - }; - - const auto vk_dst_subresource_layers = VkImageSubresourceLayers { - .aspectMask = vk::to_vk(region.dst.aspect_mask), - .mipLevel = region.dst.mip_level, - .baseArrayLayer = region.dst.base_array_layer, - .layerCount = region.dst.layer_count - }; - - return VkImageBlit { - .srcSubresource = vk_src_subresource_layers, - .srcOffsets = { vk::to_vk(region.src_offset.position), - vk::to_vk(region.src_offset.extent) }, - .dstSubresource = vk_dst_subresource_layers, - .dstOffsets = { vk::to_vk(region.dst_offset.position), - vk::to_vk(region.dst_offset.extent) }, - }; - }); - - vk::call(device_table.vkCmdBlitImage, - cmb, - vk::to_vk(src), - vk::to_vk(src_layout), - vk::to_vk(dst), - vk::to_vk(dst_layout), - stdr::size(vk_regions), - stdr::data(vk_regions), - vk::to_vk(filter)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto transition_image_layout(const CommandBufferType& cmb, - view::Image&& image, - ImageLayout src_layout, - ImageLayout dst_layout, - const ImageSubresourceRange& subresource_range) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); + return VkImageBlit { + .srcSubresource = vk_src_subresource_layers, + .srcOffsets = { vk::to_vk(region.src_offset.position), + vk::to_vk(region.src_offset.extent) }, + .dstSubresource = vk_dst_subresource_layers, + .dstOffsets = { vk::to_vk(region.dst_offset.position), + vk::to_vk(region.dst_offset.extent) }, + }; + }); + + vk::call(device_table.vkCmdBlitImage, + cmb, + vk::to_vk(src), + vk::to_vk(src_layout), + vk::to_vk(dst), + vk::to_vk(dst_layout), + stdr::size(vk_regions), + stdr::data(vk_regions), + vk::to_vk(filter)); + } - const auto vk_src_layout = vk::to_vk(src_layout); - const auto vk_dst_layout = vk::to_vk(dst_layout); + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto transition_image_layout(const CommandBufferType& cmb, + view::Image&& image, + ImageLayout src_layout, + ImageLayout dst_layout, + const ImageSubresourceRange& subresource_range) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + const auto vk_src_layout = vk::to_vk(src_layout); + const auto vk_dst_layout = vk::to_vk(dst_layout); + + const auto& src_access = OLD_LAYOUT_ACCESS_MAP.find(vk_src_layout); + const auto& dst_access = NEW_LAYOUT_ACCESS_MAP.find(vk_dst_layout); + + const auto src_stage = src_access->second.second; + const auto dst_stage = dst_access->second.second; + + const auto vk_subresource_range = VkImageSubresourceRange { + .aspectMask = vk::to_vk(subresource_range.aspect_mask), + .baseMipLevel = subresource_range.base_mip_level, + .levelCount = subresource_range.level_count, + .baseArrayLayer = subresource_range.base_array_layer, + .layerCount = subresource_range.layer_count, + }; + + const auto barriers = into_array({ + VkImageMemoryBarrier { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = src_access->second.first, + .dstAccessMask = dst_access->second.first, + .oldLayout = vk_src_layout, + .newLayout = vk_dst_layout, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = vk::to_vk(image), + .subresourceRange = vk_subresource_range + + }, + }); + + vk::call(device_table.vkCmdPipelineBarrier, + cmb, + src_stage, + dst_stage, + 0, + 0, + nullptr, + 0, + nullptr, + stdr::size(barriers), + stdr::data(barriers)); + } - const auto& src_access = OLD_LAYOUT_ACCESS_MAP.find(vk_src_layout); - const auto& dst_access = NEW_LAYOUT_ACCESS_MAP.find(vk_dst_layout); + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto pipeline_barrier(const CommandBufferType& cmb, + PipelineStageFlag src_mask, + PipelineStageFlag dst_mask, + DependencyFlag dependency, + std::span&& memory_barriers, + std::span&& buffer_memory_barriers, + std::span&& image_memory_barriers) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); - const auto src_stage = src_access->second.second; - const auto dst_stage = dst_access->second.second; + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); - const auto vk_subresource_range = VkImageSubresourceRange { - .aspectMask = vk::to_vk(subresource_range.aspect_mask), - .baseMipLevel = subresource_range.base_mip_level, - .levelCount = subresource_range.level_count, - .baseArrayLayer = subresource_range.base_array_layer, - .layerCount = subresource_range.layer_count, + const auto vk_memory_barriers = transform(memory_barriers, [](const auto& barrier) static noexcept -> decltype(auto) { + return VkMemoryBarrier { + .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = vk::to_vk(barrier.src), + .dstAccessMask = vk::to_vk(barrier.dst), }; + }); + const auto vk_buffer_memory_barriers = transform(buffer_memory_barriers, + [](const auto& barrier) static noexcept -> decltype(auto) { + return VkBufferMemoryBarrier { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = vk::to_vk(barrier.src), + .dstAccessMask = vk::to_vk(barrier.dst), + .srcQueueFamilyIndex = barrier.src_queue_family_index, + .dstQueueFamilyIndex = barrier.dst_queue_family_index, + .buffer = vk::to_vk(barrier.buffer), + .offset = barrier.offset, + .size = barrier.size + }; + }); + const auto vk_image_memory_barriers = transform(image_memory_barriers, + [](const auto& barrier) static noexcept -> decltype(auto) { + const auto vk_subresource_range = VkImageSubresourceRange { + .aspectMask = vk::to_vk(barrier.range + .aspect_mask), + .baseMipLevel = barrier.range.base_mip_level, + .levelCount = barrier.range.level_count, + .baseArrayLayer = barrier.range.base_array_layer, + .layerCount = barrier.range.layer_count + }; + + return VkImageMemoryBarrier { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = vk::to_vk(barrier.src), + .dstAccessMask = vk::to_vk(barrier.dst), + .oldLayout = vk::to_vk(barrier.old_layout), + .newLayout = vk::to_vk(barrier.new_layout), + .srcQueueFamilyIndex = barrier.src_queue_family_index, + .dstQueueFamilyIndex = barrier.dst_queue_family_index, + .image = vk::to_vk(barrier.image), + .subresourceRange = vk_subresource_range + }; + }); + + vk::call(device_table.vkCmdPipelineBarrier, + cmb, + vk::to_vk(src_mask), + vk::to_vk(dst_mask), + vk::to_vk(dependency), + stdr::size(vk_memory_barriers), + stdr::data(vk_memory_barriers), + stdr::size(vk_buffer_memory_barriers), + stdr::data(vk_buffer_memory_barriers), + stdr::size(vk_image_memory_barriers), + stdr::data(vk_image_memory_barriers)); + } - const auto barriers = into_array({ - VkImageMemoryBarrier { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = src_access->second.first, - .dstAccessMask = dst_access->second.first, - .oldLayout = vk_src_layout, - .newLayout = vk_dst_layout, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .image = vk::to_vk(image), - .subresourceRange = vk_subresource_range - - }, - }); - - vk::call(device_table.vkCmdPipelineBarrier, - cmb, - src_stage, - dst_stage, - 0, - 0, - nullptr, - 0, - nullptr, - stdr::size(barriers), - stdr::data(barriers)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto pipeline_barrier(const CommandBufferType& cmb, - PipelineStageFlag src_mask, - PipelineStageFlag dst_mask, - DependencyFlag dependency, - std::span&& memory_barriers, - std::span&& buffer_memory_barriers, - std::span&& image_memory_barriers) noexcept -> void { - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto vk_memory_barriers = transform(memory_barriers, - [](const auto& barrier) static noexcept -> decltype(auto) { - return VkMemoryBarrier { - .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = vk::to_vk(barrier.src), - .dstAccessMask = vk::to_vk(barrier.dst), - }; - }); - const auto vk_buffer_memory_barriers = transform(buffer_memory_barriers, - [](const auto& barrier) static noexcept -> decltype(auto) { - return VkBufferMemoryBarrier { - .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = vk::to_vk(barrier.src), - .dstAccessMask = vk::to_vk(barrier.dst), - .srcQueueFamilyIndex = barrier.src_queue_family_index, - .dstQueueFamilyIndex = barrier.dst_queue_family_index, - .buffer = vk::to_vk(barrier.buffer), - .offset = barrier.offset, - .size = barrier.size - }; - }); - const auto - vk_image_memory_barriers = transform(image_memory_barriers, - [](const auto& barrier) static noexcept -> decltype(auto) { - const auto vk_subresource_range = VkImageSubresourceRange { - .aspectMask = vk::to_vk(barrier.range - .aspect_mask), - .baseMipLevel = barrier.range.base_mip_level, - .levelCount = barrier.range.level_count, - .baseArrayLayer = barrier.range.base_array_layer, - .layerCount = barrier.range.layer_count - }; - - return VkImageMemoryBarrier { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = vk::to_vk(barrier.src), - .dstAccessMask = vk::to_vk(barrier.dst), - .oldLayout = vk::to_vk(barrier.old_layout), - .newLayout = vk::to_vk(barrier.new_layout), - .srcQueueFamilyIndex = barrier.src_queue_family_index, - .dstQueueFamilyIndex = barrier.dst_queue_family_index, - .image = vk::to_vk(barrier.image), - .subresourceRange = vk_subresource_range - }; - }); - - vk::call(device_table.vkCmdPipelineBarrier, - cmb, - vk::to_vk(src_mask), - vk::to_vk(dst_mask), - vk::to_vk(dependency), - stdr::size(vk_memory_barriers), - stdr::data(vk_memory_barriers), - stdr::size(vk_buffer_memory_barriers), - stdr::data(vk_buffer_memory_barriers), - stdr::size(vk_image_memory_barriers), - stdr::data(vk_image_memory_barriers)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto push_constants(const CommandBufferType& cmb, - view::PipelineLayout&& pipeline_layout, - ShaderStageFlag stage, - std::span&& data, - u32 offset) noexcept -> void { - EXPECTS(not std::empty(data)); - - const auto& state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdPushConstants, - cmb, - vk::to_vk(pipeline_layout), - vk::to_vk(stage), - offset, - stdr::size(data), - stdr::data(data)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto execute_sub_command_buffers(const CommandBufferType& cmb, - std::span&& commandbuffers) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - constexpr auto expects_secondary = [](auto&& cmb) noexcept -> decltype(auto) { - EXPECTS(cmb.level() == CommandBufferLevel::SECONDARY); - return cmb; - }; + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto push_constants(const CommandBufferType& cmb, + view::PipelineLayout&& pipeline_layout, + ShaderStageFlag stage, + std::span&& data, + u32 offset) noexcept -> void { + EXPECTS(not std::empty(data)); - const auto vk_command_buffers = transform(commandbuffers, cmonadic::map(expects_secondary, vk::monadic::to_vk())); - vk::call(device_table.vkCmdExecuteCommands, cmb, stdr::size(vk_command_buffers), stdr::data(vk_command_buffers)); - } - }; - } // namespace + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdPushConstants, + cmb, + vk::to_vk(pipeline_layout), + vk::to_vk(stage), + offset, + stdr::size(data), + stdr::data(data)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto execute_sub_command_buffers(const CommandBufferType& cmb, + std::span&& commandbuffers) noexcept -> void { + const auto state = cmb.state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = cmb.device(); + const auto& device_table = device.device_table(); + + constexpr auto expects_secondary = [](auto&& cmb) noexcept -> decltype(auto) { + EXPECTS(cmb.level() == CommandBufferLevel::SECONDARY); + return cmb; + }; + + const auto vk_command_buffers = transform(commandbuffers, cmonadic::map(expects_secondary, vk::monadic::to_vk())); + vk::call(device_table.vkCmdExecuteCommands, cmb, stdr::size(vk_command_buffers), stdr::data(vk_command_buffers)); + } + }; ///////////////////////////////////// ///////////////////////////////////// @@ -1196,6 +1174,14 @@ namespace stormkit::gpu { return CommandBufferAPI::end(*this); } + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::begin_debug_region(std::string_view name, const fcolor_rgb& color) const noexcept + -> const CommandBuffer& { + CommandBufferAPI::begin_debug_region(*this, std::move(name), color); + return *this; + } + ///////////////////////////////////// ///////////////////////////////////// auto CommandBuffer::insert_debug_label(std::string_view name, const fcolor_rgb& color) const noexcept @@ -1246,6 +1232,13 @@ namespace stormkit::gpu { return *this; } + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::end_rendering() const noexcept -> const CommandBuffer& { + CommandBufferAPI::end_rendering(*this); + return *this; + } + ///////////////////////////////////// ///////////////////////////////////// auto CommandBuffer::bind_pipeline(view::Pipeline pipeline) const noexcept -> const CommandBuffer& { @@ -1291,7 +1284,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::set_depth_bounds(u32 min, u32 max) const noexcept -> const CommandBuffer& { + auto CommandBuffer::set_depth_bounds(f32 min, f32 max) const noexcept -> const CommandBuffer& { CommandBufferAPI::set_depth_bounds(*this, min, max); return *this; } @@ -1319,14 +1312,15 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::dispatch(u32 group_count_x, u32 group_count_y, u32 group_count_z) const noexcept -> void { + auto CommandBuffer::dispatch(u32 group_count_x, u32 group_count_y, u32 group_count_z) const noexcept -> const CommandBuffer& { CommandBufferAPI::dispatch(*this, group_count_x, group_count_y, group_count_z); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::draw(u32 vertex_count, u32 instance_count, u32 first_vertex, u32 first_instance) const noexcept -> void { + auto CommandBuffer::draw(u32 vertex_count, u32 instance_count, u32 first_vertex, u32 first_instance) const noexcept + -> const CommandBuffer& { CommandBufferAPI::draw(*this, vertex_count, instance_count, first_vertex, first_instance); return *this; } @@ -1334,14 +1328,15 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// auto CommandBuffer::draw_indexed(u32 index_count, u32 instance_count, u32 first_index, i32 vertex_offset, u32 first_instance) - const noexcept -> void { + const noexcept -> const CommandBuffer& { CommandBufferAPI::draw_indexed(*this, index_count, instance_count, first_index, vertex_offset, first_instance); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::draw_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept -> void { + auto CommandBuffer::draw_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept + -> const CommandBuffer& { CommandBufferAPI::draw_indirect(*this, std::move(buffer), offset, draw_count, stride); return *this; } @@ -1349,14 +1344,15 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// auto CommandBuffer::draw_indexed_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept - -> void { + -> const CommandBuffer& { CommandBufferAPI::draw_indexed_indirect(*this, std::move(buffer), offset, draw_count, stride); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::bind_vertex_buffers(std::span buffers, std::span offsets) const noexcept { + auto CommandBuffer::bind_vertex_buffers(std::span buffers, std::span offsets) const noexcept + -> const CommandBuffer& { CommandBufferAPI::bind_vertex_buffers(*this, std::move(buffers), std::move(offsets)); return *this; } @@ -1385,9 +1381,9 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::copy_buffer_to_image(view::Buffer src, - view::Image dst, - std::span& buffer_image_copies) const noexcept + auto CommandBuffer::copy_buffer_to_image(view::Buffer src, + view::Image dst, + std::span buffer_image_copies) const noexcept -> const CommandBuffer& { CommandBufferAPI::copy_buffer_to_image(*this, std::move(src), std::move(dst), std::move(buffer_image_copies)); return *this; @@ -1450,13 +1446,13 @@ namespace stormkit::gpu { ImageLayout dst_layout, std::span regions, Filter filter) const noexcept -> const CommandBuffer& { - CommandBufferAPI::blit_image(*this, std::move(src), std::move(dst), src_layout, dst_layout, regions, filter); + CommandBufferAPI::blit_image(*this, std::move(src), std::move(dst), src_layout, dst_layout, std::move(regions), filter); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::transition_image_layout(const Image& image, + auto CommandBuffer::transition_image_layout(view::Image image, ImageLayout src_layout, ImageLayout dst_layout, const ImageSubresourceRange& subresource_range) const noexcept @@ -1486,10 +1482,10 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::push_constants(const view::PipelineLayout& pipeline_layout, - ShaderStageFlag stage, - std::span data, - u32 offset) const noexcept -> const CommandBuffer& { + auto CommandBuffer::push_constants(view::PipelineLayout pipeline_layout, + ShaderStageFlag stage, + std::span data, + u32 offset) const noexcept -> const CommandBuffer& { CommandBufferAPI::push_constants(*this, std::move(pipeline_layout), stage, std::move(data), offset); return *this; } @@ -1497,43 +1493,46 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// auto CommandBuffer::execute_sub_command_buffers(std::span command_buffers) const noexcept - -> CommandBuffer { + -> const CommandBuffer& { CommandBufferAPI::execute_sub_command_buffers(*this, std::move(command_buffers)); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::do_init(PrivateTag, - view::CommandPool pool, - CommandBufferLevel level, - VkCommandBuffer&& handle, - Deleter&& deleter) const noexcept -> Expected { - m_pool = pool; + auto CommandBuffer::do_init(PrivateTag, CommandBufferLevel level, VkCommandBuffer&& handle, Deleter&& deleter) noexcept + -> void { m_level = level; - m_vk_handle = handle; + m_vk_handle = std::move(handle); m_deleter = std::move(deleter); } namespace view { - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::reset() const noexcept -> Expected { - return CommandBufferAPI::reset(*this); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::begin(bool one_time_submit, InheritanceInfo inheritance_info_variant) const noexcept - -> Expected { - return CommandBufferAPI::begin(*this, one_time_submit, std::move(inheritance_info_variant)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::end() const noexcept -> Expected { - return CommandBufferAPI::end(*this); + // ///////////////////////////////////// + // ///////////////////////////////////// + // auto CommandBuffer::reset() const noexcept -> Expected { + // return CommandBufferAPI::reset(*this); + // } + + // ///////////////////////////////////// + // ///////////////////////////////////// + // auto CommandBuffer::begin(bool one_time_submit, InheritanceInfo inheritance_info_variant) const noexcept + // -> Expected { + // return CommandBufferAPI::begin(*this, one_time_submit, std::move(inheritance_info_variant)); + // } + + // ///////////////////////////////////// + // ///////////////////////////////////// + // auto CommandBuffer::end() const noexcept -> Expected { + // return CommandBufferAPI::end(*this); + // } + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::begin_debug_region(std::string_view name, const fcolor_rgb& color) const noexcept + -> const CommandBuffer& { + CommandBufferAPI::begin_debug_region(*this, std::move(name), color); + return *this; } ///////////////////////////////////// @@ -1560,8 +1559,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::begin_render_pass(const RenderPass& render_pass, - const FrameBuffer& framebuffer, + auto CommandBuffer::begin_render_pass(view::RenderPass render_pass, + view::FrameBuffer framebuffer, std::span clear_values, bool secondary_commandbuffers) const noexcept -> const CommandBuffer& { CommandBufferAPI::begin_render_pass(*this, @@ -1586,6 +1585,13 @@ namespace stormkit::gpu { return *this; } + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandBuffer::end_rendering() const noexcept -> const CommandBuffer& { + CommandBufferAPI::end_rendering(*this); + return *this; + } + ///////////////////////////////////// ///////////////////////////////////// auto CommandBuffer::bind_pipeline(view::Pipeline pipeline) const noexcept -> const CommandBuffer& { @@ -1633,7 +1639,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::set_depth_bounds(u32 min, u32 max) const noexcept -> const CommandBuffer& { + auto CommandBuffer::set_depth_bounds(f32 min, f32 max) const noexcept -> const CommandBuffer& { CommandBufferAPI::set_depth_bounds(*this, min, max); return *this; } @@ -1661,7 +1667,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::dispatch(u32 group_count_x, u32 group_count_y, u32 group_count_z) const noexcept -> void { + auto CommandBuffer::dispatch(u32 group_count_x, u32 group_count_y, u32 group_count_z) const noexcept + -> const CommandBuffer& { CommandBufferAPI::dispatch(*this, group_count_x, group_count_y, group_count_z); return *this; } @@ -1669,7 +1676,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// auto CommandBuffer::draw(u32 vertex_count, u32 instance_count, u32 first_vertex, u32 first_instance) const noexcept - -> void { + -> const CommandBuffer& { CommandBufferAPI::draw(*this, vertex_count, instance_count, first_vertex, first_instance); return *this; } @@ -1680,37 +1687,39 @@ namespace stormkit::gpu { u32 instance_count, u32 first_index, i32 vertex_offset, - u32 first_instance) const noexcept -> void { + u32 first_instance) const noexcept -> const CommandBuffer& { CommandBufferAPI::draw_indexed(*this, index_count, instance_count, first_index, vertex_offset, first_instance); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::draw_indirect(const Buffer& buffer, usize offset, u32 draw_count, u32 stride) const noexcept -> void { + auto CommandBuffer::draw_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept + -> const CommandBuffer& { CommandBufferAPI::draw_indirect(*this, std::move(buffer), offset, draw_count, stride); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::draw_indexed_indirect(const Buffer& buffer, usize offset, u32 draw_count, u32 stride) const noexcept - -> void { + auto CommandBuffer::draw_indexed_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept + -> const CommandBuffer& { CommandBufferAPI::draw_indexed_indirect(*this, std::move(buffer), offset, draw_count, stride); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::bind_vertex_buffers(std::span buffers, std::span offsets) const noexcept { + auto CommandBuffer::bind_vertex_buffers(std::span buffers, std::span offsets) const noexcept + -> const CommandBuffer& { CommandBufferAPI::bind_vertex_buffers(*this, std::move(buffers), std::move(offsets)); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::bind_descriptor_sets(const Pipeline& pipeline, - const PipelineLayout& layout, + auto CommandBuffer::bind_descriptor_sets(view::Pipeline pipeline, + view::PipelineLayout layout, std::span descriptor_sets, std::span dynamic_offsets) const noexcept -> const CommandBuffer& { CommandBufferAPI::bind_descriptor_sets(*this, @@ -1723,17 +1732,17 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::copy_buffer(const Buffer& src, const Buffer& dst, usize size, u64 src_offset, u64 dst_offset) + auto CommandBuffer::copy_buffer(view::Buffer src, view::Buffer dst, usize size, u64 src_offset, u64 dst_offset) const noexcept -> const CommandBuffer& { - CommandBufferAPI::copy_buffer(*this, src, dst, size, src_offset, dst_offset); + CommandBufferAPI::copy_buffer(*this, std::move(src), std::move(dst), size, src_offset, dst_offset); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::copy_buffer_to_image(const Buffer& src, - const Image& dst, - std::span& buffer_image_copies) const noexcept + auto CommandBuffer::copy_buffer_to_image(view::Buffer src, + view::Image dst, + std::span buffer_image_copies) const noexcept -> const CommandBuffer& { CommandBufferAPI::copy_buffer_to_image(*this, std::move(src), std::move(dst), std::move(buffer_image_copies)); return *this; @@ -1741,8 +1750,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::copy_image_to_buffer(const Image& src, - const Buffer& dst, + auto CommandBuffer::copy_image_to_buffer(view::Image src, + view::Buffer dst, std::span buffer_image_copies) const noexcept -> const CommandBuffer& { CommandBufferAPI::copy_image_to_buffer(*this, std::move(src), std::move(dst), std::move(buffer_image_copies)); @@ -1751,8 +1760,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::copy_image(const Image& src, - const Image& dst, + auto CommandBuffer::copy_image(view::Image src, + view::Image dst, ImageLayout src_layout, ImageLayout dst_layout, const ImageSubresourceLayers& src_subresource_layers, @@ -1771,8 +1780,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::resolve_image(const Image& src, - const Image& dst, + auto CommandBuffer::resolve_image(view::Image src, + view::Image dst, ImageLayout src_layout, ImageLayout dst_layout, const ImageSubresourceLayers& src_subresource_layers, @@ -1790,24 +1799,30 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::blit_image(const Image& src, - const Image& dst, + auto CommandBuffer::blit_image(view::Image src, + view::Image dst, ImageLayout src_layout, ImageLayout dst_layout, std::span regions, Filter filter) const noexcept -> const CommandBuffer& { - CommandBufferAPI::blit_image(*this, std::move(src), std::move(dst), src_layout, dst_layout, regions, filter); + CommandBufferAPI::blit_image(*this, + std::move(src), + std::move(dst), + src_layout, + dst_layout, + std::move(regions), + filter); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::transition_image_layout(const Image& image, + auto CommandBuffer::transition_image_layout(view::Image image, ImageLayout src_layout, ImageLayout dst_layout, const ImageSubresourceRange& subresource_range) const noexcept -> const CommandBuffer& { - CommandBufferAPI::transition_image_layout(*this, image, src_layout, dst_layout, subresource_range); + CommandBufferAPI::transition_image_layout(*this, std::move(image), src_layout, dst_layout, subresource_range); return *this; } @@ -1832,11 +1847,11 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::push_constants(const PipelineLayout& pipeline_layout, + auto CommandBuffer::push_constants(view::PipelineLayout pipeline_layout, ShaderStageFlag stage, std::span data, u32 offset) const noexcept -> const CommandBuffer& { - CommandBufferAPI::push_constants(*this, pipeline_layout, stage, data, offset); + CommandBufferAPI::push_constants(*this, std::move(pipeline_layout), stage, std::move(data), offset); return *this; } @@ -1844,7 +1859,7 @@ namespace stormkit::gpu { ///////////////////////////////////// auto CommandBuffer::execute_sub_command_buffers(std::span command_buffers) const noexcept -> const CommandBuffer& { - CommandBufferAPI::execute_sub_command_buffers(*this, command_buffers); + CommandBufferAPI::execute_sub_command_buffers(*this, std::move(command_buffers)); return *this; } } // namespace view diff --git a/src/gpu/execution/command_pool.cpp b/src/gpu/execution/command_pool.cpp index 8de7b61cf..70df8484e 100644 --- a/src/gpu/execution/command_pool.cpp +++ b/src/gpu/execution/command_pool.cpp @@ -4,6 +4,8 @@ module; +#include + #include module stormkit.gpu.execution; @@ -25,9 +27,9 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - static auto create_vk_command_buffers(const CommandPoolType& pool, usize count, CommandBufferLevel level) - const noexcept -> Expected> { - const auto& device = cmb.device(); + static auto create_vk_command_buffers(const CommandPoolType& pool, usize count, CommandBufferLevel level) noexcept + -> Expected> { + const auto& device = pool.device(); const auto& device_table = device.device_table(); const auto allocate_info = VkCommandBufferAllocateInfo { @@ -46,9 +48,10 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - static auto delete_vk_command_buffers(Device device, - CommandPool command_pool, - VkCommandBuffer command_buffer) noexcept -> void { + static auto delete_vk_command_buffers(view::Device device, + view::CommandPool command_pool, + VkCommandBuffer command_buffer) noexcept -> void { + const auto& device_table = device.device_table(); vk::call(device_table.vkFreeCommandBuffers, device, command_pool, 1, &command_buffer); } }; @@ -56,8 +59,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto CommandPool::do_init() noexcept -> Expected { - const auto& device = device(); + auto CommandPool::do_init(PrivateTag) noexcept -> Expected { + const auto& device = this->device(); const auto& device_table = device.device_table(); const auto create_info = VkCommandPoolCreateInfo { @@ -80,8 +83,9 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto CommandPool::delete_vk_command_buffers(Device device, CommandPool pool, VkCommandBuffer cmb) noexcept -> void { - return CommandPoolAPI::create_vk_command_buffers(std::move(device), std::move(pool), cmb); + auto CommandPool::delete_vk_command_buffers(view::Device device, view::CommandPool pool, VkCommandBuffer cmb) noexcept + -> void { + CommandPoolAPI::delete_vk_command_buffers(std::move(device), std::move(pool), cmb); } namespace view { @@ -95,7 +99,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// auto CommandPool::delete_vk_command_buffers(Device device, CommandPool pool, VkCommandBuffer cmb) noexcept -> void { - return CommandPoolAPI::create_vk_command_buffers(std::move(device), std::move(pool), cmb); + CommandPoolAPI::delete_vk_command_buffers(std::move(device), std::move(pool), cmb); } } // namespace view } // namespace stormkit::gpu diff --git a/src/gpu/execution/descriptor_pool.cpp b/src/gpu/execution/descriptor_pool.cpp new file mode 100644 index 000000000..576c3d9dc --- /dev/null +++ b/src/gpu/execution/descriptor_pool.cpp @@ -0,0 +1,116 @@ + +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +module stormkit.gpu.execution; + +import std; + +import stormkit.core; + +import stormkit.gpu.core; + +namespace stdr = std::ranges; +namespace stdv = std::views; + +using namespace std::literals; + +namespace stormkit::gpu { + namespace { + struct DescriptorPoolAPI { + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto create_vk_descriptor_sets(const DescriptorPoolType& descriptor_pool, + usize count, + view::DescriptorSetLayout&& layout) noexcept + -> Expected> { + const auto vk_layout = vk::to_vk(layout); + const auto allocate_info = VkDescriptorSetAllocateInfo { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .pNext = nullptr, + .descriptorPool = descriptor_pool, + .descriptorSetCount = as(count), + .pSetLayouts = &vk_layout, + }; + + const auto& device = descriptor_pool.device(); + const auto& device_table = device.device_table(); + + return vk::allocate_checked(count, + device_table.vkAllocateDescriptorSets, + device, + &allocate_info); + } + + ///////////////////////////////////// + ///////////////////////////////////// + static auto delete_vk_descriptor_set(view::Device&&, view::DescriptorPool&&, VkDescriptorSet) -> void {} + }; + } // namespace + + ///////////////////////////////////// + ///////////////////////////////////// + auto DescriptorPool::do_init(PrivateTag, std::span&& sizes, u32 max_sets) noexcept -> Expected { + const auto pool_sizes = transform(sizes, [](const Size& size) static noexcept { + return VkDescriptorPoolSize { + .type = vk::to_vk(size.type), + .descriptorCount = size.descriptor_count, + }; + }); + + const auto create_info = VkDescriptorPoolCreateInfo { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, + .pNext = nullptr, + .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, + .maxSets = max_sets, + .poolSizeCount = as(stdr::size(sizes)), + .pPoolSizes = stdr::data(pool_sizes), + }; + + const auto& device = this->device(); + const auto& device_table = device.device_table(); + + m_vk_handle = Try(vk::call_checked(device_table.vkCreateDescriptorPool, device, &create_info, nullptr)); + Return {}; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto DescriptorPool::create_vk_descriptor_sets(usize count, view::DescriptorSetLayout&& layout) const noexcept + -> Expected> { + return DescriptorPoolAPI::create_vk_descriptor_sets(*this, count, std::move(layout)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto DescriptorPool::delete_vk_descriptor_set(view::Device device, + view::DescriptorPool command_pool, + VkDescriptorSet descriptor_set) noexcept -> void { + DescriptorPoolAPI::delete_vk_descriptor_set(std::move(device), std::move(command_pool), descriptor_set); + } + + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + auto DescriptorPool::create_vk_descriptor_sets(usize count, DescriptorSetLayout&& layout) const noexcept + -> Expected> { + return DescriptorPoolAPI::create_vk_descriptor_sets(*this, count, std::move(layout)); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto DescriptorPool::delete_vk_descriptor_set(Device device, + DescriptorPool command_pool, + VkDescriptorSet descriptor_set) noexcept -> void { + DescriptorPoolAPI::delete_vk_descriptor_set(std::move(device), std::move(command_pool), descriptor_set); + } + } // namespace view +} // namespace stormkit::gpu diff --git a/src/gpu/execution/descriptor_set.cpp b/src/gpu/execution/descriptor_set.cpp new file mode 100644 index 000000000..6b1b65fb5 --- /dev/null +++ b/src/gpu/execution/descriptor_set.cpp @@ -0,0 +1,117 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +module stormkit.gpu.execution; + +import std; + +import stormkit.core; + +import stormkit.gpu.core; + +namespace stdr = std::ranges; +namespace stdv = std::views; + +using namespace std::literals; + +namespace stormkit::gpu { + namespace { + struct DescriptorSetAPI { + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto update(const DescriptorSetType& descriptor_set, std::span&& descriptors) -> void { + const auto& device = descriptor_set.device(); + const auto& device_table = device.device_table(); + + auto&& [_, _, _writes] = [&descriptor_set, descriptors = std::move(descriptors)] noexcept -> decltype(auto) { + auto buffers = std::vector {}; + auto images = std::vector {}; + auto writes = std::vector {}; + buffers.reserve(std::size(descriptors)); + images.reserve(std::size(descriptors)); + writes.reserve(std::size(descriptors)); + + stdr::for_each(std::move(descriptors), + core::monadic::either( + [&descriptor_set, &buffers, &writes](const BufferDescriptor& descriptor) noexcept + -> decltype(auto) { + buffers.push_back(VkDescriptorBufferInfo { + .buffer = descriptor.buffer, + .offset = descriptor.offset, + .range = descriptor.range.value_or(VK_WHOLE_SIZE), + }); + const auto& buffer_descriptor = buffers.back(); + + writes.push_back(VkWriteDescriptorSet { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = nullptr, + .dstSet = descriptor_set, + .dstBinding = descriptor.binding, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = vk::to_vk(descriptor.type), + .pImageInfo = nullptr, + .pBufferInfo = &buffer_descriptor, + .pTexelBufferView = nullptr, + }); + }, + [&descriptor_set, &images, &writes](const ImageDescriptor& descriptor) noexcept + -> decltype(auto) { + images.push_back(VkDescriptorImageInfo { + .sampler = descriptor.sampler, + .imageView = descriptor.image_view, + .imageLayout = vk::to_vk(descriptor.layout), + }); + const auto& image_descriptor = images.back(); + + writes.push_back(VkWriteDescriptorSet { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = nullptr, + .dstSet = descriptor_set, + .dstBinding = descriptor.binding, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = vk::to_vk(descriptor.type), + .pImageInfo = &image_descriptor, + .pBufferInfo = nullptr, + .pTexelBufferView = nullptr, + }); + })); + + return std::tuple { std::move(buffers), std::move(images), std::move(writes) }; + }(); + + vk::call(device_table.vkUpdateDescriptorSets, device, stdr::size(_writes), stdr::data(_writes), 0, nullptr); + } + }; + } // namespace + + ///////////////////////////////////// + ///////////////////////////////////// + auto DescriptorSet::do_init(VkDescriptorSet&& descriptor_set, Deleter&& deleter) noexcept -> void { + m_vk_handle = std::move(descriptor_set); + m_deleter = std::move(deleter); + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto DescriptorSet::update(std::span descriptors) const noexcept -> void { + DescriptorSetAPI::update(*this, std::move(descriptors)); + } + + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + auto DescriptorSet::update(std::span descriptors) const noexcept -> void { + DescriptorSetAPI::update(*this, std::move(descriptors)); + } + } // namespace view +} // namespace stormkit::gpu diff --git a/src/gpu/execution/descriptor_set_layout.cpp b/src/gpu/execution/descriptor_set_layout.cpp new file mode 100644 index 000000000..2ba9c843b --- /dev/null +++ b/src/gpu/execution/descriptor_set_layout.cpp @@ -0,0 +1,54 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +module stormkit.gpu.execution; + +import std; + +import stormkit.core; + +import stormkit.gpu.core; + +namespace stdr = std::ranges; +namespace stdv = std::views; + +using namespace std::literals; + +namespace stormkit::gpu { + auto DescriptorSetLayout::do_init(PrivateTag, std::vector&& bindings) noexcept -> Expected { + m_bindings = std::move(bindings); + const auto vk_bindings = transform(m_bindings, [](const DescriptorSetLayoutBinding& binding) static noexcept { + return VkDescriptorSetLayoutBinding { + .binding = binding.binding, + .descriptorType = vk::to_vk(binding.type), + .descriptorCount = as(binding.descriptor_count), + .stageFlags = vk::to_vk(binding.stages), + .pImmutableSamplers = nullptr, + }; + }); + + const auto create_info = VkDescriptorSetLayoutCreateInfo { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .bindingCount = as(stdr::size(vk_bindings)), + .pBindings = stdr::data(vk_bindings) + }; + + const auto& device = this->device(); + const auto& device_table = device.device_table(); + m_vk_handle = Try(vk::call_checked(device_table.vkCreateDescriptorSetLayout, + device, + &create_info, + nullptr)); + + Return {}; + } +} // namespace stormkit::gpu diff --git a/src/gpu/execution/frame_buffer.cpp b/src/gpu/execution/frame_buffer.cpp index 8e6d3260d..dabb4a094 100644 --- a/src/gpu/execution/frame_buffer.cpp +++ b/src/gpu/execution/frame_buffer.cpp @@ -4,6 +4,8 @@ module; +#include + #include module stormkit.gpu.execution; @@ -22,18 +24,18 @@ using namespace std::literals; namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto FrameBuffer::do_init(view::RenderPass&& render_pass, - const math::uextent2&, - std::vector attachments) noexcept -> Expected { + auto FrameBuffer::do_init(view::RenderPass&& render_pass, + const math::uextent2& extent, + std::vector&& attachments) noexcept -> Expected { m_extent = extent; m_attachments = std::move(attachments); - const auto vk_attachments = transform(m_attachments, , vk::monadic::to_vk()); + const auto vk_attachments = transform(m_attachments, vk::monadic::to_vk()); const auto create_info = VkFramebufferCreateInfo { .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, .pNext = nullptr, .flags = 0, - .renderPass = vk::to_vk(render_pass), + .renderPass = render_pass, .attachmentCount = as(std::ranges::size(vk_attachments)), .pAttachments = std::ranges::data(vk_attachments), .width = m_extent.width, @@ -41,7 +43,7 @@ namespace stormkit::gpu { .layers = 1, }; - const auto& device = device(); + const auto& device = this->device(); const auto& device_table = device.device_table(); m_vk_handle = Try(vk::call_checked(device_table.vkCreateFramebuffer, device, &create_info, nullptr)); diff --git a/src/gpu/execution/pipeline.cpp b/src/gpu/execution/pipeline.cpp index dfca33d64..cb8a61637 100644 --- a/src/gpu/execution/pipeline.cpp +++ b/src/gpu/execution/pipeline.cpp @@ -4,6 +4,8 @@ module; +#include + #include module stormkit.gpu.execution; @@ -17,210 +19,305 @@ import stormkit.gpu.core; namespace stdr = std::ranges; namespace stdv = std::views; +namespace cmonadic = stormkit::core::monadic; + using namespace std::literals; namespace stormkit::gpu { - ///////////////////////////////////// - ///////////////////////////////////// - auto Pipeline::do_init(const PipelineLayout& layout, - OptionalRef render_pass, - OptionalRef rendering_info, - OptionalRef pipeline_cache) noexcept -> Expected { - const auto& state = as(m_state); - - if (not render_pass) expects(rendering_info != std::nullopt); - else - expects(render_pass != std::nullopt); - - const auto binding_descriptions = state.vertex_input_state.binding_descriptions - | stdv::transform([](auto&& binding_description) static noexcept { - return VkVertexInputBindingDescription { - .binding = binding_description.binding, - .stride = binding_description.stride, - .inputRate = vk::to_vk(binding_description.input_rate) - - }; - }) - | stdr::to(); - - const auto attribute_descriptions = state.vertex_input_state.input_attribute_descriptions - | stdv::transform([](auto&& input_attribute_description) static noexcept { - return VkVertexInputAttributeDescription { - .location = input_attribute_description.location, - .binding = input_attribute_description.binding, - .format = vk::to_vk(input_attribute_description.format), - .offset = input_attribute_description.offset - }; - }) - | stdr::to(); - - const auto vertex_input_info = VkPipelineVertexInputStateCreateInfo { - .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .vertexBindingDescriptionCount = as(stdr::size(binding_descriptions)), - .pVertexBindingDescriptions = std::data(binding_descriptions), - .vertexAttributeDescriptionCount = as(stdr::size(attribute_descriptions)), - .pVertexAttributeDescriptions = stdr::data(attribute_descriptions), + namespace { + struct PipelineData { + std::vector binding_descriptions; + std::vector input_attribute_descriptions; + VkPipelineVertexInputStateCreateInfo vertex_input_info; + VkPipelineInputAssemblyStateCreateInfo input_assembly; + std::vector viewports; + std::vector scissors; + VkPipelineViewportStateCreateInfo viewport_state; + VkPipelineRasterizationStateCreateInfo rasterizer; + VkPipelineMultisampleStateCreateInfo multisample; + std::vector blend_attachments; + VkPipelineColorBlendStateCreateInfo color_blending; + std::vector states; + VkPipelineDynamicStateCreateInfo dynamic_state; + std::vector shaders; + VkPipelineDepthStencilStateCreateInfo depth_stencil; }; - const auto input_assembly = VkPipelineInputAssemblyStateCreateInfo { - .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .topology = vk::to_vk(state.input_assembly_state.topology), - .primitiveRestartEnable = state.input_assembly_state.primitive_restart_enable - }; + auto do_init(const RasterPipelineState& state) noexcept -> PipelineData { + auto out = PipelineData {}; + out.binding_descriptions = transform(state.vertex_input_state.binding_descriptions, + [](const auto& binding_description) static noexcept { + return VkVertexInputBindingDescription { + .binding = binding_description.binding, + .stride = binding_description.stride, + .inputRate = vk::to_vk(binding_description.input_rate) + + }; + }); + + out + .input_attribute_descriptions = transform(state.vertex_input_state.input_attribute_descriptions, + [](auto&& input_attribute_description) static noexcept { + return VkVertexInputAttributeDescription { + .location = input_attribute_description.location, + .binding = input_attribute_description.binding, + .format = vk::to_vk(input_attribute_description.format), + .offset = input_attribute_description.offset + }; + }); + out.vertex_input_info = VkPipelineVertexInputStateCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .vertexBindingDescriptionCount = as(stdr::size(out.binding_descriptions)), + .pVertexBindingDescriptions = std::data(out.binding_descriptions), + .vertexAttributeDescriptionCount = as(stdr::size(out.input_attribute_descriptions)), + .pVertexAttributeDescriptions = stdr::data(out.input_attribute_descriptions), + }; - const auto viewports = state.viewport_state.viewports | stdv::transform(vk::monadic::to_vk()) | stdr::to(); + out.input_assembly = VkPipelineInputAssemblyStateCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .topology = vk::to_vk(state.input_assembly_state.topology), + .primitiveRestartEnable = state.input_assembly_state.primitive_restart_enable + }; - const auto scissors = state.viewport_state.scissors | stdv::transform(vk::monadic::to_vk()) | stdr::to(); + out.viewports = transform(state.viewport_state.viewports, vk::monadic::to_vk()); - const auto viewport_state = VkPipelineViewportStateCreateInfo { - .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .viewportCount = as(stdr::size(viewports)), - .pViewports = stdr::data(viewports), - .scissorCount = as(stdr::size(scissors)), - .pScissors = stdr::data(scissors), - }; + out.scissors = transform(state.viewport_state.scissors, vk::monadic::to_vk()); - const auto rasterizer = VkPipelineRasterizationStateCreateInfo { - .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .depthClampEnable = state.rasterization_state.depth_clamp_enable, - .rasterizerDiscardEnable = state.rasterization_state.rasterizer_discard_enable, - .polygonMode = vk::to_vk(state.rasterization_state.polygon_mode), - .cullMode = vk::to_vk(state.rasterization_state.cull_mode), - .frontFace = vk::to_vk(state.rasterization_state.front_face), - .depthBiasEnable = state.rasterization_state.depth_bias_enable, - .depthBiasConstantFactor = state.rasterization_state.depth_bias_constant_factor, - .depthBiasClamp = state.rasterization_state.depth_bias_clamp, - .depthBiasSlopeFactor = state.rasterization_state.depth_bias_slope_factor, - .lineWidth = state.rasterization_state.line_width, - }; + out.viewport_state = VkPipelineViewportStateCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .viewportCount = as(stdr::size(out.viewports)), + .pViewports = stdr::data(out.viewports), + .scissorCount = as(stdr::size(out.scissors)), + .pScissors = stdr::data(out.scissors), + }; - const auto multisampling = VkPipelineMultisampleStateCreateInfo { - .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .rasterizationSamples = vk::to_vk(state.multisample_state.rasterization_samples), - .sampleShadingEnable = state.multisample_state.sample_shading_enable, - .minSampleShading = state.multisample_state.min_sample_shading, - .pSampleMask = nullptr, - .alphaToCoverageEnable = false, - .alphaToOneEnable = false, - }; + out.rasterizer = VkPipelineRasterizationStateCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .depthClampEnable = state.rasterization_state.depth_clamp_enable, + .rasterizerDiscardEnable = state.rasterization_state.rasterizer_discard_enable, + .polygonMode = vk::to_vk(state.rasterization_state.polygon_mode), + .cullMode = vk::to_vk(state.rasterization_state.cull_mode), + .frontFace = vk::to_vk(state.rasterization_state.front_face), + .depthBiasEnable = state.rasterization_state.depth_bias_enable, + .depthBiasConstantFactor = state.rasterization_state.depth_bias_constant_factor, + .depthBiasClamp = state.rasterization_state.depth_bias_clamp, + .depthBiasSlopeFactor = state.rasterization_state.depth_bias_slope_factor, + .lineWidth = state.rasterization_state.line_width, + }; - const auto blend_attachments = state.color_blend_state.attachments - | stdv::transform([](auto&& attachment) static noexcept { - return VkPipelineColorBlendAttachmentState { - .blendEnable = attachment.blend_enable, - .srcColorBlendFactor = vk::to_vk(attachment.src_color_blend_factor), - .dstColorBlendFactor = vk::to_vk(attachment.dst_color_blend_factor), - .colorBlendOp = vk::to_vk(attachment.color_blend_operation), - .srcAlphaBlendFactor = vk::to_vk(attachment.src_alpha_blend_factor), - .dstAlphaBlendFactor = vk::to_vk(attachment.dst_alpha_blend_factor), - .alphaBlendOp = vk::to_vk(attachment.alpha_blend_operation), - .colorWriteMask = vk::to_vk(attachment.color_write_mask) - }; - }) - | stdr::to(); - - const auto color_blending = VkPipelineColorBlendStateCreateInfo { - .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .logicOpEnable = state.color_blend_state.logic_operation_enable, - .logicOp = vk::to_vk(state.color_blend_state.logic_operation), - .attachmentCount = as(stdr::size(blend_attachments)), - .pAttachments = stdr::data(blend_attachments), - .blendConstants = { state.color_blend_state.blend_constants[0], - state.color_blend_state.blend_constants[1], - state.color_blend_state.blend_constants[2], - state.color_blend_state.blend_constants[3] }, - }; + out.multisample = VkPipelineMultisampleStateCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .rasterizationSamples = vk::to_vk(state.multisample_state.rasterization_samples), + .sampleShadingEnable = state.multisample_state.sample_shading_enable, + .minSampleShading = state.multisample_state.min_sample_shading, + .pSampleMask = nullptr, + .alphaToCoverageEnable = false, + .alphaToOneEnable = false, + }; - const auto states = state.dynamic_state | stdv::transform(vk::monadic::to_vk()) | stdr::to(); + out.blend_attachments = transform(state.color_blend_state.attachments, [](auto&& attachment) static noexcept { + return VkPipelineColorBlendAttachmentState { + .blendEnable = attachment.blend_enable, + .srcColorBlendFactor = vk::to_vk(attachment.src_color_blend_factor), + .dstColorBlendFactor = vk::to_vk(attachment.dst_color_blend_factor), + .colorBlendOp = vk::to_vk(attachment.color_blend_operation), + .srcAlphaBlendFactor = vk::to_vk(attachment.src_alpha_blend_factor), + .dstAlphaBlendFactor = vk::to_vk(attachment.dst_alpha_blend_factor), + .alphaBlendOp = vk::to_vk(attachment.alpha_blend_operation), + .colorWriteMask = vk::to_vk(attachment.color_write_mask) + }; + }); + + out.color_blending = VkPipelineColorBlendStateCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .logicOpEnable = state.color_blend_state.logic_operation_enable, + .logicOp = vk::to_vk(state.color_blend_state.logic_operation), + .attachmentCount = as(stdr::size(out.blend_attachments)), + .pAttachments = stdr::data(out.blend_attachments), + .blendConstants = { state.color_blend_state.blend_constants[0], + state.color_blend_state.blend_constants[1], + state.color_blend_state.blend_constants[2], + state.color_blend_state.blend_constants[3] }, + }; - const auto dynamic_state = VkPipelineDynamicStateCreateInfo { - .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .dynamicStateCount = as(stdr::size(states)), - .pDynamicStates = stdr::data(states), - }; + out.states = transform(state.dynamic_state, vk::monadic::to_vk()); - const auto shaders = state.shader_state - | stdv::transform(core::monadic::unref()) - | stdv::transform([](auto&& shader) static noexcept { - const auto name = [](const auto& shader) static noexcept { - if (shader.type() == ShaderStageFlag::VERTEX) return "vert_main"sv; - else if (shader.type() == ShaderStageFlag::FRAGMENT) - return "frag_main"sv; - else - return "main"sv; - }(shader); - - return VkPipelineShaderStageCreateInfo { - .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .stage = vk::to_vk(shader.type()), - .module = vk::to_vk(shader), - .pName = stdr::data(name), - .pSpecializationInfo = nullptr, - }; - }) - | stdr::to(); - - const auto depth_stencil = VkPipelineDepthStencilStateCreateInfo { - .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, - .pNext = nullptr, - .flags = 0, - .depthTestEnable = state.depth_stencil_state.depth_test_enable, - .depthWriteEnable = state.depth_stencil_state.depth_write_enable, - .depthCompareOp = vk::to_vk(state.depth_stencil_state.depth_compare_op), - .depthBoundsTestEnable = state.depth_stencil_state.depth_bounds_test_enable, - .stencilTestEnable = false, - .front = {}, - .back = {}, - .minDepthBounds = state.depth_stencil_state.min_depth_bounds, - .maxDepthBounds = state.depth_stencil_state.max_depth_bounds - }; + out.dynamic_state = VkPipelineDynamicStateCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .dynamicStateCount = as(stdr::size(out.states)), + .pDynamicStates = stdr::data(out.states), + }; + + out.shaders = transform(state.shader_state, [](const auto& shader) static noexcept { + const auto name = [](const auto& shader) static noexcept { + if (shader.type() == ShaderStageFlag::VERTEX) return "vert_main"sv; + else if (shader.type() == ShaderStageFlag::FRAGMENT) + return "frag_main"sv; + else + return "main"sv; + }(shader); + + return VkPipelineShaderStageCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .stage = vk::to_vk(shader.type()), + .module = shader, + .pName = stdr::data(name), + .pSpecializationInfo = nullptr, + }; + }); + + out.depth_stencil = VkPipelineDepthStencilStateCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .depthTestEnable = state.depth_stencil_state.depth_test_enable, + .depthWriteEnable = state.depth_stencil_state.depth_write_enable, + .depthCompareOp = vk::to_vk(state.depth_stencil_state.depth_compare_op), + .depthBoundsTestEnable = state.depth_stencil_state.depth_bounds_test_enable, + .stencilTestEnable = false, + .front = {}, + .back = {}, + .minDepthBounds = state.depth_stencil_state.min_depth_bounds, + .maxDepthBounds = state.depth_stencil_state.max_depth_bounds + }; - const auto [_, render_info] = [&]() { - auto info = VkPipelineRenderingCreateInfo {}; - if (not rendering_info) return std::make_pair(std::vector {}, std::move(info)); + return out; + } + } // namespace - auto formats = rendering_info->color_attachment_formats - | stdv::transform(vk::monadic::to_vk()) - | stdr::to(); + ///////////////////////////////////// + ///////////////////////////////////// + auto Pipeline::do_init(PrivateTag, + const RasterPipelineState& _state, + view::PipelineLayout&& layout, + const RasterPipelineRenderingInfo& rendering_info, + std::optional&& pipeline_cache) noexcept -> Expected { + m_type = Type::RASTER; + m_state = _state; - info = VkPipelineRenderingCreateInfo { + const auto& state = as(m_state); + + const auto [binding_descriptions, + attribute_descriptions, + vertex_input_info, + input_assembly, + viewports, + scissors, + viewport_state, + rasterizer, + multisampling, + blend_attachments, + color_blending, + states, + dynamic_state, + shaders, + depth_stencil] = gpu::do_init(state); + + const auto formats = transform(rendering_info.color_attachment_formats, vk::monadic::to_vk()); + + const auto _rendering_info = [&] noexcept { + auto info = VkPipelineRenderingCreateInfo { .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, .pNext = nullptr, - .viewMask = rendering_info->view_mask, + .viewMask = rendering_info.view_mask, .colorAttachmentCount = as(stdr::size(formats)), .pColorAttachmentFormats = stdr::data(formats), .depthAttachmentFormat = {}, .stencilAttachmentFormat = {} }; - if (rendering_info->depth_attachment_format) - info.depthAttachmentFormat = vk::to_vk(*rendering_info->depth_attachment_format); + if (rendering_info.depth_attachment_format) + info.depthAttachmentFormat = vk::to_vk(*rendering_info.depth_attachment_format); - if (rendering_info->stencil_attachment_format) - info.stencilAttachmentFormat = vk::to_vk(*rendering_info->stencil_attachment_format); + if (rendering_info.stencil_attachment_format) + info.stencilAttachmentFormat = vk::to_vk(*rendering_info.stencil_attachment_format); - return std::make_pair(std::move(formats), std::move(info)); + return info; }(); const auto create_info = VkGraphicsPipelineCreateInfo { .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, - .pNext = not render_pass ? &render_info : nullptr, + .pNext = &_rendering_info, + .flags = 0, + .stageCount = as(stdr::size(shaders)), + .pStages = stdr::data(shaders), + .pVertexInputState = &vertex_input_info, + .pInputAssemblyState = &input_assembly, + .pTessellationState = nullptr, + .pViewportState = &viewport_state, + .pRasterizationState = &rasterizer, + .pMultisampleState = &multisampling, + .pDepthStencilState = &depth_stencil, + .pColorBlendState = &color_blending, + .pDynamicState = &dynamic_state, + .layout = vk::to_vk(layout), + .renderPass = VK_NULL_HANDLE, + .subpass = 0, + .basePipelineHandle = nullptr, + .basePipelineIndex = -1, + }; + + const auto vk_pipeline_cache = either(pipeline_cache, vk::monadic::to_vk(), cmonadic::init(nullptr)); + + const auto& device = this->device(); + const auto& device_table = device.device_table(); + + m_vk_handle = Try(vk::call_checked(device_table.vkCreateGraphicsPipelines, + device, + vk_pipeline_cache, + 1, + &create_info, + nullptr)); + Return {}; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto Pipeline::do_init(PrivateTag, + const RasterPipelineState& _state, + view::PipelineLayout&& layout, + view::RenderPass&& render_pass, + std::optional&& pipeline_cache) noexcept -> Expected { + m_type = Type::RASTER; + m_state = _state; + + const auto& state = as(m_state); + + const auto [binding_descriptions, + attribute_descriptions, + vertex_input_info, + input_assembly, + viewports, + scissors, + viewport_state, + rasterizer, + multisampling, + blend_attachments, + color_blending, + states, + dynamic_state, + shaders, + depth_stencil] = gpu::do_init(state); + + const auto create_info = VkGraphicsPipelineCreateInfo { + .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, + .pNext = nullptr, .flags = 0, .stageCount = as(stdr::size(shaders)), .pStages = stdr::data(shaders), @@ -234,21 +331,23 @@ namespace stormkit::gpu { .pColorBlendState = &color_blending, .pDynamicState = &dynamic_state, .layout = vk::to_vk(layout), - .renderPass = render_pass ? vk::to_vk(render_pass) : nullptr, + .renderPass = render_pass, .subpass = 0, .basePipelineHandle = nullptr, .basePipelineIndex = -1, }; - using namespace core::monadic; - const auto vk_pipeline_cache = core::either(pipeline_cache, vk::monadic::to_vk(), init(nullptr)); + const auto vk_pipeline_cache = either(pipeline_cache, vk::monadic::to_vk(), cmonadic::init(nullptr)); + + const auto& device = this->device(); + const auto& device_table = device.device_table(); - return vk::call_checked(m_vk_device_table->vkCreateGraphicsPipelines, - m_vk_device, - vk_pipeline_cache, - 1, - &create_info, - nullptr) - .transform(set(m_vk_handle)); + m_vk_handle = Try(vk::call_checked(device_table.vkCreateGraphicsPipelines, + device, + vk_pipeline_cache, + 1, + &create_info, + nullptr)); + Return {}; } } // namespace stormkit::gpu diff --git a/src/gpu/execution/pipeline_cache.cpp b/src/gpu/execution/pipeline_cache.cpp index a666e6ea3..2268d8124 100644 --- a/src/gpu/execution/pipeline_cache.cpp +++ b/src/gpu/execution/pipeline_cache.cpp @@ -6,8 +6,6 @@ module; #include -#include - #include module stormkit.gpu.execution; @@ -19,35 +17,43 @@ import stormkit.log; import stormkit.gpu.core; -namespace stdr = std::ranges; +namespace stdr = std::ranges; +namespace stdfs = std::filesystem; using namespace stormkit::literals; -LOGGER("stormkit.gpu") - namespace stormkit::gpu { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto sys_to_load_error(SystemError error) noexcept -> PipelineCache::LoadSaveError { - return PipelineCache::LoadSaveError { { error } }; - } + namespace { + ///////////////////////////////////// + ///////////////////////////////////// + auto sys_to_load_error(SystemError error) noexcept -> PipelineCache::LoadSaveError { + return PipelineCache::LoadSaveError { { error } }; + } + + ///////////////////////////////////// + ///////////////////////////////////// + auto result_to_load_error(Result error) noexcept -> PipelineCache::LoadSaveError { + return PipelineCache::LoadSaveError { { error } }; + } + } // namespace ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto result_to_load_error(Result error) noexcept -> PipelineCache::LoadSaveError { - return PipelineCache::LoadSaveError { { error } }; - } + PipelineCache::~PipelineCache() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - PipelineCache::~PipelineCache() noexcept = default; + auto PipelineCache::do_init(PrivateTag, stdfs::path&& path) noexcept -> LoadSaveExpected { + m_path = std::move(path); + Return read_pipeline_cache(); + } ///////////////////////////////////// ///////////////////////////////////// - auto PipelineCache::create_new_pipeline_cache(const Device& device) noexcept -> LoadSaveExpected { - const auto physical_device_infos = device.physical_device().info(); + auto PipelineCache::create_new_pipeline_cache() noexcept -> LoadSaveExpected { + const auto& device = this->device(); + const auto& device_table = device.device_table(); + const auto& physical_device_infos = device.physical_device().info(); m_serialized.guard.magic = MAGIC; m_serialized.guard.data_size = 0u; @@ -67,63 +73,40 @@ namespace stormkit::gpu { .pInitialData = nullptr, }; - m_vk_handle = Try(vk::call_checked(m_vk_device_table->vkCreatePipelineCache, - m_vk_device, - &create_info, - nullptr) - .transform_error(result_to_load_error)); + m_vk_handle = TryTransformError(vk::call_checked(device_table.vkCreatePipelineCache, + device, + &create_info, + nullptr), + result_to_load_error); Return {}; } ///////////////////////////////////// ///////////////////////////////////// - auto PipelineCache::read_pipeline_cache(const Device& device) noexcept -> LoadSaveExpected { - if (not std::filesystem::exists(m_path)) Return create_new_pipeline_cache(device); + auto PipelineCache::read_pipeline_cache() noexcept -> LoadSaveExpected { + if (not stdfs::exists(m_path)) Return create_new_pipeline_cache(); - const auto physical_device_infos = device.physical_device().info(); + const auto& device = this->device(); + const auto& device_table = device.device_table(); + const auto& physical_device_infos = device.physical_device().info(); - auto file = Try(io::File::open(m_path, io::Access::READ).transform_error(sys_to_load_error)); - Try(file.read_to(as_bytes_mut(m_serialized.guard)).transform_error(sys_to_load_error)); - Try(file.read_to(as_bytes_mut(m_serialized.infos)).transform_error(sys_to_load_error)); - Try(file.read_to(as_bytes_mut(m_serialized.uuid.value)).transform_error(sys_to_load_error)); - - if (m_serialized.guard.magic != MAGIC) { - elog("Invalid pipeline cache magic number, have {}, expected: {}", m_serialized.guard.magic, MAGIC); - - Return create_new_pipeline_cache(device); - } + auto file = TryTransformError(io::File::open(m_path, io::Access::READ), sys_to_load_error); + TryTransformError(file.read_to(as_bytes_mut(m_serialized.guard)), sys_to_load_error); + TryTransformError(file.read_to(as_bytes_mut(m_serialized.infos)), sys_to_load_error); + TryTransformError(file.read_to(as_bytes_mut(m_serialized.uuid.value)), sys_to_load_error); - if (m_serialized.infos.version != VERSION) { - elog("Mismatch pipeline cache version, have {}, expected: {}", m_serialized.infos.version, VERSION); - - Return create_new_pipeline_cache(device); - } - - if (m_serialized.infos.vendor_id != physical_device_infos.vendor_id) { - elog("Mismatch pipeline cache vendor id, have {:#06x}, expected: {:#06x}", - m_serialized.infos.vendor_id, - physical_device_infos.vendor_id); - - Return create_new_pipeline_cache(device); - } - - if (m_serialized.infos.device_id != physical_device_infos.device_id) { - elog("Mismatch pipeline cache device id, have {:#06x}, expected: {:#06x}", - m_serialized.infos.device_id, - physical_device_infos.device_id); - - Return create_new_pipeline_cache(device); - } - - if (not stdr::equal(m_serialized.uuid.value, physical_device_infos.pipeline_cache_uuid)) { - Return create_new_pipeline_cache(device); - } + if (m_serialized.guard.magic != MAGIC) Return create_new_pipeline_cache(); + if (m_serialized.infos.version != VERSION) Return create_new_pipeline_cache(); + if (m_serialized.infos.vendor_id != physical_device_infos.vendor_id) Return create_new_pipeline_cache(); + if (m_serialized.infos.device_id != physical_device_infos.device_id) Return create_new_pipeline_cache(); + if (not stdr::equal(m_serialized.uuid.value, physical_device_infos.pipeline_cache_uuid)) + Return create_new_pipeline_cache(); auto data = std::vector {}; data.resize(m_serialized.guard.data_size); - Try(io::read_to(m_path, data).transform_error(sys_to_load_error)); + TryTransformError(io::read_to(m_path, data), sys_to_load_error); const auto create_info = VkPipelineCacheCreateInfo { .sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, @@ -133,11 +116,11 @@ namespace stormkit::gpu { .pInitialData = stdr::data(data), }; - m_vk_handle = Try(vk::call_checked(m_vk_device_table->vkCreatePipelineCache, - m_vk_device, - &create_info, - nullptr) - .transform_error(result_to_load_error)); + m_vk_handle = TryTransformError(vk::call_checked(device_table.vkCreatePipelineCache, + device, + &create_info, + nullptr), + result_to_load_error); Return {}; } @@ -145,33 +128,26 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// auto PipelineCache::save_cache() noexcept -> LoadSaveExpected { + const auto& device = this->device(); + const auto& device_table = device.device_table(); + auto size = 0_usize; - { - const auto - result = vk::call_checked(m_vk_device_table->vkGetPipelineCacheData, m_vk_device, m_vk_handle, &size, nullptr); - if (not result) Return std::unexpected { result_to_load_error(result.error()) }; - } + TryTransformError(vk::call_checked(device_table.vkGetPipelineCacheData, device, m_vk_handle, &size, nullptr), + result_to_load_error); auto data = std::vector {}; data.resize(size, 0_b); - { - const auto result = vk::call_checked(m_vk_device_table->vkGetPipelineCacheData, - m_vk_device, - m_vk_handle, - &size, - stdr::data(data)); - if (not result) Return std::unexpected { result_to_load_error(result.error()) }; - } + TryTransformError(vk::call_checked(device_table.vkGetPipelineCacheData, device, m_vk_handle, &size, stdr::data(data)), + result_to_load_error); m_serialized.guard.data_size = stdr::size(data); m_serialized.guard.data_hash = 0u; hash_combine(m_serialized.guard.data_hash, data); - auto file = Try(io::File::open(m_path, io::Access::WRITE).transform_error(sys_to_load_error)); - - Try(file.write(as_bytes(m_serialized.infos)).transform_error(sys_to_load_error)); - Try(file.write(as_bytes(m_serialized.uuid.value)).transform_error(sys_to_load_error)); - Try(file.write(as_bytes(data)).transform_error(sys_to_load_error)); + auto file = TryTransformError(io::File::open(m_path, io::Access::WRITE), sys_to_load_error); + TryTransformError(file.write(as_bytes(m_serialized.infos)), sys_to_load_error); + TryTransformError(file.write(as_bytes(m_serialized.uuid.value)), sys_to_load_error); + TryTransformError(file.write(as_bytes(data)), sys_to_load_error); Return {}; } diff --git a/src/gpu/execution/pipeline_layout.cpp b/src/gpu/execution/pipeline_layout.cpp new file mode 100644 index 000000000..e4fb71378 --- /dev/null +++ b/src/gpu/execution/pipeline_layout.cpp @@ -0,0 +1,56 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +#include + +module stormkit.gpu.execution; + +import std; + +import stormkit.core; + +import stormkit.gpu.core; + +namespace stdr = std::ranges; +namespace stdv = std::views; + +using namespace std::literals; + +namespace stormkit::gpu { + ///////////////////////////////////// + ///////////////////////////////////// + auto PipelineLayout::do_init(PrivateTag, const RasterPipelineLayout& layout) noexcept -> Expected { + m_layout = layout; + + const auto set_layouts = transform(m_layout.descriptor_set_layouts, vk::monadic::to_vk()); + + const auto push_constant_ranges = transform(m_layout.push_constant_ranges, [](const auto& push_constant_range) noexcept { + return VkPushConstantRange { + .stageFlags = vk::to_vk(push_constant_range.stages), + .offset = push_constant_range.offset, + .size = as(push_constant_range.size), + }; + }); + + const auto create_info = VkPipelineLayoutCreateInfo { + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .setLayoutCount = as(stdr::size(set_layouts)), + .pSetLayouts = stdr::data(set_layouts), + .pushConstantRangeCount = as(stdr::size(push_constant_ranges)), + .pPushConstantRanges = stdr::data(push_constant_ranges), + }; + + const auto& device = this->device(); + const auto& device_table = device.device_table(); + + m_vk_handle = Try(vk::call_checked(device_table.vkCreatePipelineLayout, device, &create_info, nullptr)); + Return {}; + } +} // namespace stormkit::gpu diff --git a/src/gpu/execution/queue.cpp b/src/gpu/execution/queue.cpp index 155d950e4..2bb64b31c 100644 --- a/src/gpu/execution/queue.cpp +++ b/src/gpu/execution/queue.cpp @@ -31,17 +31,17 @@ namespace stormkit::gpu { template static auto wait_idle(const QueueType& queue) noexcept -> Expected { const auto& device = queue.device(); - const auto& device_table = queue.device_table(); + const auto& device_table = device.device_table(); - return vk::call_checked(device_table->vkQueueWaitIdle, queue); + return vk::call_checked(device_table.vkQueueWaitIdle, queue); } ///////////////////////////////////// ///////////////////////////////////// template - static auto submit(const QueueType& queue, - std::span&& submit_infos, - std::optional&& fence) noexcept -> Expected { + static auto submit(const QueueType& queue, + std::span&& submit_infos, + std::optional&& fence) noexcept -> Expected { struct SubmitInfoRange { std::span wait_semaphores; std::span wait_dst_stages; @@ -131,7 +131,7 @@ namespace stormkit::gpu { }) | stdr::to(); - const auto vk_fence = core::either(fence, vk::monadic::to_vk(), core::monadic::init(nullptr)); + const auto vk_fence = either(fence, vk::monadic::to_vk(), core::monadic::init(VK_NULL_HANDLE)); const auto& device = queue.device(); const auto& device_table = device.device_table(); @@ -204,14 +204,14 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto Queue::submit(std::span submit_infos, std::optional fence) const noexcept + auto Queue::submit(std::span submit_infos, std::optional fence) const noexcept -> Expected { return QueueAPI::submit(*this, std::move(submit_infos), std::move(fence)); } ///////////////////////////////////// ///////////////////////////////////// - auto Queue::do_init(const Device::QueueEntry& entry) -> void { + auto Queue::do_init(PrivateTag, const Device::QueueEntry& entry) -> void { m_entry = entry; const auto& device = this->device(); @@ -236,7 +236,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto Queue::submit(std::span submit_infos, std::optional fence) const noexcept + auto Queue::submit(std::span submit_infos, std::optional fence) const noexcept -> Expected { return QueueAPI::submit(*this, std::move(submit_infos), std::move(fence)); } diff --git a/src/gpu/execution/render_pass.cpp b/src/gpu/execution/render_pass.cpp index 7e792b497..5cb737f85 100644 --- a/src/gpu/execution/render_pass.cpp +++ b/src/gpu/execution/render_pass.cpp @@ -4,6 +4,8 @@ module; +#include + #include module stormkit.gpu.execution; @@ -60,10 +62,10 @@ namespace stormkit::gpu { subpasses_deps.reserve(stdr::size(m_description.subpasses)); for (const auto& subpass : m_description.subpasses) { - auto& color_attachment_ref = color_attachment_refs.emplace_back(transform(subpass.color_attachment_refs, - monadic::vk_ref()); - auto& resolve_attachment_ref = resolve_attachment_refs.emplace_back(transform(subpass.resolve_attachment_refs, - monadic::vk_ref()); + auto& color_attachment_ref = color_attachment_refs + .emplace_back(transform(subpass.color_attachment_refs, monadic::vk_ref())); + auto& resolve_attachment_ref = resolve_attachment_refs + .emplace_back(transform(subpass.resolve_attachment_refs, monadic::vk_ref())); if (subpass.depth_attachment_ref) depth_attachment_ref = monadic::vk_ref()(*subpass.depth_attachment_ref); subpasses.emplace_back(VkSubpassDescription { @@ -102,7 +104,7 @@ namespace stormkit::gpu { .pDependencies = stdr::data(subpasses_deps), }; - const auto& device = device(); + const auto& device = this->device(); const auto& device_table = device.device_table(); m_vk_handle = Try(vk::call_checked(device_table.vkCreateRenderPass, device, &create_info, nullptr)); diff --git a/src/gpu/execution/swapchain.cpp b/src/gpu/execution/swapchain.cpp index 448e41db0..26863cffe 100644 --- a/src/gpu/execution/swapchain.cpp +++ b/src/gpu/execution/swapchain.cpp @@ -1,6 +1,7 @@ module; #include +#include #include @@ -13,161 +14,169 @@ import stormkit.core; import stormkit.gpu.core; import stormkit.gpu.resource; -namespace stormkit::gpu { namespace { - ///////////////////////////////////// - ///////////////////////////////////// - auto choose_swap_surface_format(std::span formats) noexcept -> VkSurfaceFormatKHR { - for (const auto& format : formats) { - if (format.format == VK_FORMAT_B8G8R8A8_UNORM && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) - return format; +namespace stormkit::gpu { + namespace { + ///////////////////////////////////// + ///////////////////////////////////// + auto choose_swap_surface_format(std::span formats) noexcept -> VkSurfaceFormatKHR { + for (const auto& format : formats) { + if (format.format == VK_FORMAT_B8G8R8A8_UNORM && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) + return format; + } + + return formats[0]; } - return formats[0]; - } + ///////////////////////////////////// + ///////////////////////////////////// + auto choose_swap_present_mode(std::span present_modes) noexcept -> VkPresentModeKHR { + auto present_mode_ = VK_PRESENT_MODE_FIFO_KHR; - ///////////////////////////////////// - ///////////////////////////////////// - auto choose_swap_present_mode(std::span present_modes) noexcept -> VkPresentModeKHR { - auto present_mode_ = VK_PRESENT_MODE_FIFO_KHR; + for (const auto& present_mode : present_modes) { + if (present_mode == VK_PRESENT_MODE_IMMEDIATE_KHR) return present_mode; + else if (present_mode == VK_PRESENT_MODE_MAILBOX_KHR) + return present_mode; + } - for (const auto& present_mode : present_modes) { - if (present_mode == VK_PRESENT_MODE_IMMEDIATE_KHR) return present_mode; - else if (present_mode == VK_PRESENT_MODE_MAILBOX_KHR) - return present_mode; + return present_mode_; } - return present_mode_; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto choose_swap_extent(const VkSurfaceCapabilitiesKHR& capabilities, const math::uextent2& extent) noexcept -> VkExtent2D { - static constexpr auto int_max = std::numeric_limits::max(); + ///////////////////////////////////// + ///////////////////////////////////// + auto choose_swap_extent(const VkSurfaceCapabilitiesKHR& capabilities, const math::uextent2& extent) noexcept + -> VkExtent2D { + static constexpr auto int_max = std::numeric_limits::max(); - if (capabilities.currentExtent.width != int_max && capabilities.currentExtent.height != int_max) - return capabilities.currentExtent; + if (capabilities.currentExtent.width != int_max && capabilities.currentExtent.height != int_max) + return capabilities.currentExtent; - auto actual_extent = vk::to_vk(extent); - actual_extent - .width = std::max(capabilities.minImageExtent.width, std::min(capabilities.maxImageExtent.width, actual_extent.width)); - actual_extent.height = std::max(capabilities.minImageExtent.height, - std::min(capabilities.maxImageExtent.height, actual_extent.height)); + auto actual_extent = vk::to_vk(extent); + actual_extent.width = std::max(capabilities.minImageExtent.width, + std::min(capabilities.maxImageExtent.width, actual_extent.width)); + actual_extent.height = std::max(capabilities.minImageExtent.height, + std::min(capabilities.maxImageExtent.height, actual_extent.height)); - return actual_extent; - } + return actual_extent; + } - ///////////////////////////////////// - ///////////////////////////////////// - auto choose_image_count(const VkSurfaceCapabilitiesKHR& capabilities) noexcept -> u32 { - auto image_count = capabilities.minImageCount + 1; + ///////////////////////////////////// + ///////////////////////////////////// + auto choose_image_count(const VkSurfaceCapabilitiesKHR& capabilities) noexcept -> u32 { + auto image_count = capabilities.minImageCount + 1; - if (capabilities.maxImageCount > 0 && image_count > capabilities.maxImageCount) image_count = capabilities.maxImageCount; + if (capabilities.maxImageCount > 0 && image_count > capabilities.maxImageCount) + image_count = capabilities.maxImageCount; - return image_count; - } + return image_count; + } - struct SwapChainAPI { - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto acquire_next_image(const SwapChainType& swapchain, - std::chrono::nanoseconds wait, - view::Semaphore&& image_available) const noexcept -> Expected { - const auto& device = device(); - const auto& device_table = device.device_table(); - - auto id = u32 { 0 }; - Try(vk::call_checked(device_table->vkAcquireNextImageKHR, - device, - swapchain, - wait.count(), - image_available, - nullptr, - &id)); - Return SwapChain::NextImage { .result = vk::from_vk(result), .id = id }; + struct SwapChainAPI { + ///////////////////////////////////// + ///////////////////////////////////// + template + static auto acquire_next_image(const SwapChainType& swapchain, + std::chrono::nanoseconds wait, + view::Semaphore&& image_available) noexcept -> Expected { + const auto& device = swapchain.device(); + const auto& device_table = device.device_table(); + + auto id = u32 { 0 }; + const auto + result = Try((vk::call_checked(device_table + .vkAcquireNextImageKHR, + device, + swapchain, + wait.count(), + image_available, + nullptr, + &id))); + Return SwapChain::NextImage { .result = vk::from_vk(result), .id = id }; + } }; - } -}; } // namespace - -///////////////////////////////////// -///////////////////////////////////// -auto SwapChain::do_init(view::Surface&& surface, const math::uextent2& extent, VkSwapchainKHR old_swapchain) noexcept - -> Expected { - const auto& device = device(); - const auto& device_table = device.device_table(); - const auto& physical_device = device.physical_device(); - - const auto capabilities = Try(vk::call_checked(vkGetPhysicalDeviceSurfaceCapabilitiesKHR, - physical_device, - surface)); - const auto - formats = Try(vk::enumerate_checked(vkGetPhysicalDeviceSurfaceFormatsKHR, physical_device, surface)); - const auto present_modes = Try(vk::enumerate_checked(vkGetPhysicalDeviceSurfacePresentModesKHR, - physical_device, - surface)); - - const auto format = choose_swap_surface_format(formats); - const auto present_mode = choose_swap_present_mode(present_modes); - const auto swapchain_extent = choose_swap_extent(capabilities, extent.to<2uz>()); - const auto image_count = choose_image_count(capabilities); - const auto image_sharing_mode = VK_SHARING_MODE_EXCLUSIVE; - const auto image_usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; - - m_extent = extent; - m_pixel_format = vk::from_vk(format.format); - - const auto create_info = VkSwapchainCreateInfoKHR { - .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, - .pNext = nullptr, - .flags = 0, - .surface = surface, - .minImageCount = image_count, - .imageFormat = format.format, - .imageColorSpace = format.colorSpace, - .imageExtent = swapchain_extent, - .imageArrayLayers = 1, - .imageUsage = image_usage, - .imageSharingMode = image_sharing_mode, - .queueFamilyIndexCount = 0, - .pQueueFamilyIndices = nullptr, - .preTransform = capabilities.currentTransform, - .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, - .presentMode = present_mode, - .clipped = true, - .oldSwapchain = old_swapchain - }; - - ENSURES(device_table.vkCreateSwapchainKHR != nullptr); - ENSURES(device_table.vkGetSwapchainImagesKHR != nullptr); - - m_vk_handle = Try(vk::call_checked(device_table.vkCreateSwapchainKHR, device, &create_info, nullptr)); - const auto vk_images = Try(vk::enumerate_checked(device_table.vkGetSwapchainImagesKHR, device, m_vk_handle)); - - m_image_count = as(stdr::size(vk_images)); - m_images = transform(vk_images, [this, &device](auto image) noexcept { - const auto create_info = Image::CreateInfo { - .extent = { m_extent.width, m_extent.height, 1_u32 }, - .format = m_pixel_format + } // namespace + + ///////////////////////////////////// + ///////////////////////////////////// + auto SwapChain::do_init(PrivateTag, + view::Surface&& surface, + const math::uextent2& extent, + VkSwapchainKHR old_swapchain) noexcept -> Expected { + const auto& device = this->device(); + const auto& device_table = device.device_table(); + const auto& physical_device = device.physical_device(); + + const auto capabilities = Try(vk::call_checked(vkGetPhysicalDeviceSurfaceCapabilitiesKHR, + physical_device, + surface)); + const auto formats = Try(vk::enumerate_checked(vkGetPhysicalDeviceSurfaceFormatsKHR, + physical_device, + surface)); + const auto present_modes = Try(vk::enumerate_checked(vkGetPhysicalDeviceSurfacePresentModesKHR, + physical_device, + surface)); + + const auto format = choose_swap_surface_format(formats); + const auto present_mode = choose_swap_present_mode(present_modes); + const auto swapchain_extent = choose_swap_extent(capabilities, extent.to<2uz>()); + const auto image_count = choose_image_count(capabilities); + const auto image_sharing_mode = VK_SHARING_MODE_EXCLUSIVE; + const auto image_usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; + + m_extent = extent; + m_pixel_format = vk::from_vk(format.format); + + const auto create_info = VkSwapchainCreateInfoKHR { + .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, + .pNext = nullptr, + .flags = 0, + .surface = surface, + .minImageCount = image_count, + .imageFormat = format.format, + .imageColorSpace = format.colorSpace, + .imageExtent = swapchain_extent, + .imageArrayLayers = 1, + .imageUsage = image_usage, + .imageSharingMode = image_sharing_mode, + .queueFamilyIndexCount = 0, + .pQueueFamilyIndices = nullptr, + .preTransform = capabilities.currentTransform, + .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, + .presentMode = present_mode, + .clipped = true, + .oldSwapchain = old_swapchain, }; - return Image::from_existing(device, create_info, image); - }); - Return {}; -} + ENSURES(device_table.vkCreateSwapchainKHR != nullptr); + ENSURES(device_table.vkGetSwapchainImagesKHR != nullptr); + + m_vk_handle = Try(vk::call_checked(device_table.vkCreateSwapchainKHR, device, &create_info, nullptr)); + const auto vk_images = Try(vk::enumerate_checked(device_table.vkGetSwapchainImagesKHR, device, m_vk_handle)); -///////////////////////////////////// -///////////////////////////////////// -auto SwapChain::acquire_next_image(std::chrono::nanoseconds wait, view::Semaphore image_available) const noexcept - -> Expected { - return SwapChainAPI::acquire_next_image(*this, std::move(wait), std::move(image_available)) -} + m_image_count = as(stdr::size(vk_images)); + m_images = transform(vk_images, [this, &device](auto image) noexcept { + const auto create_info = Image::CreateInfo { + .extent = { m_extent.width, m_extent.height, 1_u32 }, + .format = m_pixel_format + }; + return Image::from_existing(device, create_info, image); + }); + + Return {}; + } -namespace view { ///////////////////////////////////// ///////////////////////////////////// - auto SwapChain::acquire_next_image(std::chrono::nanoseconds wait, Semaphore image_available) const noexcept + auto SwapChain::acquire_next_image(std::chrono::nanoseconds wait, view::Semaphore image_available) const noexcept -> Expected { - return SwapChainAPI::acquire_next_image(*this, std::move(wait), std::move(image_available)) + return SwapChainAPI::acquire_next_image(*this, std::move(wait), std::move(image_available)); } -} // namespace view + + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + auto SwapChain::acquire_next_image(std::chrono::nanoseconds wait, Semaphore image_available) const noexcept + -> Expected { + return SwapChainAPI::acquire_next_image(*this, std::move(wait), std::move(image_available)); + } + } // namespace view } // namespace stormkit::gpu From a5da65b529abee9c59cfdb8cb2b776039de4380f Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 16 Mar 2026 19:30:18 +0100 Subject: [PATCH 167/194] (core) some fixes --- modules/stormkit/core/meta/algorithms.cppm | 17 ++++++++++++++++- modules/stormkit/core/meta/concepts.cppm | 2 +- modules/stormkit/core/meta/type_query.cppm | 11 ++++++++++- modules/stormkit/core/typesafe/byte.cppm | 2 +- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/modules/stormkit/core/meta/algorithms.cppm b/modules/stormkit/core/meta/algorithms.cppm index 435f3c570..d00e5cf1f 100644 --- a/modules/stormkit/core/meta/algorithms.cppm +++ b/modules/stormkit/core/meta/algorithms.cppm @@ -12,9 +12,24 @@ import std; import :meta.concepts; +namespace stormkit { inline namespace core { namespace meta::details { + template + struct If; + + template + struct If { + using Type = IfRes; + }; + + template + struct If { + using Type = ElseRes; + }; +}}} // namespace stormkit::core::meta::details + export namespace stormkit { inline namespace core { namespace meta { template - using If = std::conditional_t; + using If = details::If::Type; template using Select = std::conditional_t; diff --git a/modules/stormkit/core/meta/concepts.cppm b/modules/stormkit/core/meta/concepts.cppm index 40d78a6f7..1b6a3c9b2 100644 --- a/modules/stormkit/core/meta/concepts.cppm +++ b/modules/stormkit/core/meta/concepts.cppm @@ -184,7 +184,7 @@ export namespace stormkit { inline namespace core { namespace meta { concept IsNotPointer = not IsPointer; template - concept IsPointerOf = IsPointer and SameAs; + concept IsPointerOf = IsPointer and SameAs::element_type, U>; template concept IsMovedOwningPointer = IsOwningPointer and IsRValueReference; diff --git a/modules/stormkit/core/meta/type_query.cppm b/modules/stormkit/core/meta/type_query.cppm index 034cbd62f..11df747d9 100644 --- a/modules/stormkit/core/meta/type_query.cppm +++ b/modules/stormkit/core/meta/type_query.cppm @@ -86,6 +86,15 @@ namespace stormkit { inline namespace core { namespace meta { struct ContainedType { using Type = typename T::value_type; }; + + template + struct ContainedOrPointedType; + + template + struct ContainedOrPointedType: ContainedType {}; + + template + struct ContainedOrPointedType: PointedType {}; } // namespace details export { @@ -102,7 +111,7 @@ namespace stormkit { inline namespace core { namespace meta { using ContainedType = details::ContainedType::Type; template - using ContainedOrPointedType = If, ContainedType, PointedType>; + using ContainedOrPointedType = details::ContainedOrPointedType::Type; template using IteratorType = stdr::iterator_t; diff --git a/modules/stormkit/core/typesafe/byte.cppm b/modules/stormkit/core/typesafe/byte.cppm index 789295044..be1f5b5fa 100644 --- a/modules/stormkit/core/typesafe/byte.cppm +++ b/modules/stormkit/core/typesafe/byte.cppm @@ -90,7 +90,7 @@ export namespace stormkit { inline namespace core { constexpr auto bytes_as(std::span bytes) noexcept -> const T&; template - requires(meta::SameAs, byte>) + requires(meta::SameAs>, byte>) [[nodiscard]] constexpr auto bytes_as_span(const Range& bytes) noexcept -> std::span; From f918a492fd66b7d5ec81aabaffbf46a83eb95900 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 16 Mar 2026 19:35:53 +0100 Subject: [PATCH 168/194] (core) rename Ref to ref --- examples/gpu/imgui/src/main.cpp | 2 +- examples/gpu/textured_cube/src/main.cpp | 2 +- modules/stormkit/core/containers/dag.cppm | 6 +- modules/stormkit/core/parallelism/locked.cppm | 2 +- modules/stormkit/core/typesafe/ref.cppm | 278 +++++++++--------- modules/stormkit/entities.cppm | 16 +- .../stormkit/gpu/core/physical_device.cppm | 2 +- .../gpu/execution/command_buffer.cppm | 2 +- modules/stormkit/gpu/resource/buffer.cppm | 16 +- src/wsi/common/window_base.cppm | 2 +- src/wsi/linux/x11/context.cpp | 6 +- src/wsi/linux/x11/context.cppm | 4 +- tests/core/typesafe/ref.cpp | 16 +- 13 files changed, 177 insertions(+), 177 deletions(-) diff --git a/examples/gpu/imgui/src/main.cpp b/examples/gpu/imgui/src/main.cpp index 9018fdd70..28d819592 100644 --- a/examples/gpu/imgui/src/main.cpp +++ b/examples/gpu/imgui/src/main.cpp @@ -30,7 +30,7 @@ struct SubmissionResource { }; struct SwapchainImageResource { - Ref image; + ref image; gpu::ImageView view; gpu::Semaphore render_finished; }; diff --git a/examples/gpu/textured_cube/src/main.cpp b/examples/gpu/textured_cube/src/main.cpp index 131682f3d..c04a29528 100644 --- a/examples/gpu/textured_cube/src/main.cpp +++ b/examples/gpu/textured_cube/src/main.cpp @@ -41,7 +41,7 @@ struct SubmissionResource { }; struct SwapchainImageResource { - Ref image; + ref image; gpu::ImageView view; gpu::Image depth_image; gpu::ImageView depth_view; diff --git a/modules/stormkit/core/containers/dag.cppm b/modules/stormkit/core/containers/dag.cppm index 0018153ec..e748b1e3a 100644 --- a/modules/stormkit/core/containers/dag.cppm +++ b/modules/stormkit/core/containers/dag.cppm @@ -105,7 +105,7 @@ export namespace stormkit { inline namespace core { constexpr auto topological_sort() const noexcept -> std::expected, std::vector>; constexpr auto find_cycle() const noexcept -> std::optional>; - constexpr auto reverse_view() const noexcept -> DAG>; + constexpr auto reverse_view() const noexcept -> DAG>; constexpr auto reverse_clone() const noexcept -> DAG; constexpr auto dump(Closures closures = {}) const noexcept -> std::string; @@ -487,8 +487,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - constexpr auto DAG::reverse_view() const noexcept -> DAG> { - return DAG>::template reverse_from, true>(m_next_id, m_vertices, m_edges); + constexpr auto DAG::reverse_view() const noexcept -> DAG> { + return DAG>::template reverse_from, true>(m_next_id, m_vertices, m_edges); } //////////////////////////////////////// diff --git a/modules/stormkit/core/parallelism/locked.cppm b/modules/stormkit/core/parallelism/locked.cppm index 5cc419859..b964a3a71 100644 --- a/modules/stormkit/core/parallelism/locked.cppm +++ b/modules/stormkit/core/parallelism/locked.cppm @@ -99,7 +99,7 @@ export namespace stormkit { inline namespace core { class Access { public: using AccessValueType = std::conditional_t; - using RefContainerType = std::conditional_t, Ref>; + using RefContainerType = std::conditional_t, ref>; template Access(ReferenceType value, MutexType& mutex, LockArgs&&... args) noexcept; diff --git a/modules/stormkit/core/typesafe/ref.cppm b/modules/stormkit/core/typesafe/ref.cppm index 583e1d575..5955fd653 100644 --- a/modules/stormkit/core/typesafe/ref.cppm +++ b/modules/stormkit/core/typesafe/ref.cppm @@ -29,59 +29,59 @@ export { using owned_ptr = T*; template - class Ref; + class ref; template - using OptionalRef = Ref; + using optref = ref; inline constexpr struct Raw { } RAW; template - class Ref { + class ref { public: using ElementType = T; - using ReferenceType = ElementType&; + using referenceType = ElementType&; using PointerType = ElementType*; // STL compatible using element_type = ElementType; using pointer = PointerType; - constexpr Ref(std::nullopt_t) noexcept + constexpr ref(std::nullopt_t) noexcept requires(Optional == true); - constexpr Ref(std::nullptr_t) noexcept + constexpr ref(std::nullptr_t) noexcept requires(Optional == true); - constexpr Ref() noexcept + constexpr ref() noexcept requires(Optional == true); - constexpr ~Ref() noexcept; + constexpr ~ref() noexcept; template U, bool OptionalU> requires(not(meta::IsConst and not meta::IsConst)) - constexpr Ref(const Ref&) noexcept; + constexpr ref(const ref&) noexcept; template U, bool OptionalU> requires(not(meta::IsConst and not meta::IsConst)) - constexpr Ref(Ref&&) noexcept; + constexpr ref(ref&&) noexcept; - constexpr auto operator=(const Ref&) noexcept -> Ref& = delete; + constexpr auto operator=(const ref&) noexcept -> ref& = delete; template U, bool OptionalU> requires(not(meta::IsConst and not meta::IsConst)) - constexpr auto operator=(Ref&& other) noexcept -> decltype(auto); + constexpr auto operator=(ref&& other) noexcept -> decltype(auto); [[nodiscard]] constexpr auto get() const noexcept STORMKIT_LIFETIMEBOUND -> PointerType; [[nodiscard]] constexpr auto operator->() const noexcept STORMKIT_LIFETIMEBOUND->PointerType; [[nodiscard]] - constexpr auto operator*() const noexcept STORMKIT_LIFETIMEBOUND->ReferenceType; + constexpr auto operator*() const noexcept STORMKIT_LIFETIMEBOUND->referenceType; constexpr explicit operator bool() const noexcept; [[nodiscard]] constexpr auto has_value() const noexcept -> Boolean; [[nodiscard]] - constexpr operator ReferenceType() const noexcept STORMKIT_LIFETIMEBOUND; + constexpr operator referenceType() const noexcept STORMKIT_LIFETIMEBOUND; [[nodiscard]] constexpr operator PointerType() const noexcept STORMKIT_LIFETIMEBOUND; @@ -97,8 +97,8 @@ export { constexpr auto operator>=(std::nullptr_t) const noexcept -> bool; [[nodiscard]] constexpr auto operator<=>(std::nullptr_t) const noexcept - -> std::compare_three_way_result_t::PointerType, typename Ref::PointerType> - requires std::three_way_comparable::PointerType, typename Ref::PointerType> + -> std::compare_three_way_result_t::PointerType, typename ref::PointerType> + requires std::three_way_comparable::PointerType, typename ref::PointerType> ; [[nodiscard]] @@ -118,175 +118,175 @@ export { requires(Optional == true); [[nodiscard]] constexpr auto operator<=>(std::nullopt_t) const noexcept - -> std::compare_three_way_result_t::PointerType, typename Ref::PointerType> - requires(std::three_way_comparable::PointerType, typename Ref::PointerType> + -> std::compare_three_way_result_t::PointerType, typename ref::PointerType> + requires(std::three_way_comparable::PointerType, typename ref::PointerType> and Optional == true); template [[nodiscard]] - constexpr auto operator==(const Ref&) const noexcept -> bool; + constexpr auto operator==(const ref&) const noexcept -> bool; template [[nodiscard]] - constexpr auto operator<(const Ref&) const noexcept -> bool; + constexpr auto operator<(const ref&) const noexcept -> bool; template [[nodiscard]] - constexpr auto operator<=(const Ref&) const noexcept -> bool; + constexpr auto operator<=(const ref&) const noexcept -> bool; template [[nodiscard]] - constexpr auto operator>(const Ref&) const noexcept -> bool; + constexpr auto operator>(const ref&) const noexcept -> bool; template [[nodiscard]] - constexpr auto operator>=(const Ref&) const noexcept -> bool; + constexpr auto operator>=(const ref&) const noexcept -> bool; template - requires std::three_way_comparable::PointerType, - typename Ref::PointerType> + requires std::three_way_comparable::PointerType, + typename ref::PointerType> [[nodiscard]] - constexpr auto operator<=>(const Ref& other) const noexcept - -> std::compare_three_way_result_t::PointerType, typename Ref::PointerType>; + constexpr auto operator<=>(const ref& other) const noexcept + -> std::compare_three_way_result_t::PointerType, typename ref::PointerType>; [[nodiscard]] constexpr operator std::reference_wrapper() const noexcept; private: - constexpr Ref(ReferenceType value STORMKIT_LIFETIMEBOUND) noexcept; - constexpr Ref(PointerType value STORMKIT_LIFETIMEBOUND) noexcept; + constexpr ref(referenceType value STORMKIT_LIFETIMEBOUND) noexcept; + constexpr ref(PointerType value STORMKIT_LIFETIMEBOUND) noexcept; - friend class Ref; - friend class Ref, T, const T>, not Optional>; + friend class ref; + friend class ref, T, const T>, not Optional>; PointerType m_value; template - friend constexpr auto as_ref_raw(const U&) noexcept -> Ref; + friend constexpr auto as_ref_raw(const U&) noexcept -> ref; template requires(not meta::IsConst) - friend constexpr auto as_ref_mut_raw(U&) noexcept -> Ref; + friend constexpr auto as_ref_mut_raw(U&) noexcept -> ref; template - friend constexpr auto as_ref_like_raw(U&) noexcept -> Ref; + friend constexpr auto as_ref_like_raw(U&) noexcept -> ref; template - friend constexpr auto as_optref_raw(const U&) noexcept -> OptionalRef; + friend constexpr auto as_optref_raw(const U&) noexcept -> optref; template requires(not meta::IsConst) - friend constexpr auto as_optref_mut_raw(U&) noexcept -> OptionalRef; + friend constexpr auto as_optref_mut_raw(U&) noexcept -> optref; template - friend constexpr auto as_optref_like_raw(U&) noexcept -> OptionalRef; + friend constexpr auto as_optref_like_raw(U&) noexcept -> optref; }; template [[nodiscard]] - constexpr auto as_ref_raw(const T& value) noexcept -> Ref; + constexpr auto as_ref_raw(const T& value) noexcept -> ref; template requires(not meta::IsContainerOrPointer) [[nodiscard]] - constexpr auto as_ref(const T& value) noexcept -> Ref; + constexpr auto as_ref(const T& value) noexcept -> ref; template [[nodiscard]] - constexpr auto as_ref(const T& value) noexcept -> Ref>; + constexpr auto as_ref(const T& value) noexcept -> ref>; template [[nodiscard]] - constexpr auto as_ref(const T& value) noexcept -> Ref>; + constexpr auto as_ref(const T& value) noexcept -> ref>; template [[nodiscard]] - constexpr auto as_ref_mut_raw(const T& value) noexcept -> Ref; + constexpr auto as_ref_mut_raw(const T& value) noexcept -> ref; template requires(not meta::IsContainerOrPointer and not meta::IsConst) [[nodiscard]] - constexpr auto as_ref_mut(T& value) noexcept -> Ref; + constexpr auto as_ref_mut(T& value) noexcept -> ref; template requires(not meta::IsConst>) [[nodiscard]] - constexpr auto as_ref_mut(T& value) noexcept -> Ref>; + constexpr auto as_ref_mut(T& value) noexcept -> ref>; template requires(not meta::IsConst>) [[nodiscard]] - constexpr auto as_ref_mut(T& value) noexcept -> Ref>; + constexpr auto as_ref_mut(T& value) noexcept -> ref>; template [[nodiscard]] - constexpr auto as_ref_mut_like(const T& value) noexcept -> Ref; + constexpr auto as_ref_mut_like(const T& value) noexcept -> ref; template [[nodiscard]] - constexpr auto as_ref_like_raw(T& value) noexcept -> Ref; + constexpr auto as_ref_like_raw(T& value) noexcept -> ref; template requires(not meta::IsContainerOrPointer) [[nodiscard]] - constexpr auto as_ref_like(T& value) noexcept -> Ref; + constexpr auto as_ref_like(T& value) noexcept -> ref; template [[nodiscard]] - constexpr auto as_ref_like(T& value) noexcept -> Ref>; + constexpr auto as_ref_like(T& value) noexcept -> ref>; template [[nodiscard]] - constexpr auto as_ref_like(T& value) noexcept -> Ref>; + constexpr auto as_ref_like(T& value) noexcept -> ref>; template [[nodiscard]] - constexpr auto as_optref_raw(const T& value) noexcept -> OptionalRef; + constexpr auto as_optref_raw(const T& value) noexcept -> optref; template requires(not meta::IsContainerOrPointer) [[nodiscard]] - constexpr auto as_optref(const T& value) noexcept -> OptionalRef; + constexpr auto as_optref(const T& value) noexcept -> optref; template [[nodiscard]] - constexpr auto as_optref(const T& value) noexcept -> OptionalRef>; + constexpr auto as_optref(const T& value) noexcept -> optref>; template [[nodiscard]] - constexpr auto as_optref(const T& value) noexcept -> OptionalRef>; + constexpr auto as_optref(const T& value) noexcept -> optref>; template requires(not meta::IsConst) [[nodiscard]] - constexpr auto as_optref_mut_raw(T& value) noexcept -> OptionalRef; + constexpr auto as_optref_mut_raw(T& value) noexcept -> optref; template requires(not meta::IsContainerOrPointer and not meta::IsConst) [[nodiscard]] - constexpr auto as_optref_mut(T& value) noexcept -> OptionalRef; + constexpr auto as_optref_mut(T& value) noexcept -> optref; template requires(not meta::IsConst>) [[nodiscard]] - constexpr auto as_optref_mut(T& value) noexcept -> OptionalRef>; + constexpr auto as_optref_mut(T& value) noexcept -> optref>; template requires(not meta::IsConst>) [[nodiscard]] - constexpr auto as_optref_mut(T& value) noexcept -> OptionalRef>; + constexpr auto as_optref_mut(T& value) noexcept -> optref>; template [[nodiscard]] - constexpr auto as_optref_like_raw(T& value) noexcept -> OptionalRef; + constexpr auto as_optref_like_raw(T& value) noexcept -> optref; template requires(not meta::IsContainerOrPointer) [[nodiscard]] - constexpr auto as_optref_like(T& value) noexcept -> OptionalRef; + constexpr auto as_optref_like(T& value) noexcept -> optref; template [[nodiscard]] - constexpr auto as_optref_like(T& value) noexcept -> OptionalRef>; + constexpr auto as_optref_like(T& value) noexcept -> optref>; template [[nodiscard]] - constexpr auto as_optref_like(T& value) noexcept -> OptionalRef>; + constexpr auto as_optref_like(T& value) noexcept -> optref>; template [[nodiscard]] @@ -358,16 +358,16 @@ export { constexpr auto to_mut_opt_refs(T& range) noexcept -> decltype(auto); template - constexpr auto hasher(const Ref& value) noexcept -> Ret; + constexpr auto hasher(const ref& value) noexcept -> Ret; template - auto format_as(const Ref& value, FormatContext& ctx) noexcept -> decltype(ctx.out()); + auto format_as(const ref& value, FormatContext& ctx) noexcept -> decltype(ctx.out()); }} // namespace stormkit::core template - struct std::pointer_traits> { - using pointer = typename stormkit::Ref::PointerType; - using element_type = typename stormkit::Ref::ElementType; + struct std::pointer_traits> { + using pointer = typename stormkit::ref::PointerType; + using element_type = typename stormkit::ref::ElementType; using difference_type = std::ptrdiff_t; }; } @@ -381,7 +381,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr Ref::Ref() noexcept + constexpr ref::ref() noexcept requires(Optional == true) : m_value { nullptr } { } @@ -390,7 +390,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr Ref::Ref(std::nullopt_t) noexcept + constexpr ref::ref(std::nullopt_t) noexcept requires(Optional == true) : m_value { nullptr } { } @@ -399,7 +399,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr Ref::Ref(std::nullptr_t) noexcept + constexpr ref::ref(std::nullptr_t) noexcept requires(Optional == true) : m_value { nullptr } { } @@ -408,7 +408,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr Ref::Ref(ReferenceType value) noexcept + constexpr ref::ref(referenceType value) noexcept : m_value { &value } { } @@ -416,7 +416,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr Ref::Ref(PointerType value) noexcept + constexpr ref::ref(PointerType value) noexcept : m_value { value } { EXPECTS(m_value != nullptr); } @@ -425,7 +425,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr Ref::~Ref() noexcept = default; + constexpr ref::~ref() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// @@ -433,7 +433,7 @@ namespace stormkit { inline namespace core { template U, bool OptionalU> requires(not(meta::IsConst and not meta::IsConst)) STORMKIT_FORCE_INLINE - constexpr Ref::Ref(const Ref& other) noexcept + constexpr ref::ref(const ref& other) noexcept : m_value { other.m_value } { } @@ -443,7 +443,7 @@ namespace stormkit { inline namespace core { template U, bool OptionalU> requires(not(meta::IsConst and not meta::IsConst)) STORMKIT_FORCE_INLINE - constexpr Ref::Ref(Ref&& other) noexcept + constexpr ref::ref(ref&& other) noexcept : m_value { std::exchange(other.m_value, nullptr) } { } @@ -452,7 +452,7 @@ namespace stormkit { inline namespace core { template template U, bool OptionalU> requires(not(meta::IsConst and not meta::IsConst)) - constexpr auto Ref::operator=(Ref&& other) noexcept -> decltype(auto) { + constexpr auto ref::operator=(ref&& other) noexcept -> decltype(auto) { if constexpr (meta::SameAs and Optional == OptionalU) if (&other == this) return *this; @@ -465,7 +465,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto Ref::get() const noexcept -> PointerType { + constexpr auto ref::get() const noexcept -> PointerType { return m_value; } @@ -473,7 +473,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator->() const noexcept -> PointerType { + constexpr auto ref::operator->() const noexcept -> PointerType { EXPECTS(m_value != nullptr); return get(); } @@ -482,7 +482,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator*() const noexcept -> ReferenceType { + constexpr auto ref::operator*() const noexcept -> referenceType { EXPECTS(m_value != nullptr); return *get(); } @@ -491,7 +491,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr Ref::operator bool() const noexcept { + constexpr ref::operator bool() const noexcept { return m_value != nullptr; } @@ -499,7 +499,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto Ref::has_value() const noexcept -> Boolean { + constexpr auto ref::has_value() const noexcept -> Boolean { return operator bool(); } @@ -507,7 +507,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr Ref::operator ReferenceType() const noexcept { + constexpr ref::operator referenceType() const noexcept { EXPECTS(m_value != nullptr); return *m_value; } @@ -516,7 +516,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr Ref::operator PointerType() const noexcept { + constexpr ref::operator PointerType() const noexcept { return m_value; } @@ -524,7 +524,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator==(std::nullptr_t) const noexcept -> bool { + constexpr auto ref::operator==(std::nullptr_t) const noexcept -> bool { return !m_value; } @@ -532,15 +532,15 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator<(std::nullptr_t) const noexcept -> bool { - return std::less::pointer> {}(m_value, nullptr); + constexpr auto ref::operator<(std::nullptr_t) const noexcept -> bool { + return std::less::pointer> {}(m_value, nullptr); } ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator<=(std::nullptr_t) const noexcept -> bool { + constexpr auto ref::operator<=(std::nullptr_t) const noexcept -> bool { return !(nullptr < *this); } @@ -548,7 +548,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator>(std::nullptr_t) const noexcept -> bool { + constexpr auto ref::operator>(std::nullptr_t) const noexcept -> bool { return nullptr < *this; } @@ -556,7 +556,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator>=(std::nullptr_t) const noexcept -> bool { + constexpr auto ref::operator>=(std::nullptr_t) const noexcept -> bool { return !(*this < nullptr); } @@ -564,19 +564,19 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator<=>(std::nullptr_t) const noexcept - -> std::compare_three_way_result_t::PointerType, typename Ref::PointerType> - requires std::three_way_comparable::PointerType, typename Ref::PointerType> + constexpr auto ref::operator<=>(std::nullptr_t) const noexcept + -> std::compare_three_way_result_t::PointerType, typename ref::PointerType> + requires std::three_way_comparable::PointerType, typename ref::PointerType> { - return std::compare_three_way {}(m_value, static_cast::pointer>(nullptr)); + return std::compare_three_way {}(m_value, static_cast::pointer>(nullptr)); } ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator==(std::nullopt_t) const noexcept -> bool + constexpr auto ref::operator==(std::nullopt_t) const noexcept -> bool requires(Optional == true) { return !m_value; @@ -586,17 +586,17 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator<(std::nullopt_t) const noexcept -> bool + constexpr auto ref::operator<(std::nullopt_t) const noexcept -> bool requires(Optional == true) { - return std::less::pointer> {}(m_value, std::nullopt); + return std::less::pointer> {}(m_value, std::nullopt); } ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator<=(std::nullopt_t) const noexcept -> bool + constexpr auto ref::operator<=(std::nullopt_t) const noexcept -> bool requires(Optional == true) { return !(std::nullopt < *this); @@ -606,7 +606,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator>(std::nullopt_t) const noexcept -> bool + constexpr auto ref::operator>(std::nullopt_t) const noexcept -> bool requires(Optional == true) { return std::nullopt < *this; @@ -616,7 +616,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator>=(std::nullopt_t) const noexcept -> bool + constexpr auto ref::operator>=(std::nullopt_t) const noexcept -> bool requires(Optional == true) { return !(*this < std::nullopt); @@ -626,12 +626,12 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator<=>(std::nullopt_t) const noexcept - -> std::compare_three_way_result_t::PointerType, typename Ref::PointerType> - requires(std::three_way_comparable::PointerType, typename Ref::PointerType> + constexpr auto ref::operator<=>(std::nullopt_t) const noexcept + -> std::compare_three_way_result_t::PointerType, typename ref::PointerType> + requires(std::three_way_comparable::PointerType, typename ref::PointerType> and Optional == true) { - return std::compare_three_way {}(m_value, static_cast::pointer>(std::nullopt)); + return std::compare_three_way {}(m_value, static_cast::pointer>(std::nullopt)); } ///////////////////////////////////// @@ -639,7 +639,7 @@ namespace stormkit { inline namespace core { template template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator==(const Ref& other) const noexcept -> bool { + constexpr auto ref::operator==(const ref& other) const noexcept -> bool { return m_value == other.m_value; } @@ -648,9 +648,9 @@ namespace stormkit { inline namespace core { template template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator<(const Ref& other) const noexcept -> bool { + constexpr auto ref::operator<(const ref& other) const noexcept -> bool { return std::less< - std::common_type_t::PointerType, typename Ref::PointerType>> {}(m_value, other.m_value); + std::common_type_t::PointerType, typename ref::PointerType>> {}(m_value, other.m_value); } ///////////////////////////////////// @@ -658,7 +658,7 @@ namespace stormkit { inline namespace core { template template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator<=(const Ref& other) const noexcept -> bool { + constexpr auto ref::operator<=(const ref& other) const noexcept -> bool { return !(other < *this); } @@ -667,7 +667,7 @@ namespace stormkit { inline namespace core { template template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator>(const Ref& other) const noexcept -> bool { + constexpr auto ref::operator>(const ref& other) const noexcept -> bool { return other < *this; } @@ -676,7 +676,7 @@ namespace stormkit { inline namespace core { template template STORMKIT_FORCE_INLINE - constexpr auto Ref::operator>=(const Ref& other) const noexcept -> bool { + constexpr auto ref::operator>=(const ref& other) const noexcept -> bool { return !(*this < other); } @@ -684,10 +684,10 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template template - requires std::three_way_comparable::PointerType, typename Ref::PointerType> + requires std::three_way_comparable::PointerType, typename ref::PointerType> STORMKIT_FORCE_INLINE - constexpr auto Ref::operator<=>(const Ref& other) const noexcept - -> std::compare_three_way_result_t::PointerType, typename Ref::PointerType> { + constexpr auto ref::operator<=>(const ref& other) const noexcept + -> std::compare_three_way_result_t::PointerType, typename ref::PointerType> { return m_value <=> other.m_value; } @@ -695,7 +695,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr Ref::operator std::reference_wrapper() const noexcept { + constexpr ref::operator std::reference_wrapper() const noexcept { if constexpr (meta::IsConst) return std::cref(*m_value); else return std::ref(*m_value); @@ -705,7 +705,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto as_ref_raw(const T& value) noexcept -> Ref { + constexpr auto as_ref_raw(const T& value) noexcept -> ref { return { std::addressof(value) }; } @@ -714,7 +714,7 @@ namespace stormkit { inline namespace core { template requires(not meta::IsContainerOrPointer) STORMKIT_FORCE_INLINE - constexpr auto as_ref(const T& value) noexcept -> Ref { + constexpr auto as_ref(const T& value) noexcept -> ref { return as_ref_raw(value); } @@ -722,7 +722,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto as_ref(const T& value) noexcept -> Ref> { + constexpr auto as_ref(const T& value) noexcept -> ref> { EXPECTS(value != nullptr); return as_ref(unref(value)); } @@ -731,7 +731,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto as_ref(const T& value) noexcept -> Ref> { + constexpr auto as_ref(const T& value) noexcept -> ref> { EXPECTS(value.operator bool()); return as_ref(value.value()); } @@ -741,7 +741,7 @@ namespace stormkit { inline namespace core { template requires(not meta::IsConst) STORMKIT_FORCE_INLINE - constexpr auto as_ref_mut_raw(T& value) noexcept -> Ref { + constexpr auto as_ref_mut_raw(T& value) noexcept -> ref { return { std::addressof(value) }; } @@ -750,7 +750,7 @@ namespace stormkit { inline namespace core { template requires(not meta::IsContainerOrPointer and not meta::IsConst) STORMKIT_FORCE_INLINE - constexpr auto as_ref_mut(T& value) noexcept -> Ref { + constexpr auto as_ref_mut(T& value) noexcept -> ref { return as_ref_mut_raw(value); } @@ -759,7 +759,7 @@ namespace stormkit { inline namespace core { template requires(not meta::IsConst>) STORMKIT_FORCE_INLINE - constexpr auto as_ref_mut(T& value) noexcept -> Ref> { + constexpr auto as_ref_mut(T& value) noexcept -> ref> { EXPECTS(value != nullptr); return as_ref_mut(unref_mut(value)); } @@ -769,7 +769,7 @@ namespace stormkit { inline namespace core { template requires(not meta::IsConst>) STORMKIT_FORCE_INLINE - constexpr auto as_ref_mut(T& value) noexcept -> Ref> { + constexpr auto as_ref_mut(T& value) noexcept -> ref> { if constexpr (requires { value.has_value(); }) EXPECTS(value.has_value()); return as_ref_mut(value.value()); } @@ -778,7 +778,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto as_ref_like_raw(T& value) noexcept -> Ref { + constexpr auto as_ref_like_raw(T& value) noexcept -> ref { return { std::addressof(value) }; } @@ -787,7 +787,7 @@ namespace stormkit { inline namespace core { template requires(not meta::IsContainerOrPointer) STORMKIT_FORCE_INLINE - constexpr auto as_ref_like(T& value, Raw) noexcept -> Ref { + constexpr auto as_ref_like(T& value, Raw) noexcept -> ref { return as_ref_like_raw(value); } @@ -795,7 +795,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto as_ref_like(T& value) noexcept -> Ref> { + constexpr auto as_ref_like(T& value) noexcept -> ref> { EXPECTS(value != nullptr); if (meta::IsConst>) return as_ref_like(unref(value)); else @@ -806,7 +806,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto as_ref_like(T& value) noexcept -> Ref> { + constexpr auto as_ref_like(T& value) noexcept -> ref> { if constexpr (requires { value.has_value(); }) EXPECTS(value.has_value()); return as_ref_like(value.value()); } @@ -815,7 +815,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto as_optref_raw(const T& value) noexcept -> OptionalRef { + constexpr auto as_optref_raw(const T& value) noexcept -> optref { return { std::addressof(value) }; } @@ -824,7 +824,7 @@ namespace stormkit { inline namespace core { template requires(not meta::IsContainerOrPointer) STORMKIT_FORCE_INLINE - constexpr auto as_optref(const T& value) noexcept -> OptionalRef { + constexpr auto as_optref(const T& value) noexcept -> optref { return as_optref_raw(value); } @@ -832,7 +832,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto as_optref(const T& value) noexcept -> OptionalRef> { + constexpr auto as_optref(const T& value) noexcept -> optref> { EXPECTS(value != nullptr); return as_optref(unref(value)); } @@ -841,7 +841,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto as_optref(const T& value) noexcept -> OptionalRef> { + constexpr auto as_optref(const T& value) noexcept -> optref> { EXPECTS(value.operator bool()); return as_optref(value.value()); } @@ -851,7 +851,7 @@ namespace stormkit { inline namespace core { template requires(not meta::IsConst) STORMKIT_FORCE_INLINE - constexpr auto as_optref_mut_raw(T& value) noexcept -> OptionalRef { + constexpr auto as_optref_mut_raw(T& value) noexcept -> optref { return { std::addressof(value) }; } @@ -860,7 +860,7 @@ namespace stormkit { inline namespace core { template requires(not meta::IsContainerOrPointer and not meta::IsConst) STORMKIT_FORCE_INLINE - constexpr auto as_optref_mut(T& value) noexcept -> OptionalRef { + constexpr auto as_optref_mut(T& value) noexcept -> optref { return as_optref_mut(value); } @@ -869,7 +869,7 @@ namespace stormkit { inline namespace core { template requires(not meta::IsConst>) STORMKIT_FORCE_INLINE - constexpr auto as_optref_mut(T& value) noexcept -> OptionalRef> { + constexpr auto as_optref_mut(T& value) noexcept -> optref> { EXPECTS(value != nullptr); return as_optref_mut(unref_mut(value)); } @@ -879,7 +879,7 @@ namespace stormkit { inline namespace core { template requires(not meta::IsConst>) STORMKIT_FORCE_INLINE - constexpr auto as_optref_mut(T& value) noexcept -> OptionalRef> { + constexpr auto as_optref_mut(T& value) noexcept -> optref> { if constexpr (requires { value.has_value(); }) EXPECTS(value.has_value()); return as_optref_mut(value.value()); } @@ -888,7 +888,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto as_optref_like_raw(T& value) noexcept -> OptionalRef { + constexpr auto as_optref_like_raw(T& value) noexcept -> optref { return { std::addressof(value) }; } @@ -897,7 +897,7 @@ namespace stormkit { inline namespace core { template requires(not meta::IsContainerOrPointer) STORMKIT_FORCE_INLINE - constexpr auto as_optref_like(T& value) noexcept -> OptionalRef { + constexpr auto as_optref_like(T& value) noexcept -> optref { return as_optref_like_raw(value); } @@ -905,7 +905,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto as_optref_like(T& value) noexcept -> OptionalRef> { + constexpr auto as_optref_like(T& value) noexcept -> optref> { EXPECTS(value != nullptr); if (meta::IsConst>) return as_optref_like(unref(value)); else @@ -916,7 +916,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto as_optref_like(T& value) noexcept -> OptionalRef> { + constexpr auto as_optref_like(T& value) noexcept -> optref> { if constexpr (requires { value.has_value(); }) EXPECTS(value.has_value()); return as_optref_like(value.value()); } @@ -1066,14 +1066,14 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto hasher(const Ref& value) noexcept -> Ret { + constexpr auto hasher(const ref& value) noexcept -> Ret { return hash(value.get()); } ///////////////////////////////////// ///////////////////////////////////// template - inline auto format_as(const Ref& value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { + inline auto format_as(const ref& value, FormatContext& ctx) noexcept -> decltype(ctx.out()) { if constexpr (Optional) { if (value == nullptr) return std::format_to(ctx.out(), "[ref value: null]"); else diff --git a/modules/stormkit/entities.cppm b/modules/stormkit/entities.cppm index fd5e71a54..d6f9e0d48 100644 --- a/modules/stormkit/entities.cppm +++ b/modules/stormkit/entities.cppm @@ -209,12 +209,12 @@ export namespace stormkit::entities { auto get_component(this Self& self, Entity entity, std::string_view) noexcept -> cmeta::ForwardConst&; template - auto components_of_type(this Self& self) noexcept -> std::vector>>; + auto components_of_type(this Self& self) noexcept -> std::vector>>; template - auto components_of_type(this Self& self, ComponentType type) noexcept -> std::vector>>; + auto components_of_type(this Self& self, ComponentType type) noexcept -> std::vector>>; template auto components_of_type(this Self& self, std::string_view name) noexcept - -> std::vector>>; + -> std::vector>>; auto components_types_of(Entity entity) const noexcept -> std::vector; @@ -225,7 +225,7 @@ export namespace stormkit::entities { auto remove_system(std::string_view name) noexcept -> void; template - auto systems(this Self& self) noexcept -> std::vector>>; + auto systems(this Self& self) noexcept -> std::vector>>; template auto get_system(this Self& self, std::string_view name) noexcept -> cmeta::ForwardConst; @@ -391,7 +391,7 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// template - auto EntityManager::components_of_type(this Self& self) noexcept -> std::vector>> { + auto EntityManager::components_of_type(this Self& self) noexcept -> std::vector>> { return self.template components_of_type(T::type()); } @@ -399,7 +399,7 @@ namespace stormkit::entities { ///////////////////////////////////// template auto EntityManager::components_of_type(this Self& self, ComponentType type) noexcept - -> std::vector>> { + -> std::vector>> { // clang-format off return self.m_entities | stdv::filter([&self, type](auto entity) noexcept { return self.has_component(entity, type); }) @@ -414,7 +414,7 @@ namespace stormkit::entities { ///////////////////////////////////// template auto EntityManager::components_of_type(this Self& self, std::string_view name) noexcept - -> std::vector>> { + -> std::vector>> { return self.template components_of_type(hash(name)); } @@ -491,7 +491,7 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// template - auto EntityManager::systems(this Self& self) noexcept -> std::vector>> { + auto EntityManager::systems(this Self& self) noexcept -> std::vector>> { constexpr auto as_refer = [] { if constexpr (cmeta::IsConst) return monadic::as_ref(); else diff --git a/modules/stormkit/gpu/core/physical_device.cppm b/modules/stormkit/gpu/core/physical_device.cppm index 3dc8bb23e..ce69e059b 100644 --- a/modules/stormkit/gpu/core/physical_device.cppm +++ b/modules/stormkit/gpu/core/physical_device.cppm @@ -128,7 +128,7 @@ export namespace stormkit::gpu { auto formats_properties() const noexcept -> std::span>; private: - Ref m_data; + ref m_data; std::span m_memory_types; std::span m_queue_families; diff --git a/modules/stormkit/gpu/execution/command_buffer.cppm b/modules/stormkit/gpu/execution/command_buffer.cppm index 8a8ef429a..be69ad630 100644 --- a/modules/stormkit/gpu/execution/command_buffer.cppm +++ b/modules/stormkit/gpu/execution/command_buffer.cppm @@ -182,7 +182,7 @@ export namespace stormkit::gpu { gpu::ImageLayout layout = ImageLayout::ATTACHMENT_OPTIMAL; }; - Ref image_view; + ref image_view; gpu::ImageLayout layout = ImageLayout::ATTACHMENT_OPTIMAL; std::optional resolve = std::nullopt; diff --git a/modules/stormkit/gpu/resource/buffer.cppm b/modules/stormkit/gpu/resource/buffer.cppm index 7f759d861..5eb3af7ad 100644 --- a/modules/stormkit/gpu/resource/buffer.cppm +++ b/modules/stormkit/gpu/resource/buffer.cppm @@ -78,7 +78,7 @@ export namespace stormkit::gpu { auto map(ioffset offset, usize size) noexcept -> Expected>; template - auto map_as(ioffset offset) noexcept -> Expected>; + auto map_as(ioffset offset) noexcept -> Expected>; bool mapped() const noexcept; @@ -92,7 +92,7 @@ export namespace stormkit::gpu { template [[nodiscard]] - auto data_as(this auto& self) noexcept -> Ref; + auto data_as(this auto& self) noexcept -> ref; auto flush(ioffset offset, usize size) noexcept -> Expected; auto unmap() noexcept -> void; @@ -161,7 +161,7 @@ export namespace stormkit::gpu { auto map(ioffset offset, usize size) noexcept -> Expected>; template - auto map_as(ioffset offset) noexcept -> Expected>; + auto map_as(ioffset offset) noexcept -> Expected>; bool mapped() const noexcept; @@ -175,7 +175,7 @@ export namespace stormkit::gpu { template [[nodiscard]] - auto data_as(this auto& self) noexcept -> Ref; + auto data_as(this auto& self) noexcept -> ref; auto flush(ioffset offset, usize size) noexcept -> Expected; auto unmap() noexcept -> void; @@ -296,7 +296,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Buffer::map_as(ioffset offset) noexcept -> Expected> { + inline auto Buffer::map_as(ioffset offset) noexcept -> Expected> { EXPECTS(m_vma_allocation and m_vk_handle); const auto ptr = Try(map(offset)); @@ -339,7 +339,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Buffer::data_as(this Self& self) noexcept -> Ref { + inline auto Buffer::data_as(this Self& self) noexcept -> ref { EXPECTS(self.m_vma_allocation and self.m_vk_handle); EXPECTS(self.m_mapped_pointer); @@ -460,7 +460,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Buffer::map_as(ioffset offset) noexcept -> Expected> { + inline auto Buffer::map_as(ioffset offset) noexcept -> Expected> { EXPECTS(m_vma_allocation and m_vk_handle); const auto ptr = Try(map(offset)); @@ -503,7 +503,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Buffer::data_as(this Self& self) noexcept -> Ref { + inline auto Buffer::data_as(this Self& self) noexcept -> ref { EXPECTS(self.m_vma_allocation and self.m_vk_handle); EXPECTS(self.m_mapped_pointer); diff --git a/src/wsi/common/window_base.cppm b/src/wsi/common/window_base.cppm index 89e7d26a5..e477b6e5b 100644 --- a/src/wsi/common/window_base.cppm +++ b/src/wsi/common/window_base.cppm @@ -101,7 +101,7 @@ export namespace stormkit::wsi::common { bool fullscreen = false; bool visible = false; math::uextent2 extent; - OptionalRef current_monitor; + optref current_monitor; std::string title; f32 dpi = 1.f; diff --git a/src/wsi/linux/x11/context.cpp b/src/wsi/linux/x11/context.cpp index 3151fe049..c08f54d9c 100644 --- a/src/wsi/linux/x11/context.cpp +++ b/src/wsi/linux/x11/context.cpp @@ -107,7 +107,7 @@ namespace stormkit::wsi::linux::x11::xcb { ///////////////////////////////////// ///////////////////////////////////// - auto get_error(Ref error) -> std::string { + auto get_error(ref error) -> std::string { auto guard = xcb::GenericError::take(error); const auto major = xcb_errors_get_name_for_major_code(globals.error_context, error->major_code); @@ -125,8 +125,8 @@ namespace stormkit::wsi::linux::x11::xcb { ///////////////////////////////////// ///////////////////////////////////// - auto get_xi_device_info(xcb_input_device_id_t device_id) -> std::expected, Error> { - auto out = std::expected, Error> { std::unexpect }; + auto get_xi_device_info(xcb_input_device_id_t device_id) -> std::expected, Error> { + auto out = std::expected, Error> { std::unexpect }; const auto cookie = xcb_input_xi_query_device(globals.connection, device_id); auto error = xcb::GenericError::empty(); diff --git a/src/wsi/linux/x11/context.cppm b/src/wsi/linux/x11/context.cppm index 43250beca..48a727c3c 100644 --- a/src/wsi/linux/x11/context.cppm +++ b/src/wsi/linux/x11/context.cppm @@ -34,9 +34,9 @@ export namespace stormkit::wsi::linux::x11::xcb { auto get_atom(std::string_view name, bool only_if_exists) noexcept -> std::expected; auto get_atom_name(xcb_atom_t atom) -> std::expected; - auto get_error(Ref error) -> std::string; + auto get_error(ref error) -> std::string; - auto get_xi_device_info(xcb_input_device_id_t device_id) -> std::expected, Error>; + auto get_xi_device_info(xcb_input_device_id_t device_id) -> std::expected, Error>; // template // auto get_xft_value(std::string_view name) -> std::optional; diff --git a/tests/core/typesafe/ref.cpp b/tests/core/typesafe/ref.cpp index f21148e7f..24c80ff42 100644 --- a/tests/core/typesafe/ref.cpp +++ b/tests/core/typesafe/ref.cpp @@ -15,7 +15,7 @@ namespace { auto _ = test::TestSuite { "Core.typesafe", { - { "Ref.to_refs.std_vector.all_ref", + { "ref.to_refs.std_vector.all_ref", [] static noexcept { auto a = 0; auto b = 1; @@ -29,7 +29,7 @@ namespace { auto i = 0; for (auto&& ref : refs) EXPECTS(*ref == i++); } }, - { "Ref.as_refs.std_array.all_ref", + { "ref.as_refs.std_array.all_ref", [] static noexcept { auto a = 0; auto b = 1; @@ -43,7 +43,7 @@ namespace { auto i = 0; for (auto&& ref : refs) EXPECTS(*ref == i++); } }, - { "Ref.as_refs.default.all_ref", + { "ref.as_refs.default.all_ref", [] static noexcept { auto a = 0; auto b = 1; @@ -57,7 +57,7 @@ namespace { auto i = 0; for (auto&& ref : refs) EXPECTS(*ref == i++); } }, - { "Ref.to_refs.std_vector.all_ptr", + { "ref.to_refs.std_vector.all_ptr", [] static noexcept { auto a = std::make_unique(0); auto b = std::make_unique(1); @@ -74,7 +74,7 @@ namespace { delete d; delete e; } }, - { "Ref.as_refs.std_array.all_ptr", + { "ref.as_refs.std_array.all_ptr", [] static noexcept { auto a = std::make_unique(0); auto b = std::make_unique(1); @@ -91,7 +91,7 @@ namespace { delete d; delete e; } }, - { "Ref.as_refs.default.all_ptr", + { "ref.as_refs.default.all_ptr", [] static noexcept { auto a = std::make_unique(0); auto b = std::make_unique(1); @@ -108,7 +108,7 @@ namespace { delete d; delete e; } }, - { "Ref.to_refs.std_set", + { "ref.to_refs.std_set", [] static noexcept { auto vec = std::vector { 1, 3, 5, 6, 9 }; auto refs = to_refs(vec); @@ -116,7 +116,7 @@ namespace { auto i = 0u; for (auto&& ref : refs) EXPECTS(*ref == vec[i++]); } }, - { "Ref.to_refs.default", + { "ref.to_refs.default", [] static noexcept { constexpr auto vec = std::array { 1, 3, 5, 6, 9 }; auto refs = to_refs(vec); From b87b6a2e766cb24b30c283a729b8b93c5a88df75 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 16 Mar 2026 19:41:29 +0100 Subject: [PATCH 169/194] (gpu) remove a warning --- modules/stormkit/gpu/resource/image.cppm | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/modules/stormkit/gpu/resource/image.cppm b/modules/stormkit/gpu/resource/image.cppm index 1fbb3a14e..d77ffa290 100644 --- a/modules/stormkit/gpu/resource/image.cppm +++ b/modules/stormkit/gpu/resource/image.cppm @@ -302,15 +302,18 @@ export namespace stormkit::gpu { auto allocation() const noexcept -> vk::Observer; private: - math::uextent3 m_extent = { 0, 0, 0 }; - PixelFormat m_format = {}; - u32 m_layers = 0; - u32 m_faces = 0; - u32 m_mip_levels = 0; - ImageType m_type = {}; - ImageCreateFlag m_flags = {}; - SampleCountFlag m_samples = {}; - ImageUsageFlag m_usages = {}; + math::uextent3 m_extent = { 0, 0, 0 }; + PixelFormat m_format = {}; + u32 m_layers = 0; + u32 m_faces = 0; + u32 m_mip_levels = 0; + ImageType m_type = {}; + STORMKIT_PUSH_WARNINGS +#pragma clang diagnostic ignored "-Wunused-private-field" + ImageCreateFlag m_flags = {}; + STORMKIT_POP_WARNINGS + SampleCountFlag m_samples = {}; + ImageUsageFlag m_usages = {}; vk::Observer m_vma_allocation = VK_NULL_HANDLE; }; From d7fcbcedbb0d616aa81a0869408ab54e69d0bc3a Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 16 Mar 2026 19:41:39 +0100 Subject: [PATCH 170/194] (gpu) ElementType => ValueType --- modules/stormkit/gpu/core/base.cppm | 34 +++++++++---------- modules/stormkit/gpu/core/debug_callback.cppm | 2 +- modules/stormkit/gpu/core/device.cppm | 12 +++---- modules/stormkit/gpu/core/instance.cppm | 12 +++---- .../stormkit/gpu/core/physical_device.cppm | 6 ++-- modules/stormkit/gpu/core/surface.cppm | 2 +- modules/stormkit/gpu/core/sync.cppm | 6 ++-- modules/stormkit/gpu/core/vulkan/structs.cppm | 4 +-- .../gpu/execution/command_buffer.cppm | 10 +++--- .../stormkit/gpu/execution/descriptors.cppm | 12 +++---- modules/stormkit/gpu/execution/pipeline.cppm | 8 ++--- .../stormkit/gpu/execution/render_pass.cppm | 8 ++--- modules/stormkit/gpu/execution/swapchain.cppm | 4 +-- modules/stormkit/gpu/resource/buffer.cppm | 4 +-- modules/stormkit/gpu/resource/image.cppm | 24 ++++++------- modules/stormkit/gpu/resource/shader.cppm | 4 +-- 16 files changed, 76 insertions(+), 76 deletions(-) diff --git a/modules/stormkit/gpu/core/base.cppm b/modules/stormkit/gpu/core/base.cppm index b626f687c..349a3add5 100644 --- a/modules/stormkit/gpu/core/base.cppm +++ b/modules/stormkit/gpu/core/base.cppm @@ -54,9 +54,9 @@ export namespace stormkit::gpu { namespace meta { template concept IsView = not IsOwned> and requires(T value) { - typename cmeta::CanonicalType::ElementType; + typename cmeta::CanonicalType::ValueType; typename cmeta::CanonicalType::ViewType; - { value.native_handle() } -> cmeta::Is::ElementType>; + { value.native_handle() } -> cmeta::Is::ValueType>; }; template @@ -78,9 +78,9 @@ export namespace stormkit::gpu { template class View { public: - using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; - using ViewType = ObjectInfo::ViewType; + using ObjectInfo = typename meta::ObjectInfo; + using ValueType = ObjectInfo::ValueType; + using ViewType = ObjectInfo::ViewType; View(const T& of) noexcept; template U> @@ -94,19 +94,19 @@ export namespace stormkit::gpu { auto operator=(View&&) noexcept -> View&; [[nodiscard]] - auto native_handle() const noexcept -> ElementType; + auto native_handle() const noexcept -> ValueType; - operator ElementType() const noexcept; + operator ValueType() const noexcept; protected: - ElementType m_vk_handle; + ValueType m_vk_handle; }; template class Owned { public: using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; + using ValueType = ObjectInfo::ValueType; using DeleterType = ObjectInfo::DeleterType; using ViewType = ObjectInfo::ViewType; @@ -167,9 +167,9 @@ export namespace stormkit::gpu { requires(not meta::CreateAllocateDisabled); [[nodiscard]] - auto native_handle() const noexcept -> ElementType; + auto native_handle() const noexcept -> ValueType; - operator ElementType() const noexcept; + operator ValueType() const noexcept; protected: static constexpr struct PrivateTag { @@ -177,7 +177,7 @@ export namespace stormkit::gpu { explicit Owned(DeleterType&& deleter_ptr) noexcept; - ElementType m_vk_handle; + ValueType m_vk_handle; DeleterType m_deleter_ptr; }; @@ -226,7 +226,7 @@ namespace stormkit::gpu { template STORMKIT_FORCE_INLINE inline Owned::~Owned() noexcept { - if constexpr (cmeta::SameAs) { + if constexpr (cmeta::SameAs) { if (m_deleter_ptr != nullptr and m_vk_handle != VK_NULL_HANDLE) vk::call(m_deleter_ptr, m_vk_handle, nullptr); m_vk_handle = VK_NULL_HANDLE; } @@ -259,7 +259,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Owned::native_handle() const noexcept -> ElementType { + inline auto Owned::native_handle() const noexcept -> ValueType { EXPECTS(m_vk_handle != VK_NULL_HANDLE); return m_vk_handle; } @@ -268,7 +268,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline Owned::operator ElementType() const noexcept { + inline Owned::operator ValueType() const noexcept { return native_handle(); } @@ -437,7 +437,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto View::native_handle() const noexcept -> ElementType { + inline auto View::native_handle() const noexcept -> ValueType { EXPECTS(m_vk_handle != VK_NULL_HANDLE); return m_vk_handle; } @@ -446,7 +446,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline View::operator ElementType() const noexcept { + inline View::operator ValueType() const noexcept { return native_handle(); } diff --git a/modules/stormkit/gpu/core/debug_callback.cppm b/modules/stormkit/gpu/core/debug_callback.cppm index e61be8ad3..e518612ef 100644 --- a/modules/stormkit/gpu/core/debug_callback.cppm +++ b/modules/stormkit/gpu/core/debug_callback.cppm @@ -31,7 +31,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = DebugCallback; - using ElementType = VkDebugUtilsMessengerEXT; + using ValueType = VkDebugUtilsMessengerEXT; using DeleterType = PFN_vkDestroyDebugUtilsMessengerEXT; using ViewType = view::DebugCallback; using OwnedBy = Instance; diff --git a/modules/stormkit/gpu/core/device.cppm b/modules/stormkit/gpu/core/device.cppm index a6c785d15..69e1835f1 100644 --- a/modules/stormkit/gpu/core/device.cppm +++ b/modules/stormkit/gpu/core/device.cppm @@ -39,7 +39,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = Device; - using ElementType = VkDevice; + using ValueType = VkDevice; using DeleterType = PFN_vkDestroyDevice VolkDeviceTable::*; using ViewType = view::Device; using OwnedBy = PhysicalDevice; @@ -158,9 +158,9 @@ export namespace stormkit::gpu { template class DeviceObject: public PhysicalDeviceObject { public: - using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; - using ViewType = ObjectInfo::ViewType; + using ObjectInfo = typename meta::ObjectInfo; + using ValueType = ObjectInfo::ValueType; + using ViewType = ObjectInfo::ViewType; DeviceObject(const T& child) noexcept; template U> @@ -185,7 +185,7 @@ export namespace stormkit::gpu { class OwnedByDevice: public OwnedByPhysicalDevice { public: using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; + using ValueType = ObjectInfo::ValueType; using DeleterType = ObjectInfo::DeleterType; using ViewType = ObjectInfo::ViewType; @@ -433,7 +433,7 @@ namespace stormkit::gpu { template STORMKIT_FORCE_INLINE inline OwnedByDevice::~OwnedByDevice() noexcept { - if constexpr (cmeta::SameAs) { + if constexpr (cmeta::SameAs) { const auto& device_table = device().device_table(); auto& vk_handle = Parent::m_vk_handle; auto& deleter_ptr = Parent::m_deleter_ptr; diff --git a/modules/stormkit/gpu/core/instance.cppm b/modules/stormkit/gpu/core/instance.cppm index 52023664b..0f7427799 100644 --- a/modules/stormkit/gpu/core/instance.cppm +++ b/modules/stormkit/gpu/core/instance.cppm @@ -36,7 +36,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = Instance; - using ElementType = VkInstance; + using ValueType = VkInstance; using DeleterType = PFN_vkDestroyInstance; using ViewType = view::Instance; @@ -75,9 +75,9 @@ export namespace stormkit::gpu { template class InstanceObject: public View { public: - using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; - using ViewType = ObjectInfo::ViewType; + using ObjectInfo = typename meta::ObjectInfo; + using ValueType = ObjectInfo::ValueType; + using ViewType = ObjectInfo::ViewType; InstanceObject(const T& child) noexcept; template U> @@ -102,7 +102,7 @@ export namespace stormkit::gpu { class OwnedByInstance: public Owned { public: using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; + using ValueType = ObjectInfo::ValueType; using DeleterType = ObjectInfo::DeleterType; using ViewType = ObjectInfo::ViewType; @@ -208,7 +208,7 @@ namespace stormkit::gpu { template STORMKIT_FORCE_INLINE inline OwnedByInstance::~OwnedByInstance() noexcept { - if constexpr (cmeta::SameAs) { + if constexpr (cmeta::SameAs) { auto& vk_handle = Parent::m_vk_handle; auto& deleter_ptr = Parent::m_deleter_ptr; if (deleter_ptr != nullptr and vk_handle != VK_NULL_HANDLE) vk::call(deleter_ptr, m_instance, vk_handle, nullptr); diff --git a/modules/stormkit/gpu/core/physical_device.cppm b/modules/stormkit/gpu/core/physical_device.cppm index ce69e059b..ad9171ddc 100644 --- a/modules/stormkit/gpu/core/physical_device.cppm +++ b/modules/stormkit/gpu/core/physical_device.cppm @@ -33,7 +33,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = PhysicalDevice; - using ElementType = VkPhysicalDevice; + using ValueType = VkPhysicalDevice; using DeleterType = decltype(monadic::noop()); using ViewType = view::PhysicalDevice; using OwnedBy = Instance; @@ -140,7 +140,7 @@ export namespace stormkit::gpu { class PhysicalDeviceObject: public InstanceObject { public: using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; + using ValueType = ObjectInfo::ValueType; using ViewType = ObjectInfo::ViewType; PhysicalDeviceObject(const T& child) noexcept; @@ -166,7 +166,7 @@ export namespace stormkit::gpu { class OwnedByPhysicalDevice: public OwnedByInstance { public: using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; + using ValueType = ObjectInfo::ValueType; using DeleterType = ObjectInfo::DeleterType; using ViewType = ObjectInfo::ViewType; diff --git a/modules/stormkit/gpu/core/surface.cppm b/modules/stormkit/gpu/core/surface.cppm index 53ef8f708..c58d25c88 100644 --- a/modules/stormkit/gpu/core/surface.cppm +++ b/modules/stormkit/gpu/core/surface.cppm @@ -34,7 +34,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = Surface; - using ElementType = VkSurfaceKHR; + using ValueType = VkSurfaceKHR; using DeleterType = PFN_vkDestroySurfaceKHR; using ViewType = view::Surface; using OwnedBy = Instance; diff --git a/modules/stormkit/gpu/core/sync.cppm b/modules/stormkit/gpu/core/sync.cppm index 506d71b11..eedea9480 100644 --- a/modules/stormkit/gpu/core/sync.cppm +++ b/modules/stormkit/gpu/core/sync.cppm @@ -34,7 +34,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = Fence; - using ElementType = VkFence; + using ValueType = VkFence; using DeleterType = PFN_vkDestroyFence VolkDeviceTable::*; using ViewType = view::Fence; using OwnedBy = Device; @@ -45,7 +45,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = Semaphore; - using ElementType = VkSemaphore; + using ValueType = VkSemaphore; using DeleterType = PFN_vkDestroySemaphore VolkDeviceTable::*; using ViewType = view::Semaphore; using OwnedBy = Device; @@ -87,7 +87,7 @@ export namespace stormkit::gpu { class STORMKIT_GPU_API Fence: public view::DeviceObject { public: using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; + using ValueType = ObjectInfo::ValueType; using ViewType = ObjectInfo::ViewType; using view::DeviceObject::DeviceObject; diff --git a/modules/stormkit/gpu/core/vulkan/structs.cppm b/modules/stormkit/gpu/core/vulkan/structs.cppm index 0ffdbc97c..61ffc8180 100644 --- a/modules/stormkit/gpu/core/vulkan/structs.cppm +++ b/modules/stormkit/gpu/core/vulkan/structs.cppm @@ -206,7 +206,7 @@ namespace stormkit::gpu::vk { STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto from_vk(const VkExtent2D& extent) noexcept -> Out { - using T = typename Out::ElementType; + using T = typename Out::ValueType; return Out { .width = as(extent.width), .height = as(extent.height) }; } @@ -216,7 +216,7 @@ namespace stormkit::gpu::vk { STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto from_vk(const VkExtent3D& extent) noexcept -> Out { - using T = typename Out::ElementType; + using T = typename Out::ValueType; return Out { .width = as(extent.width), .height = as(extent.height) }; } } // namespace stormkit::gpu::vk diff --git a/modules/stormkit/gpu/execution/command_buffer.cppm b/modules/stormkit/gpu/execution/command_buffer.cppm index be69ad630..0f870cf3a 100644 --- a/modules/stormkit/gpu/execution/command_buffer.cppm +++ b/modules/stormkit/gpu/execution/command_buffer.cppm @@ -44,7 +44,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = Queue; - using ElementType = VkQueue; + using ValueType = VkQueue; using DeleterType = decltype(cmonadic::noop()); using ViewType = view::Queue; using OwnedBy = Device; @@ -55,7 +55,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = CommandBuffer; - using ElementType = VkCommandBuffer; + using ValueType = VkCommandBuffer; using DeleterType = decltype(cmonadic::noop()); using ViewType = view::CommandBuffer; using OwnedBy = Device; @@ -67,7 +67,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = CommandPool; - using ElementType = VkCommandPool; + using ValueType = VkCommandPool; using DeleterType = PFN_vkDestroyCommandPool VolkDeviceTable::*; using ViewType = view::CommandPool; using OwnedBy = Device; @@ -123,7 +123,7 @@ export namespace stormkit::gpu { class Queue: public DeviceObject { public: using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; + using ValueType = ObjectInfo::ValueType; using ViewType = ObjectInfo::ViewType; Queue(const gpu::Queue& of) noexcept; @@ -530,7 +530,7 @@ export namespace stormkit::gpu { class CommandPool: public DeviceObject { public: using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; + using ValueType = ObjectInfo::ValueType; using ViewType = ObjectInfo::ViewType; using DeviceObject::DeviceObject; diff --git a/modules/stormkit/gpu/execution/descriptors.cppm b/modules/stormkit/gpu/execution/descriptors.cppm index 2a9bda525..9a9b1f0ab 100644 --- a/modules/stormkit/gpu/execution/descriptors.cppm +++ b/modules/stormkit/gpu/execution/descriptors.cppm @@ -40,7 +40,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = DescriptorSet; - using ElementType = VkDescriptorSet; + using ValueType = VkDescriptorSet; using DeleterType = decltype(cmonadic::noop()); using ViewType = view::DescriptorSet; using OwnedBy = Device; @@ -52,7 +52,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = DescriptorSetLayout; - using ElementType = VkDescriptorSetLayout; + using ValueType = VkDescriptorSetLayout; using DeleterType = PFN_vkDestroyDescriptorSetLayout VolkDeviceTable::*; using ViewType = view::DescriptorSetLayout; using OwnedBy = Device; @@ -63,7 +63,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = DescriptorPool; - using ElementType = VkDescriptorPool; + using ValueType = VkDescriptorPool; using DeleterType = PFN_vkDestroyDescriptorPool VolkDeviceTable::*; using ViewType = view::DescriptorPool; using OwnedBy = Device; @@ -130,7 +130,7 @@ export namespace stormkit::gpu { class DescriptorSet: public DeviceObject { public: using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; + using ValueType = ObjectInfo::ValueType; using ViewType = ObjectInfo::ViewType; using DeviceObject::DeviceObject; @@ -173,7 +173,7 @@ export namespace stormkit::gpu { class DescriptorSetLayout: public DeviceObject { public: using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; + using ValueType = ObjectInfo::ValueType; using ViewType = ObjectInfo::ViewType; DescriptorSetLayout(const gpu::DescriptorSetLayout& of) noexcept; @@ -236,7 +236,7 @@ export namespace stormkit::gpu { class DescriptorPool: public DeviceObject { public: using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; + using ValueType = ObjectInfo::ValueType; using ViewType = ObjectInfo::ViewType; using DeviceObject::DeviceObject; diff --git a/modules/stormkit/gpu/execution/pipeline.cppm b/modules/stormkit/gpu/execution/pipeline.cppm index f3ce0fba4..cf5d43f2e 100644 --- a/modules/stormkit/gpu/execution/pipeline.cppm +++ b/modules/stormkit/gpu/execution/pipeline.cppm @@ -41,7 +41,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = PipelineCache; - using ElementType = VkPipelineCache; + using ValueType = VkPipelineCache; using DeleterType = PFN_vkDestroyPipelineCache VolkDeviceTable::*; using ViewType = view::PipelineCache; using OwnedBy = Device; @@ -53,7 +53,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = Pipeline; - using ElementType = VkPipeline; + using ValueType = VkPipeline; using DeleterType = PFN_vkDestroyPipeline VolkDeviceTable::*; using ViewType = view::Pipeline; using OwnedBy = Device; @@ -64,7 +64,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = PipelineLayout; - using ElementType = VkPipelineLayout; + using ValueType = VkPipelineLayout; using DeleterType = PFN_vkDestroyPipelineLayout VolkDeviceTable::*; using ViewType = view::PipelineLayout; using OwnedBy = Device; @@ -193,7 +193,7 @@ export namespace stormkit::gpu { class STORMKIT_GPU_API Pipeline: public DeviceObject { public: using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; + using ValueType = ObjectInfo::ValueType; using ViewType = ObjectInfo::ViewType; Pipeline(const gpu::Pipeline& of) noexcept; diff --git a/modules/stormkit/gpu/execution/render_pass.cppm b/modules/stormkit/gpu/execution/render_pass.cppm index 22d4cc2e7..68d416c32 100644 --- a/modules/stormkit/gpu/execution/render_pass.cppm +++ b/modules/stormkit/gpu/execution/render_pass.cppm @@ -34,7 +34,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = FrameBuffer; - using ElementType = VkFramebuffer; + using ValueType = VkFramebuffer; using DeleterType = PFN_vkDestroyFramebuffer VolkDeviceTable::*; using ViewType = view::FrameBuffer; using OwnedBy = Device; @@ -46,7 +46,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = RenderPass; - using ElementType = VkRenderPass; + using ValueType = VkRenderPass; using DeleterType = PFN_vkDestroyRenderPass VolkDeviceTable::*; using ViewType = view::RenderPass; using OwnedBy = Device; @@ -97,7 +97,7 @@ export namespace stormkit::gpu { class STORMKIT_GPU_API FrameBuffer: public DeviceObject { public: using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; + using ValueType = ObjectInfo::ValueType; using ViewType = ObjectInfo::ViewType; FrameBuffer(const gpu::FrameBuffer& of) noexcept; @@ -201,7 +201,7 @@ export namespace stormkit::gpu { class STORMKIT_GPU_API RenderPass: public DeviceObject { public: using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; + using ValueType = ObjectInfo::ValueType; using ViewType = ObjectInfo::ViewType; // RenderPass(const gpu::RenderPass& of) noexcept; diff --git a/modules/stormkit/gpu/execution/swapchain.cppm b/modules/stormkit/gpu/execution/swapchain.cppm index a7f33c395..6869311c6 100644 --- a/modules/stormkit/gpu/execution/swapchain.cppm +++ b/modules/stormkit/gpu/execution/swapchain.cppm @@ -30,7 +30,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = SwapChain; - using ElementType = VkSwapchainKHR; + using ValueType = VkSwapchainKHR; using DeleterType = PFN_vkDestroySwapchainKHR VolkDeviceTable::*; using ViewType = view::SwapChain; using OwnedBy = Device; @@ -82,7 +82,7 @@ export namespace stormkit::gpu { class STORMKIT_GPU_API SwapChain: public DeviceObject { public: using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; + using ValueType = ObjectInfo::ValueType; using ViewType = ObjectInfo::ViewType; SwapChain(const gpu::SwapChain& of) noexcept; diff --git a/modules/stormkit/gpu/resource/buffer.cppm b/modules/stormkit/gpu/resource/buffer.cppm index 5eb3af7ad..131c5ab92 100644 --- a/modules/stormkit/gpu/resource/buffer.cppm +++ b/modules/stormkit/gpu/resource/buffer.cppm @@ -38,7 +38,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = Buffer; - using ElementType = VkBuffer; + using ValueType = VkBuffer; using DeleterType = PFN_vkDestroyBuffer VolkDeviceTable::*; using ViewType = view::Buffer; using OwnedBy = Device; @@ -134,7 +134,7 @@ export namespace stormkit::gpu { class STORMKIT_GPU_API Buffer: public DeviceObject { public: using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; + using ValueType = ObjectInfo::ValueType; using ViewType = ObjectInfo::ViewType; Buffer(const gpu::Buffer& of) noexcept; diff --git a/modules/stormkit/gpu/resource/image.cppm b/modules/stormkit/gpu/resource/image.cppm index d77ffa290..40b87200d 100644 --- a/modules/stormkit/gpu/resource/image.cppm +++ b/modules/stormkit/gpu/resource/image.cppm @@ -36,7 +36,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = Sampler; - using ElementType = VkSampler; + using ValueType = VkSampler; using DeleterType = PFN_vkDestroySampler VolkDeviceTable::*; using ViewType = view::Sampler; using OwnedBy = Device; @@ -47,7 +47,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = ImageView; - using ElementType = VkImageView; + using ValueType = VkImageView; using DeleterType = PFN_vkDestroyImageView VolkDeviceTable::*; using ViewType = view::ImageView; using OwnedBy = Device; @@ -58,7 +58,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = Image; - using ElementType = VkImage; + using ValueType = VkImage; using DeleterType = PFN_vkDestroyImage VolkDeviceTable::*; using ViewType = view::Image; using OwnedBy = Device; @@ -118,9 +118,9 @@ export namespace stormkit::gpu { namespace view { class STORMKIT_GPU_API Sampler: public view::DeviceObject { public: - using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; - using ViewType = ObjectInfo::ViewType; + using ObjectInfo = typename meta::ObjectInfo; + using ValueType = ObjectInfo::ValueType; + using ViewType = ObjectInfo::ViewType; Sampler(const gpu::Sampler& of) noexcept; template T> @@ -171,9 +171,9 @@ export namespace stormkit::gpu { namespace view { class STORMKIT_GPU_API ImageView: public view::DeviceObject { public: - using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; - using ViewType = ObjectInfo::ViewType; + using ObjectInfo = typename meta::ObjectInfo; + using ValueType = ObjectInfo::ValueType; + using ViewType = ObjectInfo::ViewType; ImageView(const gpu::ImageView& of) noexcept; template T> @@ -267,9 +267,9 @@ export namespace stormkit::gpu { namespace view { class STORMKIT_GPU_API Image: public view::DeviceObject { public: - using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; - using ViewType = ObjectInfo::ViewType; + using ObjectInfo = typename meta::ObjectInfo; + using ValueType = ObjectInfo::ValueType; + using ViewType = ObjectInfo::ViewType; Image(const gpu::Image& of) noexcept; template T> diff --git a/modules/stormkit/gpu/resource/shader.cppm b/modules/stormkit/gpu/resource/shader.cppm index 1c6ca712b..390b57b59 100644 --- a/modules/stormkit/gpu/resource/shader.cppm +++ b/modules/stormkit/gpu/resource/shader.cppm @@ -34,7 +34,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = Shader; - using ElementType = VkShaderModule; + using ValueType = VkShaderModule; using DeleterType = PFN_vkDestroyShaderModule VolkDeviceTable::*; using ViewType = view::Shader; using OwnedBy = Device; @@ -100,7 +100,7 @@ export namespace stormkit::gpu { class STORMKIT_GPU_API Shader: public view::DeviceObject { public: using ObjectInfo = typename meta::ObjectInfo; - using ElementType = ObjectInfo::ElementType; + using ValueType = ObjectInfo::ValueType; using ViewType = ObjectInfo::ViewType; Shader(const gpu::Shader& of) noexcept; From 39564007e2facc09da861ffef0a81bbd2c19e93b Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 16 Mar 2026 19:47:47 +0100 Subject: [PATCH 171/194] (all) format --- .../core/containers/multi_buffer.cppm | 9 +- modules/stormkit/core/string/encodings.cppm | 24 +- modules/stormkit/core/string/operations.cppm | 9 +- modules/stormkit/gpu/core/debug_callback.cppm | 2 +- .../stormkit/gpu/core/physical_device.cppm | 10 +- modules/stormkit/gpu/core/surface.cppm | 2 +- modules/stormkit/gpu/core/sync.cppm | 10 +- modules/stormkit/gpu/core/vulkan/enums.cppm | 5616 ++++++++--------- .../gpu/execution/command_buffer.cppm | 18 +- .../stormkit/gpu/execution/descriptors.cppm | 24 +- modules/stormkit/gpu/execution/pipeline.cppm | 12 +- .../stormkit/gpu/execution/render_pass.cppm | 16 +- modules/stormkit/gpu/execution/swapchain.cppm | 8 +- modules/stormkit/gpu/resource/buffer.cppm | 8 +- modules/stormkit/gpu/resource/shader.cppm | 8 +- src/wsi/common/window_base.cppm | 24 +- src/wsi/linux/wayland/monitor.cppm | 4 +- src/wsi/linux/window.cppm | 6 +- src/wsi/linux/x11/context.cpp | 10 +- src/wsi/linux/x11/window.cppm | 3 +- 20 files changed, 2876 insertions(+), 2947 deletions(-) diff --git a/modules/stormkit/core/containers/multi_buffer.cppm b/modules/stormkit/core/containers/multi_buffer.cppm index e294bdcc6..e0a702ef5 100644 --- a/modules/stormkit/core/containers/multi_buffer.cppm +++ b/modules/stormkit/core/containers/multi_buffer.cppm @@ -82,7 +82,8 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - STORMKIT_FORCE_INLINE constexpr MultiBuffer::MultiBuffer(const MultiBuffer&) = default; + STORMKIT_FORCE_INLINE + constexpr MultiBuffer::MultiBuffer(const MultiBuffer&) = default; ///////////////////////////////////// ///////////////////////////////////// @@ -93,7 +94,8 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - STORMKIT_FORCE_INLINE constexpr MultiBuffer::MultiBuffer(MultiBuffer&&) noexcept = default; + STORMKIT_FORCE_INLINE + constexpr MultiBuffer::MultiBuffer(MultiBuffer&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// @@ -104,7 +106,8 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - STORMKIT_FORCE_INLINE constexpr MultiBuffer::~MultiBuffer() = default; + STORMKIT_FORCE_INLINE + constexpr MultiBuffer::~MultiBuffer() = default; ///////////////////////////////////// ///////////////////////////////////// diff --git a/modules/stormkit/core/string/encodings.cppm b/modules/stormkit/core/string/encodings.cppm index 3e204bafe..2f841a481 100644 --- a/modules/stormkit/core/string/encodings.cppm +++ b/modules/stormkit/core/string/encodings.cppm @@ -81,20 +81,16 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// inline auto ascii_to_wide(std::string_view input) -> std::wstring { [[maybe_unused]] - auto state - = std::mbstate_t {}; + auto state = std::mbstate_t {}; auto output = std::wstring {}; output.resize(stdr::size(input)); [[maybe_unused]] - auto len - = 0ull; + auto len = 0ull; [[maybe_unused]] - auto input_it - = stdr::data(input); + auto input_it = stdr::data(input); [[maybe_unused]] - auto i - = 0; + auto i = 0; #if defined(STORMKIT_COMPILER_MSVC) while ((len = std::mbrtoc16(std::bit_cast(stdr::data(output)) + i++, input_it, MB_CUR_MAX, &state)) > 0u) input_it += len; @@ -112,11 +108,9 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// inline auto wide_to_ascii(std::wstring_view input) -> std::string { [[maybe_unused]] - auto state - = std::mbstate_t {}; + auto state = std::mbstate_t {}; [[maybe_unused]] - auto output - = std::string {}; + auto output = std::string {}; output.resize(stdr::size(input)); #if defined(STORMKIT_COMPILER_MSVC) @@ -134,8 +128,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// inline auto ascii_to_utf8(std::string_view input) -> std::u8string { [[maybe_unused]] - auto output - = std::u8string {}; + auto output = std::u8string {}; output.resize(stdr::size(input) * narrow(MB_LEN_MAX)); #if defined(STORMKIT_COMPILER_MSVC) @@ -160,8 +153,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// inline auto utf8_to_ascii(std::u8string_view input) -> std::string { [[maybe_unused]] - auto output - = std::string {}; + auto output = std::string {}; output.resize(stdr::size(input)); #if defined(STORMKIT_COMPILER_MSVC) diff --git a/modules/stormkit/core/string/operations.cppm b/modules/stormkit/core/string/operations.cppm index b0e9f89a7..23586cd01 100644 --- a/modules/stormkit/core/string/operations.cppm +++ b/modules/stormkit/core/string/operations.cppm @@ -40,18 +40,15 @@ export namespace stormkit { inline namespace core { template [[nodiscard]] - constexpr auto as_string(T) noexcept -> std::string_view - = delete; + constexpr auto as_string(T) noexcept -> std::string_view = delete; template [[nodiscard]] - constexpr auto to_string(T) noexcept -> std::string - = delete; + constexpr auto to_string(T) noexcept -> std::string = delete; template [[nodiscard]] - constexpr auto from_string(std::string_view) noexcept -> T - = delete; + constexpr auto from_string(std::string_view) noexcept -> T = delete; template requires(as_string(std::declval())) diff --git a/modules/stormkit/gpu/core/debug_callback.cppm b/modules/stormkit/gpu/core/debug_callback.cppm index e518612ef..6d1efa475 100644 --- a/modules/stormkit/gpu/core/debug_callback.cppm +++ b/modules/stormkit/gpu/core/debug_callback.cppm @@ -31,7 +31,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = DebugCallback; - using ValueType = VkDebugUtilsMessengerEXT; + using ValueType = VkDebugUtilsMessengerEXT; using DeleterType = PFN_vkDestroyDebugUtilsMessengerEXT; using ViewType = view::DebugCallback; using OwnedBy = Instance; diff --git a/modules/stormkit/gpu/core/physical_device.cppm b/modules/stormkit/gpu/core/physical_device.cppm index ad9171ddc..e76c57cd6 100644 --- a/modules/stormkit/gpu/core/physical_device.cppm +++ b/modules/stormkit/gpu/core/physical_device.cppm @@ -33,7 +33,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = PhysicalDevice; - using ValueType = VkPhysicalDevice; + using ValueType = VkPhysicalDevice; using DeleterType = decltype(monadic::noop()); using ViewType = view::PhysicalDevice; using OwnedBy = Instance; @@ -139,9 +139,9 @@ export namespace stormkit::gpu { template class PhysicalDeviceObject: public InstanceObject { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; + using ObjectInfo = typename meta::ObjectInfo; + using ValueType = ObjectInfo::ValueType; + using ViewType = ObjectInfo::ViewType; PhysicalDeviceObject(const T& child) noexcept; template U> @@ -166,7 +166,7 @@ export namespace stormkit::gpu { class OwnedByPhysicalDevice: public OwnedByInstance { public: using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; + using ValueType = ObjectInfo::ValueType; using DeleterType = ObjectInfo::DeleterType; using ViewType = ObjectInfo::ViewType; diff --git a/modules/stormkit/gpu/core/surface.cppm b/modules/stormkit/gpu/core/surface.cppm index c58d25c88..2bfa616be 100644 --- a/modules/stormkit/gpu/core/surface.cppm +++ b/modules/stormkit/gpu/core/surface.cppm @@ -34,7 +34,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = Surface; - using ValueType = VkSurfaceKHR; + using ValueType = VkSurfaceKHR; using DeleterType = PFN_vkDestroySurfaceKHR; using ViewType = view::Surface; using OwnedBy = Instance; diff --git a/modules/stormkit/gpu/core/sync.cppm b/modules/stormkit/gpu/core/sync.cppm index eedea9480..b1f6d006f 100644 --- a/modules/stormkit/gpu/core/sync.cppm +++ b/modules/stormkit/gpu/core/sync.cppm @@ -34,7 +34,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = Fence; - using ValueType = VkFence; + using ValueType = VkFence; using DeleterType = PFN_vkDestroyFence VolkDeviceTable::*; using ViewType = view::Fence; using OwnedBy = Device; @@ -45,7 +45,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = Semaphore; - using ValueType = VkSemaphore; + using ValueType = VkSemaphore; using DeleterType = PFN_vkDestroySemaphore VolkDeviceTable::*; using ViewType = view::Semaphore; using OwnedBy = Device; @@ -86,9 +86,9 @@ export namespace stormkit::gpu { namespace view { class STORMKIT_GPU_API Fence: public view::DeviceObject { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; + using ObjectInfo = typename meta::ObjectInfo; + using ValueType = ObjectInfo::ValueType; + using ViewType = ObjectInfo::ViewType; using view::DeviceObject::DeviceObject; diff --git a/modules/stormkit/gpu/core/vulkan/enums.cppm b/modules/stormkit/gpu/core/vulkan/enums.cppm index 0f4c96abe..c505dc746 100644 --- a/modules/stormkit/gpu/core/vulkan/enums.cppm +++ b/modules/stormkit/gpu/core/vulkan/enums.cppm @@ -4,8 +4,8 @@ module; -#include #include +#include #include #include @@ -18,11 +18,10 @@ import stormkit.image; import :vulkan.volk; - export { namespace stormkit::gpu { namespace details { - template + template inline constexpr auto IS_VULKAN_ENUMERATION = false; } @@ -32,770 +31,726 @@ export { } inline constexpr auto QUEUE_FAMILY_IGNORED = std::numeric_limits::max(); - + enum class AccessFlag : u32 { - COLOR_ATTACHMENT_READ = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, - COLOR_ATTACHMENT_WRITE = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, - DEPTH_STENCIL_ATTACHMENT_READ = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, - DEPTH_STENCIL_ATTACHMENT_WRITE = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, - HOST_READ = VK_ACCESS_HOST_READ_BIT, - HOST_WRITE = VK_ACCESS_HOST_WRITE_BIT, - INDIRECT_COMMAND_READ = VK_ACCESS_INDIRECT_COMMAND_READ_BIT, - INPUT_ATTACHMENT_READ = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, - MEMORY_READ = VK_ACCESS_MEMORY_READ_BIT, - MEMORY_WRITE = VK_ACCESS_MEMORY_WRITE_BIT, - NONE = 0, - SHADER_READ = VK_ACCESS_SHADER_READ_BIT, - SHADER_WRITE = VK_ACCESS_SHADER_WRITE_BIT, - TRANSFER_READ = VK_ACCESS_TRANSFER_READ_BIT, - TRANSFER_WRITE = VK_ACCESS_TRANSFER_WRITE_BIT, - UNIFORM_READ = VK_ACCESS_UNIFORM_READ_BIT, - VERTEX_ATTRIBUTE_READ = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, - - }; - - template <> + COLOR_ATTACHMENT_READ = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, + COLOR_ATTACHMENT_WRITE = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + DEPTH_STENCIL_ATTACHMENT_READ = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT, + DEPTH_STENCIL_ATTACHMENT_WRITE = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + HOST_READ = VK_ACCESS_HOST_READ_BIT, + HOST_WRITE = VK_ACCESS_HOST_WRITE_BIT, + INDIRECT_COMMAND_READ = VK_ACCESS_INDIRECT_COMMAND_READ_BIT, + INPUT_ATTACHMENT_READ = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, + MEMORY_READ = VK_ACCESS_MEMORY_READ_BIT, + MEMORY_WRITE = VK_ACCESS_MEMORY_WRITE_BIT, + NONE = 0, + SHADER_READ = VK_ACCESS_SHADER_READ_BIT, + SHADER_WRITE = VK_ACCESS_SHADER_WRITE_BIT, + TRANSFER_READ = VK_ACCESS_TRANSFER_READ_BIT, + TRANSFER_WRITE = VK_ACCESS_TRANSFER_WRITE_BIT, + UNIFORM_READ = VK_ACCESS_UNIFORM_READ_BIT, + VERTEX_ATTRIBUTE_READ = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class AttachmentLoadOperation : u8 { - CLEAR = VK_ATTACHMENT_LOAD_OP_CLEAR, - DONT_CARE = VK_ATTACHMENT_LOAD_OP_DONT_CARE, - LOAD = VK_ATTACHMENT_LOAD_OP_LOAD, - + CLEAR = VK_ATTACHMENT_LOAD_OP_CLEAR, + DONT_CARE = VK_ATTACHMENT_LOAD_OP_DONT_CARE, + LOAD = VK_ATTACHMENT_LOAD_OP_LOAD, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class AttachmentStoreOperation : u8 { - DONT_CARE = VK_ATTACHMENT_STORE_OP_DONT_CARE, - STORE = VK_ATTACHMENT_STORE_OP_STORE, - + DONT_CARE = VK_ATTACHMENT_STORE_OP_DONT_CARE, + STORE = VK_ATTACHMENT_STORE_OP_STORE, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class BlendFactor : u8 { - CONSTANT_ALPHA = VK_BLEND_FACTOR_CONSTANT_ALPHA, - CONSTANT_COLOR = VK_BLEND_FACTOR_CONSTANT_COLOR, - DST_ALPHA = VK_BLEND_FACTOR_DST_ALPHA, - DST_COLOR = VK_BLEND_FACTOR_DST_COLOR, - ONE = VK_BLEND_FACTOR_ONE, - ONE_MINUS_CONSTANT_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA, - ONE_MINUS_CONSTANT_COLOR = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, - ONE_MINUS_DST_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, - ONE_MINUS_DST_COLOR = VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, - ONE_MINUS_SRC1_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, - ONE_MINUS_SRC1_COLOR = VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, - ONE_MINUS_SRC_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, - ONE_MINUS_SRC_COLOR = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, - SRC1_ALPHA = VK_BLEND_FACTOR_SRC1_ALPHA, - SRC1_COLOR = VK_BLEND_FACTOR_SRC1_COLOR, - SRC_ALPHA = VK_BLEND_FACTOR_SRC_ALPHA, - SRC_ALPHA_SATURATE = VK_BLEND_FACTOR_SRC_ALPHA_SATURATE, - SRC_COLOR = VK_BLEND_FACTOR_SRC_COLOR, - ZERO = VK_BLEND_FACTOR_ZERO, - - }; - - template <> + CONSTANT_ALPHA = VK_BLEND_FACTOR_CONSTANT_ALPHA, + CONSTANT_COLOR = VK_BLEND_FACTOR_CONSTANT_COLOR, + DST_ALPHA = VK_BLEND_FACTOR_DST_ALPHA, + DST_COLOR = VK_BLEND_FACTOR_DST_COLOR, + ONE = VK_BLEND_FACTOR_ONE, + ONE_MINUS_CONSTANT_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA, + ONE_MINUS_CONSTANT_COLOR = VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR, + ONE_MINUS_DST_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA, + ONE_MINUS_DST_COLOR = VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR, + ONE_MINUS_SRC1_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA, + ONE_MINUS_SRC1_COLOR = VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR, + ONE_MINUS_SRC_ALPHA = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, + ONE_MINUS_SRC_COLOR = VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, + SRC1_ALPHA = VK_BLEND_FACTOR_SRC1_ALPHA, + SRC1_COLOR = VK_BLEND_FACTOR_SRC1_COLOR, + SRC_ALPHA = VK_BLEND_FACTOR_SRC_ALPHA, + SRC_ALPHA_SATURATE = VK_BLEND_FACTOR_SRC_ALPHA_SATURATE, + SRC_COLOR = VK_BLEND_FACTOR_SRC_COLOR, + ZERO = VK_BLEND_FACTOR_ZERO, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class BlendOperation : u8 { - ADD = VK_BLEND_OP_ADD, - MAX = VK_BLEND_OP_MAX, - MIN = VK_BLEND_OP_MIN, - REVERSE_SUBTRACT = VK_BLEND_OP_REVERSE_SUBTRACT, - SUBTRACT = VK_BLEND_OP_SUBTRACT, - + ADD = VK_BLEND_OP_ADD, + MAX = VK_BLEND_OP_MAX, + MIN = VK_BLEND_OP_MIN, + REVERSE_SUBTRACT = VK_BLEND_OP_REVERSE_SUBTRACT, + SUBTRACT = VK_BLEND_OP_SUBTRACT, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class BorderColor : u8 { - FLOAT_OPAQUE_BLACK = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK, - FLOAT_OPAQUE_WHITE = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE, - FLOAT_TRANSPARENT_BLACK = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, - INT_OPAQUE_BLACK = VK_BORDER_COLOR_INT_OPAQUE_BLACK, - INT_OPAQUE_WHITE = VK_BORDER_COLOR_INT_OPAQUE_WHITE, - INT_TRANSPARENT_BLACK = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK, - + FLOAT_OPAQUE_BLACK = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK, + FLOAT_OPAQUE_WHITE = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE, + FLOAT_TRANSPARENT_BLACK = VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, + INT_OPAQUE_BLACK = VK_BORDER_COLOR_INT_OPAQUE_BLACK, + INT_OPAQUE_WHITE = VK_BORDER_COLOR_INT_OPAQUE_WHITE, + INT_TRANSPARENT_BLACK = VK_BORDER_COLOR_INT_TRANSPARENT_BLACK, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class BufferUsageFlag : u16 { - INDEX = VK_BUFFER_USAGE_INDEX_BUFFER_BIT, - INDIRECT = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, - STORAGE = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, - STORAGE_TEXEL = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, - TRANSFER_DST = VK_BUFFER_USAGE_TRANSFER_DST_BIT, - TRANSFER_SRC = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - UNIFORM = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, - UNIFORM_TEXEL = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, - VERTEX = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, - - }; - - template <> + INDEX = VK_BUFFER_USAGE_INDEX_BUFFER_BIT, + INDIRECT = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT, + STORAGE = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, + STORAGE_TEXEL = VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT, + TRANSFER_DST = VK_BUFFER_USAGE_TRANSFER_DST_BIT, + TRANSFER_SRC = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + UNIFORM = VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + UNIFORM_TEXEL = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, + VERTEX = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ColorComponentFlag : u8 { - A = VK_COLOR_COMPONENT_A_BIT, - B = VK_COLOR_COMPONENT_B_BIT, - G = VK_COLOR_COMPONENT_G_BIT, - NONE = 0, - R = VK_COLOR_COMPONENT_R_BIT, - RG = R | G, - RGB = RG | B, - RGBA = RGB | A, - - }; - - template <> + A = VK_COLOR_COMPONENT_A_BIT, + B = VK_COLOR_COMPONENT_B_BIT, + G = VK_COLOR_COMPONENT_G_BIT, + NONE = 0, + R = VK_COLOR_COMPONENT_R_BIT, + RG = R | G, + RGB = RG | B, + RGBA = RGB | A, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ColorSpace : u32 { - ADOBERGB_LINEAR = VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT, - ADOBERGB_NONLINEAR = VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT, - BT2020_LINEAR = VK_COLOR_SPACE_BT2020_LINEAR_EXT, - BT709_LINEAR = VK_COLOR_SPACE_BT709_LINEAR_EXT, - BT709_NONLINEAR = VK_COLOR_SPACE_BT709_NONLINEAR_EXT, - DCI_P3_NONLINEAR = VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT, - DISPLAY_NATIVE_AMD = VK_COLOR_SPACE_DISPLAY_NATIVE_AMD, - DISPLAY_P3_LINEAR = VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT, - DISPLAY_P3_NONLINEAR = VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT, - DOLBYVISION = VK_COLOR_SPACE_DOLBYVISION_EXT, - EXTENDED_SRGB_LINEAR = VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT, - EXTENDED_SRGB_NONLINEAR = VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT, - HDR10_HLG = VK_COLOR_SPACE_HDR10_HLG_EXT, - HDR10_ST2084 = VK_COLOR_SPACE_HDR10_ST2084_EXT, - PASS_THROUGH = VK_COLOR_SPACE_PASS_THROUGH_EXT, - SRGB_NONLINEAR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, - - }; - - template <> + ADOBERGB_LINEAR = VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT, + ADOBERGB_NONLINEAR = VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT, + BT2020_LINEAR = VK_COLOR_SPACE_BT2020_LINEAR_EXT, + BT709_LINEAR = VK_COLOR_SPACE_BT709_LINEAR_EXT, + BT709_NONLINEAR = VK_COLOR_SPACE_BT709_NONLINEAR_EXT, + DCI_P3_NONLINEAR = VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT, + DISPLAY_NATIVE_AMD = VK_COLOR_SPACE_DISPLAY_NATIVE_AMD, + DISPLAY_P3_LINEAR = VK_COLOR_SPACE_DISPLAY_P3_LINEAR_EXT, + DISPLAY_P3_NONLINEAR = VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT, + DOLBYVISION = VK_COLOR_SPACE_DOLBYVISION_EXT, + EXTENDED_SRGB_LINEAR = VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT, + EXTENDED_SRGB_NONLINEAR = VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT, + HDR10_HLG = VK_COLOR_SPACE_HDR10_HLG_EXT, + HDR10_ST2084 = VK_COLOR_SPACE_HDR10_ST2084_EXT, + PASS_THROUGH = VK_COLOR_SPACE_PASS_THROUGH_EXT, + SRGB_NONLINEAR = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class CommandBufferLevel : u8 { - PRIMARY = VK_COMMAND_BUFFER_LEVEL_PRIMARY, - SECONDARY = VK_COMMAND_BUFFER_LEVEL_SECONDARY, - + PRIMARY = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + SECONDARY = VK_COMMAND_BUFFER_LEVEL_SECONDARY, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class CompareOperation : u8 { - ALWAYS = VK_COMPARE_OP_ALWAYS, - EQUAL = VK_COMPARE_OP_EQUAL, - GREATER = VK_COMPARE_OP_GREATER, - GREATER_OR_EQUAL = VK_COMPARE_OP_GREATER_OR_EQUAL, - LESS = VK_COMPARE_OP_LESS, - LESS_OR_EQUAL = VK_COMPARE_OP_LESS_OR_EQUAL, - NEVER = VK_COMPARE_OP_NEVER, - NOT_EQUAL = VK_COMPARE_OP_NOT_EQUAL, - - }; - - template <> + ALWAYS = VK_COMPARE_OP_ALWAYS, + EQUAL = VK_COMPARE_OP_EQUAL, + GREATER = VK_COMPARE_OP_GREATER, + GREATER_OR_EQUAL = VK_COMPARE_OP_GREATER_OR_EQUAL, + LESS = VK_COMPARE_OP_LESS, + LESS_OR_EQUAL = VK_COMPARE_OP_LESS_OR_EQUAL, + NEVER = VK_COMPARE_OP_NEVER, + NOT_EQUAL = VK_COMPARE_OP_NOT_EQUAL, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class CullModeFlag : u8 { - BACK = VK_CULL_MODE_BACK_BIT, - FRONT = VK_CULL_MODE_FRONT_BIT, - FRONT_BACK = FRONT | BACK, - NONE = 0, - + BACK = VK_CULL_MODE_BACK_BIT, + FRONT = VK_CULL_MODE_FRONT_BIT, + FRONT_BACK = FRONT | BACK, + NONE = 0, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class DebugObjectType : u32 { - BUFFER = VK_OBJECT_TYPE_BUFFER, - BUFFER_VIEW = VK_OBJECT_TYPE_BUFFER_VIEW, - COMMAND_BUFFER = VK_OBJECT_TYPE_COMMAND_BUFFER, - COMMAND_POOL = VK_OBJECT_TYPE_COMMAND_POOL, - DEBUG_REPORT_CALLBACK = VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT, - DEBUG_UTILS_MESSENGER = VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT, - DESCRIPTOR_POOL = VK_OBJECT_TYPE_DESCRIPTOR_POOL, - DESCRIPTOR_SET = VK_OBJECT_TYPE_DESCRIPTOR_SET, - DESCRIPTOR_SET_LAYOUT = VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, - DEVICE = VK_OBJECT_TYPE_DEVICE, - DEVICE_MEMORY = VK_OBJECT_TYPE_DEVICE_MEMORY, - DISPLAY = VK_OBJECT_TYPE_DISPLAY_KHR, - EVENT = VK_OBJECT_TYPE_EVENT, - FENCE = VK_OBJECT_TYPE_FENCE, - FRAMEBUFFER = VK_OBJECT_TYPE_FRAMEBUFFER, - IMAGE = VK_OBJECT_TYPE_IMAGE, - IMAGE_VIEW = VK_OBJECT_TYPE_IMAGE_VIEW, - INSTANCE = VK_OBJECT_TYPE_INSTANCE, - PHYSICAL_DEVICE = VK_OBJECT_TYPE_PHYSICAL_DEVICE, - PIPELINE = VK_OBJECT_TYPE_PIPELINE, - PIPELINE_CACHE = VK_OBJECT_TYPE_PIPELINE_CACHE, - PIPELINE_LAYOUT = VK_OBJECT_TYPE_PIPELINE_LAYOUT, - QUERY_POOL = VK_OBJECT_TYPE_QUERY_POOL, - QUEUE = VK_OBJECT_TYPE_QUEUE, - RENDER_PASS = VK_OBJECT_TYPE_RENDER_PASS, - SAMPLER = VK_OBJECT_TYPE_SAMPLER, - SEMAPHORE = VK_OBJECT_TYPE_SEMAPHORE, - SHADER_MODULE = VK_OBJECT_TYPE_SHADER_MODULE, - SURFACE = VK_OBJECT_TYPE_SURFACE_KHR, - SWAPCHAIN = VK_OBJECT_TYPE_SWAPCHAIN_KHR, - UNKNOWN = VK_OBJECT_TYPE_UNKNOWN, - - }; - - template <> + BUFFER = VK_OBJECT_TYPE_BUFFER, + BUFFER_VIEW = VK_OBJECT_TYPE_BUFFER_VIEW, + COMMAND_BUFFER = VK_OBJECT_TYPE_COMMAND_BUFFER, + COMMAND_POOL = VK_OBJECT_TYPE_COMMAND_POOL, + DEBUG_REPORT_CALLBACK = VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT, + DEBUG_UTILS_MESSENGER = VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT, + DESCRIPTOR_POOL = VK_OBJECT_TYPE_DESCRIPTOR_POOL, + DESCRIPTOR_SET = VK_OBJECT_TYPE_DESCRIPTOR_SET, + DESCRIPTOR_SET_LAYOUT = VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT, + DEVICE = VK_OBJECT_TYPE_DEVICE, + DEVICE_MEMORY = VK_OBJECT_TYPE_DEVICE_MEMORY, + DISPLAY = VK_OBJECT_TYPE_DISPLAY_KHR, + EVENT = VK_OBJECT_TYPE_EVENT, + FENCE = VK_OBJECT_TYPE_FENCE, + FRAMEBUFFER = VK_OBJECT_TYPE_FRAMEBUFFER, + IMAGE = VK_OBJECT_TYPE_IMAGE, + IMAGE_VIEW = VK_OBJECT_TYPE_IMAGE_VIEW, + INSTANCE = VK_OBJECT_TYPE_INSTANCE, + PHYSICAL_DEVICE = VK_OBJECT_TYPE_PHYSICAL_DEVICE, + PIPELINE = VK_OBJECT_TYPE_PIPELINE, + PIPELINE_CACHE = VK_OBJECT_TYPE_PIPELINE_CACHE, + PIPELINE_LAYOUT = VK_OBJECT_TYPE_PIPELINE_LAYOUT, + QUERY_POOL = VK_OBJECT_TYPE_QUERY_POOL, + QUEUE = VK_OBJECT_TYPE_QUEUE, + RENDER_PASS = VK_OBJECT_TYPE_RENDER_PASS, + SAMPLER = VK_OBJECT_TYPE_SAMPLER, + SEMAPHORE = VK_OBJECT_TYPE_SEMAPHORE, + SHADER_MODULE = VK_OBJECT_TYPE_SHADER_MODULE, + SURFACE = VK_OBJECT_TYPE_SURFACE_KHR, + SWAPCHAIN = VK_OBJECT_TYPE_SWAPCHAIN_KHR, + UNKNOWN = VK_OBJECT_TYPE_UNKNOWN, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class DependencyFlag : u8 { - BY_REGION = VK_DEPENDENCY_BY_REGION_BIT, - DEVICE_GROUP = VK_DEPENDENCY_DEVICE_GROUP_BIT, - NONE = 0, - VIEW_LOCAL = VK_DEPENDENCY_VIEW_LOCAL_BIT, - + BY_REGION = VK_DEPENDENCY_BY_REGION_BIT, + DEVICE_GROUP = VK_DEPENDENCY_DEVICE_GROUP_BIT, + NONE = 0, + VIEW_LOCAL = VK_DEPENDENCY_VIEW_LOCAL_BIT, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class DescriptorType : u8 { - COMBINED_IMAGE_SAMPLER = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - INPUT_ATTACHMENT = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, - SAMPLED_IMAGE = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, - SAMPLER = VK_DESCRIPTOR_TYPE_SAMPLER, - STORAGE_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - STORAGE_BUFFER_DYNAMIC = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, - STORAGE_IMAGE = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, - STORAGE_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, - UNIFORM_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - UNIFORM_BUFFER_DYNAMIC = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, - UNIFORM_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, - - }; - - template <> + COMBINED_IMAGE_SAMPLER = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, + INPUT_ATTACHMENT = VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, + SAMPLED_IMAGE = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, + SAMPLER = VK_DESCRIPTOR_TYPE_SAMPLER, + STORAGE_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + STORAGE_BUFFER_DYNAMIC = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, + STORAGE_IMAGE = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, + STORAGE_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, + UNIFORM_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + UNIFORM_BUFFER_DYNAMIC = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, + UNIFORM_TEXEL_BUFFER = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class DynamicState : u8 { - BLEND_CONSTANTS = VK_DYNAMIC_STATE_BLEND_CONSTANTS, - DEPTH_BIAS = VK_DYNAMIC_STATE_DEPTH_BIAS, - DEPTH_BOUNDS = VK_DYNAMIC_STATE_DEPTH_BOUNDS, - LINE_WIDTH = VK_DYNAMIC_STATE_LINE_WIDTH, - SCISSOR = VK_DYNAMIC_STATE_SCISSOR, - STENCIL_COMPARE_MASK = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, - STENCIL_REFERENCE = VK_DYNAMIC_STATE_STENCIL_REFERENCE, - STENCIL_WRITE_MASK = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, - VIEWPORT = VK_DYNAMIC_STATE_VIEWPORT, - - }; - - template <> + BLEND_CONSTANTS = VK_DYNAMIC_STATE_BLEND_CONSTANTS, + DEPTH_BIAS = VK_DYNAMIC_STATE_DEPTH_BIAS, + DEPTH_BOUNDS = VK_DYNAMIC_STATE_DEPTH_BOUNDS, + LINE_WIDTH = VK_DYNAMIC_STATE_LINE_WIDTH, + SCISSOR = VK_DYNAMIC_STATE_SCISSOR, + STENCIL_COMPARE_MASK = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, + STENCIL_REFERENCE = VK_DYNAMIC_STATE_STENCIL_REFERENCE, + STENCIL_WRITE_MASK = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, + VIEWPORT = VK_DYNAMIC_STATE_VIEWPORT, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class Filter : u32 { - CUBIC_IMG = VK_FILTER_CUBIC_IMG, - LINEAR = VK_FILTER_LINEAR, - NEAREST = VK_FILTER_NEAREST, - + CUBIC_IMG = VK_FILTER_CUBIC_IMG, + LINEAR = VK_FILTER_LINEAR, + NEAREST = VK_FILTER_NEAREST, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class FormatFeatureFlag : u32 { - BLIT_DST = VK_FORMAT_FEATURE_BLIT_DST_BIT, - BLIT_SRC = VK_FORMAT_FEATURE_BLIT_SRC_BIT, - COLOR_ATTACHMENT = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, - COLOR_ATTACHMENT_BLEND = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT, - COSITED_CHROMA_SAMPLES = VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT, - DEPTH_STENCIL_ATTACHMENT = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, - DISJOINT = VK_FORMAT_FEATURE_DISJOINT_BIT, - MIDPOINT_CHROMA_SAMPLES = VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT, - SAMPLED_IMAGE = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, - SAMPLED_IMAGE_FILTER_LINEAR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT, - SAMPLED_IMAGE_FILTER_MINMAX = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT, - SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT, - SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT, - SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT, - SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT, - STORAGE_IMAGE = VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT, - STORAGE_IMAGE_ATOMIC = VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT, - STORAGE_TEXEL_BUFFER = VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT, - STORAGE_TEXEL_BUFFER_ATOMIC = VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT, - TRANSFER_DST = VK_FORMAT_FEATURE_TRANSFER_DST_BIT, - TRANSFER_SRC = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT, - UNIFORM_TEXEL_BUFFER = VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT, - VERTEX_BUFFER = VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT, - - }; - - template <> + BLIT_DST = VK_FORMAT_FEATURE_BLIT_DST_BIT, + BLIT_SRC = VK_FORMAT_FEATURE_BLIT_SRC_BIT, + COLOR_ATTACHMENT = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT, + COLOR_ATTACHMENT_BLEND = VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT, + COSITED_CHROMA_SAMPLES = VK_FORMAT_FEATURE_COSITED_CHROMA_SAMPLES_BIT, + DEPTH_STENCIL_ATTACHMENT = VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, + DISJOINT = VK_FORMAT_FEATURE_DISJOINT_BIT, + MIDPOINT_CHROMA_SAMPLES = VK_FORMAT_FEATURE_MIDPOINT_CHROMA_SAMPLES_BIT, + SAMPLED_IMAGE = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT, + SAMPLED_IMAGE_FILTER_LINEAR = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT, + SAMPLED_IMAGE_FILTER_MINMAX = VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_MINMAX_BIT, + SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT + = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_BIT, + SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE + = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE_BIT, + SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT, + SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER + = VK_FORMAT_FEATURE_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT, + STORAGE_IMAGE = VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT, + STORAGE_IMAGE_ATOMIC = VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT, + STORAGE_TEXEL_BUFFER = VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT, + STORAGE_TEXEL_BUFFER_ATOMIC = VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT, + TRANSFER_DST = VK_FORMAT_FEATURE_TRANSFER_DST_BIT, + TRANSFER_SRC = VK_FORMAT_FEATURE_TRANSFER_SRC_BIT, + UNIFORM_TEXEL_BUFFER = VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT, + VERTEX_BUFFER = VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class FrontFace : u8 { - CLOCKWISE = VK_FRONT_FACE_CLOCKWISE, - COUNTER_CLOCKWISE = VK_FRONT_FACE_COUNTER_CLOCKWISE, - + CLOCKWISE = VK_FRONT_FACE_CLOCKWISE, + COUNTER_CLOCKWISE = VK_FRONT_FACE_COUNTER_CLOCKWISE, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class GeometryFlag : u8 { - NO_DUPLICATE_ANY_HIT_INVOCATION = VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR, - OPAQUE = VK_GEOMETRY_OPAQUE_BIT_KHR, - + NO_DUPLICATE_ANY_HIT_INVOCATION = VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR, + OPAQUE = VK_GEOMETRY_OPAQUE_BIT_KHR, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class GeometryType : u8 { - AABBS = VK_GEOMETRY_TYPE_AABBS_KHR, - INSTANCES = VK_GEOMETRY_TYPE_INSTANCES_KHR, - TRIANGLES = VK_GEOMETRY_TYPE_TRIANGLES_KHR, - + AABBS = VK_GEOMETRY_TYPE_AABBS_KHR, + INSTANCES = VK_GEOMETRY_TYPE_INSTANCES_KHR, + TRIANGLES = VK_GEOMETRY_TYPE_TRIANGLES_KHR, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageAspectFlag : u8 { - COLOR = VK_IMAGE_ASPECT_COLOR_BIT, - DEPTH = VK_IMAGE_ASPECT_DEPTH_BIT, - NONE = VK_IMAGE_ASPECT_NONE_KHR, - STENCIL = VK_IMAGE_ASPECT_STENCIL_BIT, - + COLOR = VK_IMAGE_ASPECT_COLOR_BIT, + DEPTH = VK_IMAGE_ASPECT_DEPTH_BIT, + NONE = VK_IMAGE_ASPECT_NONE_KHR, + STENCIL = VK_IMAGE_ASPECT_STENCIL_BIT, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageCreateFlag : u16 { - ALIAS = VK_IMAGE_CREATE_ALIAS_BIT, - ARRAY_2D_COMPATIBLE = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, - BLOCK_TEXEL_VIEW_COMPATIBLE = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, - CUBE_COMPATIBLE = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, - DISJOINT = VK_IMAGE_CREATE_DISJOINT_BIT, - EXTENDED_USAGE = VK_IMAGE_CREATE_EXTENDED_USAGE_BIT, - MUTABLE_FORMAT = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, - NONE = 0, - PROTECTED = VK_IMAGE_CREATE_PROTECTED_BIT, - SPARSE_ALIASED = VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, - SPARSE_BINDING = VK_IMAGE_CREATE_SPARSE_BINDING_BIT, - SPARSE_RESIDENCY = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, - SPLIT_INSTANCE_BIND_REGIONS = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT, - - }; - - template <> + ALIAS = VK_IMAGE_CREATE_ALIAS_BIT, + ARRAY_2D_COMPATIBLE = VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, + BLOCK_TEXEL_VIEW_COMPATIBLE = VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT, + CUBE_COMPATIBLE = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, + DISJOINT = VK_IMAGE_CREATE_DISJOINT_BIT, + EXTENDED_USAGE = VK_IMAGE_CREATE_EXTENDED_USAGE_BIT, + MUTABLE_FORMAT = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT, + NONE = 0, + PROTECTED = VK_IMAGE_CREATE_PROTECTED_BIT, + SPARSE_ALIASED = VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, + SPARSE_BINDING = VK_IMAGE_CREATE_SPARSE_BINDING_BIT, + SPARSE_RESIDENCY = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, + SPLIT_INSTANCE_BIND_REGIONS = VK_IMAGE_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageLayout : u32 { - ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, - COLOR_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, - DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, - DEPTH_STENCIL_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - DEPTH_STENCIL_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, - GENERAL = VK_IMAGE_LAYOUT_GENERAL, - PREINITIALIZED = VK_IMAGE_LAYOUT_PREINITIALIZED, - PRESENT_SRC = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - SHADER_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, - SHARED_PRESENT = VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, - TRANSFER_DST_OPTIMAL = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - TRANSFER_SRC_OPTIMAL = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, - UNDEFINED = VK_IMAGE_LAYOUT_UNDEFINED, - - }; - - template <> + ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, + COLOR_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, + DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, + DEPTH_STENCIL_ATTACHMENT_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + DEPTH_STENCIL_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, + GENERAL = VK_IMAGE_LAYOUT_GENERAL, + PREINITIALIZED = VK_IMAGE_LAYOUT_PREINITIALIZED, + PRESENT_SRC = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + SHADER_READ_ONLY_OPTIMAL = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + SHARED_PRESENT = VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR, + TRANSFER_DST_OPTIMAL = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + TRANSFER_SRC_OPTIMAL = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + UNDEFINED = VK_IMAGE_LAYOUT_UNDEFINED, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageTiling : u8 { - LINEAR = VK_IMAGE_TILING_LINEAR, - OPTIMAL = VK_IMAGE_TILING_OPTIMAL, - + LINEAR = VK_IMAGE_TILING_LINEAR, + OPTIMAL = VK_IMAGE_TILING_OPTIMAL, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageType : u8 { - T1D = VK_IMAGE_TYPE_1D, - T2D = VK_IMAGE_TYPE_2D, - T3D = VK_IMAGE_TYPE_3D, - + T1D = VK_IMAGE_TYPE_1D, + T2D = VK_IMAGE_TYPE_2D, + T3D = VK_IMAGE_TYPE_3D, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageUsageFlag : u16 { - COLOR_ATTACHMENT = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, - DEPTH_STENCIL_ATTACHMENT = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, - INPUT_ATTACHMENT = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, - SAMPLED = VK_IMAGE_USAGE_SAMPLED_BIT, - STORAGE = VK_IMAGE_USAGE_STORAGE_BIT, - TRANSFER_DST = VK_IMAGE_USAGE_TRANSFER_DST_BIT, - TRANSFER_SRC = VK_IMAGE_USAGE_TRANSFER_SRC_BIT, - TRANSIENT_ATTACHMENT = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, - - }; - - template <> + COLOR_ATTACHMENT = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + DEPTH_STENCIL_ATTACHMENT = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + INPUT_ATTACHMENT = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT, + SAMPLED = VK_IMAGE_USAGE_SAMPLED_BIT, + STORAGE = VK_IMAGE_USAGE_STORAGE_BIT, + TRANSFER_DST = VK_IMAGE_USAGE_TRANSFER_DST_BIT, + TRANSFER_SRC = VK_IMAGE_USAGE_TRANSFER_SRC_BIT, + TRANSIENT_ATTACHMENT = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ImageViewType : u8 { - CUBE = VK_IMAGE_VIEW_TYPE_CUBE, - CUBE_ARRAY = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, - T1D = VK_IMAGE_VIEW_TYPE_1D, - T1D_ARRAY = VK_IMAGE_VIEW_TYPE_1D_ARRAY, - T2D = VK_IMAGE_VIEW_TYPE_2D, - T2D_ARRAY = VK_IMAGE_VIEW_TYPE_2D_ARRAY, - T3D = VK_IMAGE_VIEW_TYPE_3D, - + CUBE = VK_IMAGE_VIEW_TYPE_CUBE, + CUBE_ARRAY = VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, + T1D = VK_IMAGE_VIEW_TYPE_1D, + T1D_ARRAY = VK_IMAGE_VIEW_TYPE_1D_ARRAY, + T2D = VK_IMAGE_VIEW_TYPE_2D, + T2D_ARRAY = VK_IMAGE_VIEW_TYPE_2D_ARRAY, + T3D = VK_IMAGE_VIEW_TYPE_3D, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class LogicOperation : u8 { - AND = VK_LOGIC_OP_AND, - AND_INVERTED = VK_LOGIC_OP_AND_INVERTED, - AND_REVERSE = VK_LOGIC_OP_AND_REVERSE, - CLEAR = VK_LOGIC_OP_CLEAR, - COPY = VK_LOGIC_OP_COPY, - COPY_INVERTED = VK_LOGIC_OP_COPY_INVERTED, - EQUIVALENT = VK_LOGIC_OP_EQUIVALENT, - INVERT = VK_LOGIC_OP_INVERT, - NAND = VK_LOGIC_OP_NAND, - NO_OP = VK_LOGIC_OP_NO_OP, - NOR = VK_LOGIC_OP_NOR, - OR = VK_LOGIC_OP_OR, - OR_INVERTED = VK_LOGIC_OP_OR_INVERTED, - OR_REVERSE = VK_LOGIC_OP_OR_REVERSE, - SET = VK_LOGIC_OP_SET, - XOR = VK_LOGIC_OP_XOR, - - }; - - template <> + AND = VK_LOGIC_OP_AND, + AND_INVERTED = VK_LOGIC_OP_AND_INVERTED, + AND_REVERSE = VK_LOGIC_OP_AND_REVERSE, + CLEAR = VK_LOGIC_OP_CLEAR, + COPY = VK_LOGIC_OP_COPY, + COPY_INVERTED = VK_LOGIC_OP_COPY_INVERTED, + EQUIVALENT = VK_LOGIC_OP_EQUIVALENT, + INVERT = VK_LOGIC_OP_INVERT, + NAND = VK_LOGIC_OP_NAND, + NO_OP = VK_LOGIC_OP_NO_OP, + NOR = VK_LOGIC_OP_NOR, + OR = VK_LOGIC_OP_OR, + OR_INVERTED = VK_LOGIC_OP_OR_INVERTED, + OR_REVERSE = VK_LOGIC_OP_OR_REVERSE, + SET = VK_LOGIC_OP_SET, + XOR = VK_LOGIC_OP_XOR, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class MemoryPropertyFlag : u8 { - DEVICE_LOCAL = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, - HOST_CACHED = VK_MEMORY_PROPERTY_HOST_CACHED_BIT, - HOST_COHERENT = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, - HOST_VISIBLE = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, - + DEVICE_LOCAL = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + HOST_CACHED = VK_MEMORY_PROPERTY_HOST_CACHED_BIT, + HOST_COHERENT = VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, + HOST_VISIBLE = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PhysicalDeviceType : u8 { - CPU = VK_PHYSICAL_DEVICE_TYPE_CPU, - DISCRETE_GPU = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, - INTEGRATED_GPU = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, - OTHER = VK_PHYSICAL_DEVICE_TYPE_OTHER, - VIRTUAL_GPU = VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, - + CPU = VK_PHYSICAL_DEVICE_TYPE_CPU, + DISCRETE_GPU = VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU, + INTEGRATED_GPU = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU, + OTHER = VK_PHYSICAL_DEVICE_TYPE_OTHER, + VIRTUAL_GPU = VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PipelineBindPoint : u8 { - COMPUTE = VK_PIPELINE_BIND_POINT_COMPUTE, - GRAPHICS = VK_PIPELINE_BIND_POINT_GRAPHICS, - + COMPUTE = VK_PIPELINE_BIND_POINT_COMPUTE, + GRAPHICS = VK_PIPELINE_BIND_POINT_GRAPHICS, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PipelineStageFlag : u32 { - ALL_COMMANDS = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - ALL_GRAPHICS = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, - BOTTOM_OF_PIPE = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, - COLOR_ATTACHMENT_OUTPUT = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - COMPUTE_SHADER = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - DRAW_INDIRECT = VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, - EARLY_FRAGMENT_TESTS = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, - FRAGMENT_SHADER = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - GEOMETRY_SHADER = VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, - HOST = VK_PIPELINE_STAGE_HOST_BIT, - LATE_FRAGMENT_TESTS = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, - TESSELLATION_CONTROL_SHADER = VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, - TESSELLATION_EVALUATION_SHADER = VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, - TOP_OF_PIPE = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - TRANSFER = VK_PIPELINE_STAGE_TRANSFER_BIT, - VERTEX_INPUT = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, - VERTEX_SHADER = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, - - }; - - template <> + ALL_COMMANDS = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, + ALL_GRAPHICS = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, + BOTTOM_OF_PIPE = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, + COLOR_ATTACHMENT_OUTPUT = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + COMPUTE_SHADER = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + DRAW_INDIRECT = VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, + EARLY_FRAGMENT_TESTS = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, + FRAGMENT_SHADER = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + GEOMETRY_SHADER = VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT, + HOST = VK_PIPELINE_STAGE_HOST_BIT, + LATE_FRAGMENT_TESTS = VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + TESSELLATION_CONTROL_SHADER = VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT, + TESSELLATION_EVALUATION_SHADER = VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT, + TOP_OF_PIPE = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + TRANSFER = VK_PIPELINE_STAGE_TRANSFER_BIT, + VERTEX_INPUT = VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, + VERTEX_SHADER = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PixelFormat : u32 { - A1_RGB5_UNORM_PACK16 = VK_FORMAT_A1R5G5B5_UNORM_PACK16, - A2_RGB10I_PACK32 = VK_FORMAT_A2R10G10B10_SINT_PACK32, - A2_RGB10_SNORM_PACK32 = VK_FORMAT_A2R10G10B10_SNORM_PACK32, - A2_RGB10_UNORM_PACK32 = VK_FORMAT_A2R10G10B10_UNORM_PACK32, - A2_RGB10U_PACK32 = VK_FORMAT_A2R10G10B10_UINT_PACK32, - B10_GR11UF_PACK32 = VK_FORMAT_B10G11R11_UFLOAT_PACK32, - BGR8_UNORM = VK_FORMAT_B8G8R8_UNORM, - BGRA8_UNORM = VK_FORMAT_B8G8R8A8_UNORM, - DEPTH16_UNORM = VK_FORMAT_D16_UNORM, - DEPTH16_UNORM_STENCIL8U = VK_FORMAT_D16_UNORM_S8_UINT, - DEPTH24_UNORM_PACK32 = VK_FORMAT_X8_D24_UNORM_PACK32, - DEPTH24_UNORM_STENCIL8U = VK_FORMAT_D24_UNORM_S8_UINT, - DEPTH32F = VK_FORMAT_D32_SFLOAT, - DEPTH32F_STENCIL8U = VK_FORMAT_D32_SFLOAT_S8_UINT, - R16F = VK_FORMAT_R16_SFLOAT, - R16I = VK_FORMAT_R16_SINT, - R16_SNORM = VK_FORMAT_R16_SNORM, - R16U = VK_FORMAT_R16_UINT, - R16_UNORM = VK_FORMAT_R16_UNORM, - R32F = VK_FORMAT_R32_SFLOAT, - R32I = VK_FORMAT_R32_SINT, - R32U = VK_FORMAT_R32_UINT, - R5_G6_B5_UNORM_PACK16 = VK_FORMAT_R5G6B5_UNORM_PACK16, - R8I = VK_FORMAT_R8_SINT, - R8_SNORM = VK_FORMAT_R8_SNORM, - R8U = VK_FORMAT_R8_UINT, - R8_UNORM = VK_FORMAT_R8_UNORM, - RG16F = VK_FORMAT_R16G16_SFLOAT, - RG16I = VK_FORMAT_R16G16_SINT, - RG16_SNORM = VK_FORMAT_R16G16_SNORM, - RG16U = VK_FORMAT_R16G16_UINT, - RG16_UNORM = VK_FORMAT_R16G16_UNORM, - RG32F = VK_FORMAT_R32G32_SFLOAT, - RG32I = VK_FORMAT_R32G32_SINT, - RG32U = VK_FORMAT_R32G32_UINT, - RG8I = VK_FORMAT_R8G8_SINT, - RG8_SNORM = VK_FORMAT_R8G8_SNORM, - RG8U = VK_FORMAT_R8G8_UINT, - RG8_UNORM = VK_FORMAT_R8G8_UNORM, - RGB16F = VK_FORMAT_R16G16B16_SFLOAT, - RGB16I = VK_FORMAT_R16G16B16_SINT, - RGB16_SNORM = VK_FORMAT_R16G16B16_SNORM, - RGB16U = VK_FORMAT_R16G16B16_UINT, - RGB16_UNORM = VK_FORMAT_R16G16B16_UNORM, - RGB32F = VK_FORMAT_R32G32B32_SFLOAT, - RGB32I = VK_FORMAT_R32G32B32_SINT, - RGB32U = VK_FORMAT_R32G32B32_UINT, - RGB8I = VK_FORMAT_R8G8B8_SINT, - RGB8_SNORM = VK_FORMAT_R8G8B8_SNORM, - RGB8U = VK_FORMAT_R8G8B8_UINT, - RGB8_UNORM = VK_FORMAT_R8G8B8_UNORM, - RGBA16F = VK_FORMAT_R16G16B16A16_SFLOAT, - RGBA16I = VK_FORMAT_R16G16B16A16_SINT, - RGBA16_SNORM = VK_FORMAT_R16G16B16A16_SNORM, - RGBA16U = VK_FORMAT_R16G16B16A16_UINT, - RGBA16_UNORM = VK_FORMAT_R16G16B16A16_UNORM, - RGBA32F = VK_FORMAT_R32G32B32A32_SFLOAT, - RGBA32I = VK_FORMAT_R32G32B32A32_SINT, - RGBA32U = VK_FORMAT_R32G32B32A32_UINT, - RGBA4_UNORM_PACK16 = VK_FORMAT_R4G4B4A4_UNORM_PACK16, - RGBA8I = VK_FORMAT_R8G8B8A8_SINT, - RGBA8_SNORM = VK_FORMAT_R8G8B8A8_SNORM, - RGBA8U = VK_FORMAT_R8G8B8A8_UINT, - RGBA8_UNORM = VK_FORMAT_R8G8B8A8_UNORM, - S8U = VK_FORMAT_S8_UINT, - SBGR8 = VK_FORMAT_B8G8R8_SRGB, - SBGRA8 = VK_FORMAT_B8G8R8A8_SRGB, - SR8 = VK_FORMAT_R8_SRGB, - SRG8 = VK_FORMAT_R8G8_SRGB, - SRGB8 = VK_FORMAT_R8G8B8_SRGB, - SRGBA8 = VK_FORMAT_R8G8B8A8_SRGB, - UNDEFINED = VK_FORMAT_UNDEFINED, - - }; - - template <> + A1_RGB5_UNORM_PACK16 = VK_FORMAT_A1R5G5B5_UNORM_PACK16, + A2_RGB10I_PACK32 = VK_FORMAT_A2R10G10B10_SINT_PACK32, + A2_RGB10_SNORM_PACK32 = VK_FORMAT_A2R10G10B10_SNORM_PACK32, + A2_RGB10_UNORM_PACK32 = VK_FORMAT_A2R10G10B10_UNORM_PACK32, + A2_RGB10U_PACK32 = VK_FORMAT_A2R10G10B10_UINT_PACK32, + B10_GR11UF_PACK32 = VK_FORMAT_B10G11R11_UFLOAT_PACK32, + BGR8_UNORM = VK_FORMAT_B8G8R8_UNORM, + BGRA8_UNORM = VK_FORMAT_B8G8R8A8_UNORM, + DEPTH16_UNORM = VK_FORMAT_D16_UNORM, + DEPTH16_UNORM_STENCIL8U = VK_FORMAT_D16_UNORM_S8_UINT, + DEPTH24_UNORM_PACK32 = VK_FORMAT_X8_D24_UNORM_PACK32, + DEPTH24_UNORM_STENCIL8U = VK_FORMAT_D24_UNORM_S8_UINT, + DEPTH32F = VK_FORMAT_D32_SFLOAT, + DEPTH32F_STENCIL8U = VK_FORMAT_D32_SFLOAT_S8_UINT, + R16F = VK_FORMAT_R16_SFLOAT, + R16I = VK_FORMAT_R16_SINT, + R16_SNORM = VK_FORMAT_R16_SNORM, + R16U = VK_FORMAT_R16_UINT, + R16_UNORM = VK_FORMAT_R16_UNORM, + R32F = VK_FORMAT_R32_SFLOAT, + R32I = VK_FORMAT_R32_SINT, + R32U = VK_FORMAT_R32_UINT, + R5_G6_B5_UNORM_PACK16 = VK_FORMAT_R5G6B5_UNORM_PACK16, + R8I = VK_FORMAT_R8_SINT, + R8_SNORM = VK_FORMAT_R8_SNORM, + R8U = VK_FORMAT_R8_UINT, + R8_UNORM = VK_FORMAT_R8_UNORM, + RG16F = VK_FORMAT_R16G16_SFLOAT, + RG16I = VK_FORMAT_R16G16_SINT, + RG16_SNORM = VK_FORMAT_R16G16_SNORM, + RG16U = VK_FORMAT_R16G16_UINT, + RG16_UNORM = VK_FORMAT_R16G16_UNORM, + RG32F = VK_FORMAT_R32G32_SFLOAT, + RG32I = VK_FORMAT_R32G32_SINT, + RG32U = VK_FORMAT_R32G32_UINT, + RG8I = VK_FORMAT_R8G8_SINT, + RG8_SNORM = VK_FORMAT_R8G8_SNORM, + RG8U = VK_FORMAT_R8G8_UINT, + RG8_UNORM = VK_FORMAT_R8G8_UNORM, + RGB16F = VK_FORMAT_R16G16B16_SFLOAT, + RGB16I = VK_FORMAT_R16G16B16_SINT, + RGB16_SNORM = VK_FORMAT_R16G16B16_SNORM, + RGB16U = VK_FORMAT_R16G16B16_UINT, + RGB16_UNORM = VK_FORMAT_R16G16B16_UNORM, + RGB32F = VK_FORMAT_R32G32B32_SFLOAT, + RGB32I = VK_FORMAT_R32G32B32_SINT, + RGB32U = VK_FORMAT_R32G32B32_UINT, + RGB8I = VK_FORMAT_R8G8B8_SINT, + RGB8_SNORM = VK_FORMAT_R8G8B8_SNORM, + RGB8U = VK_FORMAT_R8G8B8_UINT, + RGB8_UNORM = VK_FORMAT_R8G8B8_UNORM, + RGBA16F = VK_FORMAT_R16G16B16A16_SFLOAT, + RGBA16I = VK_FORMAT_R16G16B16A16_SINT, + RGBA16_SNORM = VK_FORMAT_R16G16B16A16_SNORM, + RGBA16U = VK_FORMAT_R16G16B16A16_UINT, + RGBA16_UNORM = VK_FORMAT_R16G16B16A16_UNORM, + RGBA32F = VK_FORMAT_R32G32B32A32_SFLOAT, + RGBA32I = VK_FORMAT_R32G32B32A32_SINT, + RGBA32U = VK_FORMAT_R32G32B32A32_UINT, + RGBA4_UNORM_PACK16 = VK_FORMAT_R4G4B4A4_UNORM_PACK16, + RGBA8I = VK_FORMAT_R8G8B8A8_SINT, + RGBA8_SNORM = VK_FORMAT_R8G8B8A8_SNORM, + RGBA8U = VK_FORMAT_R8G8B8A8_UINT, + RGBA8_UNORM = VK_FORMAT_R8G8B8A8_UNORM, + S8U = VK_FORMAT_S8_UINT, + SBGR8 = VK_FORMAT_B8G8R8_SRGB, + SBGRA8 = VK_FORMAT_B8G8R8A8_SRGB, + SR8 = VK_FORMAT_R8_SRGB, + SRG8 = VK_FORMAT_R8G8_SRGB, + SRGB8 = VK_FORMAT_R8G8B8_SRGB, + SRGBA8 = VK_FORMAT_R8G8B8A8_SRGB, + UNDEFINED = VK_FORMAT_UNDEFINED, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PolygonMode : u8 { - FILL = VK_POLYGON_MODE_FILL, - LINE = VK_POLYGON_MODE_LINE, - POINT = VK_POLYGON_MODE_POINT, - + FILL = VK_POLYGON_MODE_FILL, + LINE = VK_POLYGON_MODE_LINE, + POINT = VK_POLYGON_MODE_POINT, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PresentMode : u32 { - FIFO = VK_PRESENT_MODE_FIFO_KHR, - FIFO_RELAXED = VK_PRESENT_MODE_FIFO_RELAXED_KHR, - IMMEDIATE = VK_PRESENT_MODE_IMMEDIATE_KHR, - MAILBOX = VK_PRESENT_MODE_MAILBOX_KHR, - SHARED_CONTINUOUS_REFRESH = VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR, - SHARED_DEMAND_REFRESH = VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR, - + FIFO = VK_PRESENT_MODE_FIFO_KHR, + FIFO_RELAXED = VK_PRESENT_MODE_FIFO_RELAXED_KHR, + IMMEDIATE = VK_PRESENT_MODE_IMMEDIATE_KHR, + MAILBOX = VK_PRESENT_MODE_MAILBOX_KHR, + SHARED_CONTINUOUS_REFRESH = VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR, + SHARED_DEMAND_REFRESH = VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class PrimitiveTopology : u8 { - LINE_LIST = VK_PRIMITIVE_TOPOLOGY_LINE_LIST, - LINE_STRIP = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, - POINT_LIST = VK_PRIMITIVE_TOPOLOGY_POINT_LIST, - TRIANGLE_FAN = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, - TRIANGLE_LIST = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, - TRIANGLE_STRIP = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, - + LINE_LIST = VK_PRIMITIVE_TOPOLOGY_LINE_LIST, + LINE_STRIP = VK_PRIMITIVE_TOPOLOGY_LINE_STRIP, + POINT_LIST = VK_PRIMITIVE_TOPOLOGY_POINT_LIST, + TRIANGLE_FAN = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN, + TRIANGLE_LIST = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, + TRIANGLE_STRIP = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class QueueFlag : u8 { - COMPUTE = VK_QUEUE_COMPUTE_BIT, - GRAPHICS = VK_QUEUE_GRAPHICS_BIT, - NONE = 0, - PROTECTED = VK_QUEUE_PROTECTED_BIT, - SPARSE_BINDING = VK_QUEUE_SPARSE_BINDING_BIT, - TRANSFER = VK_QUEUE_TRANSFER_BIT, - + COMPUTE = VK_QUEUE_COMPUTE_BIT, + GRAPHICS = VK_QUEUE_GRAPHICS_BIT, + NONE = 0, + PROTECTED = VK_QUEUE_PROTECTED_BIT, + SPARSE_BINDING = VK_QUEUE_SPARSE_BINDING_BIT, + TRANSFER = VK_QUEUE_TRANSFER_BIT, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ResolveModeFlag : u8 { - AVERAGE = VK_RESOLVE_MODE_AVERAGE_BIT, - EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID = VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID, - MAX = VK_RESOLVE_MODE_MAX_BIT, - MIN = VK_RESOLVE_MODE_MIN_BIT, - NONE = VK_RESOLVE_MODE_NONE, - SAMPLE_ZERO = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, - + AVERAGE = VK_RESOLVE_MODE_AVERAGE_BIT, + EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID = VK_RESOLVE_MODE_EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID, + MAX = VK_RESOLVE_MODE_MAX_BIT, + MIN = VK_RESOLVE_MODE_MIN_BIT, + NONE = VK_RESOLVE_MODE_NONE, + SAMPLE_ZERO = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class Result : i32 { - ERROR_DEVICE_LOST = VK_ERROR_DEVICE_LOST, - ERROR_EXTENSION_NOT_PRESENT = VK_ERROR_EXTENSION_NOT_PRESENT, - ERROR_FEATURE_NOT_PRESENT = VK_ERROR_FEATURE_NOT_PRESENT, - ERROR_FORMAT_NOT_SUPPORTED = VK_ERROR_FORMAT_NOT_SUPPORTED, - ERROR_FRAGMENTATION = VK_ERROR_FRAGMENTATION, - ERROR_FRAGMENTED_POOL = VK_ERROR_FRAGMENTED_POOL, - ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST = VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT, - ERROR_INCOMPATIBLE_DISPLAY = VK_ERROR_INCOMPATIBLE_DISPLAY_KHR, - ERROR_INCOMPATIBLE_DRIVER = VK_ERROR_INCOMPATIBLE_DRIVER, - ERROR_INITIALIZATION_FAILED = VK_ERROR_INITIALIZATION_FAILED, - ERROR_INVALID_EXTERNAL_HANDLE = VK_ERROR_INVALID_EXTERNAL_HANDLE, - ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, - ERROR_LAYER_NOT_PRESENT = VK_ERROR_LAYER_NOT_PRESENT, - ERROR_MEMORY_MAP_FAILED = VK_ERROR_MEMORY_MAP_FAILED, - ERROR_NATIVE_WINDOW_IN_USE = VK_ERROR_NATIVE_WINDOW_IN_USE_KHR, - ERROR_NOT_PERMITTED = VK_ERROR_NOT_PERMITTED, - ERROR_OUT_OF_DATE = VK_ERROR_OUT_OF_DATE_KHR, - ERROR_OUT_OF_DEVICE_MEMORY = VK_ERROR_OUT_OF_DEVICE_MEMORY, - ERROR_OUT_OF_HOST_MEMORY = VK_ERROR_OUT_OF_HOST_MEMORY, - ERROR_OUT_OF_POOL_MEMORY = VK_ERROR_OUT_OF_POOL_MEMORY, - ERROR_SURFACE_LOST = VK_ERROR_SURFACE_LOST_KHR, - ERROR_TOO_MANY_OBJECTS = VK_ERROR_TOO_MANY_OBJECTS, - ERROR_UNKNOWN = VK_ERROR_UNKNOWN, - ERROR_VALIDATION_FAILED = VK_ERROR_VALIDATION_FAILED_EXT, - EVENT_RESET = VK_EVENT_RESET, - EVENT_SET = VK_EVENT_SET, - INCOMPLETE = VK_INCOMPLETE, - NOT_READY = VK_NOT_READY, - OPERATION_DEFERRED = VK_OPERATION_DEFERRED_KHR, - OPERATION_NOT_DEFERRED = VK_OPERATION_NOT_DEFERRED_KHR, - PIPELINE_COMPILE_REQUIRED = VK_PIPELINE_COMPILE_REQUIRED, - SUBOPTIMAL = VK_SUBOPTIMAL_KHR, - SUCCESS = VK_SUCCESS, - THREAD_DONE = VK_THREAD_DONE_KHR, - THREAD_IDLE = VK_THREAD_IDLE_KHR, - TIMEOUT = VK_TIMEOUT, - - }; - - template <> + ERROR_DEVICE_LOST = VK_ERROR_DEVICE_LOST, + ERROR_EXTENSION_NOT_PRESENT = VK_ERROR_EXTENSION_NOT_PRESENT, + ERROR_FEATURE_NOT_PRESENT = VK_ERROR_FEATURE_NOT_PRESENT, + ERROR_FORMAT_NOT_SUPPORTED = VK_ERROR_FORMAT_NOT_SUPPORTED, + ERROR_FRAGMENTATION = VK_ERROR_FRAGMENTATION, + ERROR_FRAGMENTED_POOL = VK_ERROR_FRAGMENTED_POOL, + ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST = VK_ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT, + ERROR_INCOMPATIBLE_DISPLAY = VK_ERROR_INCOMPATIBLE_DISPLAY_KHR, + ERROR_INCOMPATIBLE_DRIVER = VK_ERROR_INCOMPATIBLE_DRIVER, + ERROR_INITIALIZATION_FAILED = VK_ERROR_INITIALIZATION_FAILED, + ERROR_INVALID_EXTERNAL_HANDLE = VK_ERROR_INVALID_EXTERNAL_HANDLE, + ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS = VK_ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, + ERROR_LAYER_NOT_PRESENT = VK_ERROR_LAYER_NOT_PRESENT, + ERROR_MEMORY_MAP_FAILED = VK_ERROR_MEMORY_MAP_FAILED, + ERROR_NATIVE_WINDOW_IN_USE = VK_ERROR_NATIVE_WINDOW_IN_USE_KHR, + ERROR_NOT_PERMITTED = VK_ERROR_NOT_PERMITTED, + ERROR_OUT_OF_DATE = VK_ERROR_OUT_OF_DATE_KHR, + ERROR_OUT_OF_DEVICE_MEMORY = VK_ERROR_OUT_OF_DEVICE_MEMORY, + ERROR_OUT_OF_HOST_MEMORY = VK_ERROR_OUT_OF_HOST_MEMORY, + ERROR_OUT_OF_POOL_MEMORY = VK_ERROR_OUT_OF_POOL_MEMORY, + ERROR_SURFACE_LOST = VK_ERROR_SURFACE_LOST_KHR, + ERROR_TOO_MANY_OBJECTS = VK_ERROR_TOO_MANY_OBJECTS, + ERROR_UNKNOWN = VK_ERROR_UNKNOWN, + ERROR_VALIDATION_FAILED = VK_ERROR_VALIDATION_FAILED_EXT, + EVENT_RESET = VK_EVENT_RESET, + EVENT_SET = VK_EVENT_SET, + INCOMPLETE = VK_INCOMPLETE, + NOT_READY = VK_NOT_READY, + OPERATION_DEFERRED = VK_OPERATION_DEFERRED_KHR, + OPERATION_NOT_DEFERRED = VK_OPERATION_NOT_DEFERRED_KHR, + PIPELINE_COMPILE_REQUIRED = VK_PIPELINE_COMPILE_REQUIRED, + SUBOPTIMAL = VK_SUBOPTIMAL_KHR, + SUCCESS = VK_SUCCESS, + THREAD_DONE = VK_THREAD_DONE_KHR, + THREAD_IDLE = VK_THREAD_IDLE_KHR, + TIMEOUT = VK_TIMEOUT, + }; + + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class SampleCountFlag : u8 { - C1 = VK_SAMPLE_COUNT_1_BIT, - C16 = VK_SAMPLE_COUNT_16_BIT, - C2 = VK_SAMPLE_COUNT_2_BIT, - C32 = VK_SAMPLE_COUNT_32_BIT, - C4 = VK_SAMPLE_COUNT_4_BIT, - C64 = VK_SAMPLE_COUNT_64_BIT, - C8 = VK_SAMPLE_COUNT_8_BIT, - + C1 = VK_SAMPLE_COUNT_1_BIT, + C16 = VK_SAMPLE_COUNT_16_BIT, + C2 = VK_SAMPLE_COUNT_2_BIT, + C32 = VK_SAMPLE_COUNT_32_BIT, + C4 = VK_SAMPLE_COUNT_4_BIT, + C64 = VK_SAMPLE_COUNT_64_BIT, + C8 = VK_SAMPLE_COUNT_8_BIT, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class SamplerAddressMode : u8 { - CLAMP_TO_BORDER = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, - CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, - MIRROR_CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, - MIRRORED_REPEAT = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, - REPEAT = VK_SAMPLER_ADDRESS_MODE_REPEAT, - + CLAMP_TO_BORDER = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER, + CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, + MIRROR_CLAMP_TO_EDGE = VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE, + MIRRORED_REPEAT = VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT, + REPEAT = VK_SAMPLER_ADDRESS_MODE_REPEAT, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class SamplerMipmapMode : u8 { - LINEAR = VK_SAMPLER_MIPMAP_MODE_LINEAR, - NEAREST = VK_SAMPLER_MIPMAP_MODE_NEAREST, - + LINEAR = VK_SAMPLER_MIPMAP_MODE_LINEAR, + NEAREST = VK_SAMPLER_MIPMAP_MODE_NEAREST, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class ShaderStageFlag : u8 { - COMPUTE = VK_SHADER_STAGE_COMPUTE_BIT, - FRAGMENT = VK_SHADER_STAGE_FRAGMENT_BIT, - GEOMETRY = VK_SHADER_STAGE_GEOMETRY_BIT, - NONE = 0, - VERTEX = VK_SHADER_STAGE_VERTEX_BIT, - + COMPUTE = VK_SHADER_STAGE_COMPUTE_BIT, + FRAGMENT = VK_SHADER_STAGE_FRAGMENT_BIT, + GEOMETRY = VK_SHADER_STAGE_GEOMETRY_BIT, + NONE = 0, + VERTEX = VK_SHADER_STAGE_VERTEX_BIT, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class StencilFaceFlag : u8 { - BACK = VK_STENCIL_FACE_BACK_BIT, - FRONT = VK_STENCIL_FACE_FRONT_BIT, - FRONT_AND_BACK = FRONT | BACK, - + BACK = VK_STENCIL_FACE_BACK_BIT, + FRONT = VK_STENCIL_FACE_FRONT_BIT, + FRONT_AND_BACK = FRONT | BACK, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - + enum class VertexInputRate : u8 { - INSTANCE = VK_VERTEX_INPUT_RATE_INSTANCE, - VERTEX = VK_VERTEX_INPUT_RATE_VERTEX, - + INSTANCE = VK_VERTEX_INPUT_RATE_INSTANCE, + VERTEX = VK_VERTEX_INPUT_RATE_VERTEX, }; - template <> + template<> inline constexpr auto details::IS_VULKAN_ENUMERATION = true; - namespace vk { template @@ -807,11 +762,11 @@ export { requires(core::meta::IsPlainEnumeration or core::meta::Is) [[nodiscard]] constexpr auto from_vk(U value) noexcept -> T; - } + } // namespace vk [[nodiscard]] constexpr auto from_image(image::Image::Format format) -> PixelFormat; - + [[nodiscard]] constexpr auto is_depth_only_format(PixelFormat format) noexcept -> bool; [[nodiscard]] @@ -827,2527 +782,2636 @@ export { constexpr auto get_format_channel_count(PixelFormat format) noexcept -> u8; [[nodiscard]] constexpr auto get_format_element_count(PixelFormat format) noexcept -> u8; - } + } // namespace stormkit::gpu FLAG_ENUM(stormkit::gpu::AccessFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ, - stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE, - stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ, - stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE, - stormkit::gpu::AccessFlag::HOST_READ, - stormkit::gpu::AccessFlag::HOST_WRITE, - stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ, - stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ, - stormkit::gpu::AccessFlag::MEMORY_READ, - stormkit::gpu::AccessFlag::MEMORY_WRITE, - stormkit::gpu::AccessFlag::NONE, - stormkit::gpu::AccessFlag::SHADER_READ, - stormkit::gpu::AccessFlag::SHADER_WRITE, - stormkit::gpu::AccessFlag::TRANSFER_READ, - stormkit::gpu::AccessFlag::TRANSFER_WRITE, - stormkit::gpu::AccessFlag::UNIFORM_READ, - stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ, - - }; - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::AccessFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: return "AccessFlag::COLOR_ATTACHMENT_WRITE"; - case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE"; - case stormkit::gpu::AccessFlag::HOST_READ: return "AccessFlag::HOST_READ"; - case stormkit::gpu::AccessFlag::HOST_WRITE: return "AccessFlag::HOST_WRITE"; - case stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ: return "AccessFlag::INDIRECT_COMMAND_READ"; - case stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ: return "AccessFlag::INPUT_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::MEMORY_READ: return "AccessFlag::MEMORY_READ"; - case stormkit::gpu::AccessFlag::MEMORY_WRITE: return "AccessFlag::MEMORY_WRITE"; - case stormkit::gpu::AccessFlag::NONE: return "AccessFlag::NONE"; - case stormkit::gpu::AccessFlag::SHADER_READ: return "AccessFlag::SHADER_READ"; - case stormkit::gpu::AccessFlag::SHADER_WRITE: return "AccessFlag::SHADER_WRITE"; - case stormkit::gpu::AccessFlag::TRANSFER_READ: return "AccessFlag::TRANSFER_READ"; - case stormkit::gpu::AccessFlag::TRANSFER_WRITE: return "AccessFlag::TRANSFER_WRITE"; - case stormkit::gpu::AccessFlag::UNIFORM_READ: return "AccessFlag::UNIFORM_READ"; - case stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ: return "AccessFlag::VERTEX_ATTRIBUTE_READ"; - + stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ, + stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE, + stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ, + stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE, + stormkit::gpu::AccessFlag::HOST_READ, + stormkit::gpu::AccessFlag::HOST_WRITE, + stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ, + stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ, + stormkit::gpu::AccessFlag::MEMORY_READ, + stormkit::gpu::AccessFlag::MEMORY_WRITE, + stormkit::gpu::AccessFlag::NONE, + stormkit::gpu::AccessFlag::SHADER_READ, + stormkit::gpu::AccessFlag::SHADER_WRITE, + stormkit::gpu::AccessFlag::TRANSFER_READ, + stormkit::gpu::AccessFlag::TRANSFER_WRITE, + stormkit::gpu::AccessFlag::UNIFORM_READ, + stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ, + + }; + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::AccessFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: return "AccessFlag::COLOR_ATTACHMENT_WRITE"; + case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE"; + case stormkit::gpu::AccessFlag::HOST_READ: return "AccessFlag::HOST_READ"; + case stormkit::gpu::AccessFlag::HOST_WRITE: return "AccessFlag::HOST_WRITE"; + case stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ: return "AccessFlag::INDIRECT_COMMAND_READ"; + case stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ: return "AccessFlag::INPUT_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::MEMORY_READ: return "AccessFlag::MEMORY_READ"; + case stormkit::gpu::AccessFlag::MEMORY_WRITE: return "AccessFlag::MEMORY_WRITE"; + case stormkit::gpu::AccessFlag::NONE: return "AccessFlag::NONE"; + case stormkit::gpu::AccessFlag::SHADER_READ: return "AccessFlag::SHADER_READ"; + case stormkit::gpu::AccessFlag::SHADER_WRITE: return "AccessFlag::SHADER_WRITE"; + case stormkit::gpu::AccessFlag::TRANSFER_READ: return "AccessFlag::TRANSFER_READ"; + case stormkit::gpu::AccessFlag::TRANSFER_WRITE: return "AccessFlag::TRANSFER_WRITE"; + case stormkit::gpu::AccessFlag::UNIFORM_READ: return "AccessFlag::UNIFORM_READ"; + case stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ: return "AccessFlag::VERTEX_ATTRIBUTE_READ"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::AccessFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: return "AccessFlag::COLOR_ATTACHMENT_WRITE"; - case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE"; - case stormkit::gpu::AccessFlag::HOST_READ: return "AccessFlag::HOST_READ"; - case stormkit::gpu::AccessFlag::HOST_WRITE: return "AccessFlag::HOST_WRITE"; - case stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ: return "AccessFlag::INDIRECT_COMMAND_READ"; - case stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ: return "AccessFlag::INPUT_ATTACHMENT_READ"; - case stormkit::gpu::AccessFlag::MEMORY_READ: return "AccessFlag::MEMORY_READ"; - case stormkit::gpu::AccessFlag::MEMORY_WRITE: return "AccessFlag::MEMORY_WRITE"; - case stormkit::gpu::AccessFlag::NONE: return "AccessFlag::NONE"; - case stormkit::gpu::AccessFlag::SHADER_READ: return "AccessFlag::SHADER_READ"; - case stormkit::gpu::AccessFlag::SHADER_WRITE: return "AccessFlag::SHADER_WRITE"; - case stormkit::gpu::AccessFlag::TRANSFER_READ: return "AccessFlag::TRANSFER_READ"; - case stormkit::gpu::AccessFlag::TRANSFER_WRITE: return "AccessFlag::TRANSFER_WRITE"; - case stormkit::gpu::AccessFlag::UNIFORM_READ: return "AccessFlag::UNIFORM_READ"; - case stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ: return "AccessFlag::VERTEX_ATTRIBUTE_READ"; - + switch (value) { + case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: return "AccessFlag::COLOR_ATTACHMENT_WRITE"; + case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE: return "AccessFlag::DEPTH_STENCIL_ATTACHMENT_WRITE"; + case stormkit::gpu::AccessFlag::HOST_READ: return "AccessFlag::HOST_READ"; + case stormkit::gpu::AccessFlag::HOST_WRITE: return "AccessFlag::HOST_WRITE"; + case stormkit::gpu::AccessFlag::INDIRECT_COMMAND_READ: return "AccessFlag::INDIRECT_COMMAND_READ"; + case stormkit::gpu::AccessFlag::INPUT_ATTACHMENT_READ: return "AccessFlag::INPUT_ATTACHMENT_READ"; + case stormkit::gpu::AccessFlag::MEMORY_READ: return "AccessFlag::MEMORY_READ"; + case stormkit::gpu::AccessFlag::MEMORY_WRITE: return "AccessFlag::MEMORY_WRITE"; + case stormkit::gpu::AccessFlag::NONE: return "AccessFlag::NONE"; + case stormkit::gpu::AccessFlag::SHADER_READ: return "AccessFlag::SHADER_READ"; + case stormkit::gpu::AccessFlag::SHADER_WRITE: return "AccessFlag::SHADER_WRITE"; + case stormkit::gpu::AccessFlag::TRANSFER_READ: return "AccessFlag::TRANSFER_READ"; + case stormkit::gpu::AccessFlag::TRANSFER_WRITE: return "AccessFlag::TRANSFER_WRITE"; + case stormkit::gpu::AccessFlag::UNIFORM_READ: return "AccessFlag::UNIFORM_READ"; + case stormkit::gpu::AccessFlag::VERTEX_ATTRIBUTE_READ: return "AccessFlag::VERTEX_ATTRIBUTE_READ"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::AttachmentLoadOperation) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::AttachmentLoadOperation::CLEAR, - stormkit::gpu::AttachmentLoadOperation::DONT_CARE, - stormkit::gpu::AttachmentLoadOperation::LOAD, - + stormkit::gpu::AttachmentLoadOperation::CLEAR, + stormkit::gpu::AttachmentLoadOperation::DONT_CARE, + stormkit::gpu::AttachmentLoadOperation::LOAD, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::AttachmentLoadOperation value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; - case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; - case stormkit::gpu::AttachmentLoadOperation::LOAD: return "AttachmentLoadOperation::LOAD"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::AttachmentLoadOperation + value) noexcept -> std::string_view { + switch (value) { + case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; + case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; + case stormkit::gpu::AttachmentLoadOperation::LOAD: return "AttachmentLoadOperation::LOAD"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentLoadOperation value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; - case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; - case stormkit::gpu::AttachmentLoadOperation::LOAD: return "AttachmentLoadOperation::LOAD"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentLoadOperation + value) noexcept -> std::string { + switch (value) { + case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; + case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; + case stormkit::gpu::AttachmentLoadOperation::LOAD: return "AttachmentLoadOperation::LOAD"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::AttachmentStoreOperation) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::AttachmentStoreOperation::DONT_CARE, - stormkit::gpu::AttachmentStoreOperation::STORE, - + stormkit::gpu::AttachmentStoreOperation::DONT_CARE, + stormkit::gpu::AttachmentStoreOperation::STORE, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::AttachmentStoreOperation value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; - case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::AttachmentStoreOperation + value) noexcept -> std::string_view { + switch (value) { + case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; + case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentStoreOperation value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; - case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentStoreOperation + value) noexcept -> std::string { + switch (value) { + case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; + case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::BlendFactor) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::BlendFactor::CONSTANT_ALPHA, - stormkit::gpu::BlendFactor::CONSTANT_COLOR, - stormkit::gpu::BlendFactor::DST_ALPHA, - stormkit::gpu::BlendFactor::DST_COLOR, - stormkit::gpu::BlendFactor::ONE, - stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA, - stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR, - stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA, - stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR, - stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA, - stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR, - stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA, - stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR, - stormkit::gpu::BlendFactor::SRC1_ALPHA, - stormkit::gpu::BlendFactor::SRC1_COLOR, - stormkit::gpu::BlendFactor::SRC_ALPHA, - stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE, - stormkit::gpu::BlendFactor::SRC_COLOR, - stormkit::gpu::BlendFactor::ZERO, - - }; - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::BlendFactor value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::BlendFactor::CONSTANT_ALPHA: return "BlendFactor::CONSTANT_ALPHA"; - case stormkit::gpu::BlendFactor::CONSTANT_COLOR: return "BlendFactor::CONSTANT_COLOR"; - case stormkit::gpu::BlendFactor::DST_ALPHA: return "BlendFactor::DST_ALPHA"; - case stormkit::gpu::BlendFactor::DST_COLOR: return "BlendFactor::DST_COLOR"; - case stormkit::gpu::BlendFactor::ONE: return "BlendFactor::ONE"; - case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: return "BlendFactor::ONE_MINUS_CONSTANT_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR: return "BlendFactor::ONE_MINUS_CONSTANT_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA: return "BlendFactor::ONE_MINUS_DST_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR: return "BlendFactor::ONE_MINUS_DST_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA: return "BlendFactor::ONE_MINUS_SRC1_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR: return "BlendFactor::ONE_MINUS_SRC1_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA: return "BlendFactor::ONE_MINUS_SRC_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR: return "BlendFactor::ONE_MINUS_SRC_COLOR"; - case stormkit::gpu::BlendFactor::SRC1_ALPHA: return "BlendFactor::SRC1_ALPHA"; - case stormkit::gpu::BlendFactor::SRC1_COLOR: return "BlendFactor::SRC1_COLOR"; - case stormkit::gpu::BlendFactor::SRC_ALPHA: return "BlendFactor::SRC_ALPHA"; - case stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE: return "BlendFactor::SRC_ALPHA_SATURATE"; - case stormkit::gpu::BlendFactor::SRC_COLOR: return "BlendFactor::SRC_COLOR"; - case stormkit::gpu::BlendFactor::ZERO: return "BlendFactor::ZERO"; - - } - std::unreachable(); - } - template<> - STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::BlendFactor value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::BlendFactor::CONSTANT_ALPHA: return "BlendFactor::CONSTANT_ALPHA"; - case stormkit::gpu::BlendFactor::CONSTANT_COLOR: return "BlendFactor::CONSTANT_COLOR"; - case stormkit::gpu::BlendFactor::DST_ALPHA: return "BlendFactor::DST_ALPHA"; - case stormkit::gpu::BlendFactor::DST_COLOR: return "BlendFactor::DST_COLOR"; - case stormkit::gpu::BlendFactor::ONE: return "BlendFactor::ONE"; - case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: return "BlendFactor::ONE_MINUS_CONSTANT_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR: return "BlendFactor::ONE_MINUS_CONSTANT_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA: return "BlendFactor::ONE_MINUS_DST_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR: return "BlendFactor::ONE_MINUS_DST_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA: return "BlendFactor::ONE_MINUS_SRC1_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR: return "BlendFactor::ONE_MINUS_SRC1_COLOR"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA: return "BlendFactor::ONE_MINUS_SRC_ALPHA"; - case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR: return "BlendFactor::ONE_MINUS_SRC_COLOR"; - case stormkit::gpu::BlendFactor::SRC1_ALPHA: return "BlendFactor::SRC1_ALPHA"; - case stormkit::gpu::BlendFactor::SRC1_COLOR: return "BlendFactor::SRC1_COLOR"; - case stormkit::gpu::BlendFactor::SRC_ALPHA: return "BlendFactor::SRC_ALPHA"; - case stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE: return "BlendFactor::SRC_ALPHA_SATURATE"; - case stormkit::gpu::BlendFactor::SRC_COLOR: return "BlendFactor::SRC_COLOR"; - case stormkit::gpu::BlendFactor::ZERO: return "BlendFactor::ZERO"; - + stormkit::gpu::BlendFactor::CONSTANT_ALPHA, + stormkit::gpu::BlendFactor::CONSTANT_COLOR, + stormkit::gpu::BlendFactor::DST_ALPHA, + stormkit::gpu::BlendFactor::DST_COLOR, + stormkit::gpu::BlendFactor::ONE, + stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA, + stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR, + stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA, + stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR, + stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA, + stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR, + stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA, + stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR, + stormkit::gpu::BlendFactor::SRC1_ALPHA, + stormkit::gpu::BlendFactor::SRC1_COLOR, + stormkit::gpu::BlendFactor::SRC_ALPHA, + stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE, + stormkit::gpu::BlendFactor::SRC_COLOR, + stormkit::gpu::BlendFactor::ZERO, + + }; + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::BlendFactor value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::BlendFactor::CONSTANT_ALPHA: return "BlendFactor::CONSTANT_ALPHA"; + case stormkit::gpu::BlendFactor::CONSTANT_COLOR: return "BlendFactor::CONSTANT_COLOR"; + case stormkit::gpu::BlendFactor::DST_ALPHA: return "BlendFactor::DST_ALPHA"; + case stormkit::gpu::BlendFactor::DST_COLOR: return "BlendFactor::DST_COLOR"; + case stormkit::gpu::BlendFactor::ONE: return "BlendFactor::ONE"; + case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: return "BlendFactor::ONE_MINUS_CONSTANT_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR: return "BlendFactor::ONE_MINUS_CONSTANT_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA: return "BlendFactor::ONE_MINUS_DST_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR: return "BlendFactor::ONE_MINUS_DST_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA: return "BlendFactor::ONE_MINUS_SRC1_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR: return "BlendFactor::ONE_MINUS_SRC1_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA: return "BlendFactor::ONE_MINUS_SRC_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR: return "BlendFactor::ONE_MINUS_SRC_COLOR"; + case stormkit::gpu::BlendFactor::SRC1_ALPHA: return "BlendFactor::SRC1_ALPHA"; + case stormkit::gpu::BlendFactor::SRC1_COLOR: return "BlendFactor::SRC1_COLOR"; + case stormkit::gpu::BlendFactor::SRC_ALPHA: return "BlendFactor::SRC_ALPHA"; + case stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE: return "BlendFactor::SRC_ALPHA_SATURATE"; + case stormkit::gpu::BlendFactor::SRC_COLOR: return "BlendFactor::SRC_COLOR"; + case stormkit::gpu::BlendFactor::ZERO: return "BlendFactor::ZERO"; + } + std::unreachable(); + } + + template<> + STORMKIT_FORCE_INLINE + constexpr auto stormkit::core::to_string(stormkit::gpu::BlendFactor value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::BlendFactor::CONSTANT_ALPHA: return "BlendFactor::CONSTANT_ALPHA"; + case stormkit::gpu::BlendFactor::CONSTANT_COLOR: return "BlendFactor::CONSTANT_COLOR"; + case stormkit::gpu::BlendFactor::DST_ALPHA: return "BlendFactor::DST_ALPHA"; + case stormkit::gpu::BlendFactor::DST_COLOR: return "BlendFactor::DST_COLOR"; + case stormkit::gpu::BlendFactor::ONE: return "BlendFactor::ONE"; + case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_ALPHA: return "BlendFactor::ONE_MINUS_CONSTANT_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_CONSTANT_COLOR: return "BlendFactor::ONE_MINUS_CONSTANT_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_DST_ALPHA: return "BlendFactor::ONE_MINUS_DST_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_DST_COLOR: return "BlendFactor::ONE_MINUS_DST_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_ALPHA: return "BlendFactor::ONE_MINUS_SRC1_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC1_COLOR: return "BlendFactor::ONE_MINUS_SRC1_COLOR"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_ALPHA: return "BlendFactor::ONE_MINUS_SRC_ALPHA"; + case stormkit::gpu::BlendFactor::ONE_MINUS_SRC_COLOR: return "BlendFactor::ONE_MINUS_SRC_COLOR"; + case stormkit::gpu::BlendFactor::SRC1_ALPHA: return "BlendFactor::SRC1_ALPHA"; + case stormkit::gpu::BlendFactor::SRC1_COLOR: return "BlendFactor::SRC1_COLOR"; + case stormkit::gpu::BlendFactor::SRC_ALPHA: return "BlendFactor::SRC_ALPHA"; + case stormkit::gpu::BlendFactor::SRC_ALPHA_SATURATE: return "BlendFactor::SRC_ALPHA_SATURATE"; + case stormkit::gpu::BlendFactor::SRC_COLOR: return "BlendFactor::SRC_COLOR"; + case stormkit::gpu::BlendFactor::ZERO: return "BlendFactor::ZERO"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::BlendOperation) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::BlendOperation::ADD, - stormkit::gpu::BlendOperation::MAX, - stormkit::gpu::BlendOperation::MIN, - stormkit::gpu::BlendOperation::REVERSE_SUBTRACT, - stormkit::gpu::BlendOperation::SUBTRACT, - + stormkit::gpu::BlendOperation::ADD, stormkit::gpu::BlendOperation::MAX, + stormkit::gpu::BlendOperation::MIN, stormkit::gpu::BlendOperation::REVERSE_SUBTRACT, + stormkit::gpu::BlendOperation::SUBTRACT, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::BlendOperation value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::BlendOperation::ADD: return "BlendOperation::ADD"; - case stormkit::gpu::BlendOperation::MAX: return "BlendOperation::MAX"; - case stormkit::gpu::BlendOperation::MIN: return "BlendOperation::MIN"; - case stormkit::gpu::BlendOperation::REVERSE_SUBTRACT: return "BlendOperation::REVERSE_SUBTRACT"; - case stormkit::gpu::BlendOperation::SUBTRACT: return "BlendOperation::SUBTRACT"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::BlendOperation value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::BlendOperation::ADD: return "BlendOperation::ADD"; + case stormkit::gpu::BlendOperation::MAX: return "BlendOperation::MAX"; + case stormkit::gpu::BlendOperation::MIN: return "BlendOperation::MIN"; + case stormkit::gpu::BlendOperation::REVERSE_SUBTRACT: return "BlendOperation::REVERSE_SUBTRACT"; + case stormkit::gpu::BlendOperation::SUBTRACT: return "BlendOperation::SUBTRACT"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::BlendOperation value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::BlendOperation::ADD: return "BlendOperation::ADD"; - case stormkit::gpu::BlendOperation::MAX: return "BlendOperation::MAX"; - case stormkit::gpu::BlendOperation::MIN: return "BlendOperation::MIN"; - case stormkit::gpu::BlendOperation::REVERSE_SUBTRACT: return "BlendOperation::REVERSE_SUBTRACT"; - case stormkit::gpu::BlendOperation::SUBTRACT: return "BlendOperation::SUBTRACT"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::BlendOperation value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::BlendOperation::ADD: return "BlendOperation::ADD"; + case stormkit::gpu::BlendOperation::MAX: return "BlendOperation::MAX"; + case stormkit::gpu::BlendOperation::MIN: return "BlendOperation::MIN"; + case stormkit::gpu::BlendOperation::REVERSE_SUBTRACT: return "BlendOperation::REVERSE_SUBTRACT"; + case stormkit::gpu::BlendOperation::SUBTRACT: return "BlendOperation::SUBTRACT"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::BorderColor) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK, - stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE, - stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK, - stormkit::gpu::BorderColor::INT_OPAQUE_BLACK, - stormkit::gpu::BorderColor::INT_OPAQUE_WHITE, - stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK, - + stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK, stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE, + stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK, stormkit::gpu::BorderColor::INT_OPAQUE_BLACK, + stormkit::gpu::BorderColor::INT_OPAQUE_WHITE, stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::BorderColor value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: return "BorderColor::FLOAT_OPAQUE_BLACK"; - case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: return "BorderColor::FLOAT_OPAQUE_WHITE"; - case stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK: return "BorderColor::FLOAT_TRANSPARENT_BLACK"; - case stormkit::gpu::BorderColor::INT_OPAQUE_BLACK: return "BorderColor::INT_OPAQUE_BLACK"; - case stormkit::gpu::BorderColor::INT_OPAQUE_WHITE: return "BorderColor::INT_OPAQUE_WHITE"; - case stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK: return "BorderColor::INT_TRANSPARENT_BLACK"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::BorderColor value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: return "BorderColor::FLOAT_OPAQUE_BLACK"; + case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: return "BorderColor::FLOAT_OPAQUE_WHITE"; + case stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK: return "BorderColor::FLOAT_TRANSPARENT_BLACK"; + case stormkit::gpu::BorderColor::INT_OPAQUE_BLACK: return "BorderColor::INT_OPAQUE_BLACK"; + case stormkit::gpu::BorderColor::INT_OPAQUE_WHITE: return "BorderColor::INT_OPAQUE_WHITE"; + case stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK: return "BorderColor::INT_TRANSPARENT_BLACK"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::BorderColor value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: return "BorderColor::FLOAT_OPAQUE_BLACK"; - case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: return "BorderColor::FLOAT_OPAQUE_WHITE"; - case stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK: return "BorderColor::FLOAT_TRANSPARENT_BLACK"; - case stormkit::gpu::BorderColor::INT_OPAQUE_BLACK: return "BorderColor::INT_OPAQUE_BLACK"; - case stormkit::gpu::BorderColor::INT_OPAQUE_WHITE: return "BorderColor::INT_OPAQUE_WHITE"; - case stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK: return "BorderColor::INT_TRANSPARENT_BLACK"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::BorderColor value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: return "BorderColor::FLOAT_OPAQUE_BLACK"; + case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: return "BorderColor::FLOAT_OPAQUE_WHITE"; + case stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK: return "BorderColor::FLOAT_TRANSPARENT_BLACK"; + case stormkit::gpu::BorderColor::INT_OPAQUE_BLACK: return "BorderColor::INT_OPAQUE_BLACK"; + case stormkit::gpu::BorderColor::INT_OPAQUE_WHITE: return "BorderColor::INT_OPAQUE_WHITE"; + case stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK: return "BorderColor::INT_TRANSPARENT_BLACK"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::BufferUsageFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::BufferUsageFlag::INDEX, - stormkit::gpu::BufferUsageFlag::INDIRECT, - stormkit::gpu::BufferUsageFlag::STORAGE, - stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL, - stormkit::gpu::BufferUsageFlag::TRANSFER_DST, - stormkit::gpu::BufferUsageFlag::TRANSFER_SRC, - stormkit::gpu::BufferUsageFlag::UNIFORM, - stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL, - stormkit::gpu::BufferUsageFlag::VERTEX, - + stormkit::gpu::BufferUsageFlag::INDEX, stormkit::gpu::BufferUsageFlag::INDIRECT, + stormkit::gpu::BufferUsageFlag::STORAGE, stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL, + stormkit::gpu::BufferUsageFlag::TRANSFER_DST, stormkit::gpu::BufferUsageFlag::TRANSFER_SRC, + stormkit::gpu::BufferUsageFlag::UNIFORM, stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL, + stormkit::gpu::BufferUsageFlag::VERTEX, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::BufferUsageFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::BufferUsageFlag::INDEX: return "BufferUsageFlag::INDEX"; - case stormkit::gpu::BufferUsageFlag::INDIRECT: return "BufferUsageFlag::INDIRECT"; - case stormkit::gpu::BufferUsageFlag::STORAGE: return "BufferUsageFlag::STORAGE"; - case stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL: return "BufferUsageFlag::STORAGE_TEXEL"; - case stormkit::gpu::BufferUsageFlag::TRANSFER_DST: return "BufferUsageFlag::TRANSFER_DST"; - case stormkit::gpu::BufferUsageFlag::TRANSFER_SRC: return "BufferUsageFlag::TRANSFER_SRC"; - case stormkit::gpu::BufferUsageFlag::UNIFORM: return "BufferUsageFlag::UNIFORM"; - case stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL: return "BufferUsageFlag::UNIFORM_TEXEL"; - case stormkit::gpu::BufferUsageFlag::VERTEX: return "BufferUsageFlag::VERTEX"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::BufferUsageFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::BufferUsageFlag::INDEX: return "BufferUsageFlag::INDEX"; + case stormkit::gpu::BufferUsageFlag::INDIRECT: return "BufferUsageFlag::INDIRECT"; + case stormkit::gpu::BufferUsageFlag::STORAGE: return "BufferUsageFlag::STORAGE"; + case stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL: return "BufferUsageFlag::STORAGE_TEXEL"; + case stormkit::gpu::BufferUsageFlag::TRANSFER_DST: return "BufferUsageFlag::TRANSFER_DST"; + case stormkit::gpu::BufferUsageFlag::TRANSFER_SRC: return "BufferUsageFlag::TRANSFER_SRC"; + case stormkit::gpu::BufferUsageFlag::UNIFORM: return "BufferUsageFlag::UNIFORM"; + case stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL: return "BufferUsageFlag::UNIFORM_TEXEL"; + case stormkit::gpu::BufferUsageFlag::VERTEX: return "BufferUsageFlag::VERTEX"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::BufferUsageFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::BufferUsageFlag::INDEX: return "BufferUsageFlag::INDEX"; - case stormkit::gpu::BufferUsageFlag::INDIRECT: return "BufferUsageFlag::INDIRECT"; - case stormkit::gpu::BufferUsageFlag::STORAGE: return "BufferUsageFlag::STORAGE"; - case stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL: return "BufferUsageFlag::STORAGE_TEXEL"; - case stormkit::gpu::BufferUsageFlag::TRANSFER_DST: return "BufferUsageFlag::TRANSFER_DST"; - case stormkit::gpu::BufferUsageFlag::TRANSFER_SRC: return "BufferUsageFlag::TRANSFER_SRC"; - case stormkit::gpu::BufferUsageFlag::UNIFORM: return "BufferUsageFlag::UNIFORM"; - case stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL: return "BufferUsageFlag::UNIFORM_TEXEL"; - case stormkit::gpu::BufferUsageFlag::VERTEX: return "BufferUsageFlag::VERTEX"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::BufferUsageFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::BufferUsageFlag::INDEX: return "BufferUsageFlag::INDEX"; + case stormkit::gpu::BufferUsageFlag::INDIRECT: return "BufferUsageFlag::INDIRECT"; + case stormkit::gpu::BufferUsageFlag::STORAGE: return "BufferUsageFlag::STORAGE"; + case stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL: return "BufferUsageFlag::STORAGE_TEXEL"; + case stormkit::gpu::BufferUsageFlag::TRANSFER_DST: return "BufferUsageFlag::TRANSFER_DST"; + case stormkit::gpu::BufferUsageFlag::TRANSFER_SRC: return "BufferUsageFlag::TRANSFER_SRC"; + case stormkit::gpu::BufferUsageFlag::UNIFORM: return "BufferUsageFlag::UNIFORM"; + case stormkit::gpu::BufferUsageFlag::UNIFORM_TEXEL: return "BufferUsageFlag::UNIFORM_TEXEL"; + case stormkit::gpu::BufferUsageFlag::VERTEX: return "BufferUsageFlag::VERTEX"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ColorComponentFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ColorComponentFlag::A, - stormkit::gpu::ColorComponentFlag::B, - stormkit::gpu::ColorComponentFlag::G, - stormkit::gpu::ColorComponentFlag::NONE, - stormkit::gpu::ColorComponentFlag::R, - stormkit::gpu::ColorComponentFlag::RG, - stormkit::gpu::ColorComponentFlag::RGB, - stormkit::gpu::ColorComponentFlag::RGBA, - + stormkit::gpu::ColorComponentFlag::A, stormkit::gpu::ColorComponentFlag::B, + stormkit::gpu::ColorComponentFlag::G, stormkit::gpu::ColorComponentFlag::NONE, + stormkit::gpu::ColorComponentFlag::R, stormkit::gpu::ColorComponentFlag::RG, + stormkit::gpu::ColorComponentFlag::RGB, stormkit::gpu::ColorComponentFlag::RGBA, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ColorComponentFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ColorComponentFlag::A: return "ColorComponentFlag::A"; - case stormkit::gpu::ColorComponentFlag::B: return "ColorComponentFlag::B"; - case stormkit::gpu::ColorComponentFlag::G: return "ColorComponentFlag::G"; - case stormkit::gpu::ColorComponentFlag::NONE: return "ColorComponentFlag::NONE"; - case stormkit::gpu::ColorComponentFlag::R: return "ColorComponentFlag::R"; - case stormkit::gpu::ColorComponentFlag::RG: return "ColorComponentFlag::RG"; - case stormkit::gpu::ColorComponentFlag::RGB: return "ColorComponentFlag::RGB"; - case stormkit::gpu::ColorComponentFlag::RGBA: return "ColorComponentFlag::RGBA"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::ColorComponentFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ColorComponentFlag::A: return "ColorComponentFlag::A"; + case stormkit::gpu::ColorComponentFlag::B: return "ColorComponentFlag::B"; + case stormkit::gpu::ColorComponentFlag::G: return "ColorComponentFlag::G"; + case stormkit::gpu::ColorComponentFlag::NONE: return "ColorComponentFlag::NONE"; + case stormkit::gpu::ColorComponentFlag::R: return "ColorComponentFlag::R"; + case stormkit::gpu::ColorComponentFlag::RG: return "ColorComponentFlag::RG"; + case stormkit::gpu::ColorComponentFlag::RGB: return "ColorComponentFlag::RGB"; + case stormkit::gpu::ColorComponentFlag::RGBA: return "ColorComponentFlag::RGBA"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ColorComponentFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ColorComponentFlag::A: return "ColorComponentFlag::A"; - case stormkit::gpu::ColorComponentFlag::B: return "ColorComponentFlag::B"; - case stormkit::gpu::ColorComponentFlag::G: return "ColorComponentFlag::G"; - case stormkit::gpu::ColorComponentFlag::NONE: return "ColorComponentFlag::NONE"; - case stormkit::gpu::ColorComponentFlag::R: return "ColorComponentFlag::R"; - case stormkit::gpu::ColorComponentFlag::RG: return "ColorComponentFlag::RG"; - case stormkit::gpu::ColorComponentFlag::RGB: return "ColorComponentFlag::RGB"; - case stormkit::gpu::ColorComponentFlag::RGBA: return "ColorComponentFlag::RGBA"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::ColorComponentFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::ColorComponentFlag::A: return "ColorComponentFlag::A"; + case stormkit::gpu::ColorComponentFlag::B: return "ColorComponentFlag::B"; + case stormkit::gpu::ColorComponentFlag::G: return "ColorComponentFlag::G"; + case stormkit::gpu::ColorComponentFlag::NONE: return "ColorComponentFlag::NONE"; + case stormkit::gpu::ColorComponentFlag::R: return "ColorComponentFlag::R"; + case stormkit::gpu::ColorComponentFlag::RG: return "ColorComponentFlag::RG"; + case stormkit::gpu::ColorComponentFlag::RGB: return "ColorComponentFlag::RGB"; + case stormkit::gpu::ColorComponentFlag::RGBA: return "ColorComponentFlag::RGBA"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ColorSpace) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ColorSpace::ADOBERGB_LINEAR, - stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR, - stormkit::gpu::ColorSpace::BT2020_LINEAR, - stormkit::gpu::ColorSpace::BT709_LINEAR, - stormkit::gpu::ColorSpace::BT709_NONLINEAR, - stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR, - stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD, - stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR, - stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR, - stormkit::gpu::ColorSpace::DOLBYVISION, - stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR, - stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR, - stormkit::gpu::ColorSpace::HDR10_HLG, - stormkit::gpu::ColorSpace::HDR10_ST2084, - stormkit::gpu::ColorSpace::PASS_THROUGH, - stormkit::gpu::ColorSpace::SRGB_NONLINEAR, - - }; - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ColorSpace value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; - case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: return "ColorSpace::ADOBERGB_NONLINEAR"; - case stormkit::gpu::ColorSpace::BT2020_LINEAR: return "ColorSpace::BT2020_LINEAR"; - case stormkit::gpu::ColorSpace::BT709_LINEAR: return "ColorSpace::BT709_LINEAR"; - case stormkit::gpu::ColorSpace::BT709_NONLINEAR: return "ColorSpace::BT709_NONLINEAR"; - case stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR: return "ColorSpace::DCI_P3_NONLINEAR"; - case stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD: return "ColorSpace::DISPLAY_NATIVE_AMD"; - case stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR: return "ColorSpace::DISPLAY_P3_LINEAR"; - case stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR: return "ColorSpace::DISPLAY_P3_NONLINEAR"; - case stormkit::gpu::ColorSpace::DOLBYVISION: return "ColorSpace::DOLBYVISION"; - case stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR: return "ColorSpace::EXTENDED_SRGB_LINEAR"; - case stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR: return "ColorSpace::EXTENDED_SRGB_NONLINEAR"; - case stormkit::gpu::ColorSpace::HDR10_HLG: return "ColorSpace::HDR10_HLG"; - case stormkit::gpu::ColorSpace::HDR10_ST2084: return "ColorSpace::HDR10_ST2084"; - case stormkit::gpu::ColorSpace::PASS_THROUGH: return "ColorSpace::PASS_THROUGH"; - case stormkit::gpu::ColorSpace::SRGB_NONLINEAR: return "ColorSpace::SRGB_NONLINEAR"; - + stormkit::gpu::ColorSpace::ADOBERGB_LINEAR, + stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR, + stormkit::gpu::ColorSpace::BT2020_LINEAR, + stormkit::gpu::ColorSpace::BT709_LINEAR, + stormkit::gpu::ColorSpace::BT709_NONLINEAR, + stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR, + stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD, + stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR, + stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR, + stormkit::gpu::ColorSpace::DOLBYVISION, + stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR, + stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR, + stormkit::gpu::ColorSpace::HDR10_HLG, + stormkit::gpu::ColorSpace::HDR10_ST2084, + stormkit::gpu::ColorSpace::PASS_THROUGH, + stormkit::gpu::ColorSpace::SRGB_NONLINEAR, + + }; + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::ColorSpace value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; + case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: return "ColorSpace::ADOBERGB_NONLINEAR"; + case stormkit::gpu::ColorSpace::BT2020_LINEAR: return "ColorSpace::BT2020_LINEAR"; + case stormkit::gpu::ColorSpace::BT709_LINEAR: return "ColorSpace::BT709_LINEAR"; + case stormkit::gpu::ColorSpace::BT709_NONLINEAR: return "ColorSpace::BT709_NONLINEAR"; + case stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR: return "ColorSpace::DCI_P3_NONLINEAR"; + case stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD: return "ColorSpace::DISPLAY_NATIVE_AMD"; + case stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR: return "ColorSpace::DISPLAY_P3_LINEAR"; + case stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR: return "ColorSpace::DISPLAY_P3_NONLINEAR"; + case stormkit::gpu::ColorSpace::DOLBYVISION: return "ColorSpace::DOLBYVISION"; + case stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR: return "ColorSpace::EXTENDED_SRGB_LINEAR"; + case stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR: return "ColorSpace::EXTENDED_SRGB_NONLINEAR"; + case stormkit::gpu::ColorSpace::HDR10_HLG: return "ColorSpace::HDR10_HLG"; + case stormkit::gpu::ColorSpace::HDR10_ST2084: return "ColorSpace::HDR10_ST2084"; + case stormkit::gpu::ColorSpace::PASS_THROUGH: return "ColorSpace::PASS_THROUGH"; + case stormkit::gpu::ColorSpace::SRGB_NONLINEAR: return "ColorSpace::SRGB_NONLINEAR"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::ColorSpace value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; - case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: return "ColorSpace::ADOBERGB_NONLINEAR"; - case stormkit::gpu::ColorSpace::BT2020_LINEAR: return "ColorSpace::BT2020_LINEAR"; - case stormkit::gpu::ColorSpace::BT709_LINEAR: return "ColorSpace::BT709_LINEAR"; - case stormkit::gpu::ColorSpace::BT709_NONLINEAR: return "ColorSpace::BT709_NONLINEAR"; - case stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR: return "ColorSpace::DCI_P3_NONLINEAR"; - case stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD: return "ColorSpace::DISPLAY_NATIVE_AMD"; - case stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR: return "ColorSpace::DISPLAY_P3_LINEAR"; - case stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR: return "ColorSpace::DISPLAY_P3_NONLINEAR"; - case stormkit::gpu::ColorSpace::DOLBYVISION: return "ColorSpace::DOLBYVISION"; - case stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR: return "ColorSpace::EXTENDED_SRGB_LINEAR"; - case stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR: return "ColorSpace::EXTENDED_SRGB_NONLINEAR"; - case stormkit::gpu::ColorSpace::HDR10_HLG: return "ColorSpace::HDR10_HLG"; - case stormkit::gpu::ColorSpace::HDR10_ST2084: return "ColorSpace::HDR10_ST2084"; - case stormkit::gpu::ColorSpace::PASS_THROUGH: return "ColorSpace::PASS_THROUGH"; - case stormkit::gpu::ColorSpace::SRGB_NONLINEAR: return "ColorSpace::SRGB_NONLINEAR"; - + switch (value) { + case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; + case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: return "ColorSpace::ADOBERGB_NONLINEAR"; + case stormkit::gpu::ColorSpace::BT2020_LINEAR: return "ColorSpace::BT2020_LINEAR"; + case stormkit::gpu::ColorSpace::BT709_LINEAR: return "ColorSpace::BT709_LINEAR"; + case stormkit::gpu::ColorSpace::BT709_NONLINEAR: return "ColorSpace::BT709_NONLINEAR"; + case stormkit::gpu::ColorSpace::DCI_P3_NONLINEAR: return "ColorSpace::DCI_P3_NONLINEAR"; + case stormkit::gpu::ColorSpace::DISPLAY_NATIVE_AMD: return "ColorSpace::DISPLAY_NATIVE_AMD"; + case stormkit::gpu::ColorSpace::DISPLAY_P3_LINEAR: return "ColorSpace::DISPLAY_P3_LINEAR"; + case stormkit::gpu::ColorSpace::DISPLAY_P3_NONLINEAR: return "ColorSpace::DISPLAY_P3_NONLINEAR"; + case stormkit::gpu::ColorSpace::DOLBYVISION: return "ColorSpace::DOLBYVISION"; + case stormkit::gpu::ColorSpace::EXTENDED_SRGB_LINEAR: return "ColorSpace::EXTENDED_SRGB_LINEAR"; + case stormkit::gpu::ColorSpace::EXTENDED_SRGB_NONLINEAR: return "ColorSpace::EXTENDED_SRGB_NONLINEAR"; + case stormkit::gpu::ColorSpace::HDR10_HLG: return "ColorSpace::HDR10_HLG"; + case stormkit::gpu::ColorSpace::HDR10_ST2084: return "ColorSpace::HDR10_ST2084"; + case stormkit::gpu::ColorSpace::PASS_THROUGH: return "ColorSpace::PASS_THROUGH"; + case stormkit::gpu::ColorSpace::SRGB_NONLINEAR: return "ColorSpace::SRGB_NONLINEAR"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::CommandBufferLevel) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::CommandBufferLevel::PRIMARY, - stormkit::gpu::CommandBufferLevel::SECONDARY, - + stormkit::gpu::CommandBufferLevel::PRIMARY, + stormkit::gpu::CommandBufferLevel::SECONDARY, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::CommandBufferLevel value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::CommandBufferLevel::PRIMARY: return "CommandBufferLevel::PRIMARY"; - case stormkit::gpu::CommandBufferLevel::SECONDARY: return "CommandBufferLevel::SECONDARY"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::CommandBufferLevel value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::CommandBufferLevel::PRIMARY: return "CommandBufferLevel::PRIMARY"; + case stormkit::gpu::CommandBufferLevel::SECONDARY: return "CommandBufferLevel::SECONDARY"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::CommandBufferLevel value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::CommandBufferLevel::PRIMARY: return "CommandBufferLevel::PRIMARY"; - case stormkit::gpu::CommandBufferLevel::SECONDARY: return "CommandBufferLevel::SECONDARY"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::CommandBufferLevel value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::CommandBufferLevel::PRIMARY: return "CommandBufferLevel::PRIMARY"; + case stormkit::gpu::CommandBufferLevel::SECONDARY: return "CommandBufferLevel::SECONDARY"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::CompareOperation) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::CompareOperation::ALWAYS, - stormkit::gpu::CompareOperation::EQUAL, - stormkit::gpu::CompareOperation::GREATER, - stormkit::gpu::CompareOperation::GREATER_OR_EQUAL, - stormkit::gpu::CompareOperation::LESS, - stormkit::gpu::CompareOperation::LESS_OR_EQUAL, - stormkit::gpu::CompareOperation::NEVER, - stormkit::gpu::CompareOperation::NOT_EQUAL, - + stormkit::gpu::CompareOperation::ALWAYS, stormkit::gpu::CompareOperation::EQUAL, + stormkit::gpu::CompareOperation::GREATER, stormkit::gpu::CompareOperation::GREATER_OR_EQUAL, + stormkit::gpu::CompareOperation::LESS, stormkit::gpu::CompareOperation::LESS_OR_EQUAL, + stormkit::gpu::CompareOperation::NEVER, stormkit::gpu::CompareOperation::NOT_EQUAL, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::CompareOperation value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::CompareOperation::ALWAYS: return "CompareOperation::ALWAYS"; - case stormkit::gpu::CompareOperation::EQUAL: return "CompareOperation::EQUAL"; - case stormkit::gpu::CompareOperation::GREATER: return "CompareOperation::GREATER"; - case stormkit::gpu::CompareOperation::GREATER_OR_EQUAL: return "CompareOperation::GREATER_OR_EQUAL"; - case stormkit::gpu::CompareOperation::LESS: return "CompareOperation::LESS"; - case stormkit::gpu::CompareOperation::LESS_OR_EQUAL: return "CompareOperation::LESS_OR_EQUAL"; - case stormkit::gpu::CompareOperation::NEVER: return "CompareOperation::NEVER"; - case stormkit::gpu::CompareOperation::NOT_EQUAL: return "CompareOperation::NOT_EQUAL"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::CompareOperation value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::CompareOperation::ALWAYS: return "CompareOperation::ALWAYS"; + case stormkit::gpu::CompareOperation::EQUAL: return "CompareOperation::EQUAL"; + case stormkit::gpu::CompareOperation::GREATER: return "CompareOperation::GREATER"; + case stormkit::gpu::CompareOperation::GREATER_OR_EQUAL: return "CompareOperation::GREATER_OR_EQUAL"; + case stormkit::gpu::CompareOperation::LESS: return "CompareOperation::LESS"; + case stormkit::gpu::CompareOperation::LESS_OR_EQUAL: return "CompareOperation::LESS_OR_EQUAL"; + case stormkit::gpu::CompareOperation::NEVER: return "CompareOperation::NEVER"; + case stormkit::gpu::CompareOperation::NOT_EQUAL: return "CompareOperation::NOT_EQUAL"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::CompareOperation value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::CompareOperation::ALWAYS: return "CompareOperation::ALWAYS"; - case stormkit::gpu::CompareOperation::EQUAL: return "CompareOperation::EQUAL"; - case stormkit::gpu::CompareOperation::GREATER: return "CompareOperation::GREATER"; - case stormkit::gpu::CompareOperation::GREATER_OR_EQUAL: return "CompareOperation::GREATER_OR_EQUAL"; - case stormkit::gpu::CompareOperation::LESS: return "CompareOperation::LESS"; - case stormkit::gpu::CompareOperation::LESS_OR_EQUAL: return "CompareOperation::LESS_OR_EQUAL"; - case stormkit::gpu::CompareOperation::NEVER: return "CompareOperation::NEVER"; - case stormkit::gpu::CompareOperation::NOT_EQUAL: return "CompareOperation::NOT_EQUAL"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::CompareOperation value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::CompareOperation::ALWAYS: return "CompareOperation::ALWAYS"; + case stormkit::gpu::CompareOperation::EQUAL: return "CompareOperation::EQUAL"; + case stormkit::gpu::CompareOperation::GREATER: return "CompareOperation::GREATER"; + case stormkit::gpu::CompareOperation::GREATER_OR_EQUAL: return "CompareOperation::GREATER_OR_EQUAL"; + case stormkit::gpu::CompareOperation::LESS: return "CompareOperation::LESS"; + case stormkit::gpu::CompareOperation::LESS_OR_EQUAL: return "CompareOperation::LESS_OR_EQUAL"; + case stormkit::gpu::CompareOperation::NEVER: return "CompareOperation::NEVER"; + case stormkit::gpu::CompareOperation::NOT_EQUAL: return "CompareOperation::NOT_EQUAL"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::CullModeFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::CullModeFlag::BACK, - stormkit::gpu::CullModeFlag::FRONT, - stormkit::gpu::CullModeFlag::FRONT_BACK, - stormkit::gpu::CullModeFlag::NONE, - + stormkit::gpu::CullModeFlag::BACK, + stormkit::gpu::CullModeFlag::FRONT, + stormkit::gpu::CullModeFlag::FRONT_BACK, + stormkit::gpu::CullModeFlag::NONE, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::CullModeFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::CullModeFlag::BACK: return "CullModeFlag::BACK"; - case stormkit::gpu::CullModeFlag::FRONT: return "CullModeFlag::FRONT"; - case stormkit::gpu::CullModeFlag::FRONT_BACK: return "CullModeFlag::FRONT_BACK"; - case stormkit::gpu::CullModeFlag::NONE: return "CullModeFlag::NONE"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::CullModeFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::CullModeFlag::BACK: return "CullModeFlag::BACK"; + case stormkit::gpu::CullModeFlag::FRONT: return "CullModeFlag::FRONT"; + case stormkit::gpu::CullModeFlag::FRONT_BACK: return "CullModeFlag::FRONT_BACK"; + case stormkit::gpu::CullModeFlag::NONE: return "CullModeFlag::NONE"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::CullModeFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::CullModeFlag::BACK: return "CullModeFlag::BACK"; - case stormkit::gpu::CullModeFlag::FRONT: return "CullModeFlag::FRONT"; - case stormkit::gpu::CullModeFlag::FRONT_BACK: return "CullModeFlag::FRONT_BACK"; - case stormkit::gpu::CullModeFlag::NONE: return "CullModeFlag::NONE"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::CullModeFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::CullModeFlag::BACK: return "CullModeFlag::BACK"; + case stormkit::gpu::CullModeFlag::FRONT: return "CullModeFlag::FRONT"; + case stormkit::gpu::CullModeFlag::FRONT_BACK: return "CullModeFlag::FRONT_BACK"; + case stormkit::gpu::CullModeFlag::NONE: return "CullModeFlag::NONE"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::DebugObjectType) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::DebugObjectType::BUFFER, - stormkit::gpu::DebugObjectType::BUFFER_VIEW, - stormkit::gpu::DebugObjectType::COMMAND_BUFFER, - stormkit::gpu::DebugObjectType::COMMAND_POOL, - stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK, - stormkit::gpu::DebugObjectType::DEBUG_UTILS_MESSENGER, - stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL, - stormkit::gpu::DebugObjectType::DESCRIPTOR_SET, - stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT, - stormkit::gpu::DebugObjectType::DEVICE, - stormkit::gpu::DebugObjectType::DEVICE_MEMORY, - stormkit::gpu::DebugObjectType::DISPLAY, - stormkit::gpu::DebugObjectType::EVENT, - stormkit::gpu::DebugObjectType::FENCE, - stormkit::gpu::DebugObjectType::FRAMEBUFFER, - stormkit::gpu::DebugObjectType::IMAGE, - stormkit::gpu::DebugObjectType::IMAGE_VIEW, - stormkit::gpu::DebugObjectType::INSTANCE, - stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE, - stormkit::gpu::DebugObjectType::PIPELINE, - stormkit::gpu::DebugObjectType::PIPELINE_CACHE, - stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT, - stormkit::gpu::DebugObjectType::QUERY_POOL, - stormkit::gpu::DebugObjectType::QUEUE, - stormkit::gpu::DebugObjectType::RENDER_PASS, - stormkit::gpu::DebugObjectType::SAMPLER, - stormkit::gpu::DebugObjectType::SEMAPHORE, - stormkit::gpu::DebugObjectType::SHADER_MODULE, - stormkit::gpu::DebugObjectType::SURFACE, - stormkit::gpu::DebugObjectType::SWAPCHAIN, - stormkit::gpu::DebugObjectType::UNKNOWN, - - }; - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::DebugObjectType value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::DebugObjectType::BUFFER: return "DebugObjectType::BUFFER"; - case stormkit::gpu::DebugObjectType::BUFFER_VIEW: return "DebugObjectType::BUFFER_VIEW"; - case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: return "DebugObjectType::COMMAND_BUFFER"; - case stormkit::gpu::DebugObjectType::COMMAND_POOL: return "DebugObjectType::COMMAND_POOL"; - case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: return "DebugObjectType::DEBUG_REPORT_CALLBACK"; - case stormkit::gpu::DebugObjectType::DEBUG_UTILS_MESSENGER: return "DebugObjectType::DEBUG_UTILS_MESSENGER"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: return "DebugObjectType::DESCRIPTOR_POOL"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: return "DebugObjectType::DESCRIPTOR_SET"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; - case stormkit::gpu::DebugObjectType::DEVICE: return "DebugObjectType::DEVICE"; - case stormkit::gpu::DebugObjectType::DEVICE_MEMORY: return "DebugObjectType::DEVICE_MEMORY"; - case stormkit::gpu::DebugObjectType::DISPLAY: return "DebugObjectType::DISPLAY"; - case stormkit::gpu::DebugObjectType::EVENT: return "DebugObjectType::EVENT"; - case stormkit::gpu::DebugObjectType::FENCE: return "DebugObjectType::FENCE"; - case stormkit::gpu::DebugObjectType::FRAMEBUFFER: return "DebugObjectType::FRAMEBUFFER"; - case stormkit::gpu::DebugObjectType::IMAGE: return "DebugObjectType::IMAGE"; - case stormkit::gpu::DebugObjectType::IMAGE_VIEW: return "DebugObjectType::IMAGE_VIEW"; - case stormkit::gpu::DebugObjectType::INSTANCE: return "DebugObjectType::INSTANCE"; - case stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE: return "DebugObjectType::PHYSICAL_DEVICE"; - case stormkit::gpu::DebugObjectType::PIPELINE: return "DebugObjectType::PIPELINE"; - case stormkit::gpu::DebugObjectType::PIPELINE_CACHE: return "DebugObjectType::PIPELINE_CACHE"; - case stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT: return "DebugObjectType::PIPELINE_LAYOUT"; - case stormkit::gpu::DebugObjectType::QUERY_POOL: return "DebugObjectType::QUERY_POOL"; - case stormkit::gpu::DebugObjectType::QUEUE: return "DebugObjectType::QUEUE"; - case stormkit::gpu::DebugObjectType::RENDER_PASS: return "DebugObjectType::RENDER_PASS"; - case stormkit::gpu::DebugObjectType::SAMPLER: return "DebugObjectType::SAMPLER"; - case stormkit::gpu::DebugObjectType::SEMAPHORE: return "DebugObjectType::SEMAPHORE"; - case stormkit::gpu::DebugObjectType::SHADER_MODULE: return "DebugObjectType::SHADER_MODULE"; - case stormkit::gpu::DebugObjectType::SURFACE: return "DebugObjectType::SURFACE"; - case stormkit::gpu::DebugObjectType::SWAPCHAIN: return "DebugObjectType::SWAPCHAIN"; - case stormkit::gpu::DebugObjectType::UNKNOWN: return "DebugObjectType::UNKNOWN"; - - } - std::unreachable(); - } - template<> - STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::DebugObjectType value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::DebugObjectType::BUFFER: return "DebugObjectType::BUFFER"; - case stormkit::gpu::DebugObjectType::BUFFER_VIEW: return "DebugObjectType::BUFFER_VIEW"; - case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: return "DebugObjectType::COMMAND_BUFFER"; - case stormkit::gpu::DebugObjectType::COMMAND_POOL: return "DebugObjectType::COMMAND_POOL"; - case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: return "DebugObjectType::DEBUG_REPORT_CALLBACK"; - case stormkit::gpu::DebugObjectType::DEBUG_UTILS_MESSENGER: return "DebugObjectType::DEBUG_UTILS_MESSENGER"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: return "DebugObjectType::DESCRIPTOR_POOL"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: return "DebugObjectType::DESCRIPTOR_SET"; - case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; - case stormkit::gpu::DebugObjectType::DEVICE: return "DebugObjectType::DEVICE"; - case stormkit::gpu::DebugObjectType::DEVICE_MEMORY: return "DebugObjectType::DEVICE_MEMORY"; - case stormkit::gpu::DebugObjectType::DISPLAY: return "DebugObjectType::DISPLAY"; - case stormkit::gpu::DebugObjectType::EVENT: return "DebugObjectType::EVENT"; - case stormkit::gpu::DebugObjectType::FENCE: return "DebugObjectType::FENCE"; - case stormkit::gpu::DebugObjectType::FRAMEBUFFER: return "DebugObjectType::FRAMEBUFFER"; - case stormkit::gpu::DebugObjectType::IMAGE: return "DebugObjectType::IMAGE"; - case stormkit::gpu::DebugObjectType::IMAGE_VIEW: return "DebugObjectType::IMAGE_VIEW"; - case stormkit::gpu::DebugObjectType::INSTANCE: return "DebugObjectType::INSTANCE"; - case stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE: return "DebugObjectType::PHYSICAL_DEVICE"; - case stormkit::gpu::DebugObjectType::PIPELINE: return "DebugObjectType::PIPELINE"; - case stormkit::gpu::DebugObjectType::PIPELINE_CACHE: return "DebugObjectType::PIPELINE_CACHE"; - case stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT: return "DebugObjectType::PIPELINE_LAYOUT"; - case stormkit::gpu::DebugObjectType::QUERY_POOL: return "DebugObjectType::QUERY_POOL"; - case stormkit::gpu::DebugObjectType::QUEUE: return "DebugObjectType::QUEUE"; - case stormkit::gpu::DebugObjectType::RENDER_PASS: return "DebugObjectType::RENDER_PASS"; - case stormkit::gpu::DebugObjectType::SAMPLER: return "DebugObjectType::SAMPLER"; - case stormkit::gpu::DebugObjectType::SEMAPHORE: return "DebugObjectType::SEMAPHORE"; - case stormkit::gpu::DebugObjectType::SHADER_MODULE: return "DebugObjectType::SHADER_MODULE"; - case stormkit::gpu::DebugObjectType::SURFACE: return "DebugObjectType::SURFACE"; - case stormkit::gpu::DebugObjectType::SWAPCHAIN: return "DebugObjectType::SWAPCHAIN"; - case stormkit::gpu::DebugObjectType::UNKNOWN: return "DebugObjectType::UNKNOWN"; - + stormkit::gpu::DebugObjectType::BUFFER, + stormkit::gpu::DebugObjectType::BUFFER_VIEW, + stormkit::gpu::DebugObjectType::COMMAND_BUFFER, + stormkit::gpu::DebugObjectType::COMMAND_POOL, + stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK, + stormkit::gpu::DebugObjectType::DEBUG_UTILS_MESSENGER, + stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL, + stormkit::gpu::DebugObjectType::DESCRIPTOR_SET, + stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT, + stormkit::gpu::DebugObjectType::DEVICE, + stormkit::gpu::DebugObjectType::DEVICE_MEMORY, + stormkit::gpu::DebugObjectType::DISPLAY, + stormkit::gpu::DebugObjectType::EVENT, + stormkit::gpu::DebugObjectType::FENCE, + stormkit::gpu::DebugObjectType::FRAMEBUFFER, + stormkit::gpu::DebugObjectType::IMAGE, + stormkit::gpu::DebugObjectType::IMAGE_VIEW, + stormkit::gpu::DebugObjectType::INSTANCE, + stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE, + stormkit::gpu::DebugObjectType::PIPELINE, + stormkit::gpu::DebugObjectType::PIPELINE_CACHE, + stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT, + stormkit::gpu::DebugObjectType::QUERY_POOL, + stormkit::gpu::DebugObjectType::QUEUE, + stormkit::gpu::DebugObjectType::RENDER_PASS, + stormkit::gpu::DebugObjectType::SAMPLER, + stormkit::gpu::DebugObjectType::SEMAPHORE, + stormkit::gpu::DebugObjectType::SHADER_MODULE, + stormkit::gpu::DebugObjectType::SURFACE, + stormkit::gpu::DebugObjectType::SWAPCHAIN, + stormkit::gpu::DebugObjectType::UNKNOWN, + + }; + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::DebugObjectType value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::DebugObjectType::BUFFER: return "DebugObjectType::BUFFER"; + case stormkit::gpu::DebugObjectType::BUFFER_VIEW: return "DebugObjectType::BUFFER_VIEW"; + case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: return "DebugObjectType::COMMAND_BUFFER"; + case stormkit::gpu::DebugObjectType::COMMAND_POOL: return "DebugObjectType::COMMAND_POOL"; + case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: return "DebugObjectType::DEBUG_REPORT_CALLBACK"; + case stormkit::gpu::DebugObjectType::DEBUG_UTILS_MESSENGER: return "DebugObjectType::DEBUG_UTILS_MESSENGER"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: return "DebugObjectType::DESCRIPTOR_POOL"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: return "DebugObjectType::DESCRIPTOR_SET"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; + case stormkit::gpu::DebugObjectType::DEVICE: return "DebugObjectType::DEVICE"; + case stormkit::gpu::DebugObjectType::DEVICE_MEMORY: return "DebugObjectType::DEVICE_MEMORY"; + case stormkit::gpu::DebugObjectType::DISPLAY: return "DebugObjectType::DISPLAY"; + case stormkit::gpu::DebugObjectType::EVENT: return "DebugObjectType::EVENT"; + case stormkit::gpu::DebugObjectType::FENCE: return "DebugObjectType::FENCE"; + case stormkit::gpu::DebugObjectType::FRAMEBUFFER: return "DebugObjectType::FRAMEBUFFER"; + case stormkit::gpu::DebugObjectType::IMAGE: return "DebugObjectType::IMAGE"; + case stormkit::gpu::DebugObjectType::IMAGE_VIEW: return "DebugObjectType::IMAGE_VIEW"; + case stormkit::gpu::DebugObjectType::INSTANCE: return "DebugObjectType::INSTANCE"; + case stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE: return "DebugObjectType::PHYSICAL_DEVICE"; + case stormkit::gpu::DebugObjectType::PIPELINE: return "DebugObjectType::PIPELINE"; + case stormkit::gpu::DebugObjectType::PIPELINE_CACHE: return "DebugObjectType::PIPELINE_CACHE"; + case stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT: return "DebugObjectType::PIPELINE_LAYOUT"; + case stormkit::gpu::DebugObjectType::QUERY_POOL: return "DebugObjectType::QUERY_POOL"; + case stormkit::gpu::DebugObjectType::QUEUE: return "DebugObjectType::QUEUE"; + case stormkit::gpu::DebugObjectType::RENDER_PASS: return "DebugObjectType::RENDER_PASS"; + case stormkit::gpu::DebugObjectType::SAMPLER: return "DebugObjectType::SAMPLER"; + case stormkit::gpu::DebugObjectType::SEMAPHORE: return "DebugObjectType::SEMAPHORE"; + case stormkit::gpu::DebugObjectType::SHADER_MODULE: return "DebugObjectType::SHADER_MODULE"; + case stormkit::gpu::DebugObjectType::SURFACE: return "DebugObjectType::SURFACE"; + case stormkit::gpu::DebugObjectType::SWAPCHAIN: return "DebugObjectType::SWAPCHAIN"; + case stormkit::gpu::DebugObjectType::UNKNOWN: return "DebugObjectType::UNKNOWN"; + } + std::unreachable(); + } + + template<> + STORMKIT_FORCE_INLINE + constexpr auto stormkit::core::to_string(stormkit::gpu::DebugObjectType value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::DebugObjectType::BUFFER: return "DebugObjectType::BUFFER"; + case stormkit::gpu::DebugObjectType::BUFFER_VIEW: return "DebugObjectType::BUFFER_VIEW"; + case stormkit::gpu::DebugObjectType::COMMAND_BUFFER: return "DebugObjectType::COMMAND_BUFFER"; + case stormkit::gpu::DebugObjectType::COMMAND_POOL: return "DebugObjectType::COMMAND_POOL"; + case stormkit::gpu::DebugObjectType::DEBUG_REPORT_CALLBACK: return "DebugObjectType::DEBUG_REPORT_CALLBACK"; + case stormkit::gpu::DebugObjectType::DEBUG_UTILS_MESSENGER: return "DebugObjectType::DEBUG_UTILS_MESSENGER"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_POOL: return "DebugObjectType::DESCRIPTOR_POOL"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET: return "DebugObjectType::DESCRIPTOR_SET"; + case stormkit::gpu::DebugObjectType::DESCRIPTOR_SET_LAYOUT: return "DebugObjectType::DESCRIPTOR_SET_LAYOUT"; + case stormkit::gpu::DebugObjectType::DEVICE: return "DebugObjectType::DEVICE"; + case stormkit::gpu::DebugObjectType::DEVICE_MEMORY: return "DebugObjectType::DEVICE_MEMORY"; + case stormkit::gpu::DebugObjectType::DISPLAY: return "DebugObjectType::DISPLAY"; + case stormkit::gpu::DebugObjectType::EVENT: return "DebugObjectType::EVENT"; + case stormkit::gpu::DebugObjectType::FENCE: return "DebugObjectType::FENCE"; + case stormkit::gpu::DebugObjectType::FRAMEBUFFER: return "DebugObjectType::FRAMEBUFFER"; + case stormkit::gpu::DebugObjectType::IMAGE: return "DebugObjectType::IMAGE"; + case stormkit::gpu::DebugObjectType::IMAGE_VIEW: return "DebugObjectType::IMAGE_VIEW"; + case stormkit::gpu::DebugObjectType::INSTANCE: return "DebugObjectType::INSTANCE"; + case stormkit::gpu::DebugObjectType::PHYSICAL_DEVICE: return "DebugObjectType::PHYSICAL_DEVICE"; + case stormkit::gpu::DebugObjectType::PIPELINE: return "DebugObjectType::PIPELINE"; + case stormkit::gpu::DebugObjectType::PIPELINE_CACHE: return "DebugObjectType::PIPELINE_CACHE"; + case stormkit::gpu::DebugObjectType::PIPELINE_LAYOUT: return "DebugObjectType::PIPELINE_LAYOUT"; + case stormkit::gpu::DebugObjectType::QUERY_POOL: return "DebugObjectType::QUERY_POOL"; + case stormkit::gpu::DebugObjectType::QUEUE: return "DebugObjectType::QUEUE"; + case stormkit::gpu::DebugObjectType::RENDER_PASS: return "DebugObjectType::RENDER_PASS"; + case stormkit::gpu::DebugObjectType::SAMPLER: return "DebugObjectType::SAMPLER"; + case stormkit::gpu::DebugObjectType::SEMAPHORE: return "DebugObjectType::SEMAPHORE"; + case stormkit::gpu::DebugObjectType::SHADER_MODULE: return "DebugObjectType::SHADER_MODULE"; + case stormkit::gpu::DebugObjectType::SURFACE: return "DebugObjectType::SURFACE"; + case stormkit::gpu::DebugObjectType::SWAPCHAIN: return "DebugObjectType::SWAPCHAIN"; + case stormkit::gpu::DebugObjectType::UNKNOWN: return "DebugObjectType::UNKNOWN"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::DependencyFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::DependencyFlag::BY_REGION, - stormkit::gpu::DependencyFlag::DEVICE_GROUP, - stormkit::gpu::DependencyFlag::NONE, - stormkit::gpu::DependencyFlag::VIEW_LOCAL, - + stormkit::gpu::DependencyFlag::BY_REGION, + stormkit::gpu::DependencyFlag::DEVICE_GROUP, + stormkit::gpu::DependencyFlag::NONE, + stormkit::gpu::DependencyFlag::VIEW_LOCAL, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::DependencyFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::DependencyFlag::BY_REGION: return "DependencyFlag::BY_REGION"; - case stormkit::gpu::DependencyFlag::DEVICE_GROUP: return "DependencyFlag::DEVICE_GROUP"; - case stormkit::gpu::DependencyFlag::NONE: return "DependencyFlag::NONE"; - case stormkit::gpu::DependencyFlag::VIEW_LOCAL: return "DependencyFlag::VIEW_LOCAL"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::DependencyFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::DependencyFlag::BY_REGION: return "DependencyFlag::BY_REGION"; + case stormkit::gpu::DependencyFlag::DEVICE_GROUP: return "DependencyFlag::DEVICE_GROUP"; + case stormkit::gpu::DependencyFlag::NONE: return "DependencyFlag::NONE"; + case stormkit::gpu::DependencyFlag::VIEW_LOCAL: return "DependencyFlag::VIEW_LOCAL"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::DependencyFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::DependencyFlag::BY_REGION: return "DependencyFlag::BY_REGION"; - case stormkit::gpu::DependencyFlag::DEVICE_GROUP: return "DependencyFlag::DEVICE_GROUP"; - case stormkit::gpu::DependencyFlag::NONE: return "DependencyFlag::NONE"; - case stormkit::gpu::DependencyFlag::VIEW_LOCAL: return "DependencyFlag::VIEW_LOCAL"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::DependencyFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::DependencyFlag::BY_REGION: return "DependencyFlag::BY_REGION"; + case stormkit::gpu::DependencyFlag::DEVICE_GROUP: return "DependencyFlag::DEVICE_GROUP"; + case stormkit::gpu::DependencyFlag::NONE: return "DependencyFlag::NONE"; + case stormkit::gpu::DependencyFlag::VIEW_LOCAL: return "DependencyFlag::VIEW_LOCAL"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::DescriptorType) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, - stormkit::gpu::DescriptorType::INPUT_ATTACHMENT, - stormkit::gpu::DescriptorType::SAMPLED_IMAGE, - stormkit::gpu::DescriptorType::SAMPLER, - stormkit::gpu::DescriptorType::STORAGE_BUFFER, - stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC, - stormkit::gpu::DescriptorType::STORAGE_IMAGE, - stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER, - stormkit::gpu::DescriptorType::UNIFORM_BUFFER, - stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC, - stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER, - + stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, stormkit::gpu::DescriptorType::INPUT_ATTACHMENT, + stormkit::gpu::DescriptorType::SAMPLED_IMAGE, stormkit::gpu::DescriptorType::SAMPLER, + stormkit::gpu::DescriptorType::STORAGE_BUFFER, stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC, + stormkit::gpu::DescriptorType::STORAGE_IMAGE, stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER, + stormkit::gpu::DescriptorType::UNIFORM_BUFFER, stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC, + stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::DescriptorType value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: return "DescriptorType::COMBINED_IMAGE_SAMPLER"; - case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: return "DescriptorType::INPUT_ATTACHMENT"; - case stormkit::gpu::DescriptorType::SAMPLED_IMAGE: return "DescriptorType::SAMPLED_IMAGE"; - case stormkit::gpu::DescriptorType::SAMPLER: return "DescriptorType::SAMPLER"; - case stormkit::gpu::DescriptorType::STORAGE_BUFFER: return "DescriptorType::STORAGE_BUFFER"; - case stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC: return "DescriptorType::STORAGE_BUFFER_DYNAMIC"; - case stormkit::gpu::DescriptorType::STORAGE_IMAGE: return "DescriptorType::STORAGE_IMAGE"; - case stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER: return "DescriptorType::STORAGE_TEXEL_BUFFER"; - case stormkit::gpu::DescriptorType::UNIFORM_BUFFER: return "DescriptorType::UNIFORM_BUFFER"; - case stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC: return "DescriptorType::UNIFORM_BUFFER_DYNAMIC"; - case stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER: return "DescriptorType::UNIFORM_TEXEL_BUFFER"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::DescriptorType value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: return "DescriptorType::COMBINED_IMAGE_SAMPLER"; + case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: return "DescriptorType::INPUT_ATTACHMENT"; + case stormkit::gpu::DescriptorType::SAMPLED_IMAGE: return "DescriptorType::SAMPLED_IMAGE"; + case stormkit::gpu::DescriptorType::SAMPLER: return "DescriptorType::SAMPLER"; + case stormkit::gpu::DescriptorType::STORAGE_BUFFER: return "DescriptorType::STORAGE_BUFFER"; + case stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC: return "DescriptorType::STORAGE_BUFFER_DYNAMIC"; + case stormkit::gpu::DescriptorType::STORAGE_IMAGE: return "DescriptorType::STORAGE_IMAGE"; + case stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER: return "DescriptorType::STORAGE_TEXEL_BUFFER"; + case stormkit::gpu::DescriptorType::UNIFORM_BUFFER: return "DescriptorType::UNIFORM_BUFFER"; + case stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC: return "DescriptorType::UNIFORM_BUFFER_DYNAMIC"; + case stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER: return "DescriptorType::UNIFORM_TEXEL_BUFFER"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::DescriptorType value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: return "DescriptorType::COMBINED_IMAGE_SAMPLER"; - case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: return "DescriptorType::INPUT_ATTACHMENT"; - case stormkit::gpu::DescriptorType::SAMPLED_IMAGE: return "DescriptorType::SAMPLED_IMAGE"; - case stormkit::gpu::DescriptorType::SAMPLER: return "DescriptorType::SAMPLER"; - case stormkit::gpu::DescriptorType::STORAGE_BUFFER: return "DescriptorType::STORAGE_BUFFER"; - case stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC: return "DescriptorType::STORAGE_BUFFER_DYNAMIC"; - case stormkit::gpu::DescriptorType::STORAGE_IMAGE: return "DescriptorType::STORAGE_IMAGE"; - case stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER: return "DescriptorType::STORAGE_TEXEL_BUFFER"; - case stormkit::gpu::DescriptorType::UNIFORM_BUFFER: return "DescriptorType::UNIFORM_BUFFER"; - case stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC: return "DescriptorType::UNIFORM_BUFFER_DYNAMIC"; - case stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER: return "DescriptorType::UNIFORM_TEXEL_BUFFER"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::DescriptorType value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: return "DescriptorType::COMBINED_IMAGE_SAMPLER"; + case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: return "DescriptorType::INPUT_ATTACHMENT"; + case stormkit::gpu::DescriptorType::SAMPLED_IMAGE: return "DescriptorType::SAMPLED_IMAGE"; + case stormkit::gpu::DescriptorType::SAMPLER: return "DescriptorType::SAMPLER"; + case stormkit::gpu::DescriptorType::STORAGE_BUFFER: return "DescriptorType::STORAGE_BUFFER"; + case stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC: return "DescriptorType::STORAGE_BUFFER_DYNAMIC"; + case stormkit::gpu::DescriptorType::STORAGE_IMAGE: return "DescriptorType::STORAGE_IMAGE"; + case stormkit::gpu::DescriptorType::STORAGE_TEXEL_BUFFER: return "DescriptorType::STORAGE_TEXEL_BUFFER"; + case stormkit::gpu::DescriptorType::UNIFORM_BUFFER: return "DescriptorType::UNIFORM_BUFFER"; + case stormkit::gpu::DescriptorType::UNIFORM_BUFFER_DYNAMIC: return "DescriptorType::UNIFORM_BUFFER_DYNAMIC"; + case stormkit::gpu::DescriptorType::UNIFORM_TEXEL_BUFFER: return "DescriptorType::UNIFORM_TEXEL_BUFFER"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::DynamicState) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::DynamicState::BLEND_CONSTANTS, - stormkit::gpu::DynamicState::DEPTH_BIAS, - stormkit::gpu::DynamicState::DEPTH_BOUNDS, - stormkit::gpu::DynamicState::LINE_WIDTH, - stormkit::gpu::DynamicState::SCISSOR, - stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK, - stormkit::gpu::DynamicState::STENCIL_REFERENCE, - stormkit::gpu::DynamicState::STENCIL_WRITE_MASK, - stormkit::gpu::DynamicState::VIEWPORT, - + stormkit::gpu::DynamicState::BLEND_CONSTANTS, stormkit::gpu::DynamicState::DEPTH_BIAS, + stormkit::gpu::DynamicState::DEPTH_BOUNDS, stormkit::gpu::DynamicState::LINE_WIDTH, + stormkit::gpu::DynamicState::SCISSOR, stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK, + stormkit::gpu::DynamicState::STENCIL_REFERENCE, stormkit::gpu::DynamicState::STENCIL_WRITE_MASK, + stormkit::gpu::DynamicState::VIEWPORT, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::DynamicState value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::DynamicState::BLEND_CONSTANTS: return "DynamicState::BLEND_CONSTANTS"; - case stormkit::gpu::DynamicState::DEPTH_BIAS: return "DynamicState::DEPTH_BIAS"; - case stormkit::gpu::DynamicState::DEPTH_BOUNDS: return "DynamicState::DEPTH_BOUNDS"; - case stormkit::gpu::DynamicState::LINE_WIDTH: return "DynamicState::LINE_WIDTH"; - case stormkit::gpu::DynamicState::SCISSOR: return "DynamicState::SCISSOR"; - case stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK: return "DynamicState::STENCIL_COMPARE_MASK"; - case stormkit::gpu::DynamicState::STENCIL_REFERENCE: return "DynamicState::STENCIL_REFERENCE"; - case stormkit::gpu::DynamicState::STENCIL_WRITE_MASK: return "DynamicState::STENCIL_WRITE_MASK"; - case stormkit::gpu::DynamicState::VIEWPORT: return "DynamicState::VIEWPORT"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::DynamicState value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::DynamicState::BLEND_CONSTANTS: return "DynamicState::BLEND_CONSTANTS"; + case stormkit::gpu::DynamicState::DEPTH_BIAS: return "DynamicState::DEPTH_BIAS"; + case stormkit::gpu::DynamicState::DEPTH_BOUNDS: return "DynamicState::DEPTH_BOUNDS"; + case stormkit::gpu::DynamicState::LINE_WIDTH: return "DynamicState::LINE_WIDTH"; + case stormkit::gpu::DynamicState::SCISSOR: return "DynamicState::SCISSOR"; + case stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK: return "DynamicState::STENCIL_COMPARE_MASK"; + case stormkit::gpu::DynamicState::STENCIL_REFERENCE: return "DynamicState::STENCIL_REFERENCE"; + case stormkit::gpu::DynamicState::STENCIL_WRITE_MASK: return "DynamicState::STENCIL_WRITE_MASK"; + case stormkit::gpu::DynamicState::VIEWPORT: return "DynamicState::VIEWPORT"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::DynamicState value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::DynamicState::BLEND_CONSTANTS: return "DynamicState::BLEND_CONSTANTS"; - case stormkit::gpu::DynamicState::DEPTH_BIAS: return "DynamicState::DEPTH_BIAS"; - case stormkit::gpu::DynamicState::DEPTH_BOUNDS: return "DynamicState::DEPTH_BOUNDS"; - case stormkit::gpu::DynamicState::LINE_WIDTH: return "DynamicState::LINE_WIDTH"; - case stormkit::gpu::DynamicState::SCISSOR: return "DynamicState::SCISSOR"; - case stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK: return "DynamicState::STENCIL_COMPARE_MASK"; - case stormkit::gpu::DynamicState::STENCIL_REFERENCE: return "DynamicState::STENCIL_REFERENCE"; - case stormkit::gpu::DynamicState::STENCIL_WRITE_MASK: return "DynamicState::STENCIL_WRITE_MASK"; - case stormkit::gpu::DynamicState::VIEWPORT: return "DynamicState::VIEWPORT"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::DynamicState value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::DynamicState::BLEND_CONSTANTS: return "DynamicState::BLEND_CONSTANTS"; + case stormkit::gpu::DynamicState::DEPTH_BIAS: return "DynamicState::DEPTH_BIAS"; + case stormkit::gpu::DynamicState::DEPTH_BOUNDS: return "DynamicState::DEPTH_BOUNDS"; + case stormkit::gpu::DynamicState::LINE_WIDTH: return "DynamicState::LINE_WIDTH"; + case stormkit::gpu::DynamicState::SCISSOR: return "DynamicState::SCISSOR"; + case stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK: return "DynamicState::STENCIL_COMPARE_MASK"; + case stormkit::gpu::DynamicState::STENCIL_REFERENCE: return "DynamicState::STENCIL_REFERENCE"; + case stormkit::gpu::DynamicState::STENCIL_WRITE_MASK: return "DynamicState::STENCIL_WRITE_MASK"; + case stormkit::gpu::DynamicState::VIEWPORT: return "DynamicState::VIEWPORT"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::Filter) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::Filter::CUBIC_IMG, - stormkit::gpu::Filter::LINEAR, - stormkit::gpu::Filter::NEAREST, - + stormkit::gpu::Filter::CUBIC_IMG, + stormkit::gpu::Filter::LINEAR, + stormkit::gpu::Filter::NEAREST, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::Filter value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; - case stormkit::gpu::Filter::LINEAR: return "Filter::LINEAR"; - case stormkit::gpu::Filter::NEAREST: return "Filter::NEAREST"; - + switch (value) { + case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; + case stormkit::gpu::Filter::LINEAR: return "Filter::LINEAR"; + case stormkit::gpu::Filter::NEAREST: return "Filter::NEAREST"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::Filter value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; - case stormkit::gpu::Filter::LINEAR: return "Filter::LINEAR"; - case stormkit::gpu::Filter::NEAREST: return "Filter::NEAREST"; - + switch (value) { + case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; + case stormkit::gpu::Filter::LINEAR: return "Filter::LINEAR"; + case stormkit::gpu::Filter::NEAREST: return "Filter::NEAREST"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::FormatFeatureFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::FormatFeatureFlag::BLIT_DST, - stormkit::gpu::FormatFeatureFlag::BLIT_SRC, - stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT, - stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND, - stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES, - stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT, - stormkit::gpu::FormatFeatureFlag::DISJOINT, - stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER, - stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER, - stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE, - stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC, - stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER, - stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC, - stormkit::gpu::FormatFeatureFlag::TRANSFER_DST, - stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC, - stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER, - stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER, - - }; - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::FormatFeatureFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::FormatFeatureFlag::BLIT_DST: return "FormatFeatureFlag::BLIT_DST"; - case stormkit::gpu::FormatFeatureFlag::BLIT_SRC: return "FormatFeatureFlag::BLIT_SRC"; - case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT: return "FormatFeatureFlag::COLOR_ATTACHMENT"; - case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND: return "FormatFeatureFlag::COLOR_ATTACHMENT_BLEND"; - case stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES: return "FormatFeatureFlag::COSITED_CHROMA_SAMPLES"; - case stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT: return "FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT"; - case stormkit::gpu::FormatFeatureFlag::DISJOINT: return "FormatFeatureFlag::DISJOINT"; - case stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES: return "FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE: return "FormatFeatureFlag::SAMPLED_IMAGE"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR: return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX: return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE: return "FormatFeatureFlag::STORAGE_IMAGE"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC: return "FormatFeatureFlag::STORAGE_IMAGE_ATOMIC"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC"; - case stormkit::gpu::FormatFeatureFlag::TRANSFER_DST: return "FormatFeatureFlag::TRANSFER_DST"; - case stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC: return "FormatFeatureFlag::TRANSFER_SRC"; - case stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER: return "FormatFeatureFlag::UNIFORM_TEXEL_BUFFER"; - case stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER: return "FormatFeatureFlag::VERTEX_BUFFER"; - - } - std::unreachable(); - } - template<> - STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::FormatFeatureFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::FormatFeatureFlag::BLIT_DST: return "FormatFeatureFlag::BLIT_DST"; - case stormkit::gpu::FormatFeatureFlag::BLIT_SRC: return "FormatFeatureFlag::BLIT_SRC"; - case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT: return "FormatFeatureFlag::COLOR_ATTACHMENT"; - case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND: return "FormatFeatureFlag::COLOR_ATTACHMENT_BLEND"; - case stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES: return "FormatFeatureFlag::COSITED_CHROMA_SAMPLES"; - case stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT: return "FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT"; - case stormkit::gpu::FormatFeatureFlag::DISJOINT: return "FormatFeatureFlag::DISJOINT"; - case stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES: return "FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE: return "FormatFeatureFlag::SAMPLED_IMAGE"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR: return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX: return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER"; - case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER: return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE: return "FormatFeatureFlag::STORAGE_IMAGE"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC: return "FormatFeatureFlag::STORAGE_IMAGE_ATOMIC"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER"; - case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC"; - case stormkit::gpu::FormatFeatureFlag::TRANSFER_DST: return "FormatFeatureFlag::TRANSFER_DST"; - case stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC: return "FormatFeatureFlag::TRANSFER_SRC"; - case stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER: return "FormatFeatureFlag::UNIFORM_TEXEL_BUFFER"; - case stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER: return "FormatFeatureFlag::VERTEX_BUFFER"; - + stormkit::gpu::FormatFeatureFlag::BLIT_DST, + stormkit::gpu::FormatFeatureFlag::BLIT_SRC, + stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT, + stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND, + stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES, + stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT, + stormkit::gpu::FormatFeatureFlag::DISJOINT, + stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER, + stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER, + stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE, + stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC, + stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER, + stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC, + stormkit::gpu::FormatFeatureFlag::TRANSFER_DST, + stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC, + stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER, + stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER, + + }; + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::FormatFeatureFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::FormatFeatureFlag::BLIT_DST: return "FormatFeatureFlag::BLIT_DST"; + case stormkit::gpu::FormatFeatureFlag::BLIT_SRC: return "FormatFeatureFlag::BLIT_SRC"; + case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT: return "FormatFeatureFlag::COLOR_ATTACHMENT"; + case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND: return "FormatFeatureFlag::COLOR_ATTACHMENT_BLEND"; + case stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES: return "FormatFeatureFlag::COSITED_CHROMA_SAMPLES"; + case stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT: return "FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT"; + case stormkit::gpu::FormatFeatureFlag::DISJOINT: return "FormatFeatureFlag::DISJOINT"; + case stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES: return "FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE: return "FormatFeatureFlag::SAMPLED_IMAGE"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR: + return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX: + return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT: + return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE: + return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER: + return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER: + return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE: return "FormatFeatureFlag::STORAGE_IMAGE"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC: return "FormatFeatureFlag::STORAGE_IMAGE_ATOMIC"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC: + return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC"; + case stormkit::gpu::FormatFeatureFlag::TRANSFER_DST: return "FormatFeatureFlag::TRANSFER_DST"; + case stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC: return "FormatFeatureFlag::TRANSFER_SRC"; + case stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER: return "FormatFeatureFlag::UNIFORM_TEXEL_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER: return "FormatFeatureFlag::VERTEX_BUFFER"; + } + std::unreachable(); + } + + template<> + STORMKIT_FORCE_INLINE + constexpr auto stormkit::core::to_string(stormkit::gpu::FormatFeatureFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::FormatFeatureFlag::BLIT_DST: return "FormatFeatureFlag::BLIT_DST"; + case stormkit::gpu::FormatFeatureFlag::BLIT_SRC: return "FormatFeatureFlag::BLIT_SRC"; + case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT: return "FormatFeatureFlag::COLOR_ATTACHMENT"; + case stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT_BLEND: return "FormatFeatureFlag::COLOR_ATTACHMENT_BLEND"; + case stormkit::gpu::FormatFeatureFlag::COSITED_CHROMA_SAMPLES: return "FormatFeatureFlag::COSITED_CHROMA_SAMPLES"; + case stormkit::gpu::FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT: return "FormatFeatureFlag::DEPTH_STENCIL_ATTACHMENT"; + case stormkit::gpu::FormatFeatureFlag::DISJOINT: return "FormatFeatureFlag::DISJOINT"; + case stormkit::gpu::FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES: return "FormatFeatureFlag::MIDPOINT_CHROMA_SAMPLES"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE: return "FormatFeatureFlag::SAMPLED_IMAGE"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR: + return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_LINEAR"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX: + return "FormatFeatureFlag::SAMPLED_IMAGE_FILTER_MINMAX"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT: + return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE: + return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_CHROMA_RECONSTRUCTION_EXPLICIT_FORCEABLE"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER: + return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER"; + case stormkit::gpu::FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER: + return "FormatFeatureFlag::SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE: return "FormatFeatureFlag::STORAGE_IMAGE"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_IMAGE_ATOMIC: return "FormatFeatureFlag::STORAGE_IMAGE_ATOMIC"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER: return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC: + return "FormatFeatureFlag::STORAGE_TEXEL_BUFFER_ATOMIC"; + case stormkit::gpu::FormatFeatureFlag::TRANSFER_DST: return "FormatFeatureFlag::TRANSFER_DST"; + case stormkit::gpu::FormatFeatureFlag::TRANSFER_SRC: return "FormatFeatureFlag::TRANSFER_SRC"; + case stormkit::gpu::FormatFeatureFlag::UNIFORM_TEXEL_BUFFER: return "FormatFeatureFlag::UNIFORM_TEXEL_BUFFER"; + case stormkit::gpu::FormatFeatureFlag::VERTEX_BUFFER: return "FormatFeatureFlag::VERTEX_BUFFER"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::FrontFace) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::FrontFace::CLOCKWISE, - stormkit::gpu::FrontFace::COUNTER_CLOCKWISE, - + stormkit::gpu::FrontFace::CLOCKWISE, + stormkit::gpu::FrontFace::COUNTER_CLOCKWISE, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::FrontFace value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; - case stormkit::gpu::FrontFace::COUNTER_CLOCKWISE: return "FrontFace::COUNTER_CLOCKWISE"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::FrontFace value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; + case stormkit::gpu::FrontFace::COUNTER_CLOCKWISE: return "FrontFace::COUNTER_CLOCKWISE"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::FrontFace value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; - case stormkit::gpu::FrontFace::COUNTER_CLOCKWISE: return "FrontFace::COUNTER_CLOCKWISE"; - + switch (value) { + case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; + case stormkit::gpu::FrontFace::COUNTER_CLOCKWISE: return "FrontFace::COUNTER_CLOCKWISE"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::GeometryFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION, - stormkit::gpu::GeometryFlag::OPAQUE, - + stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION, + stormkit::gpu::GeometryFlag::OPAQUE, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::GeometryFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION: return "GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION"; - case stormkit::gpu::GeometryFlag::OPAQUE: return "GeometryFlag::OPAQUE"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::GeometryFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION: + return "GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION"; + case stormkit::gpu::GeometryFlag::OPAQUE: return "GeometryFlag::OPAQUE"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION: return "GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION"; - case stormkit::gpu::GeometryFlag::OPAQUE: return "GeometryFlag::OPAQUE"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION: + return "GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION"; + case stormkit::gpu::GeometryFlag::OPAQUE: return "GeometryFlag::OPAQUE"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::GeometryType) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::GeometryType::AABBS, - stormkit::gpu::GeometryType::INSTANCES, - stormkit::gpu::GeometryType::TRIANGLES, - + stormkit::gpu::GeometryType::AABBS, + stormkit::gpu::GeometryType::INSTANCES, + stormkit::gpu::GeometryType::TRIANGLES, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::GeometryType value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::GeometryType::AABBS: return "GeometryType::AABBS"; - case stormkit::gpu::GeometryType::INSTANCES: return "GeometryType::INSTANCES"; - case stormkit::gpu::GeometryType::TRIANGLES: return "GeometryType::TRIANGLES"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::GeometryType value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::GeometryType::AABBS: return "GeometryType::AABBS"; + case stormkit::gpu::GeometryType::INSTANCES: return "GeometryType::INSTANCES"; + case stormkit::gpu::GeometryType::TRIANGLES: return "GeometryType::TRIANGLES"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryType value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::GeometryType::AABBS: return "GeometryType::AABBS"; - case stormkit::gpu::GeometryType::INSTANCES: return "GeometryType::INSTANCES"; - case stormkit::gpu::GeometryType::TRIANGLES: return "GeometryType::TRIANGLES"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryType value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::GeometryType::AABBS: return "GeometryType::AABBS"; + case stormkit::gpu::GeometryType::INSTANCES: return "GeometryType::INSTANCES"; + case stormkit::gpu::GeometryType::TRIANGLES: return "GeometryType::TRIANGLES"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageAspectFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageAspectFlag::COLOR, - stormkit::gpu::ImageAspectFlag::DEPTH, - stormkit::gpu::ImageAspectFlag::NONE, - stormkit::gpu::ImageAspectFlag::STENCIL, - + stormkit::gpu::ImageAspectFlag::COLOR, + stormkit::gpu::ImageAspectFlag::DEPTH, + stormkit::gpu::ImageAspectFlag::NONE, + stormkit::gpu::ImageAspectFlag::STENCIL, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageAspectFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ImageAspectFlag::COLOR: return "ImageAspectFlag::COLOR"; - case stormkit::gpu::ImageAspectFlag::DEPTH: return "ImageAspectFlag::DEPTH"; - case stormkit::gpu::ImageAspectFlag::NONE: return "ImageAspectFlag::NONE"; - case stormkit::gpu::ImageAspectFlag::STENCIL: return "ImageAspectFlag::STENCIL"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageAspectFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ImageAspectFlag::COLOR: return "ImageAspectFlag::COLOR"; + case stormkit::gpu::ImageAspectFlag::DEPTH: return "ImageAspectFlag::DEPTH"; + case stormkit::gpu::ImageAspectFlag::NONE: return "ImageAspectFlag::NONE"; + case stormkit::gpu::ImageAspectFlag::STENCIL: return "ImageAspectFlag::STENCIL"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageAspectFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ImageAspectFlag::COLOR: return "ImageAspectFlag::COLOR"; - case stormkit::gpu::ImageAspectFlag::DEPTH: return "ImageAspectFlag::DEPTH"; - case stormkit::gpu::ImageAspectFlag::NONE: return "ImageAspectFlag::NONE"; - case stormkit::gpu::ImageAspectFlag::STENCIL: return "ImageAspectFlag::STENCIL"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageAspectFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::ImageAspectFlag::COLOR: return "ImageAspectFlag::COLOR"; + case stormkit::gpu::ImageAspectFlag::DEPTH: return "ImageAspectFlag::DEPTH"; + case stormkit::gpu::ImageAspectFlag::NONE: return "ImageAspectFlag::NONE"; + case stormkit::gpu::ImageAspectFlag::STENCIL: return "ImageAspectFlag::STENCIL"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageCreateFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageCreateFlag::ALIAS, - stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE, - stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE, - stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE, - stormkit::gpu::ImageCreateFlag::DISJOINT, - stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE, - stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT, - stormkit::gpu::ImageCreateFlag::NONE, - stormkit::gpu::ImageCreateFlag::PROTECTED, - stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED, - stormkit::gpu::ImageCreateFlag::SPARSE_BINDING, - stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY, - stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS, - - }; - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageCreateFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ImageCreateFlag::ALIAS: return "ImageCreateFlag::ALIAS"; - case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE: return "ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE: return "ImageCreateFlag::CUBE_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::DISJOINT: return "ImageCreateFlag::DISJOINT"; - case stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE: return "ImageCreateFlag::EXTENDED_USAGE"; - case stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT: return "ImageCreateFlag::MUTABLE_FORMAT"; - case stormkit::gpu::ImageCreateFlag::NONE: return "ImageCreateFlag::NONE"; - case stormkit::gpu::ImageCreateFlag::PROTECTED: return "ImageCreateFlag::PROTECTED"; - case stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED: return "ImageCreateFlag::SPARSE_ALIASED"; - case stormkit::gpu::ImageCreateFlag::SPARSE_BINDING: return "ImageCreateFlag::SPARSE_BINDING"; - case stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY: return "ImageCreateFlag::SPARSE_RESIDENCY"; - case stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS: return "ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS"; - - } - std::unreachable(); - } - template<> - STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageCreateFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ImageCreateFlag::ALIAS: return "ImageCreateFlag::ALIAS"; - case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE: return "ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE: return "ImageCreateFlag::CUBE_COMPATIBLE"; - case stormkit::gpu::ImageCreateFlag::DISJOINT: return "ImageCreateFlag::DISJOINT"; - case stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE: return "ImageCreateFlag::EXTENDED_USAGE"; - case stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT: return "ImageCreateFlag::MUTABLE_FORMAT"; - case stormkit::gpu::ImageCreateFlag::NONE: return "ImageCreateFlag::NONE"; - case stormkit::gpu::ImageCreateFlag::PROTECTED: return "ImageCreateFlag::PROTECTED"; - case stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED: return "ImageCreateFlag::SPARSE_ALIASED"; - case stormkit::gpu::ImageCreateFlag::SPARSE_BINDING: return "ImageCreateFlag::SPARSE_BINDING"; - case stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY: return "ImageCreateFlag::SPARSE_RESIDENCY"; - case stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS: return "ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS"; - + stormkit::gpu::ImageCreateFlag::ALIAS, + stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE, + stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE, + stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE, + stormkit::gpu::ImageCreateFlag::DISJOINT, + stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE, + stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT, + stormkit::gpu::ImageCreateFlag::NONE, + stormkit::gpu::ImageCreateFlag::PROTECTED, + stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED, + stormkit::gpu::ImageCreateFlag::SPARSE_BINDING, + stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY, + stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS, + + }; + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageCreateFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ImageCreateFlag::ALIAS: return "ImageCreateFlag::ALIAS"; + case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE: + return "ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE: return "ImageCreateFlag::CUBE_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::DISJOINT: return "ImageCreateFlag::DISJOINT"; + case stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE: return "ImageCreateFlag::EXTENDED_USAGE"; + case stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT: return "ImageCreateFlag::MUTABLE_FORMAT"; + case stormkit::gpu::ImageCreateFlag::NONE: return "ImageCreateFlag::NONE"; + case stormkit::gpu::ImageCreateFlag::PROTECTED: return "ImageCreateFlag::PROTECTED"; + case stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED: return "ImageCreateFlag::SPARSE_ALIASED"; + case stormkit::gpu::ImageCreateFlag::SPARSE_BINDING: return "ImageCreateFlag::SPARSE_BINDING"; + case stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY: return "ImageCreateFlag::SPARSE_RESIDENCY"; + case stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS: + return "ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS"; + } + std::unreachable(); + } + + template<> + STORMKIT_FORCE_INLINE + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageCreateFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::ImageCreateFlag::ALIAS: return "ImageCreateFlag::ALIAS"; + case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE: + return "ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::CUBE_COMPATIBLE: return "ImageCreateFlag::CUBE_COMPATIBLE"; + case stormkit::gpu::ImageCreateFlag::DISJOINT: return "ImageCreateFlag::DISJOINT"; + case stormkit::gpu::ImageCreateFlag::EXTENDED_USAGE: return "ImageCreateFlag::EXTENDED_USAGE"; + case stormkit::gpu::ImageCreateFlag::MUTABLE_FORMAT: return "ImageCreateFlag::MUTABLE_FORMAT"; + case stormkit::gpu::ImageCreateFlag::NONE: return "ImageCreateFlag::NONE"; + case stormkit::gpu::ImageCreateFlag::PROTECTED: return "ImageCreateFlag::PROTECTED"; + case stormkit::gpu::ImageCreateFlag::SPARSE_ALIASED: return "ImageCreateFlag::SPARSE_ALIASED"; + case stormkit::gpu::ImageCreateFlag::SPARSE_BINDING: return "ImageCreateFlag::SPARSE_BINDING"; + case stormkit::gpu::ImageCreateFlag::SPARSE_RESIDENCY: return "ImageCreateFlag::SPARSE_RESIDENCY"; + case stormkit::gpu::ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS: + return "ImageCreateFlag::SPLIT_INSTANCE_BIND_REGIONS"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageLayout) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL, - stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL, - stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, - stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, - stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL, - stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL, - stormkit::gpu::ImageLayout::GENERAL, - stormkit::gpu::ImageLayout::PREINITIALIZED, - stormkit::gpu::ImageLayout::PRESENT_SRC, - stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL, - stormkit::gpu::ImageLayout::SHARED_PRESENT, - stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL, - stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL, - stormkit::gpu::ImageLayout::UNDEFINED, - - }; - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageLayout value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL: return "ImageLayout::ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: return "ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: return "ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL: return "ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL: return "ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::GENERAL: return "ImageLayout::GENERAL"; - case stormkit::gpu::ImageLayout::PREINITIALIZED: return "ImageLayout::PREINITIALIZED"; - case stormkit::gpu::ImageLayout::PRESENT_SRC: return "ImageLayout::PRESENT_SRC"; - case stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL: return "ImageLayout::SHADER_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::SHARED_PRESENT: return "ImageLayout::SHARED_PRESENT"; - case stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL: return "ImageLayout::TRANSFER_DST_OPTIMAL"; - case stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL: return "ImageLayout::TRANSFER_SRC_OPTIMAL"; - case stormkit::gpu::ImageLayout::UNDEFINED: return "ImageLayout::UNDEFINED"; - - } - std::unreachable(); - } - template<> - STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageLayout value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL: return "ImageLayout::ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: return "ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: return "ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL: return "ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL"; - case stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL: return "ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::GENERAL: return "ImageLayout::GENERAL"; - case stormkit::gpu::ImageLayout::PREINITIALIZED: return "ImageLayout::PREINITIALIZED"; - case stormkit::gpu::ImageLayout::PRESENT_SRC: return "ImageLayout::PRESENT_SRC"; - case stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL: return "ImageLayout::SHADER_READ_ONLY_OPTIMAL"; - case stormkit::gpu::ImageLayout::SHARED_PRESENT: return "ImageLayout::SHARED_PRESENT"; - case stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL: return "ImageLayout::TRANSFER_DST_OPTIMAL"; - case stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL: return "ImageLayout::TRANSFER_SRC_OPTIMAL"; - case stormkit::gpu::ImageLayout::UNDEFINED: return "ImageLayout::UNDEFINED"; - + stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL, + stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL, + stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, + stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, + stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL, + stormkit::gpu::ImageLayout::GENERAL, + stormkit::gpu::ImageLayout::PREINITIALIZED, + stormkit::gpu::ImageLayout::PRESENT_SRC, + stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL, + stormkit::gpu::ImageLayout::SHARED_PRESENT, + stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL, + stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL, + stormkit::gpu::ImageLayout::UNDEFINED, + + }; + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageLayout value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL: return "ImageLayout::ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: + return "ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: + return "ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL: + return "ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL: + return "ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::GENERAL: return "ImageLayout::GENERAL"; + case stormkit::gpu::ImageLayout::PREINITIALIZED: return "ImageLayout::PREINITIALIZED"; + case stormkit::gpu::ImageLayout::PRESENT_SRC: return "ImageLayout::PRESENT_SRC"; + case stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL: return "ImageLayout::SHADER_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::SHARED_PRESENT: return "ImageLayout::SHARED_PRESENT"; + case stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL: return "ImageLayout::TRANSFER_DST_OPTIMAL"; + case stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL: return "ImageLayout::TRANSFER_SRC_OPTIMAL"; + case stormkit::gpu::ImageLayout::UNDEFINED: return "ImageLayout::UNDEFINED"; + } + std::unreachable(); + } + + template<> + STORMKIT_FORCE_INLINE + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageLayout value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL: return "ImageLayout::ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: + return "ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: + return "ImageLayout::DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL: + return "ImageLayout::DEPTH_STENCIL_ATTACHMENT_OPTIMAL"; + case stormkit::gpu::ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL: + return "ImageLayout::DEPTH_STENCIL_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::GENERAL: return "ImageLayout::GENERAL"; + case stormkit::gpu::ImageLayout::PREINITIALIZED: return "ImageLayout::PREINITIALIZED"; + case stormkit::gpu::ImageLayout::PRESENT_SRC: return "ImageLayout::PRESENT_SRC"; + case stormkit::gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL: return "ImageLayout::SHADER_READ_ONLY_OPTIMAL"; + case stormkit::gpu::ImageLayout::SHARED_PRESENT: return "ImageLayout::SHARED_PRESENT"; + case stormkit::gpu::ImageLayout::TRANSFER_DST_OPTIMAL: return "ImageLayout::TRANSFER_DST_OPTIMAL"; + case stormkit::gpu::ImageLayout::TRANSFER_SRC_OPTIMAL: return "ImageLayout::TRANSFER_SRC_OPTIMAL"; + case stormkit::gpu::ImageLayout::UNDEFINED: return "ImageLayout::UNDEFINED"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageTiling) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageTiling::LINEAR, - stormkit::gpu::ImageTiling::OPTIMAL, - + stormkit::gpu::ImageTiling::LINEAR, + stormkit::gpu::ImageTiling::OPTIMAL, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageTiling value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ImageTiling::LINEAR: return "ImageTiling::LINEAR"; - case stormkit::gpu::ImageTiling::OPTIMAL: return "ImageTiling::OPTIMAL"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageTiling value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ImageTiling::LINEAR: return "ImageTiling::LINEAR"; + case stormkit::gpu::ImageTiling::OPTIMAL: return "ImageTiling::OPTIMAL"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageTiling value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ImageTiling::LINEAR: return "ImageTiling::LINEAR"; - case stormkit::gpu::ImageTiling::OPTIMAL: return "ImageTiling::OPTIMAL"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageTiling value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::ImageTiling::LINEAR: return "ImageTiling::LINEAR"; + case stormkit::gpu::ImageTiling::OPTIMAL: return "ImageTiling::OPTIMAL"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageType) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageType::T1D, - stormkit::gpu::ImageType::T2D, - stormkit::gpu::ImageType::T3D, - + stormkit::gpu::ImageType::T1D, + stormkit::gpu::ImageType::T2D, + stormkit::gpu::ImageType::T3D, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageType value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; - case stormkit::gpu::ImageType::T2D: return "ImageType::T2D"; - case stormkit::gpu::ImageType::T3D: return "ImageType::T3D"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageType value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; + case stormkit::gpu::ImageType::T2D: return "ImageType::T2D"; + case stormkit::gpu::ImageType::T3D: return "ImageType::T3D"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::ImageType value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; - case stormkit::gpu::ImageType::T2D: return "ImageType::T2D"; - case stormkit::gpu::ImageType::T3D: return "ImageType::T3D"; - + switch (value) { + case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; + case stormkit::gpu::ImageType::T2D: return "ImageType::T2D"; + case stormkit::gpu::ImageType::T3D: return "ImageType::T3D"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageUsageFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT, - stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT, - stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT, - stormkit::gpu::ImageUsageFlag::SAMPLED, - stormkit::gpu::ImageUsageFlag::STORAGE, - stormkit::gpu::ImageUsageFlag::TRANSFER_DST, - stormkit::gpu::ImageUsageFlag::TRANSFER_SRC, - stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT, - + stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT, stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT, + stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT, stormkit::gpu::ImageUsageFlag::SAMPLED, + stormkit::gpu::ImageUsageFlag::STORAGE, stormkit::gpu::ImageUsageFlag::TRANSFER_DST, + stormkit::gpu::ImageUsageFlag::TRANSFER_SRC, stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageUsageFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: return "ImageUsageFlag::COLOR_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT: return "ImageUsageFlag::INPUT_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::SAMPLED: return "ImageUsageFlag::SAMPLED"; - case stormkit::gpu::ImageUsageFlag::STORAGE: return "ImageUsageFlag::STORAGE"; - case stormkit::gpu::ImageUsageFlag::TRANSFER_DST: return "ImageUsageFlag::TRANSFER_DST"; - case stormkit::gpu::ImageUsageFlag::TRANSFER_SRC: return "ImageUsageFlag::TRANSFER_SRC"; - case stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT: return "ImageUsageFlag::TRANSIENT_ATTACHMENT"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageUsageFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: return "ImageUsageFlag::COLOR_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT: return "ImageUsageFlag::INPUT_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::SAMPLED: return "ImageUsageFlag::SAMPLED"; + case stormkit::gpu::ImageUsageFlag::STORAGE: return "ImageUsageFlag::STORAGE"; + case stormkit::gpu::ImageUsageFlag::TRANSFER_DST: return "ImageUsageFlag::TRANSFER_DST"; + case stormkit::gpu::ImageUsageFlag::TRANSFER_SRC: return "ImageUsageFlag::TRANSFER_SRC"; + case stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT: return "ImageUsageFlag::TRANSIENT_ATTACHMENT"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageUsageFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: return "ImageUsageFlag::COLOR_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT: return "ImageUsageFlag::INPUT_ATTACHMENT"; - case stormkit::gpu::ImageUsageFlag::SAMPLED: return "ImageUsageFlag::SAMPLED"; - case stormkit::gpu::ImageUsageFlag::STORAGE: return "ImageUsageFlag::STORAGE"; - case stormkit::gpu::ImageUsageFlag::TRANSFER_DST: return "ImageUsageFlag::TRANSFER_DST"; - case stormkit::gpu::ImageUsageFlag::TRANSFER_SRC: return "ImageUsageFlag::TRANSFER_SRC"; - case stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT: return "ImageUsageFlag::TRANSIENT_ATTACHMENT"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageUsageFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: return "ImageUsageFlag::COLOR_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT: return "ImageUsageFlag::INPUT_ATTACHMENT"; + case stormkit::gpu::ImageUsageFlag::SAMPLED: return "ImageUsageFlag::SAMPLED"; + case stormkit::gpu::ImageUsageFlag::STORAGE: return "ImageUsageFlag::STORAGE"; + case stormkit::gpu::ImageUsageFlag::TRANSFER_DST: return "ImageUsageFlag::TRANSFER_DST"; + case stormkit::gpu::ImageUsageFlag::TRANSFER_SRC: return "ImageUsageFlag::TRANSFER_SRC"; + case stormkit::gpu::ImageUsageFlag::TRANSIENT_ATTACHMENT: return "ImageUsageFlag::TRANSIENT_ATTACHMENT"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ImageViewType) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ImageViewType::CUBE, - stormkit::gpu::ImageViewType::CUBE_ARRAY, - stormkit::gpu::ImageViewType::T1D, - stormkit::gpu::ImageViewType::T1D_ARRAY, - stormkit::gpu::ImageViewType::T2D, - stormkit::gpu::ImageViewType::T2D_ARRAY, - stormkit::gpu::ImageViewType::T3D, - + stormkit::gpu::ImageViewType::CUBE, stormkit::gpu::ImageViewType::CUBE_ARRAY, + stormkit::gpu::ImageViewType::T1D, stormkit::gpu::ImageViewType::T1D_ARRAY, + stormkit::gpu::ImageViewType::T2D, stormkit::gpu::ImageViewType::T2D_ARRAY, + stormkit::gpu::ImageViewType::T3D, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageViewType value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ImageViewType::CUBE: return "ImageViewType::CUBE"; - case stormkit::gpu::ImageViewType::CUBE_ARRAY: return "ImageViewType::CUBE_ARRAY"; - case stormkit::gpu::ImageViewType::T1D: return "ImageViewType::T1D"; - case stormkit::gpu::ImageViewType::T1D_ARRAY: return "ImageViewType::T1D_ARRAY"; - case stormkit::gpu::ImageViewType::T2D: return "ImageViewType::T2D"; - case stormkit::gpu::ImageViewType::T2D_ARRAY: return "ImageViewType::T2D_ARRAY"; - case stormkit::gpu::ImageViewType::T3D: return "ImageViewType::T3D"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageViewType value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ImageViewType::CUBE: return "ImageViewType::CUBE"; + case stormkit::gpu::ImageViewType::CUBE_ARRAY: return "ImageViewType::CUBE_ARRAY"; + case stormkit::gpu::ImageViewType::T1D: return "ImageViewType::T1D"; + case stormkit::gpu::ImageViewType::T1D_ARRAY: return "ImageViewType::T1D_ARRAY"; + case stormkit::gpu::ImageViewType::T2D: return "ImageViewType::T2D"; + case stormkit::gpu::ImageViewType::T2D_ARRAY: return "ImageViewType::T2D_ARRAY"; + case stormkit::gpu::ImageViewType::T3D: return "ImageViewType::T3D"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageViewType value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ImageViewType::CUBE: return "ImageViewType::CUBE"; - case stormkit::gpu::ImageViewType::CUBE_ARRAY: return "ImageViewType::CUBE_ARRAY"; - case stormkit::gpu::ImageViewType::T1D: return "ImageViewType::T1D"; - case stormkit::gpu::ImageViewType::T1D_ARRAY: return "ImageViewType::T1D_ARRAY"; - case stormkit::gpu::ImageViewType::T2D: return "ImageViewType::T2D"; - case stormkit::gpu::ImageViewType::T2D_ARRAY: return "ImageViewType::T2D_ARRAY"; - case stormkit::gpu::ImageViewType::T3D: return "ImageViewType::T3D"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageViewType value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::ImageViewType::CUBE: return "ImageViewType::CUBE"; + case stormkit::gpu::ImageViewType::CUBE_ARRAY: return "ImageViewType::CUBE_ARRAY"; + case stormkit::gpu::ImageViewType::T1D: return "ImageViewType::T1D"; + case stormkit::gpu::ImageViewType::T1D_ARRAY: return "ImageViewType::T1D_ARRAY"; + case stormkit::gpu::ImageViewType::T2D: return "ImageViewType::T2D"; + case stormkit::gpu::ImageViewType::T2D_ARRAY: return "ImageViewType::T2D_ARRAY"; + case stormkit::gpu::ImageViewType::T3D: return "ImageViewType::T3D"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::LogicOperation) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::LogicOperation::AND, - stormkit::gpu::LogicOperation::AND_INVERTED, - stormkit::gpu::LogicOperation::AND_REVERSE, - stormkit::gpu::LogicOperation::CLEAR, - stormkit::gpu::LogicOperation::COPY, - stormkit::gpu::LogicOperation::COPY_INVERTED, - stormkit::gpu::LogicOperation::EQUIVALENT, - stormkit::gpu::LogicOperation::INVERT, - stormkit::gpu::LogicOperation::NAND, - stormkit::gpu::LogicOperation::NO_OP, - stormkit::gpu::LogicOperation::NOR, - stormkit::gpu::LogicOperation::OR, - stormkit::gpu::LogicOperation::OR_INVERTED, - stormkit::gpu::LogicOperation::OR_REVERSE, - stormkit::gpu::LogicOperation::SET, - stormkit::gpu::LogicOperation::XOR, - - }; - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::LogicOperation value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::LogicOperation::AND: return "LogicOperation::AND"; - case stormkit::gpu::LogicOperation::AND_INVERTED: return "LogicOperation::AND_INVERTED"; - case stormkit::gpu::LogicOperation::AND_REVERSE: return "LogicOperation::AND_REVERSE"; - case stormkit::gpu::LogicOperation::CLEAR: return "LogicOperation::CLEAR"; - case stormkit::gpu::LogicOperation::COPY: return "LogicOperation::COPY"; - case stormkit::gpu::LogicOperation::COPY_INVERTED: return "LogicOperation::COPY_INVERTED"; - case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; - case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; - case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; - case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; - case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; - case stormkit::gpu::LogicOperation::OR: return "LogicOperation::OR"; - case stormkit::gpu::LogicOperation::OR_INVERTED: return "LogicOperation::OR_INVERTED"; - case stormkit::gpu::LogicOperation::OR_REVERSE: return "LogicOperation::OR_REVERSE"; - case stormkit::gpu::LogicOperation::SET: return "LogicOperation::SET"; - case stormkit::gpu::LogicOperation::XOR: return "LogicOperation::XOR"; - - } - std::unreachable(); - } - template<> - STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::LogicOperation value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::LogicOperation::AND: return "LogicOperation::AND"; - case stormkit::gpu::LogicOperation::AND_INVERTED: return "LogicOperation::AND_INVERTED"; - case stormkit::gpu::LogicOperation::AND_REVERSE: return "LogicOperation::AND_REVERSE"; - case stormkit::gpu::LogicOperation::CLEAR: return "LogicOperation::CLEAR"; - case stormkit::gpu::LogicOperation::COPY: return "LogicOperation::COPY"; - case stormkit::gpu::LogicOperation::COPY_INVERTED: return "LogicOperation::COPY_INVERTED"; - case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; - case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; - case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; - case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; - case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; - case stormkit::gpu::LogicOperation::OR: return "LogicOperation::OR"; - case stormkit::gpu::LogicOperation::OR_INVERTED: return "LogicOperation::OR_INVERTED"; - case stormkit::gpu::LogicOperation::OR_REVERSE: return "LogicOperation::OR_REVERSE"; - case stormkit::gpu::LogicOperation::SET: return "LogicOperation::SET"; - case stormkit::gpu::LogicOperation::XOR: return "LogicOperation::XOR"; - + stormkit::gpu::LogicOperation::AND, stormkit::gpu::LogicOperation::AND_INVERTED, + stormkit::gpu::LogicOperation::AND_REVERSE, stormkit::gpu::LogicOperation::CLEAR, + stormkit::gpu::LogicOperation::COPY, stormkit::gpu::LogicOperation::COPY_INVERTED, + stormkit::gpu::LogicOperation::EQUIVALENT, stormkit::gpu::LogicOperation::INVERT, + stormkit::gpu::LogicOperation::NAND, stormkit::gpu::LogicOperation::NO_OP, + stormkit::gpu::LogicOperation::NOR, stormkit::gpu::LogicOperation::OR, + stormkit::gpu::LogicOperation::OR_INVERTED, stormkit::gpu::LogicOperation::OR_REVERSE, + stormkit::gpu::LogicOperation::SET, stormkit::gpu::LogicOperation::XOR, + + }; + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::LogicOperation value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::LogicOperation::AND: return "LogicOperation::AND"; + case stormkit::gpu::LogicOperation::AND_INVERTED: return "LogicOperation::AND_INVERTED"; + case stormkit::gpu::LogicOperation::AND_REVERSE: return "LogicOperation::AND_REVERSE"; + case stormkit::gpu::LogicOperation::CLEAR: return "LogicOperation::CLEAR"; + case stormkit::gpu::LogicOperation::COPY: return "LogicOperation::COPY"; + case stormkit::gpu::LogicOperation::COPY_INVERTED: return "LogicOperation::COPY_INVERTED"; + case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; + case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; + case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; + case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; + case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; + case stormkit::gpu::LogicOperation::OR: return "LogicOperation::OR"; + case stormkit::gpu::LogicOperation::OR_INVERTED: return "LogicOperation::OR_INVERTED"; + case stormkit::gpu::LogicOperation::OR_REVERSE: return "LogicOperation::OR_REVERSE"; + case stormkit::gpu::LogicOperation::SET: return "LogicOperation::SET"; + case stormkit::gpu::LogicOperation::XOR: return "LogicOperation::XOR"; + } + std::unreachable(); + } + + template<> + STORMKIT_FORCE_INLINE + constexpr auto stormkit::core::to_string(stormkit::gpu::LogicOperation value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::LogicOperation::AND: return "LogicOperation::AND"; + case stormkit::gpu::LogicOperation::AND_INVERTED: return "LogicOperation::AND_INVERTED"; + case stormkit::gpu::LogicOperation::AND_REVERSE: return "LogicOperation::AND_REVERSE"; + case stormkit::gpu::LogicOperation::CLEAR: return "LogicOperation::CLEAR"; + case stormkit::gpu::LogicOperation::COPY: return "LogicOperation::COPY"; + case stormkit::gpu::LogicOperation::COPY_INVERTED: return "LogicOperation::COPY_INVERTED"; + case stormkit::gpu::LogicOperation::EQUIVALENT: return "LogicOperation::EQUIVALENT"; + case stormkit::gpu::LogicOperation::INVERT: return "LogicOperation::INVERT"; + case stormkit::gpu::LogicOperation::NAND: return "LogicOperation::NAND"; + case stormkit::gpu::LogicOperation::NO_OP: return "LogicOperation::NO_OP"; + case stormkit::gpu::LogicOperation::NOR: return "LogicOperation::NOR"; + case stormkit::gpu::LogicOperation::OR: return "LogicOperation::OR"; + case stormkit::gpu::LogicOperation::OR_INVERTED: return "LogicOperation::OR_INVERTED"; + case stormkit::gpu::LogicOperation::OR_REVERSE: return "LogicOperation::OR_REVERSE"; + case stormkit::gpu::LogicOperation::SET: return "LogicOperation::SET"; + case stormkit::gpu::LogicOperation::XOR: return "LogicOperation::XOR"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::MemoryPropertyFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL, - stormkit::gpu::MemoryPropertyFlag::HOST_CACHED, - stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT, - stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE, - + stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL, + stormkit::gpu::MemoryPropertyFlag::HOST_CACHED, + stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT, + stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::MemoryPropertyFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: return "MemoryPropertyFlag::DEVICE_LOCAL"; - case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: return "MemoryPropertyFlag::HOST_CACHED"; - case stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT: return "MemoryPropertyFlag::HOST_COHERENT"; - case stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE: return "MemoryPropertyFlag::HOST_VISIBLE"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::MemoryPropertyFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: return "MemoryPropertyFlag::DEVICE_LOCAL"; + case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: return "MemoryPropertyFlag::HOST_CACHED"; + case stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT: return "MemoryPropertyFlag::HOST_COHERENT"; + case stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE: return "MemoryPropertyFlag::HOST_VISIBLE"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::MemoryPropertyFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: return "MemoryPropertyFlag::DEVICE_LOCAL"; - case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: return "MemoryPropertyFlag::HOST_CACHED"; - case stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT: return "MemoryPropertyFlag::HOST_COHERENT"; - case stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE: return "MemoryPropertyFlag::HOST_VISIBLE"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::MemoryPropertyFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: return "MemoryPropertyFlag::DEVICE_LOCAL"; + case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: return "MemoryPropertyFlag::HOST_CACHED"; + case stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT: return "MemoryPropertyFlag::HOST_COHERENT"; + case stormkit::gpu::MemoryPropertyFlag::HOST_VISIBLE: return "MemoryPropertyFlag::HOST_VISIBLE"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PhysicalDeviceType) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PhysicalDeviceType::CPU, - stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU, - stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU, - stormkit::gpu::PhysicalDeviceType::OTHER, - stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU, - + stormkit::gpu::PhysicalDeviceType::CPU, + stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU, + stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU, + stormkit::gpu::PhysicalDeviceType::OTHER, + stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PhysicalDeviceType value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::PhysicalDeviceType::CPU: return "PhysicalDeviceType::CPU"; - case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: return "PhysicalDeviceType::DISCRETE_GPU"; - case stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU: return "PhysicalDeviceType::INTEGRATED_GPU"; - case stormkit::gpu::PhysicalDeviceType::OTHER: return "PhysicalDeviceType::OTHER"; - case stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU: return "PhysicalDeviceType::VIRTUAL_GPU"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::PhysicalDeviceType value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::PhysicalDeviceType::CPU: return "PhysicalDeviceType::CPU"; + case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: return "PhysicalDeviceType::DISCRETE_GPU"; + case stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU: return "PhysicalDeviceType::INTEGRATED_GPU"; + case stormkit::gpu::PhysicalDeviceType::OTHER: return "PhysicalDeviceType::OTHER"; + case stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU: return "PhysicalDeviceType::VIRTUAL_GPU"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::PhysicalDeviceType value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::PhysicalDeviceType::CPU: return "PhysicalDeviceType::CPU"; - case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: return "PhysicalDeviceType::DISCRETE_GPU"; - case stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU: return "PhysicalDeviceType::INTEGRATED_GPU"; - case stormkit::gpu::PhysicalDeviceType::OTHER: return "PhysicalDeviceType::OTHER"; - case stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU: return "PhysicalDeviceType::VIRTUAL_GPU"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::PhysicalDeviceType value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::PhysicalDeviceType::CPU: return "PhysicalDeviceType::CPU"; + case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: return "PhysicalDeviceType::DISCRETE_GPU"; + case stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU: return "PhysicalDeviceType::INTEGRATED_GPU"; + case stormkit::gpu::PhysicalDeviceType::OTHER: return "PhysicalDeviceType::OTHER"; + case stormkit::gpu::PhysicalDeviceType::VIRTUAL_GPU: return "PhysicalDeviceType::VIRTUAL_GPU"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PipelineBindPoint) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PipelineBindPoint::COMPUTE, - stormkit::gpu::PipelineBindPoint::GRAPHICS, - + stormkit::gpu::PipelineBindPoint::COMPUTE, + stormkit::gpu::PipelineBindPoint::GRAPHICS, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PipelineBindPoint value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::PipelineBindPoint::COMPUTE: return "PipelineBindPoint::COMPUTE"; - case stormkit::gpu::PipelineBindPoint::GRAPHICS: return "PipelineBindPoint::GRAPHICS"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::PipelineBindPoint value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::PipelineBindPoint::COMPUTE: return "PipelineBindPoint::COMPUTE"; + case stormkit::gpu::PipelineBindPoint::GRAPHICS: return "PipelineBindPoint::GRAPHICS"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineBindPoint value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::PipelineBindPoint::COMPUTE: return "PipelineBindPoint::COMPUTE"; - case stormkit::gpu::PipelineBindPoint::GRAPHICS: return "PipelineBindPoint::GRAPHICS"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineBindPoint value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::PipelineBindPoint::COMPUTE: return "PipelineBindPoint::COMPUTE"; + case stormkit::gpu::PipelineBindPoint::GRAPHICS: return "PipelineBindPoint::GRAPHICS"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PipelineStageFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PipelineStageFlag::ALL_COMMANDS, - stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS, - stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE, - stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT, - stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER, - stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT, - stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS, - stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER, - stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER, - stormkit::gpu::PipelineStageFlag::HOST, - stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS, - stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER, - stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER, - stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE, - stormkit::gpu::PipelineStageFlag::TRANSFER, - stormkit::gpu::PipelineStageFlag::VERTEX_INPUT, - stormkit::gpu::PipelineStageFlag::VERTEX_SHADER, - - }; - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PipelineStageFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: return "PipelineStageFlag::ALL_COMMANDS"; - case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: return "PipelineStageFlag::ALL_GRAPHICS"; - case stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE: return "PipelineStageFlag::BOTTOM_OF_PIPE"; - case stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT: return "PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT"; - case stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER: return "PipelineStageFlag::COMPUTE_SHADER"; - case stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT: return "PipelineStageFlag::DRAW_INDIRECT"; - case stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS: return "PipelineStageFlag::EARLY_FRAGMENT_TESTS"; - case stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER: return "PipelineStageFlag::FRAGMENT_SHADER"; - case stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER: return "PipelineStageFlag::GEOMETRY_SHADER"; - case stormkit::gpu::PipelineStageFlag::HOST: return "PipelineStageFlag::HOST"; - case stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS: return "PipelineStageFlag::LATE_FRAGMENT_TESTS"; - case stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER: return "PipelineStageFlag::TESSELLATION_CONTROL_SHADER"; - case stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER: return "PipelineStageFlag::TESSELLATION_EVALUATION_SHADER"; - case stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE: return "PipelineStageFlag::TOP_OF_PIPE"; - case stormkit::gpu::PipelineStageFlag::TRANSFER: return "PipelineStageFlag::TRANSFER"; - case stormkit::gpu::PipelineStageFlag::VERTEX_INPUT: return "PipelineStageFlag::VERTEX_INPUT"; - case stormkit::gpu::PipelineStageFlag::VERTEX_SHADER: return "PipelineStageFlag::VERTEX_SHADER"; - - } - std::unreachable(); - } - template<> - STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineStageFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: return "PipelineStageFlag::ALL_COMMANDS"; - case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: return "PipelineStageFlag::ALL_GRAPHICS"; - case stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE: return "PipelineStageFlag::BOTTOM_OF_PIPE"; - case stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT: return "PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT"; - case stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER: return "PipelineStageFlag::COMPUTE_SHADER"; - case stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT: return "PipelineStageFlag::DRAW_INDIRECT"; - case stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS: return "PipelineStageFlag::EARLY_FRAGMENT_TESTS"; - case stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER: return "PipelineStageFlag::FRAGMENT_SHADER"; - case stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER: return "PipelineStageFlag::GEOMETRY_SHADER"; - case stormkit::gpu::PipelineStageFlag::HOST: return "PipelineStageFlag::HOST"; - case stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS: return "PipelineStageFlag::LATE_FRAGMENT_TESTS"; - case stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER: return "PipelineStageFlag::TESSELLATION_CONTROL_SHADER"; - case stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER: return "PipelineStageFlag::TESSELLATION_EVALUATION_SHADER"; - case stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE: return "PipelineStageFlag::TOP_OF_PIPE"; - case stormkit::gpu::PipelineStageFlag::TRANSFER: return "PipelineStageFlag::TRANSFER"; - case stormkit::gpu::PipelineStageFlag::VERTEX_INPUT: return "PipelineStageFlag::VERTEX_INPUT"; - case stormkit::gpu::PipelineStageFlag::VERTEX_SHADER: return "PipelineStageFlag::VERTEX_SHADER"; - + stormkit::gpu::PipelineStageFlag::ALL_COMMANDS, + stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS, + stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE, + stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT, + stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER, + stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT, + stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS, + stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER, + stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER, + stormkit::gpu::PipelineStageFlag::HOST, + stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS, + stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER, + stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER, + stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE, + stormkit::gpu::PipelineStageFlag::TRANSFER, + stormkit::gpu::PipelineStageFlag::VERTEX_INPUT, + stormkit::gpu::PipelineStageFlag::VERTEX_SHADER, + + }; + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::PipelineStageFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: return "PipelineStageFlag::ALL_COMMANDS"; + case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: return "PipelineStageFlag::ALL_GRAPHICS"; + case stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE: return "PipelineStageFlag::BOTTOM_OF_PIPE"; + case stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT: return "PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT"; + case stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER: return "PipelineStageFlag::COMPUTE_SHADER"; + case stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT: return "PipelineStageFlag::DRAW_INDIRECT"; + case stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS: return "PipelineStageFlag::EARLY_FRAGMENT_TESTS"; + case stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER: return "PipelineStageFlag::FRAGMENT_SHADER"; + case stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER: return "PipelineStageFlag::GEOMETRY_SHADER"; + case stormkit::gpu::PipelineStageFlag::HOST: return "PipelineStageFlag::HOST"; + case stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS: return "PipelineStageFlag::LATE_FRAGMENT_TESTS"; + case stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER: + return "PipelineStageFlag::TESSELLATION_CONTROL_SHADER"; + case stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER: + return "PipelineStageFlag::TESSELLATION_EVALUATION_SHADER"; + case stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE: return "PipelineStageFlag::TOP_OF_PIPE"; + case stormkit::gpu::PipelineStageFlag::TRANSFER: return "PipelineStageFlag::TRANSFER"; + case stormkit::gpu::PipelineStageFlag::VERTEX_INPUT: return "PipelineStageFlag::VERTEX_INPUT"; + case stormkit::gpu::PipelineStageFlag::VERTEX_SHADER: return "PipelineStageFlag::VERTEX_SHADER"; + } + std::unreachable(); + } + + template<> + STORMKIT_FORCE_INLINE + constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineStageFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: return "PipelineStageFlag::ALL_COMMANDS"; + case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: return "PipelineStageFlag::ALL_GRAPHICS"; + case stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE: return "PipelineStageFlag::BOTTOM_OF_PIPE"; + case stormkit::gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT: return "PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT"; + case stormkit::gpu::PipelineStageFlag::COMPUTE_SHADER: return "PipelineStageFlag::COMPUTE_SHADER"; + case stormkit::gpu::PipelineStageFlag::DRAW_INDIRECT: return "PipelineStageFlag::DRAW_INDIRECT"; + case stormkit::gpu::PipelineStageFlag::EARLY_FRAGMENT_TESTS: return "PipelineStageFlag::EARLY_FRAGMENT_TESTS"; + case stormkit::gpu::PipelineStageFlag::FRAGMENT_SHADER: return "PipelineStageFlag::FRAGMENT_SHADER"; + case stormkit::gpu::PipelineStageFlag::GEOMETRY_SHADER: return "PipelineStageFlag::GEOMETRY_SHADER"; + case stormkit::gpu::PipelineStageFlag::HOST: return "PipelineStageFlag::HOST"; + case stormkit::gpu::PipelineStageFlag::LATE_FRAGMENT_TESTS: return "PipelineStageFlag::LATE_FRAGMENT_TESTS"; + case stormkit::gpu::PipelineStageFlag::TESSELLATION_CONTROL_SHADER: + return "PipelineStageFlag::TESSELLATION_CONTROL_SHADER"; + case stormkit::gpu::PipelineStageFlag::TESSELLATION_EVALUATION_SHADER: + return "PipelineStageFlag::TESSELLATION_EVALUATION_SHADER"; + case stormkit::gpu::PipelineStageFlag::TOP_OF_PIPE: return "PipelineStageFlag::TOP_OF_PIPE"; + case stormkit::gpu::PipelineStageFlag::TRANSFER: return "PipelineStageFlag::TRANSFER"; + case stormkit::gpu::PipelineStageFlag::VERTEX_INPUT: return "PipelineStageFlag::VERTEX_INPUT"; + case stormkit::gpu::PipelineStageFlag::VERTEX_SHADER: return "PipelineStageFlag::VERTEX_SHADER"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PixelFormat) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16, - stormkit::gpu::PixelFormat::A2_RGB10I_PACK32, - stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32, - stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32, - stormkit::gpu::PixelFormat::A2_RGB10U_PACK32, - stormkit::gpu::PixelFormat::B10_GR11UF_PACK32, - stormkit::gpu::PixelFormat::BGR8_UNORM, - stormkit::gpu::PixelFormat::BGRA8_UNORM, - stormkit::gpu::PixelFormat::DEPTH16_UNORM, - stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U, - stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32, - stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U, - stormkit::gpu::PixelFormat::DEPTH32F, - stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U, - stormkit::gpu::PixelFormat::R16F, - stormkit::gpu::PixelFormat::R16I, - stormkit::gpu::PixelFormat::R16_SNORM, - stormkit::gpu::PixelFormat::R16U, - stormkit::gpu::PixelFormat::R16_UNORM, - stormkit::gpu::PixelFormat::R32F, - stormkit::gpu::PixelFormat::R32I, - stormkit::gpu::PixelFormat::R32U, - stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16, - stormkit::gpu::PixelFormat::R8I, - stormkit::gpu::PixelFormat::R8_SNORM, - stormkit::gpu::PixelFormat::R8U, - stormkit::gpu::PixelFormat::R8_UNORM, - stormkit::gpu::PixelFormat::RG16F, - stormkit::gpu::PixelFormat::RG16I, - stormkit::gpu::PixelFormat::RG16_SNORM, - stormkit::gpu::PixelFormat::RG16U, - stormkit::gpu::PixelFormat::RG16_UNORM, - stormkit::gpu::PixelFormat::RG32F, - stormkit::gpu::PixelFormat::RG32I, - stormkit::gpu::PixelFormat::RG32U, - stormkit::gpu::PixelFormat::RG8I, - stormkit::gpu::PixelFormat::RG8_SNORM, - stormkit::gpu::PixelFormat::RG8U, - stormkit::gpu::PixelFormat::RG8_UNORM, - stormkit::gpu::PixelFormat::RGB16F, - stormkit::gpu::PixelFormat::RGB16I, - stormkit::gpu::PixelFormat::RGB16_SNORM, - stormkit::gpu::PixelFormat::RGB16U, - stormkit::gpu::PixelFormat::RGB16_UNORM, - stormkit::gpu::PixelFormat::RGB32F, - stormkit::gpu::PixelFormat::RGB32I, - stormkit::gpu::PixelFormat::RGB32U, - stormkit::gpu::PixelFormat::RGB8I, - stormkit::gpu::PixelFormat::RGB8_SNORM, - stormkit::gpu::PixelFormat::RGB8U, - stormkit::gpu::PixelFormat::RGB8_UNORM, - stormkit::gpu::PixelFormat::RGBA16F, - stormkit::gpu::PixelFormat::RGBA16I, - stormkit::gpu::PixelFormat::RGBA16_SNORM, - stormkit::gpu::PixelFormat::RGBA16U, - stormkit::gpu::PixelFormat::RGBA16_UNORM, - stormkit::gpu::PixelFormat::RGBA32F, - stormkit::gpu::PixelFormat::RGBA32I, - stormkit::gpu::PixelFormat::RGBA32U, - stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16, - stormkit::gpu::PixelFormat::RGBA8I, - stormkit::gpu::PixelFormat::RGBA8_SNORM, - stormkit::gpu::PixelFormat::RGBA8U, - stormkit::gpu::PixelFormat::RGBA8_UNORM, - stormkit::gpu::PixelFormat::S8U, - stormkit::gpu::PixelFormat::SBGR8, - stormkit::gpu::PixelFormat::SBGRA8, - stormkit::gpu::PixelFormat::SR8, - stormkit::gpu::PixelFormat::SRG8, - stormkit::gpu::PixelFormat::SRGB8, - stormkit::gpu::PixelFormat::SRGBA8, - stormkit::gpu::PixelFormat::UNDEFINED, - - }; - } - template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PixelFormat value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; - case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; - case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; - case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; - case stormkit::gpu::PixelFormat::DEPTH16_UNORM: return "PixelFormat::DEPTH16_UNORM"; - case stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U: return "PixelFormat::DEPTH16_UNORM_STENCIL8U"; - case stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32: return "PixelFormat::DEPTH24_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U: return "PixelFormat::DEPTH24_UNORM_STENCIL8U"; - case stormkit::gpu::PixelFormat::DEPTH32F: return "PixelFormat::DEPTH32F"; - case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; - case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; - case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; - case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; - case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; - case stormkit::gpu::PixelFormat::R16_UNORM: return "PixelFormat::R16_UNORM"; - case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; - case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; - case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; - case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; - case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; - case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; - case stormkit::gpu::PixelFormat::R8_UNORM: return "PixelFormat::R8_UNORM"; - case stormkit::gpu::PixelFormat::RG16F: return "PixelFormat::RG16F"; - case stormkit::gpu::PixelFormat::RG16I: return "PixelFormat::RG16I"; - case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; - case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; - case stormkit::gpu::PixelFormat::RG16_UNORM: return "PixelFormat::RG16_UNORM"; - case stormkit::gpu::PixelFormat::RG32F: return "PixelFormat::RG32F"; - case stormkit::gpu::PixelFormat::RG32I: return "PixelFormat::RG32I"; - case stormkit::gpu::PixelFormat::RG32U: return "PixelFormat::RG32U"; - case stormkit::gpu::PixelFormat::RG8I: return "PixelFormat::RG8I"; - case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; - case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; - case stormkit::gpu::PixelFormat::RG8_UNORM: return "PixelFormat::RG8_UNORM"; - case stormkit::gpu::PixelFormat::RGB16F: return "PixelFormat::RGB16F"; - case stormkit::gpu::PixelFormat::RGB16I: return "PixelFormat::RGB16I"; - case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; - case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; - case stormkit::gpu::PixelFormat::RGB16_UNORM: return "PixelFormat::RGB16_UNORM"; - case stormkit::gpu::PixelFormat::RGB32F: return "PixelFormat::RGB32F"; - case stormkit::gpu::PixelFormat::RGB32I: return "PixelFormat::RGB32I"; - case stormkit::gpu::PixelFormat::RGB32U: return "PixelFormat::RGB32U"; - case stormkit::gpu::PixelFormat::RGB8I: return "PixelFormat::RGB8I"; - case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; - case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; - case stormkit::gpu::PixelFormat::RGB8_UNORM: return "PixelFormat::RGB8_UNORM"; - case stormkit::gpu::PixelFormat::RGBA16F: return "PixelFormat::RGBA16F"; - case stormkit::gpu::PixelFormat::RGBA16I: return "PixelFormat::RGBA16I"; - case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; - case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; - case stormkit::gpu::PixelFormat::RGBA16_UNORM: return "PixelFormat::RGBA16_UNORM"; - case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; - case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; - case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; - case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; - case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; - case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; - case stormkit::gpu::PixelFormat::RGBA8_UNORM: return "PixelFormat::RGBA8_UNORM"; - case stormkit::gpu::PixelFormat::S8U: return "PixelFormat::S8U"; - case stormkit::gpu::PixelFormat::SBGR8: return "PixelFormat::SBGR8"; - case stormkit::gpu::PixelFormat::SBGRA8: return "PixelFormat::SBGRA8"; - case stormkit::gpu::PixelFormat::SR8: return "PixelFormat::SR8"; - case stormkit::gpu::PixelFormat::SRG8: return "PixelFormat::SRG8"; - case stormkit::gpu::PixelFormat::SRGB8: return "PixelFormat::SRGB8"; - case stormkit::gpu::PixelFormat::SRGBA8: return "PixelFormat::SRGBA8"; - case stormkit::gpu::PixelFormat::UNDEFINED: return "PixelFormat::UNDEFINED"; - - } - std::unreachable(); - } - template<> - STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::PixelFormat value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; - case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; - case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; - case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; - case stormkit::gpu::PixelFormat::DEPTH16_UNORM: return "PixelFormat::DEPTH16_UNORM"; - case stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U: return "PixelFormat::DEPTH16_UNORM_STENCIL8U"; - case stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32: return "PixelFormat::DEPTH24_UNORM_PACK32"; - case stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U: return "PixelFormat::DEPTH24_UNORM_STENCIL8U"; - case stormkit::gpu::PixelFormat::DEPTH32F: return "PixelFormat::DEPTH32F"; - case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; - case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; - case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; - case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; - case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; - case stormkit::gpu::PixelFormat::R16_UNORM: return "PixelFormat::R16_UNORM"; - case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; - case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; - case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; - case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; - case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; - case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; - case stormkit::gpu::PixelFormat::R8_UNORM: return "PixelFormat::R8_UNORM"; - case stormkit::gpu::PixelFormat::RG16F: return "PixelFormat::RG16F"; - case stormkit::gpu::PixelFormat::RG16I: return "PixelFormat::RG16I"; - case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; - case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; - case stormkit::gpu::PixelFormat::RG16_UNORM: return "PixelFormat::RG16_UNORM"; - case stormkit::gpu::PixelFormat::RG32F: return "PixelFormat::RG32F"; - case stormkit::gpu::PixelFormat::RG32I: return "PixelFormat::RG32I"; - case stormkit::gpu::PixelFormat::RG32U: return "PixelFormat::RG32U"; - case stormkit::gpu::PixelFormat::RG8I: return "PixelFormat::RG8I"; - case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; - case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; - case stormkit::gpu::PixelFormat::RG8_UNORM: return "PixelFormat::RG8_UNORM"; - case stormkit::gpu::PixelFormat::RGB16F: return "PixelFormat::RGB16F"; - case stormkit::gpu::PixelFormat::RGB16I: return "PixelFormat::RGB16I"; - case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; - case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; - case stormkit::gpu::PixelFormat::RGB16_UNORM: return "PixelFormat::RGB16_UNORM"; - case stormkit::gpu::PixelFormat::RGB32F: return "PixelFormat::RGB32F"; - case stormkit::gpu::PixelFormat::RGB32I: return "PixelFormat::RGB32I"; - case stormkit::gpu::PixelFormat::RGB32U: return "PixelFormat::RGB32U"; - case stormkit::gpu::PixelFormat::RGB8I: return "PixelFormat::RGB8I"; - case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; - case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; - case stormkit::gpu::PixelFormat::RGB8_UNORM: return "PixelFormat::RGB8_UNORM"; - case stormkit::gpu::PixelFormat::RGBA16F: return "PixelFormat::RGBA16F"; - case stormkit::gpu::PixelFormat::RGBA16I: return "PixelFormat::RGBA16I"; - case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; - case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; - case stormkit::gpu::PixelFormat::RGBA16_UNORM: return "PixelFormat::RGBA16_UNORM"; - case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; - case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; - case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; - case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; - case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; - case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; - case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; - case stormkit::gpu::PixelFormat::RGBA8_UNORM: return "PixelFormat::RGBA8_UNORM"; - case stormkit::gpu::PixelFormat::S8U: return "PixelFormat::S8U"; - case stormkit::gpu::PixelFormat::SBGR8: return "PixelFormat::SBGR8"; - case stormkit::gpu::PixelFormat::SBGRA8: return "PixelFormat::SBGRA8"; - case stormkit::gpu::PixelFormat::SR8: return "PixelFormat::SR8"; - case stormkit::gpu::PixelFormat::SRG8: return "PixelFormat::SRG8"; - case stormkit::gpu::PixelFormat::SRGB8: return "PixelFormat::SRGB8"; - case stormkit::gpu::PixelFormat::SRGBA8: return "PixelFormat::SRGBA8"; - case stormkit::gpu::PixelFormat::UNDEFINED: return "PixelFormat::UNDEFINED"; - + stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16, + stormkit::gpu::PixelFormat::A2_RGB10I_PACK32, + stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32, + stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32, + stormkit::gpu::PixelFormat::A2_RGB10U_PACK32, + stormkit::gpu::PixelFormat::B10_GR11UF_PACK32, + stormkit::gpu::PixelFormat::BGR8_UNORM, + stormkit::gpu::PixelFormat::BGRA8_UNORM, + stormkit::gpu::PixelFormat::DEPTH16_UNORM, + stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U, + stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32, + stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U, + stormkit::gpu::PixelFormat::DEPTH32F, + stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U, + stormkit::gpu::PixelFormat::R16F, + stormkit::gpu::PixelFormat::R16I, + stormkit::gpu::PixelFormat::R16_SNORM, + stormkit::gpu::PixelFormat::R16U, + stormkit::gpu::PixelFormat::R16_UNORM, + stormkit::gpu::PixelFormat::R32F, + stormkit::gpu::PixelFormat::R32I, + stormkit::gpu::PixelFormat::R32U, + stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16, + stormkit::gpu::PixelFormat::R8I, + stormkit::gpu::PixelFormat::R8_SNORM, + stormkit::gpu::PixelFormat::R8U, + stormkit::gpu::PixelFormat::R8_UNORM, + stormkit::gpu::PixelFormat::RG16F, + stormkit::gpu::PixelFormat::RG16I, + stormkit::gpu::PixelFormat::RG16_SNORM, + stormkit::gpu::PixelFormat::RG16U, + stormkit::gpu::PixelFormat::RG16_UNORM, + stormkit::gpu::PixelFormat::RG32F, + stormkit::gpu::PixelFormat::RG32I, + stormkit::gpu::PixelFormat::RG32U, + stormkit::gpu::PixelFormat::RG8I, + stormkit::gpu::PixelFormat::RG8_SNORM, + stormkit::gpu::PixelFormat::RG8U, + stormkit::gpu::PixelFormat::RG8_UNORM, + stormkit::gpu::PixelFormat::RGB16F, + stormkit::gpu::PixelFormat::RGB16I, + stormkit::gpu::PixelFormat::RGB16_SNORM, + stormkit::gpu::PixelFormat::RGB16U, + stormkit::gpu::PixelFormat::RGB16_UNORM, + stormkit::gpu::PixelFormat::RGB32F, + stormkit::gpu::PixelFormat::RGB32I, + stormkit::gpu::PixelFormat::RGB32U, + stormkit::gpu::PixelFormat::RGB8I, + stormkit::gpu::PixelFormat::RGB8_SNORM, + stormkit::gpu::PixelFormat::RGB8U, + stormkit::gpu::PixelFormat::RGB8_UNORM, + stormkit::gpu::PixelFormat::RGBA16F, + stormkit::gpu::PixelFormat::RGBA16I, + stormkit::gpu::PixelFormat::RGBA16_SNORM, + stormkit::gpu::PixelFormat::RGBA16U, + stormkit::gpu::PixelFormat::RGBA16_UNORM, + stormkit::gpu::PixelFormat::RGBA32F, + stormkit::gpu::PixelFormat::RGBA32I, + stormkit::gpu::PixelFormat::RGBA32U, + stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16, + stormkit::gpu::PixelFormat::RGBA8I, + stormkit::gpu::PixelFormat::RGBA8_SNORM, + stormkit::gpu::PixelFormat::RGBA8U, + stormkit::gpu::PixelFormat::RGBA8_UNORM, + stormkit::gpu::PixelFormat::S8U, + stormkit::gpu::PixelFormat::SBGR8, + stormkit::gpu::PixelFormat::SBGRA8, + stormkit::gpu::PixelFormat::SR8, + stormkit::gpu::PixelFormat::SRG8, + stormkit::gpu::PixelFormat::SRGB8, + stormkit::gpu::PixelFormat::SRGBA8, + stormkit::gpu::PixelFormat::UNDEFINED, + + }; + } + + template<> + STORMKIT_FORCE_INLINE + STORMKIT_CONST + constexpr auto stormkit::core::as_string(stormkit::gpu::PixelFormat value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; + case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; + case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; + case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; + case stormkit::gpu::PixelFormat::DEPTH16_UNORM: return "PixelFormat::DEPTH16_UNORM"; + case stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U: return "PixelFormat::DEPTH16_UNORM_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32: return "PixelFormat::DEPTH24_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U: return "PixelFormat::DEPTH24_UNORM_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH32F: return "PixelFormat::DEPTH32F"; + case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; + case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; + case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; + case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; + case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; + case stormkit::gpu::PixelFormat::R16_UNORM: return "PixelFormat::R16_UNORM"; + case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; + case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; + case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; + case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; + case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; + case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; + case stormkit::gpu::PixelFormat::R8_UNORM: return "PixelFormat::R8_UNORM"; + case stormkit::gpu::PixelFormat::RG16F: return "PixelFormat::RG16F"; + case stormkit::gpu::PixelFormat::RG16I: return "PixelFormat::RG16I"; + case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; + case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; + case stormkit::gpu::PixelFormat::RG16_UNORM: return "PixelFormat::RG16_UNORM"; + case stormkit::gpu::PixelFormat::RG32F: return "PixelFormat::RG32F"; + case stormkit::gpu::PixelFormat::RG32I: return "PixelFormat::RG32I"; + case stormkit::gpu::PixelFormat::RG32U: return "PixelFormat::RG32U"; + case stormkit::gpu::PixelFormat::RG8I: return "PixelFormat::RG8I"; + case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; + case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; + case stormkit::gpu::PixelFormat::RG8_UNORM: return "PixelFormat::RG8_UNORM"; + case stormkit::gpu::PixelFormat::RGB16F: return "PixelFormat::RGB16F"; + case stormkit::gpu::PixelFormat::RGB16I: return "PixelFormat::RGB16I"; + case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; + case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; + case stormkit::gpu::PixelFormat::RGB16_UNORM: return "PixelFormat::RGB16_UNORM"; + case stormkit::gpu::PixelFormat::RGB32F: return "PixelFormat::RGB32F"; + case stormkit::gpu::PixelFormat::RGB32I: return "PixelFormat::RGB32I"; + case stormkit::gpu::PixelFormat::RGB32U: return "PixelFormat::RGB32U"; + case stormkit::gpu::PixelFormat::RGB8I: return "PixelFormat::RGB8I"; + case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; + case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; + case stormkit::gpu::PixelFormat::RGB8_UNORM: return "PixelFormat::RGB8_UNORM"; + case stormkit::gpu::PixelFormat::RGBA16F: return "PixelFormat::RGBA16F"; + case stormkit::gpu::PixelFormat::RGBA16I: return "PixelFormat::RGBA16I"; + case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; + case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; + case stormkit::gpu::PixelFormat::RGBA16_UNORM: return "PixelFormat::RGBA16_UNORM"; + case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; + case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; + case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; + case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; + case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; + case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; + case stormkit::gpu::PixelFormat::RGBA8_UNORM: return "PixelFormat::RGBA8_UNORM"; + case stormkit::gpu::PixelFormat::S8U: return "PixelFormat::S8U"; + case stormkit::gpu::PixelFormat::SBGR8: return "PixelFormat::SBGR8"; + case stormkit::gpu::PixelFormat::SBGRA8: return "PixelFormat::SBGRA8"; + case stormkit::gpu::PixelFormat::SR8: return "PixelFormat::SR8"; + case stormkit::gpu::PixelFormat::SRG8: return "PixelFormat::SRG8"; + case stormkit::gpu::PixelFormat::SRGB8: return "PixelFormat::SRGB8"; + case stormkit::gpu::PixelFormat::SRGBA8: return "PixelFormat::SRGBA8"; + case stormkit::gpu::PixelFormat::UNDEFINED: return "PixelFormat::UNDEFINED"; + } + std::unreachable(); + } + + template<> + STORMKIT_FORCE_INLINE + constexpr auto stormkit::core::to_string(stormkit::gpu::PixelFormat value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32: return "PixelFormat::A2_RGB10_SNORM_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10_UNORM_PACK32: return "PixelFormat::A2_RGB10_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::A2_RGB10U_PACK32: return "PixelFormat::A2_RGB10U_PACK32"; + case stormkit::gpu::PixelFormat::B10_GR11UF_PACK32: return "PixelFormat::B10_GR11UF_PACK32"; + case stormkit::gpu::PixelFormat::BGR8_UNORM: return "PixelFormat::BGR8_UNORM"; + case stormkit::gpu::PixelFormat::BGRA8_UNORM: return "PixelFormat::BGRA8_UNORM"; + case stormkit::gpu::PixelFormat::DEPTH16_UNORM: return "PixelFormat::DEPTH16_UNORM"; + case stormkit::gpu::PixelFormat::DEPTH16_UNORM_STENCIL8U: return "PixelFormat::DEPTH16_UNORM_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH24_UNORM_PACK32: return "PixelFormat::DEPTH24_UNORM_PACK32"; + case stormkit::gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U: return "PixelFormat::DEPTH24_UNORM_STENCIL8U"; + case stormkit::gpu::PixelFormat::DEPTH32F: return "PixelFormat::DEPTH32F"; + case stormkit::gpu::PixelFormat::DEPTH32F_STENCIL8U: return "PixelFormat::DEPTH32F_STENCIL8U"; + case stormkit::gpu::PixelFormat::R16F: return "PixelFormat::R16F"; + case stormkit::gpu::PixelFormat::R16I: return "PixelFormat::R16I"; + case stormkit::gpu::PixelFormat::R16_SNORM: return "PixelFormat::R16_SNORM"; + case stormkit::gpu::PixelFormat::R16U: return "PixelFormat::R16U"; + case stormkit::gpu::PixelFormat::R16_UNORM: return "PixelFormat::R16_UNORM"; + case stormkit::gpu::PixelFormat::R32F: return "PixelFormat::R32F"; + case stormkit::gpu::PixelFormat::R32I: return "PixelFormat::R32I"; + case stormkit::gpu::PixelFormat::R32U: return "PixelFormat::R32U"; + case stormkit::gpu::PixelFormat::R5_G6_B5_UNORM_PACK16: return "PixelFormat::R5_G6_B5_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::R8I: return "PixelFormat::R8I"; + case stormkit::gpu::PixelFormat::R8_SNORM: return "PixelFormat::R8_SNORM"; + case stormkit::gpu::PixelFormat::R8U: return "PixelFormat::R8U"; + case stormkit::gpu::PixelFormat::R8_UNORM: return "PixelFormat::R8_UNORM"; + case stormkit::gpu::PixelFormat::RG16F: return "PixelFormat::RG16F"; + case stormkit::gpu::PixelFormat::RG16I: return "PixelFormat::RG16I"; + case stormkit::gpu::PixelFormat::RG16_SNORM: return "PixelFormat::RG16_SNORM"; + case stormkit::gpu::PixelFormat::RG16U: return "PixelFormat::RG16U"; + case stormkit::gpu::PixelFormat::RG16_UNORM: return "PixelFormat::RG16_UNORM"; + case stormkit::gpu::PixelFormat::RG32F: return "PixelFormat::RG32F"; + case stormkit::gpu::PixelFormat::RG32I: return "PixelFormat::RG32I"; + case stormkit::gpu::PixelFormat::RG32U: return "PixelFormat::RG32U"; + case stormkit::gpu::PixelFormat::RG8I: return "PixelFormat::RG8I"; + case stormkit::gpu::PixelFormat::RG8_SNORM: return "PixelFormat::RG8_SNORM"; + case stormkit::gpu::PixelFormat::RG8U: return "PixelFormat::RG8U"; + case stormkit::gpu::PixelFormat::RG8_UNORM: return "PixelFormat::RG8_UNORM"; + case stormkit::gpu::PixelFormat::RGB16F: return "PixelFormat::RGB16F"; + case stormkit::gpu::PixelFormat::RGB16I: return "PixelFormat::RGB16I"; + case stormkit::gpu::PixelFormat::RGB16_SNORM: return "PixelFormat::RGB16_SNORM"; + case stormkit::gpu::PixelFormat::RGB16U: return "PixelFormat::RGB16U"; + case stormkit::gpu::PixelFormat::RGB16_UNORM: return "PixelFormat::RGB16_UNORM"; + case stormkit::gpu::PixelFormat::RGB32F: return "PixelFormat::RGB32F"; + case stormkit::gpu::PixelFormat::RGB32I: return "PixelFormat::RGB32I"; + case stormkit::gpu::PixelFormat::RGB32U: return "PixelFormat::RGB32U"; + case stormkit::gpu::PixelFormat::RGB8I: return "PixelFormat::RGB8I"; + case stormkit::gpu::PixelFormat::RGB8_SNORM: return "PixelFormat::RGB8_SNORM"; + case stormkit::gpu::PixelFormat::RGB8U: return "PixelFormat::RGB8U"; + case stormkit::gpu::PixelFormat::RGB8_UNORM: return "PixelFormat::RGB8_UNORM"; + case stormkit::gpu::PixelFormat::RGBA16F: return "PixelFormat::RGBA16F"; + case stormkit::gpu::PixelFormat::RGBA16I: return "PixelFormat::RGBA16I"; + case stormkit::gpu::PixelFormat::RGBA16_SNORM: return "PixelFormat::RGBA16_SNORM"; + case stormkit::gpu::PixelFormat::RGBA16U: return "PixelFormat::RGBA16U"; + case stormkit::gpu::PixelFormat::RGBA16_UNORM: return "PixelFormat::RGBA16_UNORM"; + case stormkit::gpu::PixelFormat::RGBA32F: return "PixelFormat::RGBA32F"; + case stormkit::gpu::PixelFormat::RGBA32I: return "PixelFormat::RGBA32I"; + case stormkit::gpu::PixelFormat::RGBA32U: return "PixelFormat::RGBA32U"; + case stormkit::gpu::PixelFormat::RGBA4_UNORM_PACK16: return "PixelFormat::RGBA4_UNORM_PACK16"; + case stormkit::gpu::PixelFormat::RGBA8I: return "PixelFormat::RGBA8I"; + case stormkit::gpu::PixelFormat::RGBA8_SNORM: return "PixelFormat::RGBA8_SNORM"; + case stormkit::gpu::PixelFormat::RGBA8U: return "PixelFormat::RGBA8U"; + case stormkit::gpu::PixelFormat::RGBA8_UNORM: return "PixelFormat::RGBA8_UNORM"; + case stormkit::gpu::PixelFormat::S8U: return "PixelFormat::S8U"; + case stormkit::gpu::PixelFormat::SBGR8: return "PixelFormat::SBGR8"; + case stormkit::gpu::PixelFormat::SBGRA8: return "PixelFormat::SBGRA8"; + case stormkit::gpu::PixelFormat::SR8: return "PixelFormat::SR8"; + case stormkit::gpu::PixelFormat::SRG8: return "PixelFormat::SRG8"; + case stormkit::gpu::PixelFormat::SRGB8: return "PixelFormat::SRGB8"; + case stormkit::gpu::PixelFormat::SRGBA8: return "PixelFormat::SRGBA8"; + case stormkit::gpu::PixelFormat::UNDEFINED: return "PixelFormat::UNDEFINED"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PolygonMode) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PolygonMode::FILL, - stormkit::gpu::PolygonMode::LINE, - stormkit::gpu::PolygonMode::POINT, - + stormkit::gpu::PolygonMode::FILL, + stormkit::gpu::PolygonMode::LINE, + stormkit::gpu::PolygonMode::POINT, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PolygonMode value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::PolygonMode::FILL: return "PolygonMode::FILL"; - case stormkit::gpu::PolygonMode::LINE: return "PolygonMode::LINE"; - case stormkit::gpu::PolygonMode::POINT: return "PolygonMode::POINT"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::PolygonMode value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::PolygonMode::FILL: return "PolygonMode::FILL"; + case stormkit::gpu::PolygonMode::LINE: return "PolygonMode::LINE"; + case stormkit::gpu::PolygonMode::POINT: return "PolygonMode::POINT"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::PolygonMode value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::PolygonMode::FILL: return "PolygonMode::FILL"; - case stormkit::gpu::PolygonMode::LINE: return "PolygonMode::LINE"; - case stormkit::gpu::PolygonMode::POINT: return "PolygonMode::POINT"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::PolygonMode value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::PolygonMode::FILL: return "PolygonMode::FILL"; + case stormkit::gpu::PolygonMode::LINE: return "PolygonMode::LINE"; + case stormkit::gpu::PolygonMode::POINT: return "PolygonMode::POINT"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PresentMode) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PresentMode::FIFO, - stormkit::gpu::PresentMode::FIFO_RELAXED, - stormkit::gpu::PresentMode::IMMEDIATE, - stormkit::gpu::PresentMode::MAILBOX, - stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH, - stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH, - + stormkit::gpu::PresentMode::FIFO, + stormkit::gpu::PresentMode::FIFO_RELAXED, + stormkit::gpu::PresentMode::IMMEDIATE, + stormkit::gpu::PresentMode::MAILBOX, + stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH, + stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PresentMode value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::PresentMode::FIFO: return "PresentMode::FIFO"; - case stormkit::gpu::PresentMode::FIFO_RELAXED: return "PresentMode::FIFO_RELAXED"; - case stormkit::gpu::PresentMode::IMMEDIATE: return "PresentMode::IMMEDIATE"; - case stormkit::gpu::PresentMode::MAILBOX: return "PresentMode::MAILBOX"; - case stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH: return "PresentMode::SHARED_CONTINUOUS_REFRESH"; - case stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH: return "PresentMode::SHARED_DEMAND_REFRESH"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::PresentMode value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::PresentMode::FIFO: return "PresentMode::FIFO"; + case stormkit::gpu::PresentMode::FIFO_RELAXED: return "PresentMode::FIFO_RELAXED"; + case stormkit::gpu::PresentMode::IMMEDIATE: return "PresentMode::IMMEDIATE"; + case stormkit::gpu::PresentMode::MAILBOX: return "PresentMode::MAILBOX"; + case stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH: return "PresentMode::SHARED_CONTINUOUS_REFRESH"; + case stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH: return "PresentMode::SHARED_DEMAND_REFRESH"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::PresentMode value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::PresentMode::FIFO: return "PresentMode::FIFO"; - case stormkit::gpu::PresentMode::FIFO_RELAXED: return "PresentMode::FIFO_RELAXED"; - case stormkit::gpu::PresentMode::IMMEDIATE: return "PresentMode::IMMEDIATE"; - case stormkit::gpu::PresentMode::MAILBOX: return "PresentMode::MAILBOX"; - case stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH: return "PresentMode::SHARED_CONTINUOUS_REFRESH"; - case stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH: return "PresentMode::SHARED_DEMAND_REFRESH"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::PresentMode value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::PresentMode::FIFO: return "PresentMode::FIFO"; + case stormkit::gpu::PresentMode::FIFO_RELAXED: return "PresentMode::FIFO_RELAXED"; + case stormkit::gpu::PresentMode::IMMEDIATE: return "PresentMode::IMMEDIATE"; + case stormkit::gpu::PresentMode::MAILBOX: return "PresentMode::MAILBOX"; + case stormkit::gpu::PresentMode::SHARED_CONTINUOUS_REFRESH: return "PresentMode::SHARED_CONTINUOUS_REFRESH"; + case stormkit::gpu::PresentMode::SHARED_DEMAND_REFRESH: return "PresentMode::SHARED_DEMAND_REFRESH"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::PrimitiveTopology) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::PrimitiveTopology::LINE_LIST, - stormkit::gpu::PrimitiveTopology::LINE_STRIP, - stormkit::gpu::PrimitiveTopology::POINT_LIST, - stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN, - stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST, - stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP, - + stormkit::gpu::PrimitiveTopology::LINE_LIST, stormkit::gpu::PrimitiveTopology::LINE_STRIP, + stormkit::gpu::PrimitiveTopology::POINT_LIST, stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN, + stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST, stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::PrimitiveTopology value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::PrimitiveTopology::LINE_LIST: return "PrimitiveTopology::LINE_LIST"; - case stormkit::gpu::PrimitiveTopology::LINE_STRIP: return "PrimitiveTopology::LINE_STRIP"; - case stormkit::gpu::PrimitiveTopology::POINT_LIST: return "PrimitiveTopology::POINT_LIST"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN: return "PrimitiveTopology::TRIANGLE_FAN"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST: return "PrimitiveTopology::TRIANGLE_LIST"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP: return "PrimitiveTopology::TRIANGLE_STRIP"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::PrimitiveTopology value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::PrimitiveTopology::LINE_LIST: return "PrimitiveTopology::LINE_LIST"; + case stormkit::gpu::PrimitiveTopology::LINE_STRIP: return "PrimitiveTopology::LINE_STRIP"; + case stormkit::gpu::PrimitiveTopology::POINT_LIST: return "PrimitiveTopology::POINT_LIST"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN: return "PrimitiveTopology::TRIANGLE_FAN"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST: return "PrimitiveTopology::TRIANGLE_LIST"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP: return "PrimitiveTopology::TRIANGLE_STRIP"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::PrimitiveTopology value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::PrimitiveTopology::LINE_LIST: return "PrimitiveTopology::LINE_LIST"; - case stormkit::gpu::PrimitiveTopology::LINE_STRIP: return "PrimitiveTopology::LINE_STRIP"; - case stormkit::gpu::PrimitiveTopology::POINT_LIST: return "PrimitiveTopology::POINT_LIST"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN: return "PrimitiveTopology::TRIANGLE_FAN"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST: return "PrimitiveTopology::TRIANGLE_LIST"; - case stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP: return "PrimitiveTopology::TRIANGLE_STRIP"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::PrimitiveTopology value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::PrimitiveTopology::LINE_LIST: return "PrimitiveTopology::LINE_LIST"; + case stormkit::gpu::PrimitiveTopology::LINE_STRIP: return "PrimitiveTopology::LINE_STRIP"; + case stormkit::gpu::PrimitiveTopology::POINT_LIST: return "PrimitiveTopology::POINT_LIST"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN: return "PrimitiveTopology::TRIANGLE_FAN"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST: return "PrimitiveTopology::TRIANGLE_LIST"; + case stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP: return "PrimitiveTopology::TRIANGLE_STRIP"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::QueueFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::QueueFlag::COMPUTE, - stormkit::gpu::QueueFlag::GRAPHICS, - stormkit::gpu::QueueFlag::NONE, - stormkit::gpu::QueueFlag::PROTECTED, - stormkit::gpu::QueueFlag::SPARSE_BINDING, - stormkit::gpu::QueueFlag::TRANSFER, - + stormkit::gpu::QueueFlag::COMPUTE, stormkit::gpu::QueueFlag::GRAPHICS, stormkit::gpu::QueueFlag::NONE, + stormkit::gpu::QueueFlag::PROTECTED, stormkit::gpu::QueueFlag::SPARSE_BINDING, stormkit::gpu::QueueFlag::TRANSFER, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::QueueFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; - case stormkit::gpu::QueueFlag::GRAPHICS: return "QueueFlag::GRAPHICS"; - case stormkit::gpu::QueueFlag::NONE: return "QueueFlag::NONE"; - case stormkit::gpu::QueueFlag::PROTECTED: return "QueueFlag::PROTECTED"; - case stormkit::gpu::QueueFlag::SPARSE_BINDING: return "QueueFlag::SPARSE_BINDING"; - case stormkit::gpu::QueueFlag::TRANSFER: return "QueueFlag::TRANSFER"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::QueueFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; + case stormkit::gpu::QueueFlag::GRAPHICS: return "QueueFlag::GRAPHICS"; + case stormkit::gpu::QueueFlag::NONE: return "QueueFlag::NONE"; + case stormkit::gpu::QueueFlag::PROTECTED: return "QueueFlag::PROTECTED"; + case stormkit::gpu::QueueFlag::SPARSE_BINDING: return "QueueFlag::SPARSE_BINDING"; + case stormkit::gpu::QueueFlag::TRANSFER: return "QueueFlag::TRANSFER"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::QueueFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; - case stormkit::gpu::QueueFlag::GRAPHICS: return "QueueFlag::GRAPHICS"; - case stormkit::gpu::QueueFlag::NONE: return "QueueFlag::NONE"; - case stormkit::gpu::QueueFlag::PROTECTED: return "QueueFlag::PROTECTED"; - case stormkit::gpu::QueueFlag::SPARSE_BINDING: return "QueueFlag::SPARSE_BINDING"; - case stormkit::gpu::QueueFlag::TRANSFER: return "QueueFlag::TRANSFER"; - + switch (value) { + case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; + case stormkit::gpu::QueueFlag::GRAPHICS: return "QueueFlag::GRAPHICS"; + case stormkit::gpu::QueueFlag::NONE: return "QueueFlag::NONE"; + case stormkit::gpu::QueueFlag::PROTECTED: return "QueueFlag::PROTECTED"; + case stormkit::gpu::QueueFlag::SPARSE_BINDING: return "QueueFlag::SPARSE_BINDING"; + case stormkit::gpu::QueueFlag::TRANSFER: return "QueueFlag::TRANSFER"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ResolveModeFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ResolveModeFlag::AVERAGE, - stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID, - stormkit::gpu::ResolveModeFlag::MAX, - stormkit::gpu::ResolveModeFlag::MIN, - stormkit::gpu::ResolveModeFlag::NONE, - stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO, - + stormkit::gpu::ResolveModeFlag::AVERAGE, stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID, + stormkit::gpu::ResolveModeFlag::MAX, stormkit::gpu::ResolveModeFlag::MIN, + stormkit::gpu::ResolveModeFlag::NONE, stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ResolveModeFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ResolveModeFlag::AVERAGE: return "ResolveModeFlag::AVERAGE"; - case stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID: return "ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID"; - case stormkit::gpu::ResolveModeFlag::MAX: return "ResolveModeFlag::MAX"; - case stormkit::gpu::ResolveModeFlag::MIN: return "ResolveModeFlag::MIN"; - case stormkit::gpu::ResolveModeFlag::NONE: return "ResolveModeFlag::NONE"; - case stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO: return "ResolveModeFlag::SAMPLE_ZERO"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::ResolveModeFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ResolveModeFlag::AVERAGE: return "ResolveModeFlag::AVERAGE"; + case stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID: + return "ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID"; + case stormkit::gpu::ResolveModeFlag::MAX: return "ResolveModeFlag::MAX"; + case stormkit::gpu::ResolveModeFlag::MIN: return "ResolveModeFlag::MIN"; + case stormkit::gpu::ResolveModeFlag::NONE: return "ResolveModeFlag::NONE"; + case stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO: return "ResolveModeFlag::SAMPLE_ZERO"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ResolveModeFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ResolveModeFlag::AVERAGE: return "ResolveModeFlag::AVERAGE"; - case stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID: return "ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID"; - case stormkit::gpu::ResolveModeFlag::MAX: return "ResolveModeFlag::MAX"; - case stormkit::gpu::ResolveModeFlag::MIN: return "ResolveModeFlag::MIN"; - case stormkit::gpu::ResolveModeFlag::NONE: return "ResolveModeFlag::NONE"; - case stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO: return "ResolveModeFlag::SAMPLE_ZERO"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::ResolveModeFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::ResolveModeFlag::AVERAGE: return "ResolveModeFlag::AVERAGE"; + case stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID: + return "ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID"; + case stormkit::gpu::ResolveModeFlag::MAX: return "ResolveModeFlag::MAX"; + case stormkit::gpu::ResolveModeFlag::MIN: return "ResolveModeFlag::MIN"; + case stormkit::gpu::ResolveModeFlag::NONE: return "ResolveModeFlag::NONE"; + case stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO: return "ResolveModeFlag::SAMPLE_ZERO"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::Result) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::Result::ERROR_DEVICE_LOST, - stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT, - stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT, - stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED, - stormkit::gpu::Result::ERROR_FRAGMENTATION, - stormkit::gpu::Result::ERROR_FRAGMENTED_POOL, - stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST, - stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY, - stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER, - stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED, - stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE, - stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, - stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT, - stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED, - stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE, - stormkit::gpu::Result::ERROR_NOT_PERMITTED, - stormkit::gpu::Result::ERROR_OUT_OF_DATE, - stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY, - stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY, - stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY, - stormkit::gpu::Result::ERROR_SURFACE_LOST, - stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS, - stormkit::gpu::Result::ERROR_UNKNOWN, - stormkit::gpu::Result::ERROR_VALIDATION_FAILED, - stormkit::gpu::Result::EVENT_RESET, - stormkit::gpu::Result::EVENT_SET, - stormkit::gpu::Result::INCOMPLETE, - stormkit::gpu::Result::NOT_READY, - stormkit::gpu::Result::OPERATION_DEFERRED, - stormkit::gpu::Result::OPERATION_NOT_DEFERRED, - stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED, - stormkit::gpu::Result::SUBOPTIMAL, - stormkit::gpu::Result::SUCCESS, - stormkit::gpu::Result::THREAD_DONE, - stormkit::gpu::Result::THREAD_IDLE, - stormkit::gpu::Result::TIMEOUT, - + stormkit::gpu::Result::ERROR_DEVICE_LOST, + stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT, + stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT, + stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED, + stormkit::gpu::Result::ERROR_FRAGMENTATION, + stormkit::gpu::Result::ERROR_FRAGMENTED_POOL, + stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST, + stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY, + stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER, + stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED, + stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE, + stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS, + stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT, + stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED, + stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE, + stormkit::gpu::Result::ERROR_NOT_PERMITTED, + stormkit::gpu::Result::ERROR_OUT_OF_DATE, + stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY, + stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY, + stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY, + stormkit::gpu::Result::ERROR_SURFACE_LOST, + stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS, + stormkit::gpu::Result::ERROR_UNKNOWN, + stormkit::gpu::Result::ERROR_VALIDATION_FAILED, + stormkit::gpu::Result::EVENT_RESET, + stormkit::gpu::Result::EVENT_SET, + stormkit::gpu::Result::INCOMPLETE, + stormkit::gpu::Result::NOT_READY, + stormkit::gpu::Result::OPERATION_DEFERRED, + stormkit::gpu::Result::OPERATION_NOT_DEFERRED, + stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED, + stormkit::gpu::Result::SUBOPTIMAL, + stormkit::gpu::Result::SUCCESS, + stormkit::gpu::Result::THREAD_DONE, + stormkit::gpu::Result::THREAD_IDLE, + stormkit::gpu::Result::TIMEOUT, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::Result value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; - case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: return "Result::ERROR_EXTENSION_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT: return "Result::ERROR_FEATURE_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED: return "Result::ERROR_FORMAT_NOT_SUPPORTED"; - case stormkit::gpu::Result::ERROR_FRAGMENTATION: return "Result::ERROR_FRAGMENTATION"; - case stormkit::gpu::Result::ERROR_FRAGMENTED_POOL: return "Result::ERROR_FRAGMENTED_POOL"; - case stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST: return "Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST"; - case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY: return "Result::ERROR_INCOMPATIBLE_DISPLAY"; - case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER: return "Result::ERROR_INCOMPATIBLE_DRIVER"; - case stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED: return "Result::ERROR_INITIALIZATION_FAILED"; - case stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE: return "Result::ERROR_INVALID_EXTERNAL_HANDLE"; - case stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: return "Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; - case stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT: return "Result::ERROR_LAYER_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED: return "Result::ERROR_MEMORY_MAP_FAILED"; - case stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE: return "Result::ERROR_NATIVE_WINDOW_IN_USE"; - case stormkit::gpu::Result::ERROR_NOT_PERMITTED: return "Result::ERROR_NOT_PERMITTED"; - case stormkit::gpu::Result::ERROR_OUT_OF_DATE: return "Result::ERROR_OUT_OF_DATE"; - case stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY: return "Result::ERROR_OUT_OF_DEVICE_MEMORY"; - case stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY: return "Result::ERROR_OUT_OF_HOST_MEMORY"; - case stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY: return "Result::ERROR_OUT_OF_POOL_MEMORY"; - case stormkit::gpu::Result::ERROR_SURFACE_LOST: return "Result::ERROR_SURFACE_LOST"; - case stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS: return "Result::ERROR_TOO_MANY_OBJECTS"; - case stormkit::gpu::Result::ERROR_UNKNOWN: return "Result::ERROR_UNKNOWN"; - case stormkit::gpu::Result::ERROR_VALIDATION_FAILED: return "Result::ERROR_VALIDATION_FAILED"; - case stormkit::gpu::Result::EVENT_RESET: return "Result::EVENT_RESET"; - case stormkit::gpu::Result::EVENT_SET: return "Result::EVENT_SET"; - case stormkit::gpu::Result::INCOMPLETE: return "Result::INCOMPLETE"; - case stormkit::gpu::Result::NOT_READY: return "Result::NOT_READY"; - case stormkit::gpu::Result::OPERATION_DEFERRED: return "Result::OPERATION_DEFERRED"; - case stormkit::gpu::Result::OPERATION_NOT_DEFERRED: return "Result::OPERATION_NOT_DEFERRED"; - case stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED: return "Result::PIPELINE_COMPILE_REQUIRED"; - case stormkit::gpu::Result::SUBOPTIMAL: return "Result::SUBOPTIMAL"; - case stormkit::gpu::Result::SUCCESS: return "Result::SUCCESS"; - case stormkit::gpu::Result::THREAD_DONE: return "Result::THREAD_DONE"; - case stormkit::gpu::Result::THREAD_IDLE: return "Result::THREAD_IDLE"; - case stormkit::gpu::Result::TIMEOUT: return "Result::TIMEOUT"; - + switch (value) { + case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; + case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: return "Result::ERROR_EXTENSION_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT: return "Result::ERROR_FEATURE_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED: return "Result::ERROR_FORMAT_NOT_SUPPORTED"; + case stormkit::gpu::Result::ERROR_FRAGMENTATION: return "Result::ERROR_FRAGMENTATION"; + case stormkit::gpu::Result::ERROR_FRAGMENTED_POOL: return "Result::ERROR_FRAGMENTED_POOL"; + case stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST: + return "Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST"; + case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY: return "Result::ERROR_INCOMPATIBLE_DISPLAY"; + case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER: return "Result::ERROR_INCOMPATIBLE_DRIVER"; + case stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED: return "Result::ERROR_INITIALIZATION_FAILED"; + case stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE: return "Result::ERROR_INVALID_EXTERNAL_HANDLE"; + case stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: + return "Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; + case stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT: return "Result::ERROR_LAYER_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED: return "Result::ERROR_MEMORY_MAP_FAILED"; + case stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE: return "Result::ERROR_NATIVE_WINDOW_IN_USE"; + case stormkit::gpu::Result::ERROR_NOT_PERMITTED: return "Result::ERROR_NOT_PERMITTED"; + case stormkit::gpu::Result::ERROR_OUT_OF_DATE: return "Result::ERROR_OUT_OF_DATE"; + case stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY: return "Result::ERROR_OUT_OF_DEVICE_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY: return "Result::ERROR_OUT_OF_HOST_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY: return "Result::ERROR_OUT_OF_POOL_MEMORY"; + case stormkit::gpu::Result::ERROR_SURFACE_LOST: return "Result::ERROR_SURFACE_LOST"; + case stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS: return "Result::ERROR_TOO_MANY_OBJECTS"; + case stormkit::gpu::Result::ERROR_UNKNOWN: return "Result::ERROR_UNKNOWN"; + case stormkit::gpu::Result::ERROR_VALIDATION_FAILED: return "Result::ERROR_VALIDATION_FAILED"; + case stormkit::gpu::Result::EVENT_RESET: return "Result::EVENT_RESET"; + case stormkit::gpu::Result::EVENT_SET: return "Result::EVENT_SET"; + case stormkit::gpu::Result::INCOMPLETE: return "Result::INCOMPLETE"; + case stormkit::gpu::Result::NOT_READY: return "Result::NOT_READY"; + case stormkit::gpu::Result::OPERATION_DEFERRED: return "Result::OPERATION_DEFERRED"; + case stormkit::gpu::Result::OPERATION_NOT_DEFERRED: return "Result::OPERATION_NOT_DEFERRED"; + case stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED: return "Result::PIPELINE_COMPILE_REQUIRED"; + case stormkit::gpu::Result::SUBOPTIMAL: return "Result::SUBOPTIMAL"; + case stormkit::gpu::Result::SUCCESS: return "Result::SUCCESS"; + case stormkit::gpu::Result::THREAD_DONE: return "Result::THREAD_DONE"; + case stormkit::gpu::Result::THREAD_IDLE: return "Result::THREAD_IDLE"; + case stormkit::gpu::Result::TIMEOUT: return "Result::TIMEOUT"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::Result value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; - case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: return "Result::ERROR_EXTENSION_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT: return "Result::ERROR_FEATURE_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED: return "Result::ERROR_FORMAT_NOT_SUPPORTED"; - case stormkit::gpu::Result::ERROR_FRAGMENTATION: return "Result::ERROR_FRAGMENTATION"; - case stormkit::gpu::Result::ERROR_FRAGMENTED_POOL: return "Result::ERROR_FRAGMENTED_POOL"; - case stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST: return "Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST"; - case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY: return "Result::ERROR_INCOMPATIBLE_DISPLAY"; - case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER: return "Result::ERROR_INCOMPATIBLE_DRIVER"; - case stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED: return "Result::ERROR_INITIALIZATION_FAILED"; - case stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE: return "Result::ERROR_INVALID_EXTERNAL_HANDLE"; - case stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: return "Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; - case stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT: return "Result::ERROR_LAYER_NOT_PRESENT"; - case stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED: return "Result::ERROR_MEMORY_MAP_FAILED"; - case stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE: return "Result::ERROR_NATIVE_WINDOW_IN_USE"; - case stormkit::gpu::Result::ERROR_NOT_PERMITTED: return "Result::ERROR_NOT_PERMITTED"; - case stormkit::gpu::Result::ERROR_OUT_OF_DATE: return "Result::ERROR_OUT_OF_DATE"; - case stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY: return "Result::ERROR_OUT_OF_DEVICE_MEMORY"; - case stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY: return "Result::ERROR_OUT_OF_HOST_MEMORY"; - case stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY: return "Result::ERROR_OUT_OF_POOL_MEMORY"; - case stormkit::gpu::Result::ERROR_SURFACE_LOST: return "Result::ERROR_SURFACE_LOST"; - case stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS: return "Result::ERROR_TOO_MANY_OBJECTS"; - case stormkit::gpu::Result::ERROR_UNKNOWN: return "Result::ERROR_UNKNOWN"; - case stormkit::gpu::Result::ERROR_VALIDATION_FAILED: return "Result::ERROR_VALIDATION_FAILED"; - case stormkit::gpu::Result::EVENT_RESET: return "Result::EVENT_RESET"; - case stormkit::gpu::Result::EVENT_SET: return "Result::EVENT_SET"; - case stormkit::gpu::Result::INCOMPLETE: return "Result::INCOMPLETE"; - case stormkit::gpu::Result::NOT_READY: return "Result::NOT_READY"; - case stormkit::gpu::Result::OPERATION_DEFERRED: return "Result::OPERATION_DEFERRED"; - case stormkit::gpu::Result::OPERATION_NOT_DEFERRED: return "Result::OPERATION_NOT_DEFERRED"; - case stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED: return "Result::PIPELINE_COMPILE_REQUIRED"; - case stormkit::gpu::Result::SUBOPTIMAL: return "Result::SUBOPTIMAL"; - case stormkit::gpu::Result::SUCCESS: return "Result::SUCCESS"; - case stormkit::gpu::Result::THREAD_DONE: return "Result::THREAD_DONE"; - case stormkit::gpu::Result::THREAD_IDLE: return "Result::THREAD_IDLE"; - case stormkit::gpu::Result::TIMEOUT: return "Result::TIMEOUT"; - + switch (value) { + case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; + case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: return "Result::ERROR_EXTENSION_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT: return "Result::ERROR_FEATURE_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_FORMAT_NOT_SUPPORTED: return "Result::ERROR_FORMAT_NOT_SUPPORTED"; + case stormkit::gpu::Result::ERROR_FRAGMENTATION: return "Result::ERROR_FRAGMENTATION"; + case stormkit::gpu::Result::ERROR_FRAGMENTED_POOL: return "Result::ERROR_FRAGMENTED_POOL"; + case stormkit::gpu::Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST: + return "Result::ERROR_FULLSCREEN_EXCLUSIVE_MODE_LOST"; + case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DISPLAY: return "Result::ERROR_INCOMPATIBLE_DISPLAY"; + case stormkit::gpu::Result::ERROR_INCOMPATIBLE_DRIVER: return "Result::ERROR_INCOMPATIBLE_DRIVER"; + case stormkit::gpu::Result::ERROR_INITIALIZATION_FAILED: return "Result::ERROR_INITIALIZATION_FAILED"; + case stormkit::gpu::Result::ERROR_INVALID_EXTERNAL_HANDLE: return "Result::ERROR_INVALID_EXTERNAL_HANDLE"; + case stormkit::gpu::Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS: + return "Result::ERROR_INVALID_OPAQUE_CAPTURE_ADDRESS"; + case stormkit::gpu::Result::ERROR_LAYER_NOT_PRESENT: return "Result::ERROR_LAYER_NOT_PRESENT"; + case stormkit::gpu::Result::ERROR_MEMORY_MAP_FAILED: return "Result::ERROR_MEMORY_MAP_FAILED"; + case stormkit::gpu::Result::ERROR_NATIVE_WINDOW_IN_USE: return "Result::ERROR_NATIVE_WINDOW_IN_USE"; + case stormkit::gpu::Result::ERROR_NOT_PERMITTED: return "Result::ERROR_NOT_PERMITTED"; + case stormkit::gpu::Result::ERROR_OUT_OF_DATE: return "Result::ERROR_OUT_OF_DATE"; + case stormkit::gpu::Result::ERROR_OUT_OF_DEVICE_MEMORY: return "Result::ERROR_OUT_OF_DEVICE_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_HOST_MEMORY: return "Result::ERROR_OUT_OF_HOST_MEMORY"; + case stormkit::gpu::Result::ERROR_OUT_OF_POOL_MEMORY: return "Result::ERROR_OUT_OF_POOL_MEMORY"; + case stormkit::gpu::Result::ERROR_SURFACE_LOST: return "Result::ERROR_SURFACE_LOST"; + case stormkit::gpu::Result::ERROR_TOO_MANY_OBJECTS: return "Result::ERROR_TOO_MANY_OBJECTS"; + case stormkit::gpu::Result::ERROR_UNKNOWN: return "Result::ERROR_UNKNOWN"; + case stormkit::gpu::Result::ERROR_VALIDATION_FAILED: return "Result::ERROR_VALIDATION_FAILED"; + case stormkit::gpu::Result::EVENT_RESET: return "Result::EVENT_RESET"; + case stormkit::gpu::Result::EVENT_SET: return "Result::EVENT_SET"; + case stormkit::gpu::Result::INCOMPLETE: return "Result::INCOMPLETE"; + case stormkit::gpu::Result::NOT_READY: return "Result::NOT_READY"; + case stormkit::gpu::Result::OPERATION_DEFERRED: return "Result::OPERATION_DEFERRED"; + case stormkit::gpu::Result::OPERATION_NOT_DEFERRED: return "Result::OPERATION_NOT_DEFERRED"; + case stormkit::gpu::Result::PIPELINE_COMPILE_REQUIRED: return "Result::PIPELINE_COMPILE_REQUIRED"; + case stormkit::gpu::Result::SUBOPTIMAL: return "Result::SUBOPTIMAL"; + case stormkit::gpu::Result::SUCCESS: return "Result::SUCCESS"; + case stormkit::gpu::Result::THREAD_DONE: return "Result::THREAD_DONE"; + case stormkit::gpu::Result::THREAD_IDLE: return "Result::THREAD_IDLE"; + case stormkit::gpu::Result::TIMEOUT: return "Result::TIMEOUT"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::SampleCountFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::SampleCountFlag::C1, - stormkit::gpu::SampleCountFlag::C16, - stormkit::gpu::SampleCountFlag::C2, - stormkit::gpu::SampleCountFlag::C32, - stormkit::gpu::SampleCountFlag::C4, - stormkit::gpu::SampleCountFlag::C64, - stormkit::gpu::SampleCountFlag::C8, - + stormkit::gpu::SampleCountFlag::C1, stormkit::gpu::SampleCountFlag::C16, stormkit::gpu::SampleCountFlag::C2, + stormkit::gpu::SampleCountFlag::C32, stormkit::gpu::SampleCountFlag::C4, stormkit::gpu::SampleCountFlag::C64, + stormkit::gpu::SampleCountFlag::C8, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::SampleCountFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::SampleCountFlag::C1: return "SampleCountFlag::C1"; - case stormkit::gpu::SampleCountFlag::C16: return "SampleCountFlag::C16"; - case stormkit::gpu::SampleCountFlag::C2: return "SampleCountFlag::C2"; - case stormkit::gpu::SampleCountFlag::C32: return "SampleCountFlag::C32"; - case stormkit::gpu::SampleCountFlag::C4: return "SampleCountFlag::C4"; - case stormkit::gpu::SampleCountFlag::C64: return "SampleCountFlag::C64"; - case stormkit::gpu::SampleCountFlag::C8: return "SampleCountFlag::C8"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::SampleCountFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::SampleCountFlag::C1: return "SampleCountFlag::C1"; + case stormkit::gpu::SampleCountFlag::C16: return "SampleCountFlag::C16"; + case stormkit::gpu::SampleCountFlag::C2: return "SampleCountFlag::C2"; + case stormkit::gpu::SampleCountFlag::C32: return "SampleCountFlag::C32"; + case stormkit::gpu::SampleCountFlag::C4: return "SampleCountFlag::C4"; + case stormkit::gpu::SampleCountFlag::C64: return "SampleCountFlag::C64"; + case stormkit::gpu::SampleCountFlag::C8: return "SampleCountFlag::C8"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::SampleCountFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::SampleCountFlag::C1: return "SampleCountFlag::C1"; - case stormkit::gpu::SampleCountFlag::C16: return "SampleCountFlag::C16"; - case stormkit::gpu::SampleCountFlag::C2: return "SampleCountFlag::C2"; - case stormkit::gpu::SampleCountFlag::C32: return "SampleCountFlag::C32"; - case stormkit::gpu::SampleCountFlag::C4: return "SampleCountFlag::C4"; - case stormkit::gpu::SampleCountFlag::C64: return "SampleCountFlag::C64"; - case stormkit::gpu::SampleCountFlag::C8: return "SampleCountFlag::C8"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::SampleCountFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::SampleCountFlag::C1: return "SampleCountFlag::C1"; + case stormkit::gpu::SampleCountFlag::C16: return "SampleCountFlag::C16"; + case stormkit::gpu::SampleCountFlag::C2: return "SampleCountFlag::C2"; + case stormkit::gpu::SampleCountFlag::C32: return "SampleCountFlag::C32"; + case stormkit::gpu::SampleCountFlag::C4: return "SampleCountFlag::C4"; + case stormkit::gpu::SampleCountFlag::C64: return "SampleCountFlag::C64"; + case stormkit::gpu::SampleCountFlag::C8: return "SampleCountFlag::C8"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::SamplerAddressMode) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER, - stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE, - stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE, - stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT, - stormkit::gpu::SamplerAddressMode::REPEAT, - + stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER, + stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE, + stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE, + stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT, + stormkit::gpu::SamplerAddressMode::REPEAT, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::SamplerAddressMode value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; - case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; - case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::SamplerAddressMode value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; + case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; + case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerAddressMode value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; - case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; - case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; - case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerAddressMode value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; + case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE: return "SamplerAddressMode::MIRROR_CLAMP_TO_EDGE"; + case stormkit::gpu::SamplerAddressMode::MIRRORED_REPEAT: return "SamplerAddressMode::MIRRORED_REPEAT"; + case stormkit::gpu::SamplerAddressMode::REPEAT: return "SamplerAddressMode::REPEAT"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::SamplerMipmapMode) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::SamplerMipmapMode::LINEAR, - stormkit::gpu::SamplerMipmapMode::NEAREST, - + stormkit::gpu::SamplerMipmapMode::LINEAR, + stormkit::gpu::SamplerMipmapMode::NEAREST, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::SamplerMipmapMode value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::SamplerMipmapMode::LINEAR: return "SamplerMipmapMode::LINEAR"; - case stormkit::gpu::SamplerMipmapMode::NEAREST: return "SamplerMipmapMode::NEAREST"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::SamplerMipmapMode value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::SamplerMipmapMode::LINEAR: return "SamplerMipmapMode::LINEAR"; + case stormkit::gpu::SamplerMipmapMode::NEAREST: return "SamplerMipmapMode::NEAREST"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerMipmapMode value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::SamplerMipmapMode::LINEAR: return "SamplerMipmapMode::LINEAR"; - case stormkit::gpu::SamplerMipmapMode::NEAREST: return "SamplerMipmapMode::NEAREST"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerMipmapMode value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::SamplerMipmapMode::LINEAR: return "SamplerMipmapMode::LINEAR"; + case stormkit::gpu::SamplerMipmapMode::NEAREST: return "SamplerMipmapMode::NEAREST"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::ShaderStageFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::ShaderStageFlag::COMPUTE, - stormkit::gpu::ShaderStageFlag::FRAGMENT, - stormkit::gpu::ShaderStageFlag::GEOMETRY, - stormkit::gpu::ShaderStageFlag::NONE, - stormkit::gpu::ShaderStageFlag::VERTEX, - + stormkit::gpu::ShaderStageFlag::COMPUTE, stormkit::gpu::ShaderStageFlag::FRAGMENT, + stormkit::gpu::ShaderStageFlag::GEOMETRY, stormkit::gpu::ShaderStageFlag::NONE, + stormkit::gpu::ShaderStageFlag::VERTEX, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ShaderStageFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::ShaderStageFlag::COMPUTE: return "ShaderStageFlag::COMPUTE"; - case stormkit::gpu::ShaderStageFlag::FRAGMENT: return "ShaderStageFlag::FRAGMENT"; - case stormkit::gpu::ShaderStageFlag::GEOMETRY: return "ShaderStageFlag::GEOMETRY"; - case stormkit::gpu::ShaderStageFlag::NONE: return "ShaderStageFlag::NONE"; - case stormkit::gpu::ShaderStageFlag::VERTEX: return "ShaderStageFlag::VERTEX"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::ShaderStageFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::ShaderStageFlag::COMPUTE: return "ShaderStageFlag::COMPUTE"; + case stormkit::gpu::ShaderStageFlag::FRAGMENT: return "ShaderStageFlag::FRAGMENT"; + case stormkit::gpu::ShaderStageFlag::GEOMETRY: return "ShaderStageFlag::GEOMETRY"; + case stormkit::gpu::ShaderStageFlag::NONE: return "ShaderStageFlag::NONE"; + case stormkit::gpu::ShaderStageFlag::VERTEX: return "ShaderStageFlag::VERTEX"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ShaderStageFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::ShaderStageFlag::COMPUTE: return "ShaderStageFlag::COMPUTE"; - case stormkit::gpu::ShaderStageFlag::FRAGMENT: return "ShaderStageFlag::FRAGMENT"; - case stormkit::gpu::ShaderStageFlag::GEOMETRY: return "ShaderStageFlag::GEOMETRY"; - case stormkit::gpu::ShaderStageFlag::NONE: return "ShaderStageFlag::NONE"; - case stormkit::gpu::ShaderStageFlag::VERTEX: return "ShaderStageFlag::VERTEX"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::ShaderStageFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::ShaderStageFlag::COMPUTE: return "ShaderStageFlag::COMPUTE"; + case stormkit::gpu::ShaderStageFlag::FRAGMENT: return "ShaderStageFlag::FRAGMENT"; + case stormkit::gpu::ShaderStageFlag::GEOMETRY: return "ShaderStageFlag::GEOMETRY"; + case stormkit::gpu::ShaderStageFlag::NONE: return "ShaderStageFlag::NONE"; + case stormkit::gpu::ShaderStageFlag::VERTEX: return "ShaderStageFlag::VERTEX"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::StencilFaceFlag) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::StencilFaceFlag::BACK, - stormkit::gpu::StencilFaceFlag::FRONT, - stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK, - + stormkit::gpu::StencilFaceFlag::BACK, + stormkit::gpu::StencilFaceFlag::FRONT, + stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::StencilFaceFlag value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::StencilFaceFlag::BACK: return "StencilFaceFlag::BACK"; - case stormkit::gpu::StencilFaceFlag::FRONT: return "StencilFaceFlag::FRONT"; - case stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK: return "StencilFaceFlag::FRONT_AND_BACK"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::StencilFaceFlag value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::StencilFaceFlag::BACK: return "StencilFaceFlag::BACK"; + case stormkit::gpu::StencilFaceFlag::FRONT: return "StencilFaceFlag::FRONT"; + case stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK: return "StencilFaceFlag::FRONT_AND_BACK"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::StencilFaceFlag value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::StencilFaceFlag::BACK: return "StencilFaceFlag::BACK"; - case stormkit::gpu::StencilFaceFlag::FRONT: return "StencilFaceFlag::FRONT"; - case stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK: return "StencilFaceFlag::FRONT_AND_BACK"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::StencilFaceFlag value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::StencilFaceFlag::BACK: return "StencilFaceFlag::BACK"; + case stormkit::gpu::StencilFaceFlag::FRONT: return "StencilFaceFlag::FRONT"; + case stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK: return "StencilFaceFlag::FRONT_AND_BACK"; } std::unreachable(); } FLAG_ENUM(stormkit::gpu::VertexInputRate) + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { return std::array { - stormkit::gpu::VertexInputRate::INSTANCE, - stormkit::gpu::VertexInputRate::VERTEX, - + stormkit::gpu::VertexInputRate::INSTANCE, + stormkit::gpu::VertexInputRate::VERTEX, + }; } + template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::VertexInputRate value) noexcept -> std::string_view { - switch(value) { - case stormkit::gpu::VertexInputRate::INSTANCE: return "VertexInputRate::INSTANCE"; - case stormkit::gpu::VertexInputRate::VERTEX: return "VertexInputRate::VERTEX"; - + constexpr auto stormkit::core::as_string(stormkit::gpu::VertexInputRate value) noexcept + -> std::string_view { + switch (value) { + case stormkit::gpu::VertexInputRate::INSTANCE: return "VertexInputRate::INSTANCE"; + case stormkit::gpu::VertexInputRate::VERTEX: return "VertexInputRate::VERTEX"; } std::unreachable(); } + template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::VertexInputRate value) noexcept -> std::string { - switch(value) { - case stormkit::gpu::VertexInputRate::INSTANCE: return "VertexInputRate::INSTANCE"; - case stormkit::gpu::VertexInputRate::VERTEX: return "VertexInputRate::VERTEX"; - + constexpr auto stormkit::core::to_string(stormkit::gpu::VertexInputRate value) noexcept + -> std::string { + switch (value) { + case stormkit::gpu::VertexInputRate::INSTANCE: return "VertexInputRate::INSTANCE"; + case stormkit::gpu::VertexInputRate::VERTEX: return "VertexInputRate::VERTEX"; } std::unreachable(); } - } //////////////////////////////////////////////////////////////////// @@ -3357,8 +3421,7 @@ export { namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE - STORMKIT_CONST + STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto is_depth_only_format(PixelFormat format) noexcept -> bool { return format == PixelFormat::DEPTH16_UNORM or format == PixelFormat::DEPTH24_UNORM_PACK32 @@ -3367,16 +3430,14 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE - STORMKIT_CONST + STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto is_stencil_only_format(PixelFormat format) noexcept -> bool { return format == PixelFormat::S8U; } ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE - STORMKIT_CONST + STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto is_depth_stencil_format(PixelFormat format) noexcept -> bool { return format == PixelFormat::DEPTH16_UNORM_STENCIL8U or format == PixelFormat::DEPTH24_UNORM_STENCIL8U @@ -3385,24 +3446,21 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE - STORMKIT_CONST + STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto is_depth_format(PixelFormat format) noexcept -> bool { return is_depth_only_format(format) or is_depth_stencil_format(format); } ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE - STORMKIT_CONST + STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto is_stencil_format(PixelFormat format) noexcept -> bool { return is_stencil_only_format(format) or is_depth_stencil_format(format); } ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE - STORMKIT_CONST + STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto get_format_channel_count(PixelFormat format) noexcept -> u8 { switch (format) { case PixelFormat::R8_SNORM: @@ -3479,8 +3537,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE - STORMKIT_CONST + STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto get_format_element_count(PixelFormat format) noexcept -> u8 { switch (format) { case PixelFormat::R8_SNORM: @@ -3552,7 +3609,7 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE STORMKIT_CONST STORMKIT_INTRINSIC - constexpr auto to_vk(U value) noexcept -> T{ + constexpr auto to_vk(U value) noexcept -> T { return narrow(value); } @@ -3566,495 +3623,382 @@ namespace stormkit::gpu { constexpr auto from_vk(U value) noexcept -> T { return narrow(value); } - } + } // namespace vk ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto from_image(image::Image::Format format) -> PixelFormat { - switch(format) { - case image::Image::Format::R8_SNORM : return PixelFormat::R8_SNORM ; - case image::Image::Format::RG8_SNORM : return PixelFormat::RG8_SNORM ; - case image::Image::Format::RGB8_SNORM : return PixelFormat::RGB8_SNORM ; - case image::Image::Format::RGBA8_SNORM : return PixelFormat::RGBA8_SNORM ; - case image::Image::Format::R8_UNORM : return PixelFormat::R8_UNORM ; - case image::Image::Format::RG8_UNORM : return PixelFormat::RG8_UNORM ; - case image::Image::Format::RGB8_UNORM : return PixelFormat::RGB8_UNORM ; - case image::Image::Format::RGBA8_UNORM : return PixelFormat::RGBA8_UNORM ; - case image::Image::Format::R16_SNORM : return PixelFormat::R16_SNORM ; - case image::Image::Format::RG16_SNORM : return PixelFormat::RG16_SNORM ; - case image::Image::Format::RGB16_SNORM : return PixelFormat::RGB16_SNORM ; - case image::Image::Format::RGBA16_SNORM : return PixelFormat::RGBA16_SNORM ; - case image::Image::Format::R16_UNORM : return PixelFormat::R16_UNORM ; - case image::Image::Format::RG16_UNORM : return PixelFormat::RG16_UNORM ; - case image::Image::Format::RGB16_UNORM : return PixelFormat::RGB16_UNORM ; - case image::Image::Format::RGBA16_UNORM : return PixelFormat::RGBA16_UNORM ; - case image::Image::Format::RGBA4_UNORM : return PixelFormat::RGBA4_UNORM_PACK16 ; - case image::Image::Format::BGR8_UNORM : return PixelFormat::BGR8_UNORM ; - case image::Image::Format::BGRA8_UNORM : return PixelFormat::BGRA8_UNORM ; - case image::Image::Format::R8I : return PixelFormat::R8I ; - case image::Image::Format::RG8I : return PixelFormat::RG8I ; - case image::Image::Format::RGB8I : return PixelFormat::RGB8I ; - case image::Image::Format::RGBA8I : return PixelFormat::RGBA8I ; - case image::Image::Format::R8U : return PixelFormat::R8U ; - case image::Image::Format::RG8U : return PixelFormat::RG8U ; - case image::Image::Format::RGB8U : return PixelFormat::RGB8U ; - case image::Image::Format::RGBA8U : return PixelFormat::RGBA8U ; - case image::Image::Format::R16I : return PixelFormat::R16I ; - case image::Image::Format::RG16I : return PixelFormat::RG16I ; - case image::Image::Format::RGB16I : return PixelFormat::RGB16I ; - case image::Image::Format::RGBA16I : return PixelFormat::RGBA16I ; - case image::Image::Format::R16U : return PixelFormat::R16U ; - case image::Image::Format::RG16U : return PixelFormat::RG16U ; - case image::Image::Format::RGB16U : return PixelFormat::RGB16U ; - case image::Image::Format::RGBA16U : return PixelFormat::RGBA16U ; - case image::Image::Format::R32I : return PixelFormat::R32I ; - case image::Image::Format::RG32I : return PixelFormat::RG32I ; - case image::Image::Format::RGB32I : return PixelFormat::RGB32I ; - case image::Image::Format::RGBA32I : return PixelFormat::RGBA32I ; - case image::Image::Format::R32U : return PixelFormat::R32U ; - case image::Image::Format::RG32U : return PixelFormat::RG32U ; - case image::Image::Format::RGB32U : return PixelFormat::RGB32U ; - case image::Image::Format::RGBA32U : return PixelFormat::RGBA32U ; - case image::Image::Format::R16F : return PixelFormat::R16F ; - case image::Image::Format::RG16F : return PixelFormat::RG16F ; - case image::Image::Format::RGB16F : return PixelFormat::RGB16F ; - case image::Image::Format::RGBA16F : return PixelFormat::RGBA16F ; - case image::Image::Format::R32F : return PixelFormat::R32F ; - case image::Image::Format::RG32F : return PixelFormat::RG32F ; - case image::Image::Format::RGB32F : return PixelFormat::RGB32F ; - case image::Image::Format::RGBA32F : return PixelFormat::RGBA32F ; - case image::Image::Format::SRGB8 : return PixelFormat::SRGB8 ; - case image::Image::Format::SRGBA8 : return PixelFormat::SRGBA8 ; - case image::Image::Format::SBGR8 : return PixelFormat::SBGR8 ; - case image::Image::Format::SBGRA8 : return PixelFormat::SBGRA8 ; - case image::Image::Format::UNDEFINED : return PixelFormat::UNDEFINED ; + switch (format) { + case image::Image::Format::R8_SNORM: return PixelFormat::R8_SNORM; + case image::Image::Format::RG8_SNORM: return PixelFormat::RG8_SNORM; + case image::Image::Format::RGB8_SNORM: return PixelFormat::RGB8_SNORM; + case image::Image::Format::RGBA8_SNORM: return PixelFormat::RGBA8_SNORM; + case image::Image::Format::R8_UNORM: return PixelFormat::R8_UNORM; + case image::Image::Format::RG8_UNORM: return PixelFormat::RG8_UNORM; + case image::Image::Format::RGB8_UNORM: return PixelFormat::RGB8_UNORM; + case image::Image::Format::RGBA8_UNORM: return PixelFormat::RGBA8_UNORM; + case image::Image::Format::R16_SNORM: return PixelFormat::R16_SNORM; + case image::Image::Format::RG16_SNORM: return PixelFormat::RG16_SNORM; + case image::Image::Format::RGB16_SNORM: return PixelFormat::RGB16_SNORM; + case image::Image::Format::RGBA16_SNORM: return PixelFormat::RGBA16_SNORM; + case image::Image::Format::R16_UNORM: return PixelFormat::R16_UNORM; + case image::Image::Format::RG16_UNORM: return PixelFormat::RG16_UNORM; + case image::Image::Format::RGB16_UNORM: return PixelFormat::RGB16_UNORM; + case image::Image::Format::RGBA16_UNORM: return PixelFormat::RGBA16_UNORM; + case image::Image::Format::RGBA4_UNORM: return PixelFormat::RGBA4_UNORM_PACK16; + case image::Image::Format::BGR8_UNORM: return PixelFormat::BGR8_UNORM; + case image::Image::Format::BGRA8_UNORM: return PixelFormat::BGRA8_UNORM; + case image::Image::Format::R8I: return PixelFormat::R8I; + case image::Image::Format::RG8I: return PixelFormat::RG8I; + case image::Image::Format::RGB8I: return PixelFormat::RGB8I; + case image::Image::Format::RGBA8I: return PixelFormat::RGBA8I; + case image::Image::Format::R8U: return PixelFormat::R8U; + case image::Image::Format::RG8U: return PixelFormat::RG8U; + case image::Image::Format::RGB8U: return PixelFormat::RGB8U; + case image::Image::Format::RGBA8U: return PixelFormat::RGBA8U; + case image::Image::Format::R16I: return PixelFormat::R16I; + case image::Image::Format::RG16I: return PixelFormat::RG16I; + case image::Image::Format::RGB16I: return PixelFormat::RGB16I; + case image::Image::Format::RGBA16I: return PixelFormat::RGBA16I; + case image::Image::Format::R16U: return PixelFormat::R16U; + case image::Image::Format::RG16U: return PixelFormat::RG16U; + case image::Image::Format::RGB16U: return PixelFormat::RGB16U; + case image::Image::Format::RGBA16U: return PixelFormat::RGBA16U; + case image::Image::Format::R32I: return PixelFormat::R32I; + case image::Image::Format::RG32I: return PixelFormat::RG32I; + case image::Image::Format::RGB32I: return PixelFormat::RGB32I; + case image::Image::Format::RGBA32I: return PixelFormat::RGBA32I; + case image::Image::Format::R32U: return PixelFormat::R32U; + case image::Image::Format::RG32U: return PixelFormat::RG32U; + case image::Image::Format::RGB32U: return PixelFormat::RGB32U; + case image::Image::Format::RGBA32U: return PixelFormat::RGBA32U; + case image::Image::Format::R16F: return PixelFormat::R16F; + case image::Image::Format::RG16F: return PixelFormat::RG16F; + case image::Image::Format::RGB16F: return PixelFormat::RGB16F; + case image::Image::Format::RGBA16F: return PixelFormat::RGBA16F; + case image::Image::Format::R32F: return PixelFormat::R32F; + case image::Image::Format::RG32F: return PixelFormat::RG32F; + case image::Image::Format::RGB32F: return PixelFormat::RGB32F; + case image::Image::Format::RGBA32F: return PixelFormat::RGBA32F; + case image::Image::Format::SRGB8: return PixelFormat::SRGB8; + case image::Image::Format::SRGBA8: return PixelFormat::SRGBA8; + case image::Image::Format::SBGR8: return PixelFormat::SBGR8; + case image::Image::Format::SBGRA8: return PixelFormat::SBGRA8; + case image::Image::Format::UNDEFINED: return PixelFormat::UNDEFINED; default: break; } std::unreachable(); } -} +} // namespace stormkit::gpu #ifndef STORMKIT_OS_WINDOWS #undef STORMKIT_GPU_API #define STORMKIT_GPU_API #endif - - template - stormkit::gpu::AccessFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::AccessFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkAccessFlagBits); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::AccessFlag); - template - VkAccessFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::AccessFlag); - - template - stormkit::gpu::AttachmentLoadOperation STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::AttachmentLoadOperation STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkAttachmentLoadOp); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::AttachmentLoadOperation); - template - VkAttachmentLoadOp STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::AttachmentLoadOperation); - - template - stormkit::gpu::AttachmentStoreOperation STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::AttachmentStoreOperation STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkAttachmentStoreOp); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::AttachmentStoreOperation); - template - VkAttachmentStoreOp STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::AttachmentStoreOperation); - - template - stormkit::gpu::BlendFactor STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::BlendFactor STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkBlendFactor); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BlendFactor); - template - VkBlendFactor STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BlendFactor); - - template - stormkit::gpu::BlendOperation STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::BlendOperation STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkBlendOp); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BlendOperation); - template - VkBlendOp STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BlendOperation); - - template - stormkit::gpu::BorderColor STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::BorderColor STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkBorderColor); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BorderColor); - template - VkBorderColor STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BorderColor); - - template - stormkit::gpu::BufferUsageFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::BufferUsageFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkBufferUsageFlagBits); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BufferUsageFlag); - template - VkBufferUsageFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BufferUsageFlag); - - template - stormkit::gpu::ColorComponentFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::ColorComponentFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkColorComponentFlagBits); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ColorComponentFlag); - template - VkColorComponentFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ColorComponentFlag); - - template - stormkit::gpu::ColorSpace STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::ColorSpace STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkColorSpaceKHR); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ColorSpace); - template - VkColorSpaceKHR STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ColorSpace); - - template - stormkit::gpu::CommandBufferLevel STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::CommandBufferLevel STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkCommandBufferLevel); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::CommandBufferLevel); - template - VkCommandBufferLevel STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::CommandBufferLevel); - - template - stormkit::gpu::CompareOperation STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::CompareOperation STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkCompareOp); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::CompareOperation); - template - VkCompareOp STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::CompareOperation); - - template - stormkit::gpu::CullModeFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::CullModeFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkCullModeFlagBits); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::CullModeFlag); - template - VkCullModeFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::CullModeFlag); - - template - stormkit::gpu::DebugObjectType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::DebugObjectType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkObjectType); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DebugObjectType); - template - VkObjectType STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DebugObjectType); - - template - stormkit::gpu::DependencyFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::DependencyFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkDependencyFlagBits); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DependencyFlag); - template - VkDependencyFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DependencyFlag); - - template - stormkit::gpu::DescriptorType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::DescriptorType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkDescriptorType); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DescriptorType); - template - VkDescriptorType STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DescriptorType); - - template - stormkit::gpu::DynamicState STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::DynamicState STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkDynamicState); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DynamicState); - template - VkDynamicState STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DynamicState); - - template - stormkit::gpu::Filter STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::Filter STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFilter); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::Filter); - template - VkFilter STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::Filter); - - template - stormkit::gpu::FormatFeatureFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::FormatFeatureFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFormatFeatureFlagBits); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::FormatFeatureFlag); - template - VkFormatFeatureFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::FormatFeatureFlag); - - template - stormkit::gpu::FrontFace STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::FrontFace STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFrontFace); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::FrontFace); - template - VkFrontFace STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::FrontFace); - - template - stormkit::gpu::GeometryFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::GeometryFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkGeometryFlagBitsKHR); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::GeometryFlag); - template - VkGeometryFlagBitsKHR STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::GeometryFlag); - - template - stormkit::gpu::GeometryType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::GeometryType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkGeometryTypeKHR); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::GeometryType); - template - VkGeometryTypeKHR STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::GeometryType); - - template - stormkit::gpu::ImageAspectFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::ImageAspectFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkImageAspectFlagBits); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageAspectFlag); - template - VkImageAspectFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageAspectFlag); - - template - stormkit::gpu::ImageCreateFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::ImageCreateFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkImageCreateFlagBits); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageCreateFlag); - template - VkImageCreateFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageCreateFlag); - - template - stormkit::gpu::ImageLayout STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::ImageLayout STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkImageLayout); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageLayout); - template - VkImageLayout STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageLayout); - - template - stormkit::gpu::ImageTiling STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::ImageTiling STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkImageTiling); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageTiling); - template - VkImageTiling STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageTiling); - - template - stormkit::gpu::ImageType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::ImageType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkImageType); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageType); - template - VkImageType STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageType); - - template - stormkit::gpu::ImageUsageFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::ImageUsageFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkImageUsageFlagBits); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageUsageFlag); - template - VkImageUsageFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageUsageFlag); - - template - stormkit::gpu::ImageViewType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::ImageViewType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkImageViewType); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageViewType); - template - VkImageViewType STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageViewType); - - template - stormkit::gpu::LogicOperation STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::LogicOperation STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkLogicOp); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::LogicOperation); - template - VkLogicOp STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::LogicOperation); - - template - stormkit::gpu::MemoryPropertyFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::MemoryPropertyFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkMemoryPropertyFlagBits); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::MemoryPropertyFlag); - template - VkMemoryPropertyFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::MemoryPropertyFlag); - - template - stormkit::gpu::PhysicalDeviceType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::PhysicalDeviceType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkPhysicalDeviceType); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PhysicalDeviceType); - template - VkPhysicalDeviceType STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PhysicalDeviceType); - - template - stormkit::gpu::PipelineBindPoint STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::PipelineBindPoint STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkPipelineBindPoint); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PipelineBindPoint); - template - VkPipelineBindPoint STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PipelineBindPoint); - - template - stormkit::gpu::PipelineStageFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::PipelineStageFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkPipelineStageFlagBits); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PipelineStageFlag); - template - VkPipelineStageFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PipelineStageFlag); - - template - stormkit::gpu::PixelFormat STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::PixelFormat STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFormat); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PixelFormat); - template - VkFormat STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PixelFormat); - - template - stormkit::gpu::PolygonMode STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::PolygonMode STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkPolygonMode); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PolygonMode); - template - VkPolygonMode STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PolygonMode); - - template - stormkit::gpu::PresentMode STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::PresentMode STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkPresentModeKHR); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PresentMode); - template - VkPresentModeKHR STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PresentMode); - - template - stormkit::gpu::PrimitiveTopology STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::PrimitiveTopology STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkPrimitiveTopology); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PrimitiveTopology); - template - VkPrimitiveTopology STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PrimitiveTopology); - - template - stormkit::gpu::QueueFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::QueueFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkQueueFlagBits); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::QueueFlag); - template - VkQueueFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::QueueFlag); - - template - stormkit::gpu::ResolveModeFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::ResolveModeFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkResolveModeFlagBits); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ResolveModeFlag); - template - VkResolveModeFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ResolveModeFlag); - - template - stormkit::gpu::Result STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::Result STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkResult); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::Result); - template - VkResult STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::Result); - - template - stormkit::gpu::SampleCountFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::SampleCountFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkSampleCountFlagBits); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::SampleCountFlag); - template - VkSampleCountFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::SampleCountFlag); - - template - stormkit::gpu::SamplerAddressMode STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::SamplerAddressMode STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkSamplerAddressMode); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::SamplerAddressMode); - template - VkSamplerAddressMode STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::SamplerAddressMode); - - template - stormkit::gpu::SamplerMipmapMode STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::SamplerMipmapMode STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkSamplerMipmapMode); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::SamplerMipmapMode); - template - VkSamplerMipmapMode STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::SamplerMipmapMode); - - template - stormkit::gpu::ShaderStageFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::ShaderStageFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkShaderStageFlagBits); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ShaderStageFlag); - template - VkShaderStageFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ShaderStageFlag); - - template - stormkit::gpu::StencilFaceFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::StencilFaceFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkStencilFaceFlagBits); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::StencilFaceFlag); - template - VkStencilFaceFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::StencilFaceFlag); - - template - stormkit::gpu::VertexInputRate STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); - template - stormkit::gpu::VertexInputRate STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkVertexInputRate); - template - VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::VertexInputRate); - template - VkVertexInputRate STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::VertexInputRate); - +template stormkit::gpu::AccessFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::AccessFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkAccessFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::AccessFlag); +template VkAccessFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::AccessFlag); + +template stormkit::gpu::AttachmentLoadOperation STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::AttachmentLoadOperation STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkAttachmentLoadOp); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::AttachmentLoadOperation); +template VkAttachmentLoadOp STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::AttachmentLoadOperation); + +template stormkit::gpu::AttachmentStoreOperation STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::AttachmentStoreOperation STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkAttachmentStoreOp); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::AttachmentStoreOperation); +template VkAttachmentStoreOp STORMKIT_GPU_API + stormkit::gpu::vk::to_vk(stormkit::gpu::AttachmentStoreOperation); + +template stormkit::gpu::BlendFactor STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::BlendFactor STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkBlendFactor); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BlendFactor); +template VkBlendFactor STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BlendFactor); + +template stormkit::gpu::BlendOperation STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::BlendOperation STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkBlendOp); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BlendOperation); +template VkBlendOp STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BlendOperation); + +template stormkit::gpu::BorderColor STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::BorderColor STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkBorderColor); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BorderColor); +template VkBorderColor STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BorderColor); + +template stormkit::gpu::BufferUsageFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::BufferUsageFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkBufferUsageFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BufferUsageFlag); +template VkBufferUsageFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::BufferUsageFlag); + +template stormkit::gpu::ColorComponentFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::ColorComponentFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkColorComponentFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ColorComponentFlag); +template VkColorComponentFlagBits STORMKIT_GPU_API + stormkit::gpu::vk::to_vk(stormkit::gpu::ColorComponentFlag); + +template stormkit::gpu::ColorSpace STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::ColorSpace STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkColorSpaceKHR); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ColorSpace); +template VkColorSpaceKHR STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ColorSpace); + +template stormkit::gpu::CommandBufferLevel STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::CommandBufferLevel STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkCommandBufferLevel); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::CommandBufferLevel); +template VkCommandBufferLevel STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::CommandBufferLevel); + +template stormkit::gpu::CompareOperation STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::CompareOperation STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkCompareOp); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::CompareOperation); +template VkCompareOp STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::CompareOperation); + +template stormkit::gpu::CullModeFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::CullModeFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkCullModeFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::CullModeFlag); +template VkCullModeFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::CullModeFlag); + +template stormkit::gpu::DebugObjectType STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::DebugObjectType STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkObjectType); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DebugObjectType); +template VkObjectType STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DebugObjectType); + +template stormkit::gpu::DependencyFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::DependencyFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkDependencyFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DependencyFlag); +template VkDependencyFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DependencyFlag); + +template stormkit::gpu::DescriptorType STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::DescriptorType STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkDescriptorType); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DescriptorType); +template VkDescriptorType STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DescriptorType); + +template stormkit::gpu::DynamicState STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::DynamicState STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkDynamicState); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DynamicState); +template VkDynamicState STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::DynamicState); + +template stormkit::gpu::Filter STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::Filter STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFilter); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::Filter); +template VkFilter STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::Filter); + +template stormkit::gpu::FormatFeatureFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::FormatFeatureFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFormatFeatureFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::FormatFeatureFlag); +template VkFormatFeatureFlagBits STORMKIT_GPU_API + stormkit::gpu::vk::to_vk(stormkit::gpu::FormatFeatureFlag); + +template stormkit::gpu::FrontFace STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::FrontFace STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFrontFace); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::FrontFace); +template VkFrontFace STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::FrontFace); + +template stormkit::gpu::GeometryFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::GeometryFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkGeometryFlagBitsKHR); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::GeometryFlag); +template VkGeometryFlagBitsKHR STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::GeometryFlag); + +template stormkit::gpu::GeometryType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::GeometryType STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkGeometryTypeKHR); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::GeometryType); +template VkGeometryTypeKHR STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::GeometryType); + +template stormkit::gpu::ImageAspectFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::ImageAspectFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkImageAspectFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageAspectFlag); +template VkImageAspectFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageAspectFlag); + +template stormkit::gpu::ImageCreateFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::ImageCreateFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkImageCreateFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageCreateFlag); +template VkImageCreateFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageCreateFlag); + +template stormkit::gpu::ImageLayout STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::ImageLayout STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkImageLayout); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageLayout); +template VkImageLayout STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageLayout); + +template stormkit::gpu::ImageTiling STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::ImageTiling STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkImageTiling); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageTiling); +template VkImageTiling STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageTiling); + +template stormkit::gpu::ImageType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::ImageType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkImageType); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageType); +template VkImageType STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageType); + +template stormkit::gpu::ImageUsageFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::ImageUsageFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkImageUsageFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageUsageFlag); +template VkImageUsageFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageUsageFlag); + +template stormkit::gpu::ImageViewType STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::ImageViewType STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkImageViewType); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageViewType); +template VkImageViewType STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ImageViewType); + +template stormkit::gpu::LogicOperation STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::LogicOperation STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkLogicOp); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::LogicOperation); +template VkLogicOp STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::LogicOperation); + +template stormkit::gpu::MemoryPropertyFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::MemoryPropertyFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkMemoryPropertyFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::MemoryPropertyFlag); +template VkMemoryPropertyFlagBits STORMKIT_GPU_API + stormkit::gpu::vk::to_vk(stormkit::gpu::MemoryPropertyFlag); + +template stormkit::gpu::PhysicalDeviceType STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::PhysicalDeviceType STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkPhysicalDeviceType); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PhysicalDeviceType); +template VkPhysicalDeviceType STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PhysicalDeviceType); + +template stormkit::gpu::PipelineBindPoint STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::PipelineBindPoint STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkPipelineBindPoint); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PipelineBindPoint); +template VkPipelineBindPoint STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PipelineBindPoint); + +template stormkit::gpu::PipelineStageFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::PipelineStageFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkPipelineStageFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PipelineStageFlag); +template VkPipelineStageFlagBits STORMKIT_GPU_API + stormkit::gpu::vk::to_vk(stormkit::gpu::PipelineStageFlag); + +template stormkit::gpu::PixelFormat STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::PixelFormat STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFormat); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PixelFormat); +template VkFormat STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PixelFormat); + +template stormkit::gpu::PolygonMode STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::PolygonMode STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkPolygonMode); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PolygonMode); +template VkPolygonMode STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PolygonMode); + +template stormkit::gpu::PresentMode STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::PresentMode STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkPresentModeKHR); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PresentMode); +template VkPresentModeKHR STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PresentMode); + +template stormkit::gpu::PrimitiveTopology STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::PrimitiveTopology STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkPrimitiveTopology); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PrimitiveTopology); +template VkPrimitiveTopology STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::PrimitiveTopology); + +template stormkit::gpu::QueueFlag STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::QueueFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkQueueFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::QueueFlag); +template VkQueueFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::QueueFlag); + +template stormkit::gpu::ResolveModeFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::ResolveModeFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkResolveModeFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ResolveModeFlag); +template VkResolveModeFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ResolveModeFlag); + +template stormkit::gpu::Result STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::Result STORMKIT_GPU_API stormkit::gpu::vk::from_vk(VkResult); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::Result); +template VkResult STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::Result); + +template stormkit::gpu::SampleCountFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::SampleCountFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkSampleCountFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::SampleCountFlag); +template VkSampleCountFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::SampleCountFlag); + +template stormkit::gpu::SamplerAddressMode STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::SamplerAddressMode STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkSamplerAddressMode); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::SamplerAddressMode); +template VkSamplerAddressMode STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::SamplerAddressMode); + +template stormkit::gpu::SamplerMipmapMode STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::SamplerMipmapMode STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkSamplerMipmapMode); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::SamplerMipmapMode); +template VkSamplerMipmapMode STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::SamplerMipmapMode); + +template stormkit::gpu::ShaderStageFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::ShaderStageFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkShaderStageFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ShaderStageFlag); +template VkShaderStageFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::ShaderStageFlag); + +template stormkit::gpu::StencilFaceFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::StencilFaceFlag STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkStencilFaceFlagBits); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::StencilFaceFlag); +template VkStencilFaceFlagBits STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::StencilFaceFlag); + +template stormkit::gpu::VertexInputRate STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkFlags); +template stormkit::gpu::VertexInputRate STORMKIT_GPU_API + stormkit::gpu::vk::from_vk(VkVertexInputRate); +template VkFlags STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::VertexInputRate); +template VkVertexInputRate STORMKIT_GPU_API stormkit::gpu::vk::to_vk(stormkit::gpu::VertexInputRate); diff --git a/modules/stormkit/gpu/execution/command_buffer.cppm b/modules/stormkit/gpu/execution/command_buffer.cppm index 0f870cf3a..65a6bed1d 100644 --- a/modules/stormkit/gpu/execution/command_buffer.cppm +++ b/modules/stormkit/gpu/execution/command_buffer.cppm @@ -44,7 +44,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = Queue; - using ValueType = VkQueue; + using ValueType = VkQueue; using DeleterType = decltype(cmonadic::noop()); using ViewType = view::Queue; using OwnedBy = Device; @@ -55,7 +55,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = CommandBuffer; - using ValueType = VkCommandBuffer; + using ValueType = VkCommandBuffer; using DeleterType = decltype(cmonadic::noop()); using ViewType = view::CommandBuffer; using OwnedBy = Device; @@ -67,7 +67,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = CommandPool; - using ValueType = VkCommandPool; + using ValueType = VkCommandPool; using DeleterType = PFN_vkDestroyCommandPool VolkDeviceTable::*; using ViewType = view::CommandPool; using OwnedBy = Device; @@ -122,9 +122,9 @@ export namespace stormkit::gpu { namespace view { class Queue: public DeviceObject { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; + using ObjectInfo = typename meta::ObjectInfo; + using ValueType = ObjectInfo::ValueType; + using ViewType = ObjectInfo::ViewType; Queue(const gpu::Queue& of) noexcept; template T> @@ -529,9 +529,9 @@ export namespace stormkit::gpu { namespace view { class CommandPool: public DeviceObject { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; + using ObjectInfo = typename meta::ObjectInfo; + using ValueType = ObjectInfo::ValueType; + using ViewType = ObjectInfo::ViewType; using DeviceObject::DeviceObject; ~CommandPool() noexcept; diff --git a/modules/stormkit/gpu/execution/descriptors.cppm b/modules/stormkit/gpu/execution/descriptors.cppm index 9a9b1f0ab..e1092a5ee 100644 --- a/modules/stormkit/gpu/execution/descriptors.cppm +++ b/modules/stormkit/gpu/execution/descriptors.cppm @@ -40,7 +40,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = DescriptorSet; - using ValueType = VkDescriptorSet; + using ValueType = VkDescriptorSet; using DeleterType = decltype(cmonadic::noop()); using ViewType = view::DescriptorSet; using OwnedBy = Device; @@ -52,7 +52,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = DescriptorSetLayout; - using ValueType = VkDescriptorSetLayout; + using ValueType = VkDescriptorSetLayout; using DeleterType = PFN_vkDestroyDescriptorSetLayout VolkDeviceTable::*; using ViewType = view::DescriptorSetLayout; using OwnedBy = Device; @@ -63,7 +63,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = DescriptorPool; - using ValueType = VkDescriptorPool; + using ValueType = VkDescriptorPool; using DeleterType = PFN_vkDestroyDescriptorPool VolkDeviceTable::*; using ViewType = view::DescriptorPool; using OwnedBy = Device; @@ -129,9 +129,9 @@ export namespace stormkit::gpu { namespace view { class DescriptorSet: public DeviceObject { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; + using ObjectInfo = typename meta::ObjectInfo; + using ValueType = ObjectInfo::ValueType; + using ViewType = ObjectInfo::ViewType; using DeviceObject::DeviceObject; ~DescriptorSet() noexcept; @@ -172,9 +172,9 @@ export namespace stormkit::gpu { namespace view { class DescriptorSetLayout: public DeviceObject { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; + using ObjectInfo = typename meta::ObjectInfo; + using ValueType = ObjectInfo::ValueType; + using ViewType = ObjectInfo::ViewType; DescriptorSetLayout(const gpu::DescriptorSetLayout& of) noexcept; template T> @@ -235,9 +235,9 @@ export namespace stormkit::gpu { namespace view { class DescriptorPool: public DeviceObject { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; + using ObjectInfo = typename meta::ObjectInfo; + using ValueType = ObjectInfo::ValueType; + using ViewType = ObjectInfo::ViewType; using DeviceObject::DeviceObject; ~DescriptorPool() noexcept; diff --git a/modules/stormkit/gpu/execution/pipeline.cppm b/modules/stormkit/gpu/execution/pipeline.cppm index cf5d43f2e..098652b1c 100644 --- a/modules/stormkit/gpu/execution/pipeline.cppm +++ b/modules/stormkit/gpu/execution/pipeline.cppm @@ -41,7 +41,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = PipelineCache; - using ValueType = VkPipelineCache; + using ValueType = VkPipelineCache; using DeleterType = PFN_vkDestroyPipelineCache VolkDeviceTable::*; using ViewType = view::PipelineCache; using OwnedBy = Device; @@ -53,7 +53,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = Pipeline; - using ValueType = VkPipeline; + using ValueType = VkPipeline; using DeleterType = PFN_vkDestroyPipeline VolkDeviceTable::*; using ViewType = view::Pipeline; using OwnedBy = Device; @@ -64,7 +64,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = PipelineLayout; - using ValueType = VkPipelineLayout; + using ValueType = VkPipelineLayout; using DeleterType = PFN_vkDestroyPipelineLayout VolkDeviceTable::*; using ViewType = view::PipelineLayout; using OwnedBy = Device; @@ -192,9 +192,9 @@ export namespace stormkit::gpu { namespace view { class STORMKIT_GPU_API Pipeline: public DeviceObject { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; + using ObjectInfo = typename meta::ObjectInfo; + using ValueType = ObjectInfo::ValueType; + using ViewType = ObjectInfo::ViewType; Pipeline(const gpu::Pipeline& of) noexcept; template T> diff --git a/modules/stormkit/gpu/execution/render_pass.cppm b/modules/stormkit/gpu/execution/render_pass.cppm index 68d416c32..34316eb71 100644 --- a/modules/stormkit/gpu/execution/render_pass.cppm +++ b/modules/stormkit/gpu/execution/render_pass.cppm @@ -34,7 +34,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = FrameBuffer; - using ValueType = VkFramebuffer; + using ValueType = VkFramebuffer; using DeleterType = PFN_vkDestroyFramebuffer VolkDeviceTable::*; using ViewType = view::FrameBuffer; using OwnedBy = Device; @@ -46,7 +46,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = RenderPass; - using ValueType = VkRenderPass; + using ValueType = VkRenderPass; using DeleterType = PFN_vkDestroyRenderPass VolkDeviceTable::*; using ViewType = view::RenderPass; using OwnedBy = Device; @@ -96,9 +96,9 @@ export namespace stormkit::gpu { namespace view { class STORMKIT_GPU_API FrameBuffer: public DeviceObject { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; + using ObjectInfo = typename meta::ObjectInfo; + using ValueType = ObjectInfo::ValueType; + using ViewType = ObjectInfo::ViewType; FrameBuffer(const gpu::FrameBuffer& of) noexcept; template T> @@ -200,9 +200,9 @@ export namespace stormkit::gpu { namespace view { class STORMKIT_GPU_API RenderPass: public DeviceObject { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; + using ObjectInfo = typename meta::ObjectInfo; + using ValueType = ObjectInfo::ValueType; + using ViewType = ObjectInfo::ViewType; // RenderPass(const gpu::RenderPass& of) noexcept; // template T> diff --git a/modules/stormkit/gpu/execution/swapchain.cppm b/modules/stormkit/gpu/execution/swapchain.cppm index 6869311c6..5cb2315c0 100644 --- a/modules/stormkit/gpu/execution/swapchain.cppm +++ b/modules/stormkit/gpu/execution/swapchain.cppm @@ -30,7 +30,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = SwapChain; - using ValueType = VkSwapchainKHR; + using ValueType = VkSwapchainKHR; using DeleterType = PFN_vkDestroySwapchainKHR VolkDeviceTable::*; using ViewType = view::SwapChain; using OwnedBy = Device; @@ -81,9 +81,9 @@ export namespace stormkit::gpu { namespace view { class STORMKIT_GPU_API SwapChain: public DeviceObject { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; + using ObjectInfo = typename meta::ObjectInfo; + using ValueType = ObjectInfo::ValueType; + using ViewType = ObjectInfo::ViewType; SwapChain(const gpu::SwapChain& of) noexcept; template T> diff --git a/modules/stormkit/gpu/resource/buffer.cppm b/modules/stormkit/gpu/resource/buffer.cppm index 131c5ab92..a89a7af58 100644 --- a/modules/stormkit/gpu/resource/buffer.cppm +++ b/modules/stormkit/gpu/resource/buffer.cppm @@ -38,7 +38,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = Buffer; - using ValueType = VkBuffer; + using ValueType = VkBuffer; using DeleterType = PFN_vkDestroyBuffer VolkDeviceTable::*; using ViewType = view::Buffer; using OwnedBy = Device; @@ -133,9 +133,9 @@ export namespace stormkit::gpu { namespace view { class STORMKIT_GPU_API Buffer: public DeviceObject { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; + using ObjectInfo = typename meta::ObjectInfo; + using ValueType = ObjectInfo::ValueType; + using ViewType = ObjectInfo::ViewType; Buffer(const gpu::Buffer& of) noexcept; template T> diff --git a/modules/stormkit/gpu/resource/shader.cppm b/modules/stormkit/gpu/resource/shader.cppm index 390b57b59..3f5b4854a 100644 --- a/modules/stormkit/gpu/resource/shader.cppm +++ b/modules/stormkit/gpu/resource/shader.cppm @@ -34,7 +34,7 @@ export namespace stormkit::gpu { template<> struct ObjectInfo { using Of = Shader; - using ValueType = VkShaderModule; + using ValueType = VkShaderModule; using DeleterType = PFN_vkDestroyShaderModule VolkDeviceTable::*; using ViewType = view::Shader; using OwnedBy = Device; @@ -99,9 +99,9 @@ export namespace stormkit::gpu { namespace view { class STORMKIT_GPU_API Shader: public view::DeviceObject { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; + using ObjectInfo = typename meta::ObjectInfo; + using ValueType = ObjectInfo::ValueType; + using ViewType = ObjectInfo::ViewType; Shader(const gpu::Shader& of) noexcept; template T> diff --git a/src/wsi/common/window_base.cppm b/src/wsi/common/window_base.cppm index e477b6e5b..29f745ca8 100644 --- a/src/wsi/common/window_base.cppm +++ b/src/wsi/common/window_base.cppm @@ -24,19 +24,17 @@ export namespace stormkit::wsi::common { m_keyboard_states.push_back({ .id = GLOBAL_KEYBOARD_ID }); } - WindowBase(const WindowBase&) = delete; - auto operator=(const WindowBase&) -> WindowBase& = delete; + WindowBase(const WindowBase&) = delete; + auto operator=(const WindowBase&) -> WindowBase& = delete; STORMKIT_FORCE_INLINE - inline WindowBase(WindowBase&&) noexcept - = default; + inline WindowBase(WindowBase&&) noexcept = default; STORMKIT_FORCE_INLINE inline auto operator=(WindowBase&&) noexcept -> WindowBase& = default; STORMKIT_FORCE_INLINE - inline ~WindowBase() noexcept - = default; + inline ~WindowBase() noexcept = default; auto set_open(bool open) noexcept -> void; [[nodiscard]] @@ -95,14 +93,14 @@ export namespace stormkit::wsi::common { protected: struct { - bool open = false; - bool minimized = false; - bool active = false; - bool fullscreen = false; - bool visible = false; - math::uextent2 extent; + bool open = false; + bool minimized = false; + bool active = false; + bool fullscreen = false; + bool visible = false; + math::uextent2 extent; optref current_monitor; - std::string title; + std::string title; f32 dpi = 1.f; diff --git a/src/wsi/linux/wayland/monitor.cppm b/src/wsi/linux/wayland/monitor.cppm index 6c154a07b..3e8cc03e1 100644 --- a/src/wsi/linux/wayland/monitor.cppm +++ b/src/wsi/linux/wayland/monitor.cppm @@ -22,8 +22,8 @@ namespace stormkit::wsi::linux::wayland { if (update or stdr::empty(monitors)) { auto& globals = wl::get_globals(); monitors = globals.monitors - | stdv::transform([](const wl::WaylandMonitor& pair) static noexcept { return pair.monitor; }) - | stdr::to(); + | stdv::transform([](const wl::WaylandMonitor& pair) static noexcept { return pair.monitor; }) + | stdr::to(); } return monitors; diff --git a/src/wsi/linux/window.cppm b/src/wsi/linux/window.cppm index dd21a602a..76b819fbc 100644 --- a/src/wsi/linux/window.cppm +++ b/src/wsi/linux/window.cppm @@ -126,14 +126,12 @@ namespace stormkit::wsi::linux { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Window::~Window() noexcept - = default; + inline Window::~Window() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Window::Window(Window&&) noexcept - = default; + inline Window::Window(Window&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// diff --git a/src/wsi/linux/x11/context.cpp b/src/wsi/linux/x11/context.cpp index c08f54d9c..bd7ea2592 100644 --- a/src/wsi/linux/x11/context.cpp +++ b/src/wsi/linux/x11/context.cpp @@ -72,12 +72,10 @@ namespace stormkit::wsi::linux::x11::xcb { auto it = atoms.find(name); if (it != stdr::end(atoms)) out = it->second; else { - const auto cookie = xcb_intern_atom(globals.connection, - (only_if_exists) ? 1 : 0, - as(stdr::size(name)), - stdr::data(name)); - auto error = xcb::GenericError::empty(); - const auto reply = xcb::InternAtomReply::create(globals.connection, cookie, &error.handle()); + const auto + cookie = xcb_intern_atom(globals.connection, (only_if_exists) ? 1 : 0, as(stdr::size(name)), stdr::data(name)); + auto error = xcb::GenericError::empty(); + const auto reply = xcb::InternAtomReply::create(globals.connection, cookie, &error.handle()); if (error or not reply.handle()) out = std::unexpected { std::in_place, get_error(as_ref_mut(*error)) }; else { diff --git a/src/wsi/linux/x11/window.cppm b/src/wsi/linux/x11/window.cppm index 99bf3275e..3f1a4c911 100644 --- a/src/wsi/linux/x11/window.cppm +++ b/src/wsi/linux/x11/window.cppm @@ -154,8 +154,7 @@ namespace stormkit::wsi::linux::x11 { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Window::Window(Window&&) noexcept - = default; + inline Window::Window(Window&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// From c47a7335d18467fe2009be230d32f4fed1697e4e Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Mon, 16 Mar 2026 20:43:00 +0100 Subject: [PATCH 172/194] (core) rename some concepts --- modules/stormkit/core/math/linear-matrix.cppm | 7 ++++++- modules/stormkit/core/math/linear-vector.cppm | 14 +++++++++++++- modules/stormkit/core/meta/concepts.cppm | 10 +++++----- modules/stormkit/core/typesafe/safecasts.cppm | 8 ++++---- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/modules/stormkit/core/math/linear-matrix.cppm b/modules/stormkit/core/math/linear-matrix.cppm index f3988bae1..26c1f731b 100644 --- a/modules/stormkit/core/math/linear-matrix.cppm +++ b/modules/stormkit/core/math/linear-matrix.cppm @@ -37,6 +37,11 @@ export { using SizeType = usize; using ExtentType = u8; + using value_type = ValueType; + using storage_type = StorageType; + using size_type = SizeType; + using extent_type = ExtentType; + static constexpr auto EXTENTS = std::array { M, N }; StorageType values; @@ -149,7 +154,7 @@ export { concept IsSquareMat = IsMat and T::EXTENTS[0] == T::EXTENTS[1]; template - concept HasOneMatType = not(core::meta::IsMdspanType and core::meta::IsMdspanType) + concept HasOneMatType = not(core::meta::IsStdMdspan and core::meta::IsStdMdspan) or meta::IsMat or meta::IsMat; } // namespace meta diff --git a/modules/stormkit/core/math/linear-vector.cppm b/modules/stormkit/core/math/linear-vector.cppm index 85c25dcca..e005d8967 100644 --- a/modules/stormkit/core/math/linear-vector.cppm +++ b/modules/stormkit/core/math/linear-vector.cppm @@ -30,6 +30,10 @@ export namespace stormkit { inline namespace core { namespace math { using SizeType = usize; using ExtentType = u8; + using value_type = ValueType; + using size_type = SizeType; + using extent_type = ExtentType; + static constexpr auto EXTENT = std::array { 2uz }; ValueType x; @@ -52,6 +56,10 @@ export namespace stormkit { inline namespace core { namespace math { using SizeType = usize; using ExtentType = u8; + using value_type = ValueType; + using size_type = SizeType; + using extent_type = ExtentType; + static constexpr auto EXTENT = std::array { 3uz }; ValueType x; @@ -75,6 +83,10 @@ export namespace stormkit { inline namespace core { namespace math { using SizeType = usize; using ExtentType = u8; + using value_type = ValueType; + using size_type = SizeType; + using extent_type = ExtentType; + static constexpr auto EXTENT = std::array { 4uz }; ValueType x; @@ -107,7 +119,7 @@ export namespace stormkit { inline namespace core { namespace math { concept IsVec = IsVec2 || IsVec3 || IsVec4; template - concept HasOneVecType = not(core::meta::IsMdspanType and core::meta::IsMdspanType) + concept HasOneVecType = not(core::meta::IsStdMdspan and core::meta::IsStdMdspan) or meta::IsVec or meta::IsVec; } // namespace meta diff --git a/modules/stormkit/core/meta/concepts.cppm b/modules/stormkit/core/meta/concepts.cppm index 1b6a3c9b2..42d6d457c 100644 --- a/modules/stormkit/core/meta/concepts.cppm +++ b/modules/stormkit/core/meta/concepts.cppm @@ -128,19 +128,19 @@ export namespace stormkit { inline namespace core { namespace meta { concept IsStringLike = std::convertible_to; template - concept IsOptionalType = IsSpecializationOf; + concept IsStdOptional = IsSpecializationOf; template - concept IsExpectedType = IsSpecializationOf; + concept IsStdExpected = IsSpecializationOf; template - concept IsVariantType = IsSpecializationOf; + concept IsStdVariant = IsSpecializationOf; template - concept IsMdspanType = IsSpecializationOf; + concept IsStdMdspan = IsSpecializationOf; template - concept IsArrayType = IsSpecializationWithNTTPOf; + concept IsStdArray = IsSpecializationWithNTTPOf; template concept IsStdReferenceWrapper = IsSpecializationOf; diff --git a/modules/stormkit/core/typesafe/safecasts.cppm b/modules/stormkit/core/typesafe/safecasts.cppm index 35cab148e..e5ea5dba4 100644 --- a/modules/stormkit/core/typesafe/safecasts.cppm +++ b/modules/stormkit/core/typesafe/safecasts.cppm @@ -228,11 +228,11 @@ export { //////////////////////////////////////////////////////////////////// /// STL /// //////////////////////////////////////////////////////////////////// - template + template [[nodiscard]] constexpr auto is_impl(const U& value) noexcept -> bool; - template + template [[nodiscard]] constexpr auto as_impl(U&& value, const std::source_location&) noexcept -> meta::ForwardLike; }} // namespace stormkit::core @@ -511,7 +511,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////////////////////////////////// ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE constexpr auto is_impl(const U& value) noexcept -> bool { return std::holds_alternative(value); @@ -519,7 +519,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE constexpr auto as_impl(U&& value, const std::source_location&) noexcept -> meta::ForwardLike { return std::forward_like(std::get(value)); From ad4af6f320b3b6c1b080b161610854ec1efa9aed Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Tue, 17 Mar 2026 18:17:38 +0100 Subject: [PATCH 173/194] (core) implement named_constructors --- modules/stormkit/core.cppm | 1 + .../stormkit/core/containers/shmbuffer.cppm | 97 +++---- modules/stormkit/core/math/geometry.cppm | 6 +- modules/stormkit/core/meta/algorithms.cppm | 45 ++- modules/stormkit/core/meta/concepts.cppm | 12 +- modules/stormkit/core/meta/type_query.cppm | 89 ++++-- modules/stormkit/core/named_constructors.cppm | 200 +++++++++++++ .../stormkit/core/typesafe/checked_value.cppm | 4 +- .../stormkit/core/typesafe/strong_type.cppm | 2 +- modules/stormkit/core/utils/filesystem.cppm | 270 ++++++++++-------- src/core/posix/shmbuffer.cpp | 16 +- src/core/win32/shmbuffer.cpp | 13 +- src/wsi/linux/wayland/context.cpp | 6 +- 13 files changed, 523 insertions(+), 238 deletions(-) create mode 100644 modules/stormkit/core/named_constructors.cppm diff --git a/modules/stormkit/core.cppm b/modules/stormkit/core.cppm index 56488a9c0..22860b658 100644 --- a/modules/stormkit/core.cppm +++ b/modules/stormkit/core.cppm @@ -14,6 +14,7 @@ export import :functional; export import :errors; export import :hash; export import :meta; +export import :named_constructors; export import :math; export import :parallelism; export import :string; diff --git a/modules/stormkit/core/containers/shmbuffer.cppm b/modules/stormkit/core/containers/shmbuffer.cppm index 3c974ff5d..568a08218 100644 --- a/modules/stormkit/core/containers/shmbuffer.cppm +++ b/modules/stormkit/core/containers/shmbuffer.cppm @@ -18,26 +18,16 @@ import :typesafe.integer; import :typesafe.byte; import :functional.monadic; import :utils.contract; +import :named_constructors; +import :utils.filesystem; export namespace stormkit { inline namespace core { - class STORMKIT_CORE_API SHMBuffer { - struct PrivateFuncTag {}; - + class STORMKIT_CORE_API SHMBuffer: public UseNamedConstructors> { public: using ValueType = byte; using value_type = ValueType; - enum class Access : u8 { - READ = 1, - WRITE = 2, - }; - - static auto create(usize size, std::string name) noexcept -> std::expected; - - static auto create_with_access(usize size, std::string name, Access access) noexcept - -> std::expected; - ~SHMBuffer(); SHMBuffer(const SHMBuffer&) = delete; @@ -55,55 +45,36 @@ export namespace stormkit { inline namespace core { auto cend() const noexcept -> decltype(auto); template - auto operator[](this Self&, usize index) noexcept -> meta::ForwardConst&; + auto operator[](this Self&, usize index) noexcept -> meta::ForwardConst&; template - auto at(this Self&, usize index) noexcept -> meta::ForwardConst&; + auto at(this Self&, usize index) noexcept -> meta::ForwardConst&; auto size() const noexcept -> usize; template - auto data(this Self&) noexcept -> meta::ForwardConst*; + auto data(this Self&) noexcept -> std::span>; template auto native_handle(this Self&) noexcept -> meta::ForwardConst*; - auto name() const noexcept -> const std::string&; - auto access() const noexcept -> Access; + auto name() const noexcept -> std::string_view; + auto access() const noexcept -> io::Access; - constexpr SHMBuffer(usize size, std::string name, Access access, PrivateFuncTag) noexcept; + constexpr SHMBuffer(PrivateTag) noexcept; + auto do_init(PrivateTag, usize, std::string, io::Access = io::Access::READ | io::Access::WRITE) noexcept + -> std::expected; private: - auto allocate_buffer() noexcept -> std::expected; - - Access m_access; - void* m_handle = nullptr; - usize m_size; - std::string m_name; - std::span m_data; + io::Access m_access; + void* m_handle = nullptr; + usize m_size; + std::string m_name; + std::span m_data; }; - - FLAG_ENUM(SHMBuffer::Access); }} // namespace stormkit::core namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto SHMBuffer::create(usize size, std::string name) noexcept -> std::expected { - return create_with_access(size, std::move(name), Access::READ | Access::WRITE); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto SHMBuffer::create_with_access(usize size, std::string name, Access access) noexcept - -> std::expected { - auto buffer = SHMBuffer { size, std::move(name), access, PrivateFuncTag {} }; - return buffer.allocate_buffer().transform(core::monadic::consume(buffer)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - constexpr SHMBuffer::SHMBuffer(usize size, std::string name, Access access, PrivateFuncTag) noexcept - : m_access { access }, m_size { size }, m_name { std::move(name) } { + constexpr SHMBuffer::SHMBuffer(PrivateTag) noexcept { } ///////////////////////////////////// @@ -136,7 +107,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - STORMKIT_PURE STORMKIT_FORCE_INLINE + STORMKIT_FORCE_INLINE inline auto SHMBuffer::begin(this Self& self) noexcept -> decltype(auto) { EXPECTS(self.m_handle); return stdr::begin(std::forward(self).m_data); @@ -144,7 +115,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_PURE STORMKIT_FORCE_INLINE + STORMKIT_FORCE_INLINE inline auto SHMBuffer::cbegin() const noexcept -> decltype(auto) { EXPECTS(m_handle); return stdr::cbegin(m_data); @@ -153,7 +124,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - STORMKIT_PURE STORMKIT_FORCE_INLINE + STORMKIT_FORCE_INLINE inline auto SHMBuffer::end(this Self& self) noexcept -> decltype(auto) { EXPECTS(self.m_handle); return stdr::end(std::forward(self).m_data); @@ -161,7 +132,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_PURE STORMKIT_FORCE_INLINE + STORMKIT_FORCE_INLINE inline auto SHMBuffer::cend() const noexcept -> decltype(auto) { EXPECTS(m_handle); return stdr::cend(m_data); @@ -170,8 +141,8 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - STORMKIT_PURE STORMKIT_FORCE_INLINE - inline auto SHMBuffer::operator[](this Self& self, usize index) noexcept -> meta::ForwardConst& { + STORMKIT_FORCE_INLINE + inline auto SHMBuffer::operator[](this Self& self, usize index) noexcept -> meta::ForwardConst& { EXPECTS(self.m_handle); EXPECTS(index < self.m_size); return std::forward(self).m_data[index]; @@ -180,8 +151,8 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - STORMKIT_PURE STORMKIT_FORCE_INLINE - inline auto SHMBuffer::at(this Self& self, usize index) noexcept -> meta::ForwardConst& { + STORMKIT_FORCE_INLINE + inline auto SHMBuffer::at(this Self& self, usize index) noexcept -> meta::ForwardConst& { EXPECTS(self.m_handle); EXPECTS(index < self.m_size); return std::forward(self).m_data.at(index); @@ -189,7 +160,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_PURE STORMKIT_FORCE_INLINE + STORMKIT_FORCE_INLINE inline auto SHMBuffer::size() const noexcept -> usize { return m_size; } @@ -197,31 +168,31 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - STORMKIT_PURE STORMKIT_FORCE_INLINE - inline auto SHMBuffer::data(this Self& self) noexcept -> meta::ForwardConst* { + STORMKIT_FORCE_INLINE + inline auto SHMBuffer::data(this Self& self) noexcept -> std::span> { EXPECTS(self.m_handle); - return stdr::data(std::forward(self).m_data); + return std::forward(self).m_data; } ///////////////////////////////////// ///////////////////////////////////// template - STORMKIT_PURE STORMKIT_FORCE_INLINE + STORMKIT_FORCE_INLINE inline auto SHMBuffer::native_handle(this Self& self) noexcept -> meta::ForwardConst* { return std::forward(self).m_handle; } ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_PURE STORMKIT_FORCE_INLINE - inline auto SHMBuffer::name() const noexcept -> const std::string& { + STORMKIT_FORCE_INLINE + inline auto SHMBuffer::name() const noexcept -> std::string_view { return m_name; } ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_PURE STORMKIT_FORCE_INLINE - inline auto SHMBuffer::access() const noexcept -> Access { + STORMKIT_FORCE_INLINE + inline auto SHMBuffer::access() const noexcept -> io::Access { return m_access; } }} // namespace stormkit::core diff --git a/modules/stormkit/core/math/geometry.cppm b/modules/stormkit/core/math/geometry.cppm index 6cb72a4cb..29d8ae926 100644 --- a/modules/stormkit/core/math/geometry.cppm +++ b/modules/stormkit/core/math/geometry.cppm @@ -20,7 +20,8 @@ import :math.linear.vector; export namespace stormkit { inline namespace core { namespace math { template struct rect { - using ValueType = T; + using ValueType = T; + using value_type = T; ValueType x = ValueType { 0 }; ValueType y = ValueType { 0 }; @@ -43,7 +44,8 @@ export namespace stormkit { inline namespace core { namespace math { template struct bounding_rect { - using ValueType = T; + using ValueType = T; + using value_type = T; ValueType left = ValueType { 0 }; ValueType top = ValueType { 0 }; diff --git a/modules/stormkit/core/meta/algorithms.cppm b/modules/stormkit/core/meta/algorithms.cppm index d00e5cf1f..8a3ef8848 100644 --- a/modules/stormkit/core/meta/algorithms.cppm +++ b/modules/stormkit/core/meta/algorithms.cppm @@ -13,26 +13,49 @@ import std; import :meta.concepts; namespace stormkit { inline namespace core { namespace meta::details { - template + // template class Then, class Arg, class Else> + // struct LazyEvaluation final { + // using type = Else; + // }; + + // template class Then, class Arg, class Else> + // struct LazyEvaluation final { + // using type = Then; + // }; + + // /* + // LazyEvaluationType permet de choisir un type basé sur une condition sans instancier préventivement la branche 'Then'. + // Contrairement à std::conditional::type, qui force l'instanciation de A ET B même si Condition est + // fausse (pouvant causer des erreurs de compilation si une branche est invalide pour les types donnés), + // LazyEvaluationType n'instancie Then que si la condition est vraie. + // */ + // template class Then, class Arg, class Else> + // using LazyEvaluationType = typename LazyEvaluation::type; + + template + struct LazyType { + using Type = T; + }; + template typename, typename, typename> struct If; - template - struct If { - using Type = IfRes; + template typename LazyType, typename Then, typename OrElse> + struct If { + using Type = LazyType::Type; }; - template - struct If { - using Type = ElseRes; + template typename LazyType, typename Then, typename OrElse> + struct If { + using Type = LazyType::Type; }; }}} // namespace stormkit::core::meta::details export namespace stormkit { inline namespace core { namespace meta { - template - using If = details::If::Type; + template + using If = details::If::Type; - template - using Select = std::conditional_t; + template + using Select = std::conditional_t; template class Variant, typename... Ts> constexpr auto variant_type_find_if(const Variant&, Predicate&& predicate) noexcept -> std::size_t; diff --git a/modules/stormkit/core/meta/concepts.cppm b/modules/stormkit/core/meta/concepts.cppm index 42d6d457c..05c6ee51d 100644 --- a/modules/stormkit/core/meta/concepts.cppm +++ b/modules/stormkit/core/meta/concepts.cppm @@ -202,9 +202,17 @@ export namespace stormkit { inline namespace core { namespace meta { template concept AreIndirections = ((IsLValueReference or IsPointer) and ...); + template + concept HasElementType = requires() { typename T::ElementType; } or requires() { typename T::element_type; }; + + template + concept HasValueType = requires() { typename T::ValueType; } or requires() { typename T::value_type; }; + + template + concept HasExpectedType = requires() { typename T::ExpectedType; } and IsStdExpected; + template - concept IsContainer = requires(T& val) { - typename T::value_type; + concept IsContainer = HasValueType and requires(T& val) { { val.operator*() } -> IsReferenceTo; { val.operator->() } -> IsReferenceTo; }; diff --git a/modules/stormkit/core/meta/type_query.cppm b/modules/stormkit/core/meta/type_query.cppm index 11df747d9..04b777c93 100644 --- a/modules/stormkit/core/meta/type_query.cppm +++ b/modules/stormkit/core/meta/type_query.cppm @@ -26,28 +26,6 @@ namespace stormkit { inline namespace core { namespace meta { template struct UnderlyingType; - template - concept HasValueType = requires() { typename T::ValueType; }; - - template - concept HasStdValueType = requires() { typename T::value_type; }; - - template - struct UnderlyingType { - using Type = typename T::ValueType; - }; - - template - requires(not HasValueType) - struct UnderlyingType { - using Type = typename T::value_type; - }; - - template - struct UnderlyingType { - using Type = std::underlying_type_t; - }; - template struct PointerType; @@ -95,11 +73,64 @@ namespace stormkit { inline namespace core { namespace meta { template struct ContainedOrPointedType: PointedType {}; + + template + struct ReturnType; + + template + struct ReturnType { + using Type = R; + }; + + template + struct ReturnType { + using Type = R; + }; + + template + concept HasStdValueType = requires() { typename T::value_type; }; + + template + concept HasValueType = requires() { typename T::ValueType; }; + + template + struct ValueType; + + template + struct ValueType { + using Type = typename T::ValueType; + }; + + template + requires(not HasValueType) + struct ValueType { + using Type = typename T::value_type; + }; + + template + concept HasStdElementType = requires() { typename T::element_type; }; + + template + concept HasElementType = requires() { typename T::ElementType; }; + + template + struct ElementType; + + template + struct ElementType { + using Type = typename T::ElementType; + }; + + template + requires(not HasElementType) + struct ElementType { + using Type = typename T::element_type; + }; } // namespace details export { template - using UnderlyingType = details::UnderlyingType::Type; + using UnderlyingType = std::underlying_type_t; template using PointerType = details::PointerType::Type; @@ -113,6 +144,18 @@ namespace stormkit { inline namespace core { namespace meta { template using ContainedOrPointedType = details::ContainedOrPointedType::Type; + template + using ReturnType = details::ReturnType::Type; + + template + using ExpectedType = typename T::ExpectedType; + + template + using ElementType = details::ElementType::Type; + + template + using ValueType = details::ValueType::Type; + template using IteratorType = stdr::iterator_t; diff --git a/modules/stormkit/core/named_constructors.cppm b/modules/stormkit/core/named_constructors.cppm new file mode 100644 index 000000000..5b7d02357 --- /dev/null +++ b/modules/stormkit/core/named_constructors.cppm @@ -0,0 +1,200 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include +#include + +export module stormkit.core:named_constructors; + +import std; + +import :meta; +import :utils.allocation; + +namespace stormkit { inline namespace core { + export { + struct TemplatedNamedConstructorHelper { + protected: + static constexpr struct PrivateTag { + } PRIVATE; + + template + friend class UseNamedConstructors; + }; + + namespace meta { + template + concept HasCreateAllocateProtected = requires() { + { T::CREATE_ALLOCATE_PROTECTED } -> IsBooleanTestable; + } and T::CREATE_ALLOCATE_PROTECTED; + + template + concept DoInitHasExpectedType = IsStdExpected>; + + template + using DoInitExpectedType = ReturnType; + + template + using TransformExpectedValueTo = std::expected; + } // namespace meta + } + + export { + template, meta::DoInitExpectedType, void>, + typename... ConstructorArgs> + class UseNamedConstructors { + using ValueType = T; + using RetType = DoInitRetType; + + public: + constexpr ~UseNamedConstructors() noexcept; + + constexpr UseNamedConstructors(const UseNamedConstructors&) noexcept; + constexpr auto operator=(const UseNamedConstructors&) noexcept -> UseNamedConstructors&; + + constexpr UseNamedConstructors(UseNamedConstructors&&) noexcept; + constexpr auto operator=(UseNamedConstructors&&) noexcept -> UseNamedConstructors&; + + template + requires(meta::IsStdExpected) + [[nodiscard]] + static constexpr auto create(ConstructorArgs... c_args, Args&&... args) noexcept + -> meta::TransformExpectedValueTo; + + template + requires(not meta::IsStdExpected) + [[nodiscard]] + static constexpr auto create(ConstructorArgs... c_args, Args&&... args) noexcept -> ValueType; + + template + requires(meta::IsStdExpected) + [[nodiscard]] + static constexpr auto allocate(ConstructorArgs... c_args, Args&&... args) noexcept + -> meta::TransformExpectedValueTo, RetType>; + + template + requires(not meta::IsStdExpected) + [[nodiscard]] + static constexpr auto allocate(ConstructorArgs... c_args, Args&&... args) noexcept -> Heap; + + protected: + using PrivateTag = TemplatedNamedConstructorHelper::PrivateTag; + static constexpr auto PRIVATE = TemplatedNamedConstructorHelper::PRIVATE; + + constexpr UseNamedConstructors() noexcept; + }; + } +}} // namespace stormkit::core + +//////////////////////////////////////////////////////////////////// +/// IMPLEMENTATION /// +//////////////////////////////////////////////////////////////////// + +namespace stormkit { inline namespace core { + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr UseNamedConstructors::UseNamedConstructors() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr UseNamedConstructors::~UseNamedConstructors() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto UseNamedConstructors::operator=(const UseNamedConstructors&) noexcept + -> UseNamedConstructors& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr UseNamedConstructors:: + UseNamedConstructors(const UseNamedConstructors&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto UseNamedConstructors::operator=(UseNamedConstructors&&) noexcept + -> UseNamedConstructors& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr UseNamedConstructors:: + UseNamedConstructors(UseNamedConstructors&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + template + requires(meta::IsStdExpected) + STORMKIT_FORCE_INLINE + constexpr auto UseNamedConstructors::create(ConstructorArgs... c_args, + Args&&... args) noexcept + -> meta::TransformExpectedValueTo { + using ReturnValue = meta::TransformExpectedValueTo; + + auto out_expected = ReturnValue { std::in_place, PRIVATE, c_args... }; + if (auto result = out_expected.value().do_init(PRIVATE, std::forward(args)...); not result) + out_expected = ReturnValue { std::unexpect, std::move(result).error() }; + + return out_expected; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + template + requires(not meta::IsStdExpected) + STORMKIT_FORCE_INLINE + constexpr auto UseNamedConstructors::create(ConstructorArgs... c_args, + Args&&... args) noexcept -> ValueType { + auto out = ValueType { PRIVATE, c_args... }; + out.do_init(PRIVATE, std::forward(args)...); + return out; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + template + requires(meta::IsStdExpected) + STORMKIT_FORCE_INLINE + constexpr auto UseNamedConstructors::allocate(ConstructorArgs... c_args, + Args&&... args) noexcept + -> meta::TransformExpectedValueTo, RetType> { + using ReturnValue = meta::TransformExpectedValueTo, RetType>; + + auto out_expected = ReturnValue { std::in_place, core::allocate_unsafe(PRIVATE, c_args...) }; + if (auto result = out_expected.value().do_init(PRIVATE, std::forward(args)...); not result) + out_expected = ReturnValue { std::unexpect, std::move(result).error() }; + + return out_expected; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + template + requires(not meta::IsStdExpected) + STORMKIT_FORCE_INLINE + constexpr auto UseNamedConstructors::allocate(ConstructorArgs... c_args, + Args&&... args) noexcept + -> Heap { + auto out = core::allocate_unsafe(PRIVATE, c_args...); + out->do_init(PRIVATE, std::forward(args)...); + return out; + } +}} // namespace stormkit::core diff --git a/modules/stormkit/core/typesafe/checked_value.cppm b/modules/stormkit/core/typesafe/checked_value.cppm index 6f6969824..fdd44704a 100644 --- a/modules/stormkit/core/typesafe/checked_value.cppm +++ b/modules/stormkit/core/typesafe/checked_value.cppm @@ -27,10 +27,10 @@ namespace stormkit { inline namespace core { namespace meta { template - concept IsCheckedValueArithmetic = meta::IsArithmetic>>; + concept IsCheckedValueArithmetic = meta::IsArithmetic>>; template - concept IsCheckedValueValueType = meta::PlainIs>>; + concept IsCheckedValueValueType = meta::PlainIs>>; } // namespace meta }} // namespace stormkit::core diff --git a/modules/stormkit/core/typesafe/strong_type.cppm b/modules/stormkit/core/typesafe/strong_type.cppm index b6d2af019..8abbd2ca8 100644 --- a/modules/stormkit/core/typesafe/strong_type.cppm +++ b/modules/stormkit/core/typesafe/strong_type.cppm @@ -18,7 +18,7 @@ export { namespace stormkit { inline namespace core { struct ArithmeticTag { template - using Type = meta::UnderlyingType>; + using Type = meta::ValueType>; template constexpr auto operator+(this Self&& self, meta::PlainIs> auto&& other) noexcept diff --git a/modules/stormkit/core/utils/filesystem.cppm b/modules/stormkit/core/utils/filesystem.cppm index 0c2414bff..bdd13cdf0 100644 --- a/modules/stormkit/core/utils/filesystem.cppm +++ b/modules/stormkit/core/utils/filesystem.cppm @@ -37,6 +37,7 @@ import :utils.contract; import :typesafe; import :functional; import :meta; +import :named_constructors; // import :containers; namespace stdfs = std::filesystem; @@ -59,75 +60,85 @@ namespace stormkit { inline namespace core { namespace io::meta { }}} // namespace stormkit::core::io::meta export { - namespace stormkit { inline namespace core { namespace io { - template - using Expected = std::expected; + namespace stormkit { inline namespace core { + namespace io { + template + using Expected = std::expected; + + enum class Access { + READ, + WRITE, + }; - enum class Access { - READ, - WRITE, - }; + template + class Descriptor; + } // namespace io - template - class Descriptor { - struct PrivateFuncTag {}; + namespace io { + template + class Descriptor final: TemplatedNamedConstructorHelper, + protected UseNamedConstructors, Expected> { + public: + static auto open(const stdfs::path& path, Access access) noexcept -> Expected; + static auto allocate_and_open(const stdfs::path& path, Access access) noexcept -> Expected; - public: - static auto open(const stdfs::path& path, Access access) noexcept -> Expected; - auto close() noexcept; + ~Descriptor() noexcept; - ~Descriptor() noexcept; + Descriptor(Descriptor&) = delete; + auto operator=(Descriptor&) -> Descriptor& = delete; - Descriptor(Descriptor&) = delete; - auto operator=(Descriptor&) -> Descriptor& = delete; + Descriptor(Descriptor&&) noexcept; + auto operator=(Descriptor&&) noexcept -> Descriptor&; - Descriptor(Descriptor&&) noexcept; - auto operator=(Descriptor&&) noexcept -> Descriptor&; + auto close() noexcept; - auto read_to(std::span out) noexcept -> Expected; - auto read_to(std::span out) noexcept -> Expected - requires(mode == Mode::UTF8 or mode == Mode::AINSI); - auto read_to(std::span out) noexcept -> Expected - requires(mode == Mode::WIDE); + auto read_to(std::span out) noexcept -> Expected; + auto read_to(std::span out) noexcept -> Expected + requires(mode == Mode::UTF8 or mode == Mode::AINSI); + auto read_to(std::span out) noexcept -> Expected + requires(mode == Mode::WIDE); - auto write(std::span bytes) noexcept -> Expected; - auto write(std::span bytes) noexcept -> Expected - requires(mode == Mode::UTF8 or mode == Mode::AINSI); - auto write(std::span bytes) noexcept -> Expected - requires(mode == Mode::WIDE); + auto write(std::span bytes) noexcept -> Expected; + auto write(std::span bytes) noexcept -> Expected + requires(mode == Mode::UTF8 or mode == Mode::AINSI); + auto write(std::span bytes) noexcept -> Expected + requires(mode == Mode::WIDE); - auto flush() noexcept -> void; + auto flush() noexcept -> void; - auto position() const noexcept -> usize; - auto size() const noexcept -> usize; + auto position() const noexcept -> usize; + auto size() const noexcept -> usize; - auto native_descriptor() const noexcept -> int; + auto native_descriptor() const noexcept -> int; - Descriptor(PrivateFuncTag, int descriptor) noexcept; + Descriptor(PrivateTag) noexcept; + auto do_init(PrivateTag, const stdfs::path&, Access) noexcept -> Expected; - private: - int m_descriptor = 0; + private: + int m_descriptor = 0; - mutable std::atomic m_size = 0; - }; + mutable std::atomic m_size = 0; + }; - using File = Descriptor; - template - requires(mode != Mode::BINARY) - using TextFile = Descriptor; + using File = Descriptor; + template + requires(mode != Mode::BINARY) + using TextFile = Descriptor; - template - auto read_text_to(const stdfs::path& path, std::span> output) noexcept -> Expected; - template - auto read_text(const stdfs::path& path) noexcept -> Expected>>; + template + auto read_text_to(const stdfs::path& path, std::span> output) noexcept -> Expected; + template + auto read_text(const stdfs::path& path) noexcept -> Expected>>; - auto read_to(const stdfs::path& path, std::span output) noexcept -> Expected; - auto read(const stdfs::path& path) noexcept -> Expected>; + auto read_to(const stdfs::path& path, std::span output) noexcept -> Expected; + auto read(const stdfs::path& path) noexcept -> Expected>; - template - auto write_text(const stdfs::path& path, std::span> data) noexcept -> Expected; - auto write(const stdfs::path& path, std::span data) noexcept -> Expected; - }}} // namespace stormkit::core::io + template + auto write_text(const stdfs::path& path, std::span> data) noexcept + -> Expected; + auto write(const stdfs::path& path, std::span data) noexcept -> Expected; + } // namespace io + }} // namespace stormkit::core FLAG_ENUM(stormkit::core::io::Access); } // namespace stormkit::core::io @@ -139,75 +150,11 @@ export { namespace stdr = std::ranges; namespace stormkit { inline namespace core { namespace io { - //////////////////////////////////////// - //////////////////////////////////////// - template - inline auto Descriptor::open(const stdfs::path& path, Access access) noexcept -> Expected> { - if (access == Access::READ and not stdfs::exists(path)) - return std::unexpected { SystemError { .code = std::errc::no_such_file_or_directory } }; - if (stdfs::is_directory(path)) return std::unexpected { SystemError { .code = std::errc::is_a_directory } }; - - const auto posix_access = [&access]() noexcept { -#ifdef STORMKIT_OS_WINDOWS - if (access == Access::READ) return _O_RDONLY; - else if (access == Access::WRITE) - return (_O_WRONLY | _O_CREAT); - else - return _O_RDWR; -#else - if (access == Access::READ) return O_RDONLY; - else if (access == Access::WRITE) - return O_WRONLY | O_CREAT; - else - return O_RDWR; -#endif - std::unreachable(); - }(); - -#ifdef STORMKIT_OS_WINDOWS - const auto text_mode = []() noexcept { - switch (mode) { - #ifdef STORMKIT_OS_WINDOWS - case Mode::BINARY: return _O_BINARY; - case Mode::AINSI: [[fallthrough]]; - case Mode::UTF8: return _O_TEXT; - case Mode::WIDE: return _O_WTEXT; - default: break; - #else - default: return 0; - #endif - }; - std::unreachable(); - }(); - - auto ret = 0; - auto str = path.string(); - const auto // - err = _sopen_s(&ret, str.c_str(), posix_access | text_mode, _SH_DENYNO, _S_IREAD); - if (err != 0) return std::unexpected { SystemError::from_errno() }; -#else - const auto ret = ::open(path.c_str(), posix_access); - if (ret == -1) return std::unexpected { SystemError::from_errno() }; -#endif - return Expected> { std::in_place, PrivateFuncTag {}, ret }; - } - //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Descriptor::close() noexcept { - if (m_descriptor != 0) { - flush(); -#ifdef STORMKIT_OS_WINDOWS - _close -#else - ::close -#endif - (m_descriptor); - m_descriptor = 0; - m_size = 0; - } + inline Descriptor::Descriptor(PrivateTag) noexcept { } //////////////////////////////////////// @@ -239,6 +186,44 @@ namespace stormkit { inline namespace core { namespace io { m_descriptor = std::exchange(other.m_descriptor, 0); m_size = other.m_size.load(); other.m_size.store(0); + + return *this; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Descriptor::open(const stdfs::path& path, Access access) noexcept -> Expected> { + auto descriptor = Try(Descriptor::create(path, access)); + Return descriptor; + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Descriptor::allocate_and_open(const stdfs::path& path, Access access) noexcept + -> Expected> { + Return Try(Descriptor::allocate(path, access)); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Descriptor::close() noexcept { + if (m_descriptor != 0) { + flush(); +#ifdef STORMKIT_OS_WINDOWS + _close +#else + ::close +#endif + (m_descriptor); + m_descriptor = 0; + m_size = 0; + } } //////////////////////////////////////// @@ -353,7 +338,6 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// //////////////////////////////////////// template - STORMKIT_FORCE_INLINE inline auto Descriptor::size() const noexcept -> usize { EXPECTS(m_descriptor != 0); if (m_size == 0) { @@ -384,9 +368,55 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// //////////////////////////////////////// template - STORMKIT_FORCE_INLINE - inline Descriptor::Descriptor(PrivateFuncTag, int descriptor) noexcept - : m_descriptor { descriptor } { + inline auto Descriptor::do_init(PrivateTag, const stdfs::path& path, Access access) noexcept -> Expected { + if (access == Access::READ and not stdfs::exists(path)) + return std::unexpected { SystemError { .code = std::errc::no_such_file_or_directory } }; + if (stdfs::is_directory(path)) return std::unexpected { SystemError { .code = std::errc::is_a_directory } }; + + const auto posix_access = [&access]() noexcept { +#ifdef STORMKIT_OS_WINDOWS + if (access == Access::READ) return _O_RDONLY; + else if (access == Access::WRITE) + return (_O_WRONLY | _O_CREAT); + else + return _O_RDWR; +#else + if (access == Access::READ) return O_RDONLY; + else if (access == Access::WRITE) + return O_WRONLY | O_CREAT; + else + return O_RDWR; +#endif + std::unreachable(); + }(); + +#ifdef STORMKIT_OS_WINDOWS + const auto text_mode = []() noexcept { + switch (mode) { + #ifdef STORMKIT_OS_WINDOWS + case Mode::BINARY: return _O_BINARY; + case Mode::AINSI: [[fallthrough]]; + case Mode::UTF8: return _O_TEXT; + case Mode::WIDE: return _O_WTEXT; + default: break; + #else + default: return 0; + #endif + }; + std::unreachable(); + }(); + + auto ret = 0; + auto str = path.string(); + const auto // + err = _sopen_s(&ret, str.c_str(), posix_access | text_mode, _SH_DENYNO, _S_IREAD); + if (err != 0) return std::unexpected { SystemError::from_errno() }; +#else + const auto ret = ::open(path.c_str(), posix_access); + if (ret == -1) return std::unexpected { SystemError::from_errno() }; +#endif + m_descriptor = ret; + return {}; } //////////////////////////////////////// diff --git a/src/core/posix/shmbuffer.cpp b/src/core/posix/shmbuffer.cpp index 5fe0c002b..b41215883 100644 --- a/src/core/posix/shmbuffer.cpp +++ b/src/core/posix/shmbuffer.cpp @@ -30,13 +30,17 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - auto SHMBuffer::allocate_buffer() noexcept -> std::expected { - const auto shm_access = (check_flag_bit(m_access, Access::WRITE) ? O_RDWR : O_RDONLY) + auto SHMBuffer::do_init(PrivateTag, usize size, std::string name, io::Access access) noexcept + -> std::expected { + m_size = size; + m_name = std::move(name); + m_access = access; + const auto shm_access = (check_flag_bit(m_access, io::Access::WRITE) ? O_RDWR : O_RDONLY) | ((m_handle != nullptr) ? O_TRUNC : O_CREAT); const auto mode = init_by([access = m_access](auto& mode) noexcept { - if (check_flag_bit(access, Access::READ)) mode |= S_IRUSR; - if (check_flag_bit(access, Access::WRITE)) mode |= S_IWUSR; + if (check_flag_bit(access, io::Access::READ)) mode |= S_IRUSR; + if (check_flag_bit(access, io::Access::WRITE)) mode |= S_IWUSR; }); m_handle = std::bit_cast(iptr { shm_open(stdr::data(m_name), shm_access, mode) }); @@ -53,8 +57,8 @@ namespace stormkit { inline namespace core { }; const auto prot_access = init_by([access = m_access](auto& prot_access) noexcept { - if (check_flag_bit(access, Access::READ)) prot_access |= PROT_READ; - if (check_flag_bit(access, Access::WRITE)) prot_access |= PROT_WRITE; + if (check_flag_bit(access, io::Access::READ)) prot_access |= PROT_READ; + if (check_flag_bit(access, io::Access::WRITE)) prot_access |= PROT_WRITE; }); auto buf = mmap(nullptr, m_size, prot_access, MAP_SHARED, fd, 0); diff --git a/src/core/win32/shmbuffer.cpp b/src/core/win32/shmbuffer.cpp index 70ad0d1e8..cfacf1e5d 100644 --- a/src/core/win32/shmbuffer.cpp +++ b/src/core/win32/shmbuffer.cpp @@ -26,9 +26,12 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - auto SHMBuffer::allocate_buffer() noexcept -> std::expected { - const auto page_access = (check_flag_bit(m_access, Access::WRITE) ? PAGE_READWRITE - : PAGE_READONLY); + auto SHMBuffer::do_init(PrivateTag, usize size, std::string name, io::Access access) noexcept + -> std::expected { + m_size = size; + m_name = std::move(name); + m_access = access; + const auto page_access = (check_flag_bit(m_access, io::Access::WRITE) ? PAGE_READWRITE : PAGE_READONLY); // TODO handle reallocation m_handle = ::CreateFileMapping(INVALID_HANDLE_VALUE, @@ -43,8 +46,8 @@ namespace stormkit { inline namespace core { }; const auto file_access = init_by([access = m_access](auto& file_access) noexcept { - if (check_flag_bit(access, Access::READ)) file_access |= FILE_MAP_READ; - if (check_flag_bit(access, Access::WRITE)) file_access |= FILE_MAP_WRITE; + if (check_flag_bit(access, io::Access::READ)) file_access |= FILE_MAP_READ; + if (check_flag_bit(access, io::Access::WRITE)) file_access |= FILE_MAP_WRITE; }); auto buf = ::MapViewOfFile(m_handle, file_access, 0, 0, as(m_size)); diff --git a/src/wsi/linux/wayland/context.cpp b/src/wsi/linux/wayland/context.cpp index 91e96a760..f12ef8f03 100644 --- a/src/wsi/linux/wayland/context.cpp +++ b/src/wsi/linux/wayland/context.cpp @@ -95,7 +95,7 @@ namespace stormkit::wsi::linux::wayland::wl { constexpr auto make_binder() noexcept -> decltype(auto) { return [](Globals& _globals, void* ptr) static noexcept { using U = meta::ToPlainType; - (_globals.*member) = U::take(std::bit_cast>(ptr)); + (_globals.*member) = U::take(std::bit_cast>(ptr)); }; } @@ -105,8 +105,8 @@ namespace stormkit::wsi::linux::wayland::wl { constexpr auto make_binder_to_array() noexcept -> decltype(auto) { return [](Globals& _globals, void* ptr) static noexcept { using Vec = meta::ToPlainType; - using U = meta::UnderlyingType; - (_globals.*member).push_back(U::take(std::bit_cast>(ptr))); + using U = meta::ValueType; + (_globals.*member).push_back(U::take(std::bit_cast>(ptr))); }; } From 33055c40a70aaa54e382a011a02f17416ba11f68 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 25 Mar 2026 21:56:26 +0100 Subject: [PATCH 174/194] (gpu) use named constructors --- examples/gpu/common/app.cppm | 3 +- examples/gpu/imgui/src/main.cpp | 14 +- examples/gpu/textured_cube/src/main.cpp | 26 +- examples/gpu/triangle/src/main.cpp | 13 +- modules/stormkit/gpu/core.cppm | 3 +- modules/stormkit/gpu/core/base.cppm | 687 +++-- modules/stormkit/gpu/core/debug_callback.cppm | 70 +- modules/stormkit/gpu/core/device.cppm | 431 +-- modules/stormkit/gpu/core/instance.cppm | 467 ++- modules/stormkit/gpu/core/meta.cppm | 78 + modules/stormkit/gpu/core/objects.cppm | 208 ++ .../stormkit/gpu/core/physical_device.cppm | 484 ---- modules/stormkit/gpu/core/surface.cppm | 96 +- modules/stormkit/gpu/core/sync.cppm | 195 +- modules/stormkit/gpu/execution.cppm | 1 + .../gpu/execution/command_buffer.cppm | 988 +++---- .../stormkit/gpu/execution/descriptors.cppm | 570 ++-- modules/stormkit/gpu/execution/objects.cppm | 267 ++ modules/stormkit/gpu/execution/pipeline.cppm | 405 +-- .../stormkit/gpu/execution/render_pass.cppm | 471 ++-- modules/stormkit/gpu/execution/swapchain.cppm | 160 +- modules/stormkit/gpu/resource.cppm | 1 + modules/stormkit/gpu/resource/buffer.cppm | 423 +-- modules/stormkit/gpu/resource/image.cppm | 684 ++--- modules/stormkit/gpu/resource/objects.cppm | 123 + modules/stormkit/gpu/resource/shader.cppm | 224 +- src/gpu/core/debug_callback.cpp | 8 +- src/gpu/core/device.cpp | 175 +- src/gpu/core/fence.cpp | 117 +- src/gpu/core/instance.cpp | 28 +- src/gpu/core/physical_device.cpp | 608 ++-- src/gpu/core/semaphore.cpp | 14 +- src/gpu/core/surface.cpp | 11 +- src/gpu/execution/command_buffer.cpp | 2508 ++++++----------- src/gpu/execution/command_pool.cpp | 96 +- src/gpu/execution/descriptor_pool.cpp | 99 +- src/gpu/execution/descriptor_set.cpp | 153 +- src/gpu/execution/descriptor_set_layout.cpp | 10 +- src/gpu/execution/frame_buffer.cpp | 12 +- src/gpu/execution/pipeline.cpp | 35 +- src/gpu/execution/pipeline_cache.cpp | 27 +- src/gpu/execution/pipeline_layout.cpp | 13 +- src/gpu/execution/queue.cpp | 346 +-- src/gpu/execution/render_pass.cpp | 21 +- src/gpu/execution/swapchain.cpp | 73 +- src/gpu/resource/buffer.cpp | 192 +- src/gpu/resource/image.cpp | 7 +- src/gpu/resource/image_view.cpp | 13 +- src/gpu/resource/sampler.cpp | 7 +- src/gpu/resource/shader.cpp | 42 +- 50 files changed, 5127 insertions(+), 6580 deletions(-) create mode 100644 modules/stormkit/gpu/core/meta.cppm create mode 100644 modules/stormkit/gpu/core/objects.cppm delete mode 100644 modules/stormkit/gpu/core/physical_device.cppm create mode 100644 modules/stormkit/gpu/execution/objects.cppm create mode 100644 modules/stormkit/gpu/resource/objects.cppm diff --git a/examples/gpu/common/app.cppm b/examples/gpu/common/app.cppm index 39713cc88..ec59caf15 100644 --- a/examples/gpu/common/app.cppm +++ b/examples/gpu/common/app.cppm @@ -128,7 +128,8 @@ export namespace base { // create swapchain const auto window_extent = m_window->extent(); - m_swapchain = TryAssert(gpu::SwapChain::create(m_device, m_surface, window_extent), "Failed to create swapchain"); + m_swapchain = TryAssert(gpu::SwapChain::create(m_device, gpu::as_view(m_surface), window_extent), + "Failed to create swapchain"); const auto queue_entries = m_device->queue_entries(); const auto it = stdr::find_if(queue_entries, gpu::monadic::find_queue()); diff --git a/examples/gpu/imgui/src/main.cpp b/examples/gpu/imgui/src/main.cpp index 28d819592..681b21085 100644 --- a/examples/gpu/imgui/src/main.cpp +++ b/examples/gpu/imgui/src/main.cpp @@ -30,9 +30,9 @@ struct SubmissionResource { }; struct SwapchainImageResource { - ref image; - gpu::ImageView view; - gpu::Semaphore render_finished; + gpu::view::Image image; + gpu::ImageView view; + gpu::Semaphore render_finished; }; namespace { @@ -85,7 +85,7 @@ class Application: public base::Application { auto view = TryAssert(gpu::ImageView::create(m_device, swap_image), "Failed to create swapchain image view!"); m_image_resources - .push_back({ .image = as_ref(swap_image), + .push_back({ .image = swap_image, .view = std::move(view), .render_finished = TryAssert(gpu::Semaphore::create(m_device), "Failed to create render " @@ -226,7 +226,7 @@ class Application: public base::Application { const auto window_extent = m_window->extent().to(); const auto rendering_info = gpu::RenderingInfo { .render_area = { .x = 0, .y = 0, .width = window_extent.width, .height = window_extent.height }, - .color_attachments = { { .image_view = as_ref(swapchain_image_resource.view), + .color_attachments = { { .image_view = swapchain_image_resource.view, .layout = gpu::ImageLayout::ATTACHMENT_OPTIMAL, .clear_value = gpu::ClearColor { .color = colors::SILVER } } } }; @@ -236,7 +236,7 @@ class Application: public base::Application { TryAssert(render_cmb.reset(), std::format("Failed to reset render cmb {}!", image_index)); TryDiscardAssert((render_cmb.record([&](auto cmb) noexcept { cmb - .transition_image_layout(gpu::as_view(swapchain_image_resource.image), + .transition_image_layout(swapchain_image_resource.image, gpu::ImageLayout::PRESENT_SRC, gpu::ImageLayout::ATTACHMENT_OPTIMAL) .begin_debug_region("Render imgui") @@ -247,7 +247,7 @@ class Application: public base::Application { cmb .end_rendering() // .end_debug_region() - .transition_image_layout(gpu::as_view(swapchain_image_resource.image), + .transition_image_layout(swapchain_image_resource.image, gpu::ImageLayout::ATTACHMENT_OPTIMAL, gpu::ImageLayout::PRESENT_SRC); })), diff --git a/examples/gpu/textured_cube/src/main.cpp b/examples/gpu/textured_cube/src/main.cpp index c04a29528..f6a5dc6d7 100644 --- a/examples/gpu/textured_cube/src/main.cpp +++ b/examples/gpu/textured_cube/src/main.cpp @@ -41,11 +41,11 @@ struct SubmissionResource { }; struct SwapchainImageResource { - ref image; - gpu::ImageView view; - gpu::Image depth_image; - gpu::ImageView depth_view; - gpu::Semaphore render_finished; + gpu::view::Image image; + gpu::ImageView view; + gpu::Image depth_image; + gpu::ImageView depth_view; + gpu::Semaphore render_finished; }; struct Vertex { @@ -280,7 +280,7 @@ class Application: public base::Application { .transition_image_layout(m_texture, gpu::ImageLayout::UNDEFINED, gpu::ImageLayout::TRANSFER_DST_OPTIMAL) - .copy_buffer_to_image(staging_buffer, m_texture, as_view(copy)) + .copy_buffer_to_image(staging_buffer, m_texture, copy) .end_debug_region() .begin_debug_region("Transition texture data") .transition_image_layout(m_texture, @@ -326,8 +326,8 @@ class Application: public base::Application { gpu::ImageDescriptor { .binding = 1, .layout = gpu::ImageLayout::SHADER_READ_ONLY_OPTIMAL, - .image_view = gpu::as_view(m_texture_view), - .sampler = gpu::as_view(m_sampler), + .image_view = m_texture_view, + .sampler = m_sampler, } }; res.descriptor_set.update(sets); @@ -360,7 +360,7 @@ class Application: public base::Application { "Failed to create depth image view!"); m_image_resources - .push_back({ .image = as_ref(swap_image), + .push_back({ .image = swap_image, .view = std::move(view), .depth_image = std::move(depth_image), .depth_view = std::move(depth_view), @@ -470,10 +470,10 @@ class Application: public base::Application { const auto rendering_info = gpu::RenderingInfo { .render_area = { .x = 0, .y = 0, .width = window_extent.to().width, .height = window_extent.to().height }, - .color_attachments = { { .image_view = as_ref(swapchain_image_resource.view), + .color_attachments = { { .image_view = swapchain_image_resource.view, .layout = gpu::ImageLayout::ATTACHMENT_OPTIMAL, .clear_value = gpu::ClearColor { .color = colors::SILVER } } }, - .depth_attachment = { { .image_view = as_ref(swapchain_image_resource.depth_view), + .depth_attachment = { { .image_view = swapchain_image_resource.depth_view, .layout = gpu::ImageLayout::ATTACHMENT_OPTIMAL, .clear_value = gpu::ClearDepthStencil {} } } }; @@ -485,7 +485,7 @@ class Application: public base::Application { TryAssert(render_cmb.reset(), std::format("Failed to reset render cmb {}!", image_index)); TryDiscardAssert((render_cmb.record([&](auto cmb) noexcept { cmb - .transition_image_layout(gpu::as_view(swapchain_image_resource.image), + .transition_image_layout(swapchain_image_resource.image, gpu::ImageLayout::PRESENT_SRC, gpu::ImageLayout::ATTACHMENT_OPTIMAL) .begin_debug_region("Render cube") @@ -496,7 +496,7 @@ class Application: public base::Application { .draw(stdr::size(VERTICES)) .end_rendering() .end_debug_region() - .transition_image_layout(gpu::as_view(swapchain_image_resource.image), + .transition_image_layout(swapchain_image_resource.image, gpu::ImageLayout::ATTACHMENT_OPTIMAL, gpu::ImageLayout::PRESENT_SRC); })), diff --git a/examples/gpu/triangle/src/main.cpp b/examples/gpu/triangle/src/main.cpp index 60b5e50d3..21e80da16 100644 --- a/examples/gpu/triangle/src/main.cpp +++ b/examples/gpu/triangle/src/main.cpp @@ -65,13 +65,6 @@ class Application: public base::Application { .extent = window_extent, }; - static_assert(meta::SameAs); - static_assert(meta::SameAs>); - static_assert(meta::SameAs>); - static_assert(meta::SameAs>); - const auto state = gpu::RasterPipelineState { .input_assembly_state = { .topology = gpu::PrimitiveTopology::TRIANGLE_LIST, }, .viewport_state = { .viewports = { window_viewport }, @@ -177,7 +170,7 @@ class Application: public base::Application { const auto window_extent = m_window->extent().to(); const auto rendering_info = gpu::RenderingInfo { .render_area = { .x = 0, .y = 0, .width = window_extent.width, .height = window_extent.height }, - .color_attachments = { { .image_view = as_ref(swapchain_image_resource.view), + .color_attachments = { { .image_view = swapchain_image_resource.view, .layout = gpu::ImageLayout::ATTACHMENT_OPTIMAL, .clear_value = gpu::ClearColor { .color = colors::SILVER } } } }; @@ -187,7 +180,7 @@ class Application: public base::Application { TryAssert(render_cmb.reset(), std::format("Failed to reset render cmb {}!", image_index)); TryDiscardAssert((render_cmb.record([&](auto cmb) noexcept { cmb - .transition_image_layout(gpu::as_view(swapchain_image_resource.image), + .transition_image_layout(swapchain_image_resource.image, gpu::ImageLayout::PRESENT_SRC, gpu::ImageLayout::ATTACHMENT_OPTIMAL) .begin_debug_region("Render triangle") @@ -196,7 +189,7 @@ class Application: public base::Application { .draw(3) .end_rendering() .end_debug_region() - .transition_image_layout(gpu::as_view(swapchain_image_resource.image), + .transition_image_layout(swapchain_image_resource.image, gpu::ImageLayout::ATTACHMENT_OPTIMAL, gpu::ImageLayout::PRESENT_SRC); })), diff --git a/modules/stormkit/gpu/core.cppm b/modules/stormkit/gpu/core.cppm index 118ef0c6b..54f568fee 100644 --- a/modules/stormkit/gpu/core.cppm +++ b/modules/stormkit/gpu/core.cppm @@ -4,9 +4,10 @@ export module stormkit.gpu.core; +export import :meta; export import :base; export import :loader; -export import :physical_device; +export import :objects; export import :instance; export import :debug_callback; export import :surface; diff --git a/modules/stormkit/gpu/core/base.cppm b/modules/stormkit/gpu/core/base.cppm index 349a3add5..b86a1face 100644 --- a/modules/stormkit/gpu/core/base.cppm +++ b/modules/stormkit/gpu/core/base.cppm @@ -16,6 +16,7 @@ import std; import stormkit.core; +import :meta; import :structs; import :vulkan; @@ -25,173 +26,205 @@ namespace stdv = std::views; namespace cmeta = stormkit::core::meta; export namespace stormkit::gpu { - template - class Owned; - - namespace meta { - template - struct ObjectInfo; - - template - concept HasRequiresInfo = requires(ObjectInfo> value) { value; }; - - template - concept CreateAllocateDisabled = HasRequiresInfo and requires() { - { ObjectInfo>::DISABLE_CREATE_ALLOCATE } -> cmeta::IsBooleanTestable; - } and ObjectInfo>::DISABLE_CREATE_ALLOCATE; - - template - concept IsOwnedByOther = HasRequiresInfo and requires(T) { typename ObjectInfo>::OwnedBy; }; - - template - concept IsOwned = HasRequiresInfo - and std::derived_from, Owned>::Of>>; - } // namespace meta - - template - class View; - - namespace meta { - template - concept IsView = not IsOwned> and requires(T value) { - typename cmeta::CanonicalType::ValueType; - typename cmeta::CanonicalType::ViewType; - { value.native_handle() } -> cmeta::Is::ValueType>; - }; - - template - concept IsOwnedOrView = IsOwned or IsView; - - template - concept DoInitReturnExpected = requires(T& foo, Args&&... args) { - { foo.do_init(cmeta::CanonicalType::PRIVATE, std::forward(args)...) } -> cmeta::SameAs>; - }; - template - concept DoInitReturnVoid = requires(T& foo, Args&&... args) { - { foo.do_init(cmeta::CanonicalType::PRIVATE, std::forward(args)...) } -> cmeta::SameAs; - }; - } // namespace meta - STORMKIT_GPU_API auto initialize_backend() -> Expected; - template - class View { + template + class GpuObjectViewImplementation; + + template + class GpuObjectBase { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; + using TagType = Tag; + using TraitType = trait::GpuObject; + using ValueType = TraitType::ValueType; + using ObjectType = TraitType::ObjectType; + using ViewType = TraitType::ViewType; - View(const T& of) noexcept; - template U> - View(const U& of) noexcept; - ~View() noexcept; + ~GpuObjectBase() noexcept; - View(const View&) noexcept; - auto operator=(const View&) noexcept -> View&; + GpuObjectBase(const GpuObjectBase&) noexcept; + auto operator=(const GpuObjectBase&) noexcept -> GpuObjectBase&; - View(View&&) noexcept; - auto operator=(View&&) noexcept -> View&; + GpuObjectBase(GpuObjectBase&&) noexcept; + auto operator=(GpuObjectBase&&) noexcept -> GpuObjectBase&; [[nodiscard]] auto native_handle() const noexcept -> ValueType; + [[nodiscard]] operator ValueType() const noexcept; protected: - ValueType m_vk_handle; + GpuObjectBase() noexcept; + + ValueType m_vk_handle = VK_NULL_HANDLE; + + friend class GpuObjectViewImplementation; }; - template - class Owned { + template + requires(meta::HasOwnerType) + class GpuObjectBase { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using DeleterType = ObjectInfo::DeleterType; - using ViewType = ObjectInfo::ViewType; + using TagType = Tag; + using TraitType = trait::GpuObject; + using ValueType = TraitType::ValueType; + using ObjectType = TraitType::ObjectType; + using ViewType = TraitType::ViewType; + using OwnerType = TraitType::OwnerType; + using OwnerViewType = typename OwnerType::ViewType; - ~Owned() noexcept; + ~GpuObjectBase() noexcept; - Owned(const Owned&) = delete; - auto operator=(const Owned&) noexcept -> Owned& = delete; + GpuObjectBase(const GpuObjectBase&) noexcept; + auto operator=(const GpuObjectBase&) noexcept -> GpuObjectBase&; - Owned(Owned&&) noexcept; - auto operator=(Owned&&) noexcept -> Owned&; + GpuObjectBase(GpuObjectBase&&) noexcept; + auto operator=(GpuObjectBase&&) noexcept -> GpuObjectBase&; - template - requires(meta::IsOwnedByOther and meta::DoInitReturnExpected) [[nodiscard]] - static auto create(Owner&& owner, Args&&... args) noexcept -> Expected - requires(not meta::CreateAllocateDisabled); + auto native_handle() const noexcept -> ValueType; - template - requires(meta::IsOwnedByOther and meta::DoInitReturnVoid) [[nodiscard]] - static auto create(Owner&& owner, Args&&... args) noexcept -> T - requires(not meta::CreateAllocateDisabled); + operator ValueType() const noexcept; - template - requires(not meta::IsOwnedByOther and meta::DoInitReturnExpected) [[nodiscard]] - static auto create(Args&&... args) noexcept -> Expected - requires(not meta::CreateAllocateDisabled); + auto owner() const noexcept -> OwnerViewType; - template - requires(not meta::IsOwnedByOther and meta::DoInitReturnVoid) - [[nodiscard]] - static auto create(Args&&... args) noexcept -> T - requires(not meta::CreateAllocateDisabled); + protected: + GpuObjectBase(OwnerViewType&&) noexcept; - template - requires(meta::IsOwnedByOther and meta::DoInitReturnExpected) - [[nodiscard]] - static auto allocate(Owner&& owner, Args&&... args) noexcept -> Expected> - requires(not meta::CreateAllocateDisabled); + ValueType m_vk_handle = VK_NULL_HANDLE; + OwnerViewType m_owner; - template - requires(meta::IsOwnedByOther and meta::DoInitReturnVoid) - [[nodiscard]] - static auto allocate(Owner&& owner, Args&&... args) noexcept -> Heap - requires(not meta::CreateAllocateDisabled); + friend class GpuObjectViewImplementation; + }; - template - requires(not meta::IsOwnedByOther and meta::DoInitReturnExpected) - [[nodiscard]] - static auto allocate(Args&&... args) noexcept -> Expected> - requires(not meta::CreateAllocateDisabled); + template + class GpuObjectImplementation; - template - requires(not meta::IsOwnedByOther and meta::DoInitReturnVoid) - [[nodiscard]] - static auto allocate(Args&&... args) noexcept -> Heap - requires(not meta::CreateAllocateDisabled); + template + class GpuObjectViewImplementation: public GpuObjectBase { + using Base = GpuObjectBase; - [[nodiscard]] - auto native_handle() const noexcept -> ValueType; + public: + using TagType = Base::TagType; + using TraitType = Base::TraitType; + using ValueType = Base::ValueType; + using ObjectType = Base::ObjectType; + using ViewType = Base::ViewType; + + GpuObjectViewImplementation(const GpuObjectImplementation&) noexcept; + template> TContainerOrPointer> + GpuObjectViewImplementation(const TContainerOrPointer&) noexcept; + ~GpuObjectViewImplementation() noexcept; + + GpuObjectViewImplementation(const GpuObjectViewImplementation&) noexcept; + auto operator=(const GpuObjectViewImplementation&) noexcept -> GpuObjectViewImplementation&; + + GpuObjectViewImplementation(GpuObjectViewImplementation&&) noexcept; + auto operator=(GpuObjectViewImplementation&&) noexcept -> GpuObjectViewImplementation&; + }; - operator ValueType() const noexcept; + template + requires(meta::HasOwnerType) + class GpuObjectViewImplementation: public GpuObjectBase { + using Base = GpuObjectBase; + + public: + using TagType = Base::TagType; + using TraitType = Base::TraitType; + using ValueType = Base::ValueType; + using ObjectType = Base::ObjectType; + using ViewType = Base::ViewType; + using OwnerType = Base::OwnerType; + using OwnerViewType = Base::OwnerViewType; + + GpuObjectViewImplementation(const GpuObjectImplementation&) noexcept; + template> TContainerOrPointer> + GpuObjectViewImplementation(const TContainerOrPointer&) noexcept; + ~GpuObjectViewImplementation() noexcept; + + GpuObjectViewImplementation(const GpuObjectViewImplementation&) noexcept; + auto operator=(const GpuObjectViewImplementation&) noexcept -> GpuObjectViewImplementation&; + + GpuObjectViewImplementation(GpuObjectViewImplementation&&) noexcept; + auto operator=(GpuObjectViewImplementation&&) noexcept -> GpuObjectViewImplementation&; + }; + + template + class GpuObjectImplementation + : public GpuObjectBase, + public UseNamedConstructors::ObjectType, meta::GpuObjectDoInitReturnType> { + using Base = GpuObjectBase; + + public: + using TagType = Base::TagType; + using TraitType = Base::TraitType; + using ValueType = Base::ValueType; + using ObjectType = Base::ObjectType; + using ViewType = Base::ViewType; + using DeleterType = TraitType::DeleterType; + + GpuObjectImplementation(DeleterType&&) noexcept; + ~GpuObjectImplementation() noexcept; + + GpuObjectImplementation(const GpuObjectImplementation&) noexcept = delete; + auto operator=(const GpuObjectImplementation&) noexcept -> GpuObjectImplementation& = delete; + + GpuObjectImplementation(GpuObjectImplementation&&) noexcept; + auto operator=(GpuObjectImplementation&&) noexcept -> GpuObjectImplementation&; protected: - static constexpr struct PrivateTag { - } PRIVATE; + DeleterType m_deleter_ptr; + }; + + template + requires(meta::HasOwnerType) + class GpuObjectImplementation + : public GpuObjectBase, + public UseNamedConstructors::ObjectType, + meta::GpuObjectDoInitReturnType, + typename trait::GpuObject::OwnerType::ViewType> { + using Base = GpuObjectBase; - explicit Owned(DeleterType&& deleter_ptr) noexcept; + public: + using TagType = Base::TagType; + using TraitType = Base::TraitType; + using ValueType = Base::ValueType; + using ObjectType = Base::ObjectType; + using ViewType = Base::ViewType; + using DeleterType = TraitType::DeleterType; + using OwnerType = Base::OwnerType; + using OwnerViewType = Base::OwnerViewType; + + GpuObjectImplementation(OwnerViewType&&, DeleterType&&) noexcept; + ~GpuObjectImplementation() noexcept; + + GpuObjectImplementation(const GpuObjectImplementation&) noexcept = delete; + auto operator=(const GpuObjectImplementation&) noexcept -> GpuObjectImplementation& = delete; - ValueType m_vk_handle; + GpuObjectImplementation(GpuObjectImplementation&&) noexcept; + auto operator=(GpuObjectImplementation&&) noexcept -> GpuObjectImplementation&; + + protected: DeleterType m_deleter_ptr; }; - template + template auto as_view(T&& value) noexcept -> T; - template - auto as_view(const T& value) noexcept -> typename meta::ObjectInfo>::ViewType; + template + auto as_view(const T& value) noexcept -> trait::GpuObject::ViewType; template - auto as_view(const T& value) noexcept -> typename meta::ObjectInfo>>::ViewType; + auto as_view(const T& value) noexcept + -> trait::GpuObject>::TagType>::ViewType; template - auto as_view(const T& value) noexcept -> typename meta::ObjectInfo>>::ViewType; + auto as_view(const T& value) noexcept + -> trait::GpuObject>::TagType>::ViewType; template class Out = std::array, typename... Args> requires(not stdr::range and ...) @@ -204,7 +237,7 @@ export namespace stormkit::gpu { template class Out = std::vector, stdr::range Range> auto to_views(const Range& range) noexcept -> decltype(auto); - template + template auto format_as(const T& object, FormatContext& ctx) noexcept -> decltype(ctx.out()); } // namespace stormkit::gpu @@ -215,244 +248,381 @@ export namespace stormkit::gpu { namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - inline Owned::Owned(DeleterType&& deleter_ptr) noexcept - : m_vk_handle { VK_NULL_HANDLE }, m_deleter_ptr { std::move(deleter_ptr) } { - } + inline GpuObjectBase::GpuObjectBase() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - inline Owned::~Owned() noexcept { - if constexpr (cmeta::SameAs) { - if (m_deleter_ptr != nullptr and m_vk_handle != VK_NULL_HANDLE) vk::call(m_deleter_ptr, m_vk_handle, nullptr); - m_vk_handle = VK_NULL_HANDLE; - } + inline GpuObjectBase::~GpuObjectBase() noexcept { + m_vk_handle = VK_NULL_HANDLE; } ///////////////////////////////////// ///////////////////////////////////// - template + template + STORMKIT_FORCE_INLINE + inline GpuObjectBase::GpuObjectBase(const GpuObjectBase&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto GpuObjectBase::operator=(const GpuObjectBase&) noexcept -> GpuObjectBase& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline Owned::Owned(Owned&& other) noexcept - : m_vk_handle { std::exchange(other.m_vk_handle, VK_NULL_HANDLE) }, - m_deleter_ptr { std::exchange(other.m_deleter_ptr, {}) } { + inline GpuObjectBase::GpuObjectBase(GpuObjectBase&& other) noexcept + : m_vk_handle { std::exchange(other.m_vk_handle, VK_NULL_HANDLE) } { } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - inline auto Owned::operator=(Owned&& other) noexcept -> Owned& { + inline auto GpuObjectBase::operator=(GpuObjectBase&& other) noexcept -> GpuObjectBase& { if (&other == this) [[unlikely]] return *this; - m_vk_handle = std::exchange(other.m_vk_handle, VK_NULL_HANDLE); - m_deleter_ptr = std::exchange(other.m_deleter_ptr, {}); + m_vk_handle = std::exchange(other.m_vk_handle, VK_NULL_HANDLE); return *this; } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - inline auto Owned::native_handle() const noexcept -> ValueType { + inline auto GpuObjectBase::native_handle() const noexcept -> ValueType { EXPECTS(m_vk_handle != VK_NULL_HANDLE); return m_vk_handle; } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - inline Owned::operator ValueType() const noexcept { + inline GpuObjectBase::operator ValueType() const noexcept { return native_handle(); } ///////////////////////////////////// ///////////////////////////////////// - template - template - requires(meta::IsOwnedByOther and meta::DoInitReturnExpected) - STORMKIT_FORCE_INLINE - inline auto Owned::create(Owner&& owner, Args&&... args) noexcept -> Expected - requires(not meta::CreateAllocateDisabled) - { - auto out = T { PRIVATE, std::forward(owner) }; - Try(out.do_init(PRIVATE, std::forward(args)...)); - Return out; + template + requires(meta::HasOwnerType) + STORMKIT_FORCE_INLINE + inline GpuObjectBase::GpuObjectBase(OwnerViewType&& owner) noexcept + : m_owner { std::move(owner) } { } ///////////////////////////////////// ///////////////////////////////////// - template - template - requires(meta::IsOwnedByOther and meta::DoInitReturnVoid) + template + requires(meta::HasOwnerType) + STORMKIT_FORCE_INLINE + inline GpuObjectBase::~GpuObjectBase() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(meta::HasOwnerType) + STORMKIT_FORCE_INLINE + inline GpuObjectBase::GpuObjectBase(const GpuObjectBase&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(meta::HasOwnerType) STORMKIT_FORCE_INLINE - inline auto Owned::create(Owner&& owner, Args&&... args) noexcept -> T - requires(not meta::CreateAllocateDisabled) - { - auto out = T { PRIVATE, std::forward(owner) }; - out.do_init(PRIVATE, std::forward(args)...); - return out; + inline auto GpuObjectBase::operator=(const GpuObjectBase&) noexcept -> GpuObjectBase& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(meta::HasOwnerType) + STORMKIT_FORCE_INLINE + inline GpuObjectBase::GpuObjectBase(GpuObjectBase&& other) noexcept + : m_vk_handle { std::exchange(other.m_vk_handle, VK_NULL_HANDLE) }, m_owner { std::move(other.m_owner) } { } ///////////////////////////////////// ///////////////////////////////////// - template - template - requires(not meta::IsOwnedByOther and meta::DoInitReturnExpected) - STORMKIT_FORCE_INLINE - inline auto Owned::create(Args&&... args) noexcept -> Expected - requires(not meta::CreateAllocateDisabled) - { - auto out = T { PRIVATE }; - Try(out.do_init(PRIVATE, std::forward(args)...)); - Return out; + template + requires(meta::HasOwnerType) + STORMKIT_FORCE_INLINE + inline auto GpuObjectBase::operator=(GpuObjectBase&& other) noexcept -> GpuObjectBase& { + if (&other == this) [[unlikely]] + return *this; + + m_vk_handle = std::exchange(other.m_vk_handle, VK_NULL_HANDLE); + m_owner = std::move(other.m_owner); + + return *this; } ///////////////////////////////////// ///////////////////////////////////// - template - template - requires(not meta::IsOwnedByOther and meta::DoInitReturnVoid) - STORMKIT_FORCE_INLINE - inline auto Owned::create(Args&&... args) noexcept -> T - requires(not meta::CreateAllocateDisabled) - { - auto out = T { PRIVATE }; - out.do_init(PRIVATE, std::forward(args)...); - return out; + template + requires(meta::HasOwnerType) + STORMKIT_FORCE_INLINE + inline auto GpuObjectBase::native_handle() const noexcept -> ValueType { + EXPECTS(m_vk_handle != VK_NULL_HANDLE); + return m_vk_handle; } ///////////////////////////////////// ///////////////////////////////////// - template - template - requires(meta::IsOwnedByOther and meta::DoInitReturnExpected) - STORMKIT_FORCE_INLINE - inline auto Owned::allocate(Owner&& owner, Args&&... args) noexcept -> Expected> - requires(not meta::CreateAllocateDisabled) - { - auto out = core::allocate_unsafe(PRIVATE, std::forward(owner)); - Try(out->do_init(PRIVATE, std::forward(args)...)); - Return out; + template + requires(meta::HasOwnerType) + STORMKIT_FORCE_INLINE + inline GpuObjectBase::operator ValueType() const noexcept { + return native_handle(); } ///////////////////////////////////// ///////////////////////////////////// - template - template - requires(meta::IsOwnedByOther and meta::DoInitReturnVoid) - STORMKIT_FORCE_INLINE - inline auto Owned::allocate(Owner&& owner, Args&&... args) noexcept -> Heap - requires(not meta::CreateAllocateDisabled) - { - auto out = core::allocate_unsafe(PRIVATE, std::forward(owner)); - out->do_init(PRIVATE, std::forward(args)...); - return out; + template + requires(meta::HasOwnerType) + STORMKIT_FORCE_INLINE + inline auto GpuObjectBase::owner() const noexcept -> OwnerViewType { + return m_owner; } ///////////////////////////////////// ///////////////////////////////////// - template - template - requires(not meta::IsOwnedByOther and meta::DoInitReturnExpected) - STORMKIT_FORCE_INLINE - inline auto Owned::allocate(Args&&... args) noexcept -> Expected> - requires(not meta::CreateAllocateDisabled) - { - auto out = core::allocate_unsafe(PRIVATE); - Try(out->do_init(PRIVATE, std::forward(args)...)); - Return out; + template + STORMKIT_FORCE_INLINE + inline GpuObjectViewImplementation::GpuObjectViewImplementation(const GpuObjectImplementation& object) noexcept + : GpuObjectBase {} { + GpuObjectBase::m_vk_handle = object.m_vk_handle; } ///////////////////////////////////// ///////////////////////////////////// - template - template - requires(not meta::IsOwnedByOther and meta::DoInitReturnVoid) - STORMKIT_FORCE_INLINE - inline auto Owned::allocate(Args&&... args) noexcept -> Heap - requires(not meta::CreateAllocateDisabled) - { - auto out = core::allocate_unsafe(PRIVATE); - out->do_init(PRIVATE, std::forward(args)...); - return out; + template + template> TContainerOrPointer> + STORMKIT_FORCE_INLINE + inline GpuObjectViewImplementation::GpuObjectViewImplementation(const TContainerOrPointer& object) noexcept + : GpuObjectBase {} { + GpuObjectBase::m_vk_handle = (*object).m_vk_handle; } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - inline View::View(const T& of) noexcept - : m_vk_handle { of.native_handle() } { - ENSURES(m_vk_handle != VK_NULL_HANDLE); + inline GpuObjectViewImplementation::GpuObjectViewImplementation(const GpuObjectViewImplementation&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto GpuObjectViewImplementation::operator=(const GpuObjectViewImplementation&) noexcept + -> GpuObjectViewImplementation& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline GpuObjectViewImplementation::GpuObjectViewImplementation(GpuObjectViewImplementation&& other) noexcept + : GpuObjectBase {} { + GpuObjectBase::m_vk_handle = other.m_vk_handle; } ///////////////////////////////////// ///////////////////////////////////// - template - template U> + template STORMKIT_FORCE_INLINE - inline View::View(const U& object) noexcept - : m_vk_handle { object->native_handle() } { - ENSURES(m_vk_handle != VK_NULL_HANDLE); + inline auto GpuObjectViewImplementation::operator=(GpuObjectViewImplementation&& other) noexcept + -> GpuObjectViewImplementation& { + if (this == &other) [[unlikely]] + return *this; + + GpuObjectBase::m_vk_handle = other.m_vk_handle; + + return *this; } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - inline View::~View() noexcept = default; + inline GpuObjectViewImplementation::~GpuObjectViewImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - template + template + requires(meta::HasOwnerType) STORMKIT_FORCE_INLINE - inline View::View(const View&) noexcept = default; + inline GpuObjectViewImplementation::GpuObjectViewImplementation(const GpuObjectImplementation& object) noexcept + : GpuObjectBase { object.owner() } { + GpuObjectBase::m_vk_handle = object.m_vk_handle; + } ///////////////////////////////////// ///////////////////////////////////// - template + template + requires(meta::HasOwnerType) + template> TContainerOrPointer> STORMKIT_FORCE_INLINE - inline auto View::operator=(const View&) noexcept -> View& = default; + inline GpuObjectViewImplementation::GpuObjectViewImplementation(const TContainerOrPointer& object) noexcept + : GpuObjectBase { (*object).owner() } { + GpuObjectBase::m_vk_handle = (*object).m_vk_handle; + } ///////////////////////////////////// ///////////////////////////////////// - template + template + requires(meta::HasOwnerType) STORMKIT_FORCE_INLINE - inline View::View(View&&) noexcept = default; + inline GpuObjectViewImplementation::GpuObjectViewImplementation(const GpuObjectViewImplementation& + other) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - template + template + requires(meta::HasOwnerType) STORMKIT_FORCE_INLINE - inline auto View::operator=(View&&) noexcept -> View& = default; + inline auto GpuObjectViewImplementation::operator=(const GpuObjectViewImplementation&) noexcept + -> GpuObjectViewImplementation& = default; ///////////////////////////////////// ///////////////////////////////////// - template + template + requires(meta::HasOwnerType) STORMKIT_FORCE_INLINE - inline auto View::native_handle() const noexcept -> ValueType { - EXPECTS(m_vk_handle != VK_NULL_HANDLE); - return m_vk_handle; + inline GpuObjectViewImplementation::GpuObjectViewImplementation(GpuObjectViewImplementation&& other) noexcept + : GpuObjectBase { other.owner() } { + GpuObjectBase::m_vk_handle = other.m_vk_handle; } ///////////////////////////////////// ///////////////////////////////////// - template + template + requires(meta::HasOwnerType) STORMKIT_FORCE_INLINE - inline View::operator ValueType() const noexcept { - return native_handle(); + inline auto GpuObjectViewImplementation::operator=(GpuObjectViewImplementation&& other) noexcept + -> GpuObjectViewImplementation& { + if (this == &other) [[unlikely]] + return *this; + + GpuObjectBase::m_vk_handle = other.m_vk_handle; + GpuObjectBase::m_owner = other.m_owner; + + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(meta::HasOwnerType) + STORMKIT_FORCE_INLINE + inline GpuObjectViewImplementation::~GpuObjectViewImplementation() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline GpuObjectImplementation::GpuObjectImplementation(DeleterType&& deleter_ptr) noexcept + : GpuObjectBase {}, m_deleter_ptr { std::move(deleter_ptr) } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline GpuObjectImplementation::GpuObjectImplementation(GpuObjectImplementation&& other) noexcept + : GpuObjectBase { std::move(other) }, m_deleter_ptr { std::exchange(other.m_deleter_ptr, {}) } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto GpuObjectImplementation::operator=(GpuObjectImplementation&& other) noexcept -> GpuObjectImplementation& { + if (&other == this) [[unlikely]] + return *this; + + GpuObjectBase::operator=(std::move(other)); + + m_deleter_ptr = std::exchange(other.m_deleter_ptr, {}); + + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline GpuObjectImplementation::~GpuObjectImplementation() noexcept { + if constexpr (cmeta::SameAs) { + if (m_deleter_ptr != nullptr and Base::m_vk_handle != VK_NULL_HANDLE) + vk::call(m_deleter_ptr, Base::m_vk_handle, nullptr); + } + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(meta::HasOwnerType) + STORMKIT_FORCE_INLINE + inline GpuObjectImplementation::GpuObjectImplementation(OwnerViewType&& owner, DeleterType&& deleter_ptr) noexcept + : GpuObjectBase { std::move(owner) }, m_deleter_ptr { std::move(deleter_ptr) } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(meta::HasOwnerType) + STORMKIT_FORCE_INLINE + inline GpuObjectImplementation::GpuObjectImplementation(GpuObjectImplementation&& other) noexcept + : GpuObjectBase { std::move(other) }, m_deleter_ptr { std::exchange(other.m_deleter_ptr, {}) } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(meta::HasOwnerType) + STORMKIT_FORCE_INLINE + inline auto GpuObjectImplementation::operator=(GpuObjectImplementation&& other) noexcept -> GpuObjectImplementation& { + if (&other == this) [[unlikely]] + return *this; + + GpuObjectBase::operator=(std::move(other)); + + m_deleter_ptr = std::exchange(other.m_deleter_ptr, {}); + + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(meta::HasOwnerType) + STORMKIT_FORCE_INLINE + inline GpuObjectImplementation::~GpuObjectImplementation() noexcept { + using OwnerValueType = OwnerType::ValueType; + + if constexpr (cmeta::SameAs) { + if constexpr (cmeta::SameAs) { + if (m_deleter_ptr != nullptr and Base::m_vk_handle != VK_NULL_HANDLE) + vk::call(m_deleter_ptr, Base::m_owner, Base::m_vk_handle, nullptr); + } else { + const auto& device = this->device(); + const auto& device_table = device.device_table(); + if (m_deleter_ptr != nullptr and Base::m_vk_handle != VK_NULL_HANDLE) + vk::call(device_table.*m_deleter_ptr, device, Base::m_vk_handle, nullptr); + } + } } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE inline auto as_view(T&& value) noexcept -> T { return std::forward(value); @@ -460,18 +630,19 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - inline auto as_view(const T& value) noexcept -> typename meta::ObjectInfo>::ViewType { - return typename meta::ObjectInfo::ViewType { value }; + inline auto as_view(const T& value) noexcept -> trait::GpuObject::ViewType { + using Out = trait::GpuObject::ViewType; + return Out { value }; } ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto as_view(const T& value) noexcept -> - typename meta::ObjectInfo>>::ViewType { + inline auto as_view(const T& value) noexcept + -> trait::GpuObject>::TagType>::ViewType { return as_view(unref(value)); } @@ -479,8 +650,8 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto as_view(const T& value) noexcept -> - typename meta::ObjectInfo>>::ViewType { + inline auto as_view(const T& value) noexcept + -> trait::GpuObject>::TagType>::ViewType { return as_view(value.value()); } @@ -514,7 +685,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE inline auto format_as(const T& object, FormatContext& ctx) noexcept -> decltype(ctx.out()) { return format_as(as_view(object), ctx); diff --git a/modules/stormkit/gpu/core/debug_callback.cppm b/modules/stormkit/gpu/core/debug_callback.cppm index 6d1efa475..dfaa0b466 100644 --- a/modules/stormkit/gpu/core/debug_callback.cppm +++ b/modules/stormkit/gpu/core/debug_callback.cppm @@ -18,48 +18,40 @@ import stormkit.core; import :base; import :vulkan; import :structs; +import :objects; import :instance; -export namespace stormkit::gpu { - class DebugCallback; - - namespace view { - using DebugCallback = View; - } - - namespace meta { - template<> - struct ObjectInfo { - using Of = DebugCallback; - using ValueType = VkDebugUtilsMessengerEXT; - using DeleterType = PFN_vkDestroyDebugUtilsMessengerEXT; - using ViewType = view::DebugCallback; - using OwnedBy = Instance; - - static constexpr auto DEBUG_TYPE = DebugObjectType::DEBUG_UTILS_MESSENGER; - }; - } // namespace meta - - class STORMKIT_GPU_API DebugCallback: public OwnedByInstance { +namespace stormkit::gpu { + export template + class DebugCallbackInterface final: public InstanceObject { public: - static constexpr auto DEBUG_TYPE = DebugObjectType::DEBUG_UTILS_MESSENGER; + using InstanceObject::InstanceObject; + using InstanceObject::operator=; + using TagType = DebugCallbackTag; + }; + class STORMKIT_GPU_API DebugCallbackImplementation: public GpuObjectImplementation { + public: using Closure = PFN_vkDebugUtilsMessengerCallbackEXT; - ~DebugCallback(); + DebugCallbackImplementation(PrivateTag, view::Instance&&) noexcept; + auto do_init(PrivateTag, Closure messenger_closure, void* user_data = nullptr) noexcept -> Expected; + ~DebugCallbackImplementation() noexcept; - DebugCallback(const DebugCallback&) = delete; - auto operator=(const DebugCallback&) -> DebugCallback& = delete; + DebugCallbackImplementation(const DebugCallbackImplementation&) noexcept = delete; + auto operator=(const DebugCallbackImplementation&) noexcept -> DebugCallbackImplementation& = delete; - DebugCallback(DebugCallback&&) noexcept; - auto operator=(DebugCallback&&) noexcept -> DebugCallback&; - - // clang-format off - // private: - // clang-format on - DebugCallback(PrivateTag, view::Instance) noexcept; - auto do_init(PrivateTag, Closure, void* = nullptr) noexcept -> Expected; + DebugCallbackImplementation(DebugCallbackImplementation&&) noexcept; + auto operator=(DebugCallbackImplementation&&) noexcept -> DebugCallbackImplementation&; }; + + namespace view { + class DebugCallbackImplementation: public GpuObjectViewImplementation { + public: + using GpuObjectViewImplementation::GpuObjectViewImplementation; + using GpuObjectViewImplementation::operator=; + }; + } // namespace view } // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// @@ -70,23 +62,23 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DebugCallback::DebugCallback(PrivateTag, view::Instance instance) noexcept - : OwnedByInstance { std::move(instance), auto(vkDestroyDebugUtilsMessengerEXT) } { + inline DebugCallbackImplementation::DebugCallbackImplementation(PrivateTag, view::Instance&& instance) noexcept + : GpuObjectImplementation { std::move(instance), auto(vkDestroyDebugUtilsMessengerEXT) } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DebugCallback::~DebugCallback() = default; + inline DebugCallbackImplementation::~DebugCallbackImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DebugCallback::DebugCallback(DebugCallback&&) noexcept = default; + inline DebugCallbackImplementation::DebugCallbackImplementation(DebugCallbackImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DebugCallback::operator=(DebugCallback&&) noexcept -> DebugCallback& = default; - + inline auto DebugCallbackImplementation::operator=(DebugCallbackImplementation&&) noexcept + -> DebugCallbackImplementation& = default; } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/core/device.cppm b/modules/stormkit/gpu/core/device.cppm index 69e1835f1..4ba0745f9 100644 --- a/modules/stormkit/gpu/core/device.cppm +++ b/modules/stormkit/gpu/core/device.cppm @@ -19,107 +19,30 @@ import stormkit.core; import :vulkan; import :base; -import :physical_device; + import :structs; +import :objects; + import :instance; namespace cmeta = stormkit::core::meta; using namespace stormkit; -export namespace stormkit::gpu { - namespace view { - class Device; - class Fence; - } // namespace view - - class Device; - - namespace meta { - template<> - struct ObjectInfo { - using Of = Device; - using ValueType = VkDevice; - using DeleterType = PFN_vkDestroyDevice VolkDeviceTable::*; - using ViewType = view::Device; - using OwnedBy = PhysicalDevice; - - static constexpr auto DEBUG_TYPE = DebugObjectType::DEVICE; - }; - } // namespace meta - - class STORMKIT_GPU_API Device: public OwnedByPhysicalDevice { - public: +namespace stormkit::gpu { + export { struct QueueEntry { u32 id; u32 count; QueueFlag flags = QueueFlag {}; }; - struct CreateInfo { - bool enable_swapchain = true; - bool enable_raytracing = false; - }; - - ~Device() noexcept; - - Device(const Device&) = delete; - auto operator=(const Device&) -> Device& = delete; - - Device(Device&&) noexcept; - auto operator=(Device&&) noexcept -> Device&; - - auto wait_idle() const noexcept -> Expected; - - auto wait_for_fences(std::span fences, - bool wait_all = true, - const std::chrono::milliseconds& timeout = std::chrono::milliseconds::max()) const noexcept - -> Expected; - auto wait_for_fence(view::Fence fence, - const std::chrono::milliseconds& timeout = std::chrono::milliseconds::max()) const noexcept - -> Expected; - - auto reset_fences(std::span fences) const noexcept -> Expected; - auto reset_fence(view::Fence fence) const noexcept -> Expected; - - template - auto set_object_name(const T& object, std::string_view name) const -> Expected; - - auto set_object_name(u64 object, DebugObjectType type, std::string_view name) const -> Expected; - - [[nodiscard]] - auto queue_entries() const noexcept -> const std::vector&; - - [[nodiscard]] - auto device_table() const noexcept -> const VolkDeviceTable&; - - [[nodiscard]] - auto allocator() const noexcept -> vk::Observer; - - Device(PrivateTag, view::PhysicalDevice) noexcept; - auto do_init(PrivateTag, const CreateInfo& = { true, false }) noexcept -> Expected; - - private: - std::vector m_queue_entries; - - VolkDeviceTable m_vk_device_table = {}; - VmaVulkanFunctions m_vma_function_table = {}; - vk::Owned m_vma_allocator = { vmaDestroyAllocator }; - }; - - namespace view { - class STORMKIT_GPU_API Device: public PhysicalDeviceObject { + template + class STORMKIT_GPU_API DeviceInterface final: public PhysicalDeviceObject { public: - Device(const gpu::Device& of) noexcept; - template T> - Device(const T& of) noexcept; - ~Device() noexcept; - - Device(const Device&) noexcept; - auto operator=(const Device&) noexcept -> Device&; - - Device(Device&&) noexcept; - auto operator=(Device&&) noexcept -> Device&; + using PhysicalDeviceObject::PhysicalDeviceObject; + using PhysicalDeviceObject::operator=; + using TagType = DeviceTag; auto wait_idle() const noexcept -> Expected; @@ -134,90 +57,77 @@ export namespace stormkit::gpu { auto reset_fences(std::span fences) const noexcept -> Expected; auto reset_fence(view::Fence fence) const noexcept -> Expected; - template - auto set_object_name(const T& object, std::string_view name) const -> Expected; + template + auto set_object_name(const T& object, std::string_view name) const noexcept -> Expected; - auto set_object_name(u64 object, DebugObjectType type, std::string_view name) const -> Expected; + auto set_object_name(u64 object, DebugObjectType type, std::string_view name) const noexcept -> Expected; [[nodiscard]] - auto queue_entries() const noexcept -> const std::vector&; + auto queue_entries() const noexcept -> std::span; [[nodiscard]] auto device_table() const noexcept -> const VolkDeviceTable&; [[nodiscard]] auto allocator() const noexcept -> vk::Observer; - - private: - std::vector m_queue_entries; - - VolkDeviceTable m_vk_device_table; - vk::Observer m_vma_allocator; }; - template - class DeviceObject: public PhysicalDeviceObject { - public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; - - DeviceObject(const T& child) noexcept; - template U> - DeviceObject(const U& child) noexcept; - ~DeviceObject() noexcept; - - DeviceObject(const DeviceObject&) noexcept; - auto operator=(const DeviceObject&) noexcept -> DeviceObject&; - - DeviceObject(DeviceObject&&) noexcept; - auto operator=(DeviceObject&&) noexcept -> DeviceObject&; - - [[nodiscard]] - auto device() const noexcept -> const view::Device&; + namespace vk { + STORMKIT_GPU_API auto imgui_vk_loader(const char* func_name, void*) noexcept -> PFN_vkVoidFunction; + } - protected: - Device m_device; - }; - } // namespace view + namespace monadic { + template + constexpr auto find_queue() noexcept -> decltype(auto); + } // namespace monadic + } - template - class OwnedByDevice: public OwnedByPhysicalDevice { + class STORMKIT_GPU_API DeviceImplementation: public GpuObjectImplementation { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using DeleterType = ObjectInfo::DeleterType; - using ViewType = ObjectInfo::ViewType; - - ~OwnedByDevice() noexcept; + struct CreateInfo { + bool enable_swapchain = true; + bool enable_raytracing = false; + }; - OwnedByDevice(const OwnedByDevice&) = delete; - auto operator=(const OwnedByDevice&) -> OwnedByDevice& = delete; + DeviceImplementation(PrivateTag, view::PhysicalDevice&&) noexcept; + auto do_init(PrivateTag, const CreateInfo& create_info = { true, false }) noexcept -> Expected; + ~DeviceImplementation() noexcept; - OwnedByDevice(OwnedByDevice&&) noexcept; - auto operator=(OwnedByDevice&&) noexcept -> OwnedByDevice&; + DeviceImplementation(const DeviceImplementation&) noexcept = delete; + auto operator=(const DeviceImplementation&) noexcept -> DeviceImplementation& = delete; - [[nodiscard]] - auto device() const noexcept -> const view::Device&; + DeviceImplementation(DeviceImplementation&&) noexcept; + auto operator=(DeviceImplementation&&) noexcept -> DeviceImplementation&; protected: - using Parent = OwnedByPhysicalDevice; - OwnedByDevice(view::Device&& device, DeleterType&& deleter_ptr) noexcept; + std::vector m_queue_entries; - view::Device m_device; + VolkDeviceTable m_vk_device_table = {}; + VmaVulkanFunctions m_vma_function_table = {}; + vk::Owned m_vma_allocator = { vmaDestroyAllocator }; }; - namespace vk { - STORMKIT_GPU_API auto imgui_vk_loader(const char* func_name, void*) noexcept -> PFN_vkVoidFunction; - } + namespace view { + class DeviceImplementation: public GpuObjectViewImplementation { + public: + DeviceImplementation(const gpu::Device& of) noexcept; + template TContainerOrPointer> + DeviceImplementation(const TContainerOrPointer&) noexcept; + ~DeviceImplementation() noexcept; - template - auto format_as(const Device::QueueEntry& physical_device, FormatContext& ctx) noexcept -> decltype(ctx.out()); + DeviceImplementation(const DeviceImplementation&) noexcept; + auto operator=(const DeviceImplementation&) noexcept -> DeviceImplementation&; - namespace monadic { - template - constexpr auto find_queue() noexcept -> decltype(auto); - } // namespace monadic + DeviceImplementation(DeviceImplementation&&) noexcept; + auto operator=(DeviceImplementation&&) noexcept -> DeviceImplementation&; + + protected: + std::span m_queue_entries; + + VolkDeviceTable m_vk_device_table; + vk::Observer m_vma_allocator; + }; + } // namespace view } // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// @@ -227,70 +137,83 @@ export namespace stormkit::gpu { namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// + template + template STORMKIT_FORCE_INLINE - inline Device::Device(PrivateTag, view::PhysicalDevice physical_device) noexcept - : OwnedByPhysicalDevice { std::move(physical_device), &VolkDeviceTable::vkDestroyDevice } { + inline auto DeviceInterface::set_object_name(const T& object, std::string_view name) const noexcept -> Expected { + if (not vkSetDebugUtilsObjectNameEXT) return {}; + + const auto vk_object = vk::to_vk(object); + return set_object_name(as(std::bit_cast(vk_object)), trait::GpuObject::DEBUG_TYPE, std::move(name)); } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline Device::~Device() noexcept { - if (m_deleter_ptr != nullptr and m_vk_handle != VK_NULL_HANDLE) - vk::call(m_vk_device_table.*Parent::m_deleter_ptr, m_vk_handle, nullptr); - m_vk_handle = VK_NULL_HANDLE; + inline auto DeviceInterface::queue_entries() const noexcept -> std::span { + return Base::m_queue_entries; } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline Device::Device(Device&&) noexcept = default; + inline auto DeviceInterface::device_table() const noexcept -> const VolkDeviceTable& { + return Base::m_vk_device_table; + } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto Device::operator=(Device&&) noexcept -> Device& = default; + inline auto DeviceInterface::allocator() const noexcept -> vk::Observer { + return Base::m_vma_allocator; + } + + namespace monadic { + ///////////////////////////////////// + ///////////////////////////////////// + template + constexpr auto find_queue() noexcept -> decltype(auto) { + return [](const auto& family) static noexcept { + return core::check_flag_bit(family.flags, flag) and (not core::check_flag_bit(family.flags, no_flag) and ...); + }; + } + } // namespace monadic ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - template - inline auto Device::set_object_name(const T& object, std::string_view name) const -> Expected { - if (not vkSetDebugUtilsObjectNameEXT) return {}; - - auto&& vk_object = vk::to_vk(object); - return set_object_name(std::bit_cast(static_cast(vk_object)), - meta::ObjectInfo::DEBUG_TYPE, - std::move(name)); + inline DeviceImplementation::DeviceImplementation(PrivateTag, view::PhysicalDevice&& physical_device) noexcept + : GpuObjectImplementation { std::move(physical_device), &VolkDeviceTable::vkDestroyDevice } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Device::queue_entries() const noexcept -> const std::vector& { - return m_queue_entries; + inline DeviceImplementation::~DeviceImplementation() noexcept { + if (m_deleter_ptr != nullptr and m_vk_handle != VK_NULL_HANDLE) + vk::call(m_vk_device_table.*m_deleter_ptr, m_vk_handle, nullptr); + m_vk_handle = VK_NULL_HANDLE; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Device::device_table() const noexcept -> const VolkDeviceTable& { - return m_vk_device_table; - } + inline DeviceImplementation::DeviceImplementation(DeviceImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Device::allocator() const noexcept -> vk::Observer { - return m_vma_allocator; - } + inline auto DeviceImplementation::operator=(DeviceImplementation&&) noexcept -> DeviceImplementation& = default; namespace view { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Device::Device(const gpu::Device& of) noexcept - : PhysicalDeviceObject { of }, + inline DeviceImplementation::DeviceImplementation(const gpu::Device& of) noexcept + : GpuObjectViewImplementation { of }, m_queue_entries { of.queue_entries() }, m_vk_device_table { of.device_table() }, m_vma_allocator { of.allocator() } { @@ -298,187 +221,59 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - template T> - STORMKIT_FORCE_INLINE - inline Device::Device(const T& of) noexcept - : PhysicalDeviceObject { of }, - m_queue_entries { of->queue_entries() }, - m_vk_device_table { of->device_table() }, - m_vma_allocator { of->allocator() } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Device::~Device() noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Device::Device(const Device&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Device::operator=(const Device&) noexcept -> Device& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Device::Device(Device&&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Device::operator=(Device&&) noexcept -> Device& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Device::set_object_name(const T& object, std::string_view name) const -> Expected { - if (not vkSetDebugUtilsObjectNameEXT) return {}; - - auto&& vk_object = vk::to_vk(object); - return set_object_name(std::bit_cast(static_cast(vk_object)), T::DEBUG_TYPE, std::move(name)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Device::queue_entries() const noexcept -> const std::vector& { - return m_queue_entries; - } - - ///////////////////////////////////// - ///////////////////////////////////// + template TContainerOrPointer> STORMKIT_FORCE_INLINE - inline auto Device::device_table() const noexcept -> const VolkDeviceTable& { - return m_vk_device_table; + inline DeviceImplementation::DeviceImplementation(const TContainerOrPointer& of) noexcept + : DeviceImplementation { *of } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Device::allocator() const noexcept -> vk::Observer { - return m_vma_allocator; - } + inline DeviceImplementation::~DeviceImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline DeviceObject::DeviceObject(const T& child) noexcept - : PhysicalDeviceObject { child }, m_device { child.device() } { - } - - /////////////////////////////////// - /////////////////////////////////// - template - template U> STORMKIT_FORCE_INLINE - inline DeviceObject::DeviceObject(const U& child) noexcept - : PhysicalDeviceObject { child }, m_device { child->device() } { - } + inline DeviceImplementation::DeviceImplementation(const DeviceImplementation&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - template STORMKIT_FORCE_INLINE - inline DeviceObject::~DeviceObject() noexcept = default; + inline auto DeviceImplementation::operator=(const DeviceImplementation&) noexcept -> DeviceImplementation& = default; ///////////////////////////////////// ///////////////////////////////////// - template STORMKIT_FORCE_INLINE - inline DeviceObject::DeviceObject(const DeviceObject&) noexcept = default; + inline DeviceImplementation::DeviceImplementation(DeviceImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto DeviceObject::operator=(const DeviceObject&) noexcept -> DeviceObject& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template STORMKIT_FORCE_INLINE - inline DeviceObject::DeviceObject(DeviceObject&&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto DeviceObject::operator=(DeviceObject&&) noexcept -> DeviceObject& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto DeviceObject::device() const noexcept -> const Device& { - return m_device; - } + inline auto DeviceImplementation::operator=(DeviceImplementation&&) noexcept -> DeviceImplementation& = default; } // namespace view ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - inline OwnedByDevice::OwnedByDevice(view::Device&& device, DeleterType&& deleter_ptr) noexcept - : Parent { clone(device.physical_device()), std::move(deleter_ptr) }, m_device { std::move(device) } { + inline auto DeviceObject::instance() const noexcept -> view::Instance { + return Interface::owner().instance(); } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - inline OwnedByDevice::~OwnedByDevice() noexcept { - if constexpr (cmeta::SameAs) { - const auto& device_table = device().device_table(); - auto& vk_handle = Parent::m_vk_handle; - auto& deleter_ptr = Parent::m_deleter_ptr; - if (deleter_ptr != nullptr and vk_handle != VK_NULL_HANDLE) - vk::call(device_table.*Parent::deleter_ptr, vk_handle, nullptr); - vk_handle = VK_NULL_HANDLE; - } + inline auto DeviceObject::physical_device() const noexcept -> view::PhysicalDevice { + return Interface::owner().physical_device(); } ///////////////////////////////////// ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline OwnedByDevice::OwnedByDevice(OwnedByDevice&&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto OwnedByDevice::operator=(OwnedByDevice&&) noexcept -> OwnedByDevice& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - inline auto OwnedByDevice::device() const noexcept -> const view::Device& { - return m_device; + inline auto DeviceObject::device() const noexcept -> view::Device { + return Interface::owner(); } - - ///////////////////////////////////// - ///////////////////////////////////// - template - inline auto format_as(const Device::QueueEntry& queue, FormatContext& ctx) noexcept -> decltype(ctx.out()) { - return std::format_to(ctx.out(), "[QueueEntry: .id = {}, .count = {}, .flags = {}]", queue.id, queue.count, queue.flags); - } - - namespace monadic { - ///////////////////////////////////// - ///////////////////////////////////// - template - constexpr auto find_queue() noexcept -> decltype(auto) { - return [](const auto& family) static noexcept { - return core::check_flag_bit(family.flags, flag) and (not core::check_flag_bit(family.flags, no_flag) and ...); - }; - } - } // namespace monadic - } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/core/instance.cppm b/modules/stormkit/gpu/core/instance.cppm index 0f7427799..def2623b0 100644 --- a/modules/stormkit/gpu/core/instance.cppm +++ b/modules/stormkit/gpu/core/instance.cppm @@ -18,112 +18,159 @@ import std; import stormkit.core; import stormkit.wsi; -import :base; import :vulkan; +import :base; + import :structs; +import :objects; -export namespace stormkit::gpu { - class PhysicalDevice; +namespace stormkit::gpu { + export { + template + class STORMKIT_GPU_API PhysicalDeviceInterface final: public InstanceObject { + public: + using InstanceObject::InstanceObject; + using InstanceObject::operator=; + using TagType = PhysicalDeviceTag; - class Instance; - class InstanceObject; + [[nodiscard]] + auto check_extension_support(std::string_view extension) const noexcept -> bool; + [[nodiscard]] + auto check_extension_support(std::span extensions) const noexcept -> bool; + [[nodiscard]] + auto check_extension_support(std::span extensions) const noexcept -> bool; - namespace view { - using Instance = View; - } + [[nodiscard]] + auto info() const noexcept -> const PhysicalDeviceInfo&; + [[nodiscard]] + auto capabilities() const noexcept -> const RenderCapabilities&; + [[nodiscard]] + auto memory_types() const noexcept -> std::span; + [[nodiscard]] + auto queue_families() const noexcept -> std::span; + [[nodiscard]] + auto extensions() const noexcept -> std::span; + [[nodiscard]] + auto formats_properties() const noexcept -> std::span>; + }; - namespace meta { - template<> - struct ObjectInfo { - using Of = Instance; - using ValueType = VkInstance; - using DeleterType = PFN_vkDestroyInstance; - using ViewType = view::Instance; + template + class InstanceInterface final: public Base { + public: + using Base::Base; + using Base::operator=; + using TagType = InstanceTag; - static constexpr auto DEBUG_TYPE = DebugObjectType::INSTANCE; + [[nodiscard]] + auto extensions() const noexcept -> std::span; + + [[nodiscard]] + auto physical_devices() const noexcept -> std::span; }; - } // namespace meta + } - class STORMKIT_GPU_API Instance: public Owned { + class STORMKIT_GPU_API InstanceImplementation: public GpuObjectImplementation { public: - ~Instance(); + explicit InstanceImplementation(PrivateTag) noexcept; + auto do_init(PrivateTag, std::string = "", bool = (STORMKIT_BUILD_TYPE == "DEBUG")) noexcept -> Expected; + ~InstanceImplementation() noexcept; - Instance(const Instance&) = delete; - auto operator=(const Instance&) -> Instance& = delete; + InstanceImplementation(const InstanceImplementation&) noexcept = delete; + auto operator=(const InstanceImplementation&) noexcept -> InstanceImplementation& = delete; - Instance(Instance&&) noexcept; - auto operator=(Instance&&) noexcept -> Instance&; + InstanceImplementation(InstanceImplementation&&) noexcept; + auto operator=(InstanceImplementation&&) noexcept -> InstanceImplementation&; - [[nodiscard]] - auto physical_devices() const noexcept -> const std::vector&; + protected: + std::vector m_extensions; + std::vector m_physical_devices; - // clang-format off - // private: - // clang-format on - explicit Instance(PrivateTag) noexcept; - auto do_init(PrivateTag, std::string = "", bool = (STORMKIT_BUILD_TYPE == "DEBUG")) noexcept -> Expected; + friend class view::InstanceImplementation; private: auto do_load_instance() noexcept -> Expected; auto do_retrieve_physical_devices() noexcept -> Expected; - - std::vector m_extensions; - std::vector m_physical_devices; }; namespace view { - template - class InstanceObject: public View { + class InstanceImplementation: public GpuObjectViewImplementation { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; - - InstanceObject(const T& child) noexcept; - template U> - InstanceObject(const U& child) noexcept; - ~InstanceObject() noexcept; + InstanceImplementation(const gpu::Instance&) noexcept; + template TContainerOrPointer> + InstanceImplementation(const TContainerOrPointer&) noexcept; + InstanceImplementation(const gpu::InstanceImplementation&) noexcept; + ~InstanceImplementation() noexcept; - InstanceObject(const InstanceObject&) noexcept; - auto operator=(const InstanceObject&) noexcept -> InstanceObject&; + InstanceImplementation(const InstanceImplementation&) noexcept; + auto operator=(const InstanceImplementation&) noexcept -> InstanceImplementation&; - InstanceObject(InstanceObject&&) noexcept; - auto operator=(InstanceObject&&) noexcept -> InstanceObject&; - - [[nodiscard]] - auto instance() const noexcept -> const Instance&; + InstanceImplementation(InstanceImplementation&&) noexcept; + auto operator=(InstanceImplementation&&) noexcept -> InstanceImplementation&; protected: - Instance m_instance; + std::span m_extensions; + std::span m_physical_devices; }; } // namespace view - template - class OwnedByInstance: public Owned { + class STORMKIT_GPU_API PhysicalDeviceImplementation: public GpuObjectImplementation { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using DeleterType = ObjectInfo::DeleterType; - using ViewType = ObjectInfo::ViewType; - - ~OwnedByInstance() noexcept; + struct Data { + PhysicalDeviceInfo device_info; + RenderCapabilities capabilities; + }; - OwnedByInstance(const OwnedByInstance&) = delete; - auto operator=(const OwnedByInstance&) -> OwnedByInstance& = delete; + PhysicalDeviceImplementation(PrivateTag, view::Instance&&) noexcept; + auto do_init(PrivateTag, VkPhysicalDevice&&) noexcept -> void; + ~PhysicalDeviceImplementation() noexcept; - OwnedByInstance(OwnedByInstance&&) noexcept; - auto operator=(OwnedByInstance&&) noexcept -> OwnedByInstance&; + PhysicalDeviceImplementation(const PhysicalDeviceImplementation&) noexcept = delete; + auto operator=(const PhysicalDeviceImplementation&) noexcept -> PhysicalDeviceImplementation& = delete; - [[nodiscard]] - auto instance() const noexcept -> const view::Instance&; + PhysicalDeviceImplementation(PhysicalDeviceImplementation&&) noexcept; + auto operator=(PhysicalDeviceImplementation&&) noexcept -> PhysicalDeviceImplementation&; protected: - using Parent = Owned; + Heap m_data; + std::vector m_memory_types; + std::vector m_queue_families; + std::vector m_extensions; + std::vector> m_format_properties; + + friend class InstanceInterface; + friend class view::PhysicalDeviceImplementation; + }; - OwnedByInstance(view::Instance&&, DeleterType&&) noexcept; + namespace view { + class PhysicalDeviceImplementation: public GpuObjectViewImplementation { + public: + PhysicalDeviceImplementation(const gpu::PhysicalDevice&) noexcept; + template TContainerOrPointer> + PhysicalDeviceImplementation(const TContainerOrPointer&) noexcept; + ~PhysicalDeviceImplementation() noexcept; - view::Instance m_instance; - }; + PhysicalDeviceImplementation(const PhysicalDeviceImplementation&) noexcept; + auto operator=(const PhysicalDeviceImplementation&) noexcept -> PhysicalDeviceImplementation&; + + PhysicalDeviceImplementation(PhysicalDeviceImplementation&&) noexcept; + auto operator=(PhysicalDeviceImplementation&&) noexcept -> PhysicalDeviceImplementation&; + + protected: + ref m_data; + std::span m_memory_types; + std::span m_queue_families; + std::span m_extensions; + std::span> m_format_properties; + }; + } // namespace view + + export { + [[nodiscard]] + STORMKIT_GPU_API auto score_physical_device(view::PhysicalDevice physical_device) noexcept -> u64; + + template + auto format_as(view::PhysicalDevice physical_device, FormatContext& ctx) noexcept -> decltype(ctx.out()); + } } // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// @@ -133,106 +180,298 @@ export namespace stormkit::gpu { namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto InstanceObject::instance() const noexcept -> view::Instance { + return Interface::owner(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto Instance::physical_devices() const noexcept -> const std::vector& { - return m_physical_devices; + inline auto PhysicalDeviceInterface::check_extension_support(std::string_view extension) const noexcept -> bool { + return stdr::any_of(extensions(), [extension](const auto& e) { return e == extension; }); } + ///////////////////////////////////// + ///////////////////////////////////// + template + inline auto PhysicalDeviceInterface::check_extension_support(std::span extensions) + const noexcept -> bool { + auto required_extensions = HashSet { stdr::begin(extensions), stdr::end(extensions) }; + + for (const auto& extension : this->extensions()) required_extensions.erase(extension); + + return stdr::empty(required_extensions); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + inline auto PhysicalDeviceInterface::check_extension_support(std::span extensions) const noexcept + -> bool { + auto required_extensions = HashSet { stdr::begin(extensions), stdr::end(extensions) }; + + for (const auto& extension : this->extensions()) required_extensions.erase(extension); + + return stdr::empty(required_extensions); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto PhysicalDeviceInterface::info() const noexcept -> const PhysicalDeviceInfo& { + return Base::m_data->device_info; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto PhysicalDeviceInterface::capabilities() const noexcept -> const RenderCapabilities& { + return Base::m_data->capabilities; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto PhysicalDeviceInterface::memory_types() const noexcept -> std::span { + return Base::m_memory_types; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto PhysicalDeviceInterface::queue_families() const noexcept -> std::span { + return Base::m_queue_families; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto PhysicalDeviceInterface::extensions() const noexcept -> std::span { + return Base::m_extensions; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto PhysicalDeviceInterface::formats_properties() const noexcept + -> std::span> { + return Base::m_format_properties; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto InstanceInterface::extensions() const noexcept -> std::span { + return Base::m_extensions; + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto InstanceInterface::physical_devices() const noexcept -> std::span { + return Base::m_physical_devices; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline InstanceImplementation::InstanceImplementation(PrivateTag) noexcept + : GpuObjectImplementation { auto(vkDestroyInstance) } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline InstanceImplementation::~InstanceImplementation() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline InstanceImplementation::InstanceImplementation(InstanceImplementation&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto InstanceImplementation::operator=(InstanceImplementation&&) noexcept -> InstanceImplementation& = default; + namespace view { ///////////////////////////////////// ///////////////////////////////////// - template STORMKIT_FORCE_INLINE - inline InstanceObject::InstanceObject(const T& child) noexcept - : View { child }, m_instance { child.instance() } { + inline InstanceImplementation::InstanceImplementation(const gpu::Instance& of) noexcept + : GpuObjectViewImplementation { of }, m_extensions { of.extensions() }, m_physical_devices { of.physical_devices() } { } ///////////////////////////////////// ///////////////////////////////////// - template - template U> + template TContainerOrPointer> STORMKIT_FORCE_INLINE - inline InstanceObject::InstanceObject(const U& child) noexcept - : View { child }, m_instance { child->instance() } { + inline InstanceImplementation::InstanceImplementation(const TContainerOrPointer& of) noexcept + : InstanceImplementation { *of } { } ///////////////////////////////////// ///////////////////////////////////// - template STORMKIT_FORCE_INLINE - inline InstanceObject::~InstanceObject() noexcept = default; + inline InstanceImplementation::InstanceImplementation(const gpu::InstanceImplementation& of) noexcept + : GpuObjectViewImplementation { of }, m_extensions { of.m_extensions }, m_physical_devices { of.m_physical_devices } { + } ///////////////////////////////////// ///////////////////////////////////// - template STORMKIT_FORCE_INLINE - inline InstanceObject::InstanceObject(const InstanceObject&) noexcept = default; + inline InstanceImplementation::~InstanceImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto InstanceObject::operator=(const InstanceObject&) noexcept -> InstanceObject& = default; + STORMKIT_FORCE_INLINE + inline InstanceImplementation::InstanceImplementation(const InstanceImplementation&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - template STORMKIT_FORCE_INLINE - inline InstanceObject::InstanceObject(InstanceObject&&) noexcept = default; + inline auto InstanceImplementation::operator=(const InstanceImplementation&) noexcept + -> InstanceImplementation& = default; ///////////////////////////////////// ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto InstanceObject::operator=(InstanceObject&&) noexcept -> InstanceObject& = default; + STORMKIT_FORCE_INLINE + inline InstanceImplementation::InstanceImplementation(InstanceImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto InstanceObject::instance() const noexcept -> const view::Instance& { - return m_instance; - } + STORMKIT_FORCE_INLINE + inline auto InstanceImplementation::operator=(InstanceImplementation&&) noexcept -> InstanceImplementation& = default; } // namespace view ///////////////////////////////////// ///////////////////////////////////// - template STORMKIT_FORCE_INLINE - inline OwnedByInstance::OwnedByInstance(view::Instance&& instance, DeleterType&& deleter_ptr) noexcept - : Parent { std::move(deleter_ptr) }, m_instance { std::move(instance) } { + inline PhysicalDeviceImplementation::PhysicalDeviceImplementation(PrivateTag, view::Instance&& instance) noexcept + : GpuObjectImplementation { std::move(instance), monadic::noop() } { } ///////////////////////////////////// ///////////////////////////////////// - template STORMKIT_FORCE_INLINE - inline OwnedByInstance::~OwnedByInstance() noexcept { - if constexpr (cmeta::SameAs) { - auto& vk_handle = Parent::m_vk_handle; - auto& deleter_ptr = Parent::m_deleter_ptr; - if (deleter_ptr != nullptr and vk_handle != VK_NULL_HANDLE) vk::call(deleter_ptr, m_instance, vk_handle, nullptr); - vk_handle = VK_NULL_HANDLE; - } - } + inline PhysicalDeviceImplementation::~PhysicalDeviceImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - template STORMKIT_FORCE_INLINE - inline OwnedByInstance::OwnedByInstance(OwnedByInstance&&) noexcept = default; + inline PhysicalDeviceImplementation::PhysicalDeviceImplementation(PhysicalDeviceImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - template STORMKIT_FORCE_INLINE - inline auto OwnedByInstance::operator=(OwnedByInstance&&) noexcept -> OwnedByInstance& = default; + inline auto PhysicalDeviceImplementation::operator=(PhysicalDeviceImplementation&&) noexcept + -> PhysicalDeviceImplementation& = default; + + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline PhysicalDeviceImplementation::PhysicalDeviceImplementation(const gpu::PhysicalDevice& of) noexcept + : GpuObjectViewImplementation { of }, + m_data { as_ref(of.m_data) }, + m_memory_types { of.m_memory_types }, + m_queue_families { of.m_queue_families }, + m_extensions { of.m_extensions }, + m_format_properties { of.m_format_properties } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + template TContainerOrPointer> + STORMKIT_FORCE_INLINE + inline PhysicalDeviceImplementation::PhysicalDeviceImplementation(const TContainerOrPointer& of) noexcept + : PhysicalDeviceImplementation { *of } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline PhysicalDeviceImplementation::~PhysicalDeviceImplementation() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline PhysicalDeviceImplementation::PhysicalDeviceImplementation(const PhysicalDeviceImplementation&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto PhysicalDeviceImplementation::operator=(const PhysicalDeviceImplementation& other) noexcept + -> PhysicalDeviceImplementation& { + if (&other == this) [[unlikely]] + return *this; + + GpuObjectViewImplementation::operator=(other); + + m_data = as_ref(other.m_data); + m_memory_types = other.m_memory_types; + m_queue_families = other.m_queue_families; + m_extensions = other.m_extensions; + m_format_properties = other.m_format_properties; + + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline PhysicalDeviceImplementation::PhysicalDeviceImplementation(PhysicalDeviceImplementation&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto PhysicalDeviceImplementation::operator=(PhysicalDeviceImplementation&&) noexcept + -> PhysicalDeviceImplementation& = default; + } // namespace view ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - inline auto OwnedByInstance::instance() const noexcept -> const view::Instance& { - return m_instance; + inline auto PhysicalDeviceObject::instance() const noexcept -> view::Instance { + return Interface::owner().instance(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto PhysicalDeviceObject::physical_device() const noexcept -> view::PhysicalDevice { + return Interface::owner(); + } + + ///////////////////////////////////// + ///////////////////////////////////// + template + inline auto format_as(view::PhysicalDevice physical_device, FormatContext& ctx) noexcept -> decltype(ctx.out()) { + const auto& info = physical_device.info(); + return std::format_to(ctx.out(), + "PhysicalDevice[name: {}, vendor: {}, id: {}, vulkan: {}.{}.{}, driver version: " + "{}.{}.{}]", + info.device_name, + info.vendor_name, + info.device_id, + info.api_major_version, + info.api_minor_version, + info.api_patch_version, + info.driver_major_version, + info.driver_minor_version, + info.driver_patch_version); } } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/core/meta.cppm b/modules/stormkit/gpu/core/meta.cppm new file mode 100644 index 000000000..b306371e6 --- /dev/null +++ b/modules/stormkit/gpu/core/meta.cppm @@ -0,0 +1,78 @@ +// Copyright (C) 2023 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +export module stormkit.gpu.core:meta; + +import std; + +import stormkit.core; + +import :vulkan; + +namespace cmeta = stormkit::core::meta; + +namespace stormkit::gpu { + export namespace trait { + template + struct GpuObject; + }; + + namespace meta { + export { + template + concept GpuObjectHasTraitDefined = requires() { + trait::GpuObject {}; + typename trait::GpuObject::ValueType; + typename trait::GpuObject::DeleterType; + typename trait::GpuObject::ObjectType; + typename trait::GpuObject::ViewType; + + { trait::GpuObject::DEBUG_TYPE } -> cmeta::SameAs; + }; + + template + concept HasDoInitReturnType = GpuObjectHasTraitDefined and requires() { + typename trait::GpuObject::DoInitReturnType; + }; + + template + concept HasOwnerType = GpuObjectHasTraitDefined and requires() { typename trait::GpuObject::OwnerType; }; + + template + concept HasTagType = requires() { typename T::TagType; }; + } + + namespace details { + template + struct GpuObjectDoInitReturnType { + using Type = Expected; + }; + + template + struct GpuObjectDoInitReturnType { + using Type = typename trait::GpuObject>::DoInitReturnType; + }; + } // namespace details + + export { + template + using GpuObjectDoInitReturnType = details::GpuObjectDoInitReturnType::Type; + + template + concept IsGpuObject = HasTagType + and GpuObjectHasTraitDefined + and cmeta::SameAs::ObjectType>; + + template + concept IsGpuView = HasTagType + and GpuObjectHasTraitDefined + and cmeta::SameAs::ViewType>; + + template + concept IsGpuObjectOrView = IsGpuObject or IsGpuView; + } + } // namespace meta +} // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/core/objects.cppm b/modules/stormkit/gpu/core/objects.cppm new file mode 100644 index 000000000..a80393cb4 --- /dev/null +++ b/modules/stormkit/gpu/core/objects.cppm @@ -0,0 +1,208 @@ +// Copyright (C) 2023 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.gpu.core:objects; + +import std; + +import stormkit.core; + +import :vulkan; +import :base; + +namespace stormkit::gpu { + class InstanceImplementation; + class DebugCallbackImplementation; + class SurfaceImplementation; + class PhysicalDeviceImplementation; + class DeviceImplementation; + class FenceImplementation; + class SemaphoreImplementation; + + namespace view { + class InstanceImplementation; + class DebugCallbackImplementation; + class SurfaceImplementation; + class PhysicalDeviceImplementation; + class DeviceImplementation; + class FenceImplementation; + class SemaphoreImplementation; + } // namespace view + + export { + class InstanceTag; + template + class InstanceInterface; + + class DebugCallbackTag; + template + class DebugCallbackInterface; + + class SurfaceTag; + template + class SurfaceInterface; + + class PhysicalDeviceTag; + template + class PhysicalDeviceInterface; + + class DeviceTag; + template + class DeviceInterface; + + class FenceTag; + template + class FenceInterface; + + class SemaphoreTag; + template + class SemaphoreInterface; + + using Instance = InstanceInterface; + + namespace view { + using Instance = InstanceInterface; + } + + template + class InstanceObject: public Interface { + public: + using Interface::Interface; + using Interface::operator=; + using TagType = Interface::TagType; + + auto instance() const noexcept -> view::Instance; + }; + + using DebugCallback = DebugCallbackInterface; + using Surface = SurfaceInterface; + using PhysicalDevice = PhysicalDeviceInterface; + + namespace view { + using PhysicalDevice = PhysicalDeviceInterface; + using Surface = SurfaceInterface; + using DebugCallback = DebugCallbackInterface; + } // namespace view + + template + class PhysicalDeviceObject: public Interface { + public: + using Interface::Interface; + using Interface::operator=; + using TagType = Interface::TagType; + + auto instance() const noexcept -> view::Instance; + auto physical_device() const noexcept -> view::PhysicalDevice; + }; + + using Device = DeviceInterface; + + namespace view { + using Device = DeviceInterface; + } + + template + class DeviceObject: public Interface { + public: + using Interface::Interface; + using Interface::operator=; + using TagType = Interface::TagType; + + auto instance() const noexcept -> view::Instance; + auto physical_device() const noexcept -> view::PhysicalDevice; + auto device() const noexcept -> view::Device; + }; + + using Fence = FenceInterface; + using Semaphore = SemaphoreInterface; + + namespace view { + using Fence = FenceInterface; + using Semaphore = SemaphoreInterface; + } // namespace view + + namespace trait { + template<> + struct GpuObject { + using ValueType = VkInstance; + using DeleterType = PFN_vkDestroyInstance; + using ObjectType = Instance; + using ViewType = view::Instance; + + static constexpr auto DEBUG_TYPE = DebugObjectType::INSTANCE; + }; + + template<> + struct GpuObject { + using ValueType = VkDebugUtilsMessengerEXT; + using DeleterType = PFN_vkDestroyDebugUtilsMessengerEXT; + using ObjectType = DebugCallback; + using ViewType = view::DebugCallback; + using OwnerType = Instance; + + static constexpr auto DEBUG_TYPE = DebugObjectType::DEBUG_UTILS_MESSENGER; + }; + + template<> + struct GpuObject { + using ValueType = VkSurfaceKHR; + using DeleterType = PFN_vkDestroySurfaceKHR; + using ObjectType = Surface; + using ViewType = view::Surface; + using OwnerType = Instance; + + static constexpr auto DEBUG_TYPE = DebugObjectType::SURFACE; + }; + + template<> + struct GpuObject { + using ValueType = VkPhysicalDevice; + using DeleterType = decltype(monadic::noop()); + using DoInitReturnType = void; + using ObjectType = PhysicalDevice; + using ViewType = view::PhysicalDevice; + using OwnerType = Instance; + + static constexpr auto DEBUG_TYPE = DebugObjectType::PHYSICAL_DEVICE; + }; + + template<> + struct GpuObject { + using ValueType = VkDevice; + using DeleterType = PFN_vkDestroyDevice VolkDeviceTable::*; + using ObjectType = Device; + using ViewType = view::Device; + using OwnerType = PhysicalDevice; + + static constexpr auto DEBUG_TYPE = DebugObjectType::DEVICE; + }; + + template<> + struct GpuObject { + using ValueType = VkFence; + using DeleterType = PFN_vkDestroyFence VolkDeviceTable::*; + using ObjectType = Fence; + using ViewType = view::Fence; + using OwnerType = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::FENCE; + }; + + template<> + struct GpuObject { + using ValueType = VkSemaphore; + using DeleterType = PFN_vkDestroySemaphore VolkDeviceTable::*; + using ObjectType = Semaphore; + using ViewType = view::Semaphore; + using OwnerType = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::SEMAPHORE; + }; + } // namespace trait + } +} // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/core/physical_device.cppm b/modules/stormkit/gpu/core/physical_device.cppm deleted file mode 100644 index e76c57cd6..000000000 --- a/modules/stormkit/gpu/core/physical_device.cppm +++ /dev/null @@ -1,484 +0,0 @@ -// Copyright (C) 2023 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -module; - -#include -#include - -#include -#include - -export module stormkit.gpu.core:physical_device; - -import std; - -import stormkit.core; - -import :base; -import :vulkan; -import :structs; -import :instance; - -export namespace stormkit::gpu { - namespace view { - class PhysicalDevice; - } - - class PhysicalDevice; - class PhysicalDeviceObject; - - namespace meta { - template<> - struct ObjectInfo { - using Of = PhysicalDevice; - using ValueType = VkPhysicalDevice; - using DeleterType = decltype(monadic::noop()); - using ViewType = view::PhysicalDevice; - using OwnedBy = Instance; - - static constexpr auto DEBUG_TYPE = DebugObjectType::PHYSICAL_DEVICE; - }; - } // namespace meta - - class STORMKIT_GPU_API PhysicalDevice: public OwnedByInstance { - public: - ~PhysicalDevice(); - - PhysicalDevice(const PhysicalDevice&) = delete; - auto operator=(const PhysicalDevice&) -> PhysicalDevice& = delete; - - PhysicalDevice(PhysicalDevice&&) noexcept; - auto operator=(PhysicalDevice&&) noexcept -> PhysicalDevice&; - - [[nodiscard]] - auto check_extension_support(std::string_view extension) const noexcept -> bool; - [[nodiscard]] - auto check_extension_support(std::span extensions) const noexcept -> bool; - [[nodiscard]] - auto check_extension_support(std::span extensions) const noexcept -> bool; - - [[nodiscard]] - auto info() const noexcept -> const PhysicalDeviceInfo&; - [[nodiscard]] - auto capabilities() const noexcept -> const RenderCapabilities&; - [[nodiscard]] - auto memory_types() const noexcept -> std::span; - [[nodiscard]] - auto queue_families() const noexcept -> std::span; - [[nodiscard]] - auto extensions() const noexcept -> std::span; - [[nodiscard]] - auto formats_properties() const noexcept -> std::span>; - - // clang-format off - // private: - // clang-format on - PhysicalDevice(PrivateTag, view::Instance&&) noexcept; - auto do_init(PrivateTag, VkPhysicalDevice&&) noexcept -> void; - - private: - struct Data { - PhysicalDeviceInfo device_info; - RenderCapabilities capabilities; - }; - - Heap m_data; - std::vector m_memory_types; - std::vector m_queue_families; - std::vector m_extensions; - std::vector> m_format_properties; - - friend class view::PhysicalDevice; - }; - - namespace view { - class STORMKIT_GPU_API PhysicalDevice: public InstanceObject { - public: - PhysicalDevice(const gpu::PhysicalDevice& of) noexcept; - template T> - PhysicalDevice(const T& of) noexcept; - ~PhysicalDevice() noexcept; - - PhysicalDevice(const PhysicalDevice&) noexcept; - auto operator=(const PhysicalDevice&) noexcept -> PhysicalDevice&; - - PhysicalDevice(PhysicalDevice&&) noexcept; - auto operator=(PhysicalDevice&&) noexcept -> PhysicalDevice&; - - [[nodiscard]] - auto check_extension_support(std::string_view extension) const noexcept -> bool; - [[nodiscard]] - auto check_extension_support(std::span extensions) const noexcept -> bool; - [[nodiscard]] - auto check_extension_support(std::span extensions) const noexcept -> bool; - - [[nodiscard]] - auto info() const noexcept -> const PhysicalDeviceInfo&; - [[nodiscard]] - auto capabilities() const noexcept -> const RenderCapabilities&; - [[nodiscard]] - auto memory_types() const noexcept -> std::span; - [[nodiscard]] - auto queue_families() const noexcept -> std::span; - [[nodiscard]] - auto extensions() const noexcept -> std::span; - [[nodiscard]] - auto formats_properties() const noexcept -> std::span>; - - private: - ref m_data; - std::span m_memory_types; - - std::span m_queue_families; - std::span m_extensions; - std::span> m_format_properties; - }; - - template - class PhysicalDeviceObject: public InstanceObject { - public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; - - PhysicalDeviceObject(const T& child) noexcept; - template U> - PhysicalDeviceObject(const U& child) noexcept; - ~PhysicalDeviceObject() noexcept; - - PhysicalDeviceObject(const PhysicalDeviceObject&) noexcept; - auto operator=(const PhysicalDeviceObject&) noexcept -> PhysicalDeviceObject&; - - PhysicalDeviceObject(PhysicalDeviceObject&&) noexcept; - auto operator=(PhysicalDeviceObject&&) noexcept -> PhysicalDeviceObject&; - - [[nodiscard]] - auto physical_device() const noexcept -> const PhysicalDevice&; - - protected: - PhysicalDevice m_physical_device; - }; - } // namespace view - - template - class OwnedByPhysicalDevice: public OwnedByInstance { - public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using DeleterType = ObjectInfo::DeleterType; - using ViewType = ObjectInfo::ViewType; - - ~OwnedByPhysicalDevice() noexcept; - - OwnedByPhysicalDevice(const OwnedByPhysicalDevice&) = delete; - auto operator=(const OwnedByPhysicalDevice&) -> OwnedByPhysicalDevice& = delete; - - OwnedByPhysicalDevice(OwnedByPhysicalDevice&&) noexcept; - auto operator=(OwnedByPhysicalDevice&&) noexcept -> OwnedByPhysicalDevice&; - - [[nodiscard]] - auto physical_device() const noexcept -> const view::PhysicalDevice&; - - protected: - using Parent = OwnedByInstance; - - OwnedByPhysicalDevice(view::PhysicalDevice&&, DeleterType&&) noexcept; - - view::PhysicalDevice m_physical_device; - }; - - [[nodiscard]] - STORMKIT_GPU_API auto score_physical_device(view::PhysicalDevice physical_device) noexcept -> u64; - - template - auto format_as(view::PhysicalDevice physical_device, FormatContext& ctx) noexcept -> decltype(ctx.out()); -} // namespace stormkit::gpu - -//////////////////////////////////////////////////////////////////// -/// IMPLEMENTATION /// -//////////////////////////////////////////////////////////////////// - -namespace stormkit::gpu { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline PhysicalDevice::PhysicalDevice(PrivateTag, view::Instance&& instance) noexcept - : OwnedByInstance { std::move(instance), monadic::noop() } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline PhysicalDevice::~PhysicalDevice() = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline PhysicalDevice::PhysicalDevice(PhysicalDevice&&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::operator=(PhysicalDevice&&) noexcept -> PhysicalDevice& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::info() const noexcept -> const PhysicalDeviceInfo& { - return m_data->device_info; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::capabilities() const noexcept -> const RenderCapabilities& { - return m_data->capabilities; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::memory_types() const noexcept -> std::span { - return m_memory_types; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::queue_families() const noexcept -> std::span { - return m_queue_families; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::extensions() const noexcept -> std::span { - return m_extensions; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::formats_properties() const noexcept -> std::span> { - return m_format_properties; - } - - namespace view { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline PhysicalDevice::PhysicalDevice(const gpu::PhysicalDevice& of) noexcept - : InstanceObject { of }, - m_data { as_ref(of.m_data) }, - m_memory_types { of.m_memory_types }, - m_queue_families { of.m_queue_families }, - m_extensions { of.m_extensions }, - m_format_properties { of.m_format_properties } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - template T> - STORMKIT_FORCE_INLINE - inline PhysicalDevice::PhysicalDevice(const T& of) noexcept - : InstanceObject { of }, - m_data { as_ref(of->m_data) }, - m_memory_types { of->m_memory_types }, - m_queue_families { of->m_queue_families }, - m_extensions { of->m_extensions }, - m_format_properties { of->m_format_properties } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline PhysicalDevice::~PhysicalDevice() noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline PhysicalDevice::PhysicalDevice(const PhysicalDevice&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::operator=(const PhysicalDevice& other) noexcept -> PhysicalDevice& { - if (&other == this) [[unlikely]] - return *this; - - m_data = as_ref(other.m_data); - m_memory_types = other.m_memory_types; - m_queue_families = other.m_queue_families; - m_extensions = other.m_extensions; - m_format_properties = other.m_format_properties; - - InstanceObject::operator=(other); - - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline PhysicalDevice::PhysicalDevice(PhysicalDevice&&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::operator=(PhysicalDevice&&) noexcept -> PhysicalDevice& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::info() const noexcept -> const PhysicalDeviceInfo& { - return m_data->device_info; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::capabilities() const noexcept -> const RenderCapabilities& { - return m_data->capabilities; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::memory_types() const noexcept -> std::span { - return m_memory_types; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::queue_families() const noexcept -> std::span { - return m_queue_families; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::extensions() const noexcept -> std::span { - return m_extensions; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto PhysicalDevice::formats_properties() const noexcept - -> std::span> { - return m_format_properties; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline PhysicalDeviceObject::PhysicalDeviceObject(const T& child) noexcept - : InstanceObject { child }, m_physical_device { child.physical_device() } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - template U> - STORMKIT_FORCE_INLINE - inline PhysicalDeviceObject::PhysicalDeviceObject(const U& child) noexcept - : InstanceObject { child }, m_physical_device { child->physical_device() } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline PhysicalDeviceObject::~PhysicalDeviceObject() noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline PhysicalDeviceObject::PhysicalDeviceObject(const PhysicalDeviceObject&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto PhysicalDeviceObject::operator=(const PhysicalDeviceObject&) noexcept -> PhysicalDeviceObject& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline PhysicalDeviceObject::PhysicalDeviceObject(PhysicalDeviceObject&&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto PhysicalDeviceObject::operator=(PhysicalDeviceObject&&) noexcept -> PhysicalDeviceObject& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto PhysicalDeviceObject::physical_device() const noexcept -> const PhysicalDevice& { - return m_physical_device; - } - } // namespace view - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline OwnedByPhysicalDevice::OwnedByPhysicalDevice(view::PhysicalDevice&& physical_device, - DeleterType&& deleter_ptr) noexcept - : Parent { clone(physical_device.instance()), std::move(deleter_ptr) }, m_physical_device { std::move(physical_device) } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline OwnedByPhysicalDevice::~OwnedByPhysicalDevice() noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline OwnedByPhysicalDevice::OwnedByPhysicalDevice(OwnedByPhysicalDevice&&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto OwnedByPhysicalDevice::operator=(OwnedByPhysicalDevice&&) noexcept -> OwnedByPhysicalDevice& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto OwnedByPhysicalDevice::physical_device() const noexcept -> const view::PhysicalDevice& { - return m_physical_device; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - inline auto format_as(view::PhysicalDevice physical_device, FormatContext& ctx) noexcept -> decltype(ctx.out()) { - const auto& info = physical_device.info(); - return std::format_to(ctx.out(), - "PhysicalDevice[name: {}, vendor: {}, id: {}, vulkan: {}.{}.{}, driver version: " - "{}.{}.{}]", - info.device_name, - info.vendor_name, - info.device_id, - info.api_major_version, - info.api_minor_version, - info.api_patch_version, - info.driver_major_version, - info.driver_minor_version, - info.driver_patch_version); - } -} // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/core/surface.cppm b/modules/stormkit/gpu/core/surface.cppm index 2bfa616be..a26038b96 100644 --- a/modules/stormkit/gpu/core/surface.cppm +++ b/modules/stormkit/gpu/core/surface.cppm @@ -18,47 +18,43 @@ import std; import stormkit.core; import stormkit.wsi; -import :base; import :vulkan; -import :structs; -import :instance; - -export namespace stormkit::gpu { - class Surface; +import :base; - namespace view { - using Surface = InstanceObject; - } +import :structs; +import :objects; - namespace meta { - template<> - struct ObjectInfo { - using Of = Surface; - using ValueType = VkSurfaceKHR; - using DeleterType = PFN_vkDestroySurfaceKHR; - using ViewType = view::Surface; - using OwnedBy = Instance; +import :instance; - static constexpr auto DEBUG_TYPE = DebugObjectType::SURFACE; - }; - } // namespace meta +namespace stormkit::gpu { + export template + class SurfaceInterface final: public InstanceObject { + public: + using InstanceObject::InstanceObject; + using InstanceObject::operator=; + using TagType = SurfaceTag; + }; - class STORMKIT_GPU_API Surface: public OwnedByInstance { + class STORMKIT_GPU_API SurfaceImplementation: public GpuObjectImplementation { public: - ~Surface(); + SurfaceImplementation(PrivateTag, view::Instance&&) noexcept; + auto do_init(PrivateTag) noexcept -> Expected; + auto do_init(PrivateTag, const wsi::Window&) noexcept -> Expected; + ~SurfaceImplementation() noexcept; - Surface(const Surface&) = delete; - auto operator=(const Surface&) -> Surface& = delete; + SurfaceImplementation(const SurfaceImplementation&) noexcept = delete; + auto operator=(const SurfaceImplementation&) noexcept -> SurfaceImplementation& = delete; - Surface(Surface&&) noexcept; - auto operator=(Surface&&) noexcept -> Surface&; + SurfaceImplementation(SurfaceImplementation&&) noexcept; + auto operator=(SurfaceImplementation&&) noexcept -> SurfaceImplementation&; #if false [[nodiscard]] - static auto create_offscreen(view::Instance instance) noexcept -> Expected; + static auto create_offscreen(view::Instance instance) noexcept + -> Expected; [[nodiscard]] static auto allocate_offscreen(view::Instance instance) noexcept - -> Expected>; + -> Expected>; #endif [[nodiscard]] @@ -66,13 +62,18 @@ export namespace stormkit::gpu { [[nodiscard]] static auto allocate_from_window(view::Instance instance, const wsi::Window& window) noexcept -> Expected>; - // clang-format off - // private: - // clang-format on - Surface(PrivateTag, view::Instance) noexcept; - auto do_init(PrivateTag) noexcept -> Expected; - auto do_init(PrivateTag, const wsi::Window&) noexcept -> Expected; + private: + using UseNamedConstructors::allocate; + using UseNamedConstructors::create; }; + + namespace view { + class SurfaceImplementation: public GpuObjectViewImplementation { + public: + using GpuObjectViewImplementation::GpuObjectViewImplementation; + using GpuObjectViewImplementation::operator=; + }; + } // namespace view } // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// @@ -83,53 +84,54 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Surface::Surface(PrivateTag, view::Instance instance) noexcept - : OwnedByInstance { std::move(instance), auto(vkDestroySurfaceKHR) } { + inline SurfaceImplementation::SurfaceImplementation(PrivateTag, view::Instance&& instance) noexcept + : GpuObjectImplementation { std::move(instance), auto(vkDestroySurfaceKHR) } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Surface::~Surface() = default; + inline SurfaceImplementation::~SurfaceImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Surface::Surface(Surface&&) noexcept = default; + inline SurfaceImplementation::SurfaceImplementation(SurfaceImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Surface::operator=(Surface&&) noexcept -> Surface& = default; + inline auto SurfaceImplementation::operator=(SurfaceImplementation&&) noexcept -> SurfaceImplementation& = default; #if false ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE inline auto Surface::create_offscreen(view::Instance instance) noexcept + STORMKIT_FORCE_INLINE inline auto SurfaceImplementation::create_offscreen(view::Instance instance) noexcept -> Expected { - return create(std::move(instance)); + return UseNamedConstructors::create(std::move(instance)); } ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE inline auto Surface::allocate_offscreen(view::Instance instance) noexcept + STORMKIT_FORCE_INLINE inline auto SurfaceImplementation::allocate_offscreen(view::Instance instance) noexcept -> Expected> { - return allocate(std::move(instance)); + return UseNamedConstructors::allocate(std::move(instance)); } #endif ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Surface::create_from_window(view::Instance instance, const wsi::Window& window) noexcept -> Expected { - return create(std::move(instance), window); + inline auto SurfaceImplementation::create_from_window(view::Instance instance, const wsi::Window& window) noexcept + -> Expected { + return UseNamedConstructors::create(std::move(instance), window); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Surface::allocate_from_window(view::Instance instance, const wsi::Window& window) noexcept + inline auto SurfaceImplementation::allocate_from_window(view::Instance instance, const wsi::Window& window) noexcept -> Expected> { - return allocate(std::move(instance), window); + return UseNamedConstructors::allocate(std::move(instance), window); } } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/core/sync.cppm b/modules/stormkit/gpu/core/sync.cppm index b1f6d006f..4407832c9 100644 --- a/modules/stormkit/gpu/core/sync.cppm +++ b/modules/stormkit/gpu/core/sync.cppm @@ -18,103 +18,77 @@ import std; import stormkit.core; import :vulkan; +import :base; + import :structs; +import :objects; + +import :instance; import :device; -export namespace stormkit::gpu { - class Fence; - class Semaphore; +namespace stormkit::gpu { + export { + struct FenceInterfaceBase { + enum class Status { + SIGNALED, + UNSIGNALED, + }; + }; - namespace view { - class Fence; - using Semaphore = DeviceObject; - } // namespace view + template + class STORMKIT_GPU_API FenceInterface final: public FenceInterfaceBase, public DeviceObject { + public: + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = FenceTag; - namespace meta { - template<> - struct ObjectInfo { - using Of = Fence; - using ValueType = VkFence; - using DeleterType = PFN_vkDestroyFence VolkDeviceTable::*; - using ViewType = view::Fence; - using OwnedBy = Device; + using Status = FenceInterfaceBase::Status; - static constexpr auto DEBUG_TYPE = DebugObjectType::FENCE; + auto status() const noexcept -> Expected; + auto wait(const std::chrono::milliseconds& wait_for = std::chrono::milliseconds::max()) const noexcept + -> Expected; + auto reset() const noexcept -> Expected; }; - template<> - struct ObjectInfo { - using Of = Semaphore; - using ValueType = VkSemaphore; - using DeleterType = PFN_vkDestroySemaphore VolkDeviceTable::*; - using ViewType = view::Semaphore; - using OwnedBy = Device; - - static constexpr auto DEBUG_TYPE = DebugObjectType::SEMAPHORE; + template + class SemaphoreInterface final: public DeviceObject { + public: + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = SemaphoreTag; }; - } // namespace meta + } - class STORMKIT_GPU_API Fence: public OwnedByDevice { + class STORMKIT_GPU_API FenceImplementation: public GpuObjectImplementation { public: - enum class Status { - SIGNALED, - UNSIGNALED, - }; + FenceImplementation(PrivateTag, view::Device&&) noexcept; + auto do_init(PrivateTag, bool = false) noexcept -> Expected; static auto create_signaled(view::Device device) noexcept -> Expected; static auto allocate_signaled(view::Device device) noexcept -> Expected>; - ~Fence(); - - Fence(const Fence&) = delete; - auto operator=(const Fence&) -> Fence& = delete; - - Fence(Fence&&) noexcept; - auto operator=(Fence&&) noexcept -> Fence&; - - auto status() const noexcept -> Expected; - auto wait(const std::chrono::milliseconds& wait_for = std::chrono::milliseconds::max()) const noexcept - -> Expected; - auto reset() const noexcept -> Expected; - - // clang-format off - // private: - // clang-format on - Fence(PrivateTag, view::Device) noexcept; - auto do_init(PrivateTag, bool = false) noexcept -> Expected; }; namespace view { - class STORMKIT_GPU_API Fence: public view::DeviceObject { + class FenceImplementation: public GpuObjectViewImplementation { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; - - using view::DeviceObject::DeviceObject; - - auto status() const noexcept -> Expected; - auto wait(const std::chrono::milliseconds& wait_for = std::chrono::milliseconds::max()) const noexcept - -> Expected; - auto reset() const noexcept -> Expected; + using GpuObjectViewImplementation::GpuObjectViewImplementation; + using GpuObjectViewImplementation::operator=; }; } // namespace view - class STORMKIT_GPU_API Semaphore: public OwnedByDevice { + class STORMKIT_GPU_API SemaphoreImplementation: public GpuObjectImplementation { public: - ~Semaphore(); - - Semaphore(const Semaphore&) = delete; - auto operator=(const Semaphore&) -> Semaphore& = delete; - - Semaphore(Semaphore&&) noexcept; - auto operator=(Semaphore&&) noexcept -> Semaphore&; - - // clang-format off - // private: - // clang-format on - Semaphore(PrivateTag, view::Device) noexcept; + SemaphoreImplementation(PrivateTag, view::Device&&) noexcept; auto do_init(PrivateTag) noexcept -> Expected; }; + + namespace view { + class SemaphoreImplementation: public GpuObjectViewImplementation { + public: + using GpuObjectViewImplementation::GpuObjectViewImplementation; + using GpuObjectViewImplementation::operator=; + }; + } // namespace view } // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// @@ -124,91 +98,46 @@ export namespace stormkit::gpu { namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline Fence::Fence(PrivateTag, view::Device device) noexcept - : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyFence } { + inline auto DeviceInterface::wait_for_fence(view::Fence fence, const std::chrono::milliseconds& timeout) const noexcept + -> Expected { + return wait_for_fences(as_views(std::move(fence)), true, timeout); } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto Fence::create_signaled(view::Device device) noexcept -> Expected { - return create(std::move(device), true); + inline auto DeviceInterface::reset_fence(view::Fence fence) const noexcept -> Expected { + return reset_fences(as_views(std::move(fence))); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Fence::allocate_signaled(view::Device device) noexcept -> Expected> { - return allocate(std::move(device), true); + inline FenceImplementation::FenceImplementation(PrivateTag, view::Device&& device) noexcept + : GpuObjectImplementation { std::move(device), &VolkDeviceTable::vkDestroyFence } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Fence::~Fence() = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Fence::Fence(Fence&&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Fence::operator=(Fence&&) noexcept -> Fence& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Semaphore::Semaphore(PrivateTag, view::Device device) noexcept - : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroySemaphore } { + inline auto FenceImplementation::create_signaled(view::Device device) noexcept -> Expected { + return UseNamedConstructors::create(std::move(device), true); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Semaphore::~Semaphore() = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Semaphore::Semaphore(Semaphore&&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Semaphore::operator=(Semaphore&&) noexcept -> Semaphore& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Device::wait_for_fence(view::Fence fence, const std::chrono::milliseconds& timeout) const noexcept - -> Expected { - return wait_for_fences(as_views(std::move(fence)), true, timeout); + inline auto FenceImplementation::allocate_signaled(view::Device device) noexcept -> Expected> { + return UseNamedConstructors::allocate(std::move(device), true); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Device::reset_fence(view::Fence fence) const noexcept -> Expected { - return reset_fences(as_views(std::move(fence))); + inline SemaphoreImplementation::SemaphoreImplementation(PrivateTag, view::Device&& device) noexcept + : GpuObjectImplementation { std::move(device), &VolkDeviceTable::vkDestroySemaphore } { } - - namespace view { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Device::wait_for_fence(view::Fence fence, const std::chrono::milliseconds& timeout) const noexcept - -> Expected { - return wait_for_fences(as_views(std::move(fence)), true, timeout); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Device::reset_fence(view::Fence fence) const noexcept -> Expected { - return reset_fences(as_views(std::move(fence))); - } - } // namespace view } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/execution.cppm b/modules/stormkit/gpu/execution.cppm index 80f2671cd..cda4a4c1d 100644 --- a/modules/stormkit/gpu/execution.cppm +++ b/modules/stormkit/gpu/execution.cppm @@ -6,6 +6,7 @@ export module stormkit.gpu.execution; export import :command_buffer; export import :descriptors; +export import :objects; export import :pipeline; export import :raster_pipeline; export import :render_pass; diff --git a/modules/stormkit/gpu/execution/command_buffer.cppm b/modules/stormkit/gpu/execution/command_buffer.cppm index 65a6bed1d..a3795feac 100644 --- a/modules/stormkit/gpu/execution/command_buffer.cppm +++ b/modules/stormkit/gpu/execution/command_buffer.cppm @@ -23,75 +23,76 @@ import :descriptors; import :render_pass; import :pipeline; import :swapchain; +import :objects; namespace stdr = std::ranges; namespace cmonadic = stormkit::core::monadic; -export namespace stormkit::gpu { - class SwapChain; - class Queue; - class CommandBuffer; - class CommandPool; +namespace stormkit::gpu { + export { + struct RenderPassInheritanceInfo { + std::optional render_pass = std::nullopt; + u32 subpass = 0; + std::optional framebuffer = std::nullopt; + }; - namespace view { - class Queue; - class CommandBuffer; - class CommandPool; - } // namespace view + struct RenderingInheritanceInfo { + u32 view_mask = 0; + std::vector color_attachments = {}; + std::optional depth_attachment = std::nullopt; + std::optional stencil_attachment = std::nullopt; + SampleCountFlag rasterization_samples = SampleCountFlag::C1; + }; - namespace meta { - template<> - struct ObjectInfo { - using Of = Queue; - using ValueType = VkQueue; - using DeleterType = decltype(cmonadic::noop()); - using ViewType = view::Queue; - using OwnedBy = Device; + using InheritanceInfo = std::variant; - static constexpr auto DEBUG_TYPE = DebugObjectType::QUEUE; - }; + struct RenderingInfo { + struct Attachment { + struct Resolve { + view::ImageView image_view; + ResolveModeFlag mode; + ImageLayout layout = ImageLayout::ATTACHMENT_OPTIMAL; + }; - template<> - struct ObjectInfo { - using Of = CommandBuffer; - using ValueType = VkCommandBuffer; - using DeleterType = decltype(cmonadic::noop()); - using ViewType = view::CommandBuffer; - using OwnedBy = Device; + view::ImageView image_view; + ImageLayout layout = ImageLayout::ATTACHMENT_OPTIMAL; - static constexpr auto DISABLE_CREATE_ALLOCATE = true; - static constexpr auto DEBUG_TYPE = DebugObjectType::COMMAND_BUFFER; - }; + std::optional resolve = std::nullopt; - template<> - struct ObjectInfo { - using Of = CommandPool; - using ValueType = VkCommandPool; - using DeleterType = PFN_vkDestroyCommandPool VolkDeviceTable::*; - using ViewType = view::CommandPool; - using OwnedBy = Device; + AttachmentLoadOperation load_op = AttachmentLoadOperation::CLEAR; + AttachmentStoreOperation store_op = AttachmentStoreOperation::STORE; + + std::optional clear_value = std::nullopt; + }; - static constexpr auto DEBUG_TYPE = DebugObjectType::COMMAND_POOL; + math::irect render_area; + u32 layer_count = 1u; + u32 view_mask = 0u; + + std::vector color_attachments = {}; + std::optional depth_attachment = std::nullopt; + std::optional stencil_attachment = std::nullopt; }; - } // namespace meta + } - class STORMKIT_GPU_API Queue: public OwnedByDevice { - public: + struct QueueInterfaceBase { struct SubmitInfo { std::span wait_semaphores = {}; std::span wait_dst_stages = {}; std::span command_buffers = {}; std::span signal_semaphores = {}; }; + }; - ~Queue() noexcept; - - Queue(const Queue&) = delete; - auto operator=(const Queue&) = delete; + export template + class QueueInterface final: public DeviceObject, public QueueInterfaceBase { + public: + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = QueueTag; - Queue(Queue&&) noexcept; - auto operator=(Queue&&) noexcept -> Queue&; + using QueueInterfaceBase::SubmitInfo; auto wait_idle() const noexcept -> Expected; @@ -107,367 +108,139 @@ export namespace stormkit::gpu { std::span image_indices) const noexcept -> Expected; [[nodiscard]] - auto entry() const noexcept -> const Device::QueueEntry&; - - // clang-format off - // private: - // clang-format on - Queue(PrivateTag, view::Device&& device) noexcept; - auto do_init(PrivateTag, const Device::QueueEntry&) -> void; - - private: - Device::QueueEntry m_entry; - }; - - namespace view { - class Queue: public DeviceObject { - public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; - - Queue(const gpu::Queue& of) noexcept; - template T> - Queue(const T& of) noexcept; - ~Queue() noexcept; - - Queue(const Queue&) noexcept; - auto operator=(const Queue&) noexcept -> Queue&; - - Queue(Queue&&) noexcept; - auto operator=(Queue&&) noexcept -> Queue&; - - auto wait_idle() const noexcept -> Expected; - - auto submit(std::span submit_infos, - std::optional fence = std::nullopt) const noexcept -> Expected; - - auto submit(const gpu::Queue::SubmitInfo& submit_info, std::optional fence = std::nullopt) const noexcept - -> Expected; - - [[nodiscard]] - auto present(std::span swapchains, - std::span wait_semaphores, - std::span image_indices) const noexcept -> Expected; - - [[nodiscard]] - auto entry() const noexcept -> const gpu::Device::QueueEntry&; - - private: - gpu::Device::QueueEntry m_entry; - }; - } // namespace view - - struct RenderPassInheritanceInfo { - std::optional render_pass = std::nullopt; - u32 subpass = 0; - std::optional framebuffer = std::nullopt; + auto entry() const noexcept -> const QueueEntry&; }; - struct RenderingInheritanceInfo { - u32 view_mask = 0; - std::vector color_attachments = {}; - std::optional depth_attachment = std::nullopt; - std::optional stencil_attachment = std::nullopt; - SampleCountFlag rasterization_samples = SampleCountFlag::C1; - }; - - using InheritanceInfo = std::variant; - - struct RenderingInfo { - struct Attachment { - struct Resolve { - gpu::view::ImageView image_view; - ResolveModeFlag mode; - gpu::ImageLayout layout = ImageLayout::ATTACHMENT_OPTIMAL; - }; - - ref image_view; - gpu::ImageLayout layout = ImageLayout::ATTACHMENT_OPTIMAL; - - std::optional resolve = std::nullopt; - - AttachmentLoadOperation load_op = AttachmentLoadOperation::CLEAR; - AttachmentStoreOperation store_op = AttachmentStoreOperation::STORE; - - std::optional clear_value = std::nullopt; - }; - - math::irect render_area; - u32 layer_count = 1u; - u32 view_mask = 0u; - - std::vector color_attachments = {}; - std::optional depth_attachment = std::nullopt; - std::optional stencil_attachment = std::nullopt; - }; - - class STORMKIT_GPU_API CommandBuffer: public OwnedByDevice { - public: + struct CommandBufferInterfaceBase { enum class State { INITIAL, RECORDING, EXECUTABLE, }; - using RecordClosure = FunctionRef; - using Deleter = std::function; - ~CommandBuffer() noexcept; - - CommandBuffer(const CommandBuffer&) = delete; - auto operator=(const CommandBuffer&) -> CommandBuffer& = delete; - - CommandBuffer(CommandBuffer&&) noexcept; - auto operator=(CommandBuffer&&) noexcept -> CommandBuffer&; - - [[nodiscard]] - auto state() const noexcept -> State; - [[nodiscard]] - auto level() const noexcept -> CommandBufferLevel; - - auto record(RecordClosure record_closure, - bool one_time_submit = false, - InheritanceInfo inheritance_info = std::monostate {}) noexcept -> Expected; - - auto reset() noexcept -> Expected; - auto begin(bool one_time_submit = false, InheritanceInfo inheritance_info = std::monostate {}) noexcept -> Expected; - auto end() noexcept -> Expected; - - auto begin_debug_region(std::string_view name, const fcolor_rgb& color = colors::WHITE) const noexcept - -> const CommandBuffer&; - auto insert_debug_label(std::string_view name, const fcolor_rgb& color = colors::WHITE) const noexcept - -> const CommandBuffer&; - auto end_debug_region() const noexcept -> const CommandBuffer&; - - auto begin_rendering(const RenderingInfo& info, bool secondary_commandbuffers = false) const noexcept - -> const CommandBuffer&; - auto begin_render_pass(view::RenderPass render_pass, - view::FrameBuffer framebuffer, - std::span clear_values = std::array { ClearValue { - ClearColor { .color = colors::SILVER } } }, - bool secondary_commandbuffers = false) const noexcept -> const CommandBuffer&; - auto next_subpass() const noexcept -> const CommandBuffer&; - auto end_render_pass() const noexcept -> const CommandBuffer&; - auto end_rendering() const noexcept -> const CommandBuffer&; - - auto bind_pipeline(view::Pipeline pipeline) const noexcept -> const CommandBuffer&; - auto set_viewport(u32 first_viewport, std::span viewports) const noexcept -> const CommandBuffer&; - auto set_scissor(u32 first_scissor, std::span scissors) const noexcept -> const CommandBuffer&; - auto set_line_width(f32 width) const noexcept -> const CommandBuffer&; - auto set_depth_bias(f32 constant_factor, f32 clamp, f32 slope_factor) const noexcept -> const CommandBuffer&; - auto set_blend_constants(std::span constants) const noexcept -> const CommandBuffer&; - auto set_depth_bounds(f32 min, f32 max) const noexcept -> const CommandBuffer&; - auto set_stencil_compare_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBuffer&; - auto set_stencil_write_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBuffer&; - auto set_stencil_reference(StencilFaceFlag face, u32 reference) const noexcept -> const CommandBuffer&; - - auto dispatch(u32 group_count_x, u32 group_count_y, u32 group_count_z) const noexcept -> const CommandBuffer&; - - auto draw(u32 vertex_count, u32 instance_count = 1u, u32 first_vertex = 0, u32 first_instance = 0) const noexcept - -> const CommandBuffer&; - auto draw_indexed(u32 index_count, - u32 instance_count = 1u, - u32 first_index = 0u, - i32 vertex_offset = 0, - u32 first_instance = 0u) const noexcept -> const CommandBuffer&; - auto draw_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept -> const CommandBuffer&; - auto draw_indexed_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept - -> const CommandBuffer&; - - auto bind_vertex_buffers(std::span buffers, std::span offsets) const noexcept - -> const CommandBuffer&; - auto bind_index_buffer(view::Buffer buffer, u64 offset = 0, bool large_indices = false) const noexcept - -> const CommandBuffer&; - auto bind_descriptor_sets(view::Pipeline pipeline, - view::PipelineLayout layout, - std::span descriptor_sets, - std::span dynamic_offsets = {}) const noexcept -> const CommandBuffer&; - - auto copy_buffer(view::Buffer src, view::Buffer dst, usize size, u64 src_offset = 0u, u64 dst_offset = 0u) const noexcept - -> const CommandBuffer&; - auto copy_buffer_to_image(view::Buffer src, view::Image dst, std::span buffer_image_copies = {}) - const noexcept -> const CommandBuffer&; - auto copy_image_to_buffer(view::Image src, view::Buffer dst, std::span buffer_image_copies = {}) - const noexcept -> const CommandBuffer&; - auto copy_image(view::Image src, - view::Image dst, - ImageLayout src_layout, - ImageLayout dst_layout, - const ImageSubresourceLayers& src_subresource_layers, - const ImageSubresourceLayers& dst_subresource_layers, - const math::uextent3& extent) const noexcept -> const CommandBuffer&; - - auto resolve_image(view::Image src, - view::Image dst, - ImageLayout src_layout, - ImageLayout dst_layout, - const ImageSubresourceLayers& src_subresource_layers = {}, - const ImageSubresourceLayers& dst_subresource_layers = {}) const noexcept -> const CommandBuffer&; - - auto blit_image(view::Image src, - view::Image dst, - ImageLayout src_layout, - ImageLayout dst_layout, - std::span regions, - Filter filter) const noexcept -> const CommandBuffer&; - - auto transition_image_layout(view::Image image, - ImageLayout src_layout, - ImageLayout dst_layout, - const ImageSubresourceRange& subresource_range = {}) const noexcept -> const CommandBuffer&; - - auto execute_sub_command_buffers(std::span commandbuffers) const noexcept - -> const CommandBuffer&; - - auto pipeline_barrier(PipelineStageFlag src_mask, - PipelineStageFlag dst_mask, - DependencyFlag dependency, - std::span memory_barriers, - std::span buffer_memory_barriers, - std::span image_memory_barriers) const noexcept -> const CommandBuffer&; - - auto push_constants(view::PipelineLayout pipeline_layout, - ShaderStageFlag stage, - std::span data, - u32 offset = 0u) const noexcept -> const CommandBuffer&; - - auto submit(view::Queue queue, - std::span wait_semaphores = {}, - std::span wait_dst_stages = {}, - std::span signal_semaphores = {}, - std::optional fence = std::nullopt) const noexcept -> Expected; - - // clang-format off - // private: - // clang-format on - CommandBuffer(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, CommandBufferLevel, VkCommandBuffer&&, Deleter&&) noexcept -> void; - - private: - static auto create(view::Device&&, CommandBufferLevel, VkCommandBuffer&&, Deleter&&) noexcept -> CommandBuffer; - static auto allocate(view::Device&&, CommandBufferLevel, VkCommandBuffer&&, Deleter&&) noexcept -> Heap; - - CommandBufferLevel m_level = CommandBufferLevel::PRIMARY; - - Deleter m_deleter; - - State m_state = State::INITIAL; - - friend struct CommandBufferAPI; - friend class CommandPool; - friend class view::CommandPool; }; - namespace view { - class STORMKIT_GPU_API CommandBuffer: public DeviceObject { + export { + template + class CommandBufferInterface final: public DeviceObject, public CommandBufferInterfaceBase { public: - CommandBuffer(const gpu::CommandBuffer& of) noexcept; - template T> - CommandBuffer(const T& of) noexcept; - ~CommandBuffer() noexcept; - - CommandBuffer(const CommandBuffer&) noexcept; - auto operator=(const CommandBuffer&) noexcept -> CommandBuffer&; + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = CommandBufferTag; - CommandBuffer(CommandBuffer&&) noexcept; - auto operator=(CommandBuffer&&) noexcept -> CommandBuffer&; + using CommandBufferInterfaceBase::RecordClosure; + using CommandBufferInterfaceBase::State; [[nodiscard]] - auto state() const noexcept -> gpu::CommandBuffer::State; + auto state() const noexcept -> State; [[nodiscard]] auto level() const noexcept -> CommandBufferLevel; + auto record(this auto&, + RecordClosure record_closure, + bool one_time_submit = false, + InheritanceInfo inheritance_info = std::monostate {}) noexcept -> Expected; + + auto reset() noexcept -> Expected; + auto begin(bool one_time_submit = false, InheritanceInfo inheritance_info = std::monostate {}) noexcept + -> Expected; + auto end() noexcept -> Expected; + auto begin_debug_region(std::string_view name, const fcolor_rgb& color = colors::WHITE) const noexcept - -> const CommandBuffer&; + -> const CommandBufferInterface&; auto insert_debug_label(std::string_view name, const fcolor_rgb& color = colors::WHITE) const noexcept - -> const CommandBuffer&; - auto end_debug_region() const noexcept -> const CommandBuffer&; + -> const CommandBufferInterface&; + auto end_debug_region() const noexcept -> const CommandBufferInterface&; auto begin_rendering(const RenderingInfo& info, bool secondary_commandbuffers = false) const noexcept - -> const CommandBuffer&; + -> const CommandBufferInterface&; auto begin_render_pass(view::RenderPass render_pass, view::FrameBuffer framebuffer, std::span clear_values = std::array { ClearValue { ClearColor { .color = colors::SILVER } } }, - bool secondary_commandbuffers = false) const noexcept -> const CommandBuffer&; - auto next_subpass() const noexcept -> const CommandBuffer&; - auto end_render_pass() const noexcept -> const CommandBuffer&; - auto end_rendering() const noexcept -> const CommandBuffer&; - - auto bind_pipeline(view::Pipeline pipeline) const noexcept -> const CommandBuffer&; - auto set_viewport(u32 first_viewport, std::span viewports) const noexcept -> const CommandBuffer&; - auto set_scissor(u32 first_scissor, std::span scissors) const noexcept -> const CommandBuffer&; - auto set_line_width(f32 width) const noexcept -> const CommandBuffer&; - auto set_depth_bias(f32 constant_factor, f32 clamp, f32 slope_factor) const noexcept -> const CommandBuffer&; - auto set_blend_constants(std::span constants) const noexcept -> const CommandBuffer&; - auto set_depth_bounds(f32 min, f32 max) const noexcept -> const CommandBuffer&; - auto set_stencil_compare_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBuffer&; - auto set_stencil_write_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBuffer&; - auto set_stencil_reference(StencilFaceFlag face, u32 reference) const noexcept -> const CommandBuffer&; - - auto dispatch(u32 group_count_x, u32 group_count_y, u32 group_count_z) const noexcept -> const CommandBuffer&; + bool secondary_commandbuffers = false) const noexcept -> const CommandBufferInterface&; + auto next_subpass() const noexcept -> const CommandBufferInterface&; + auto end_render_pass() const noexcept -> const CommandBufferInterface&; + auto end_rendering() const noexcept -> const CommandBufferInterface&; + + auto bind_pipeline(view::Pipeline pipeline) const noexcept -> const CommandBufferInterface&; + auto set_viewport(u32 first_viewport, std::span viewports) const noexcept + -> const CommandBufferInterface&; + auto set_scissor(u32 first_scissor, std::span scissors) const noexcept + -> const CommandBufferInterface&; + auto set_line_width(f32 width) const noexcept -> const CommandBufferInterface&; + auto set_depth_bias(f32 constant_factor, f32 clamp, f32 slope_factor) const noexcept -> const CommandBufferInterface&; + auto set_blend_constants(std::span constants) const noexcept -> const CommandBufferInterface&; + auto set_depth_bounds(f32 min, f32 max) const noexcept -> const CommandBufferInterface&; + auto set_stencil_compare_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBufferInterface&; + auto set_stencil_write_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBufferInterface&; + auto set_stencil_reference(StencilFaceFlag face, u32 reference) const noexcept -> const CommandBufferInterface&; + + auto dispatch(u32 group_count_x, u32 group_count_y, u32 group_count_z) const noexcept + -> const CommandBufferInterface&; auto draw(u32 vertex_count, u32 instance_count = 1u, u32 first_vertex = 0, u32 first_instance = 0) const noexcept - -> const CommandBuffer&; + -> const CommandBufferInterface&; auto draw_indexed(u32 index_count, u32 instance_count = 1u, u32 first_index = 0u, i32 vertex_offset = 0, - u32 first_instance = 0u) const noexcept -> const CommandBuffer&; + u32 first_instance = 0u) const noexcept -> const CommandBufferInterface&; auto draw_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept - -> const CommandBuffer&; + -> const CommandBufferInterface&; auto draw_indexed_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept - -> const CommandBuffer&; + -> const CommandBufferInterface&; auto bind_vertex_buffers(std::span buffers, std::span offsets) const noexcept - -> const CommandBuffer&; + -> const CommandBufferInterface&; auto bind_index_buffer(view::Buffer buffer, u64 offset = 0, bool large_indices = false) const noexcept - -> const CommandBuffer&; + -> const CommandBufferInterface&; auto bind_descriptor_sets(view::Pipeline pipeline, view::PipelineLayout layout, std::span descriptor_sets, - std::span dynamic_offsets = {}) const noexcept -> const CommandBuffer&; + std::span dynamic_offsets = {}) const noexcept -> const CommandBufferInterface&; auto copy_buffer(view::Buffer src, view::Buffer dst, usize size, u64 src_offset = 0u, u64 dst_offset = 0u) - const noexcept -> const CommandBuffer&; + const noexcept -> const CommandBufferInterface&; auto copy_buffer_to_image(view::Buffer src, view::Image dst, std::span buffer_image_copies = {}) const noexcept - -> const CommandBuffer&; + -> const CommandBufferInterface&; auto copy_image_to_buffer(view::Image src, view::Buffer dst, std::span buffer_image_copies = {}) const noexcept - -> const CommandBuffer&; + -> const CommandBufferInterface&; auto copy_image(view::Image src, view::Image dst, ImageLayout src_layout, ImageLayout dst_layout, const ImageSubresourceLayers& src_subresource_layers, const ImageSubresourceLayers& dst_subresource_layers, - const math::uextent3& extent) const noexcept -> const CommandBuffer&; + const math::uextent3& extent) const noexcept -> const CommandBufferInterface&; auto resolve_image(view::Image src, view::Image dst, ImageLayout src_layout, ImageLayout dst_layout, const ImageSubresourceLayers& src_subresource_layers = {}, - const ImageSubresourceLayers& dst_subresource_layers = {}) const noexcept -> const CommandBuffer&; + const ImageSubresourceLayers& dst_subresource_layers = {}) const noexcept + -> const CommandBufferInterface&; auto blit_image(view::Image src, view::Image dst, ImageLayout src_layout, ImageLayout dst_layout, std::span regions, - Filter filter) const noexcept -> const CommandBuffer&; + Filter filter) const noexcept -> const CommandBufferInterface&; auto transition_image_layout(view::Image image, ImageLayout src_layout, ImageLayout dst_layout, const ImageSubresourceRange& subresource_range = {}) const noexcept - -> const CommandBuffer&; + -> const CommandBufferInterface&; auto execute_sub_command_buffers(std::span commandbuffers) const noexcept - -> const CommandBuffer&; + -> const CommandBufferInterface&; auto pipeline_barrier(PipelineStageFlag src_mask, PipelineStageFlag dst_mask, @@ -475,90 +248,160 @@ export namespace stormkit::gpu { std::span memory_barriers, std::span buffer_memory_barriers, std::span image_memory_barriers) const noexcept - -> const CommandBuffer&; + -> const CommandBufferInterface&; auto push_constants(view::PipelineLayout pipeline_layout, ShaderStageFlag stage, std::span data, - u32 offset = 0u) const noexcept -> const CommandBuffer&; + u32 offset = 0u) const noexcept -> const CommandBufferInterface&; - auto submit(view::Queue queue, + auto submit(this const auto&, + view::Queue queue, std::span wait_semaphores = {}, std::span wait_dst_stages = {}, std::span signal_semaphores = {}, - std::optional fence = std::nullopt) const noexcept -> Expected; + std::optional fence = std::nullopt) noexcept -> Expected; + }; + + template + class CommandPoolInterface final: public DeviceObject { + public: + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = CommandPoolTag; + + auto create_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected; + auto create_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected>; + + auto allocate_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected>; + auto allocate_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected>>; + + protected: + auto create_vk_command_buffers(usize, CommandBufferLevel) const noexcept -> Expected>; + + static auto delete_vk_command_buffers(view::Device, view::CommandPool, VkCommandBuffer) noexcept -> void; + }; + } + + class STORMKIT_GPU_API QueueImplementation: public GpuObjectImplementation { + public: + using SubmitInfo = QueueInterfaceBase::SubmitInfo; - private: - gpu::CommandBuffer::State m_state; - CommandBufferLevel m_level; + QueueImplementation(PrivateTag, view::Device&& device) noexcept; + auto do_init(PrivateTag, const QueueEntry&) -> void; + ~QueueImplementation() noexcept; + + QueueImplementation(const QueueImplementation&) = delete; + auto operator=(const QueueImplementation&) = delete; + + QueueImplementation(QueueImplementation&&) noexcept; + auto operator=(QueueImplementation&&) noexcept -> QueueImplementation&; + + protected: + QueueEntry m_entry; + + friend class QueueInterface; + }; + + namespace view { + class QueueImplementation: public GpuObjectViewImplementation { + public: + using SubmitInfo = QueueInterfaceBase::SubmitInfo; + + QueueImplementation(const gpu::Queue& of) noexcept; + template TContainerOrPointer> + QueueImplementation(const TContainerOrPointer&) noexcept; + ~QueueImplementation() noexcept; + + QueueImplementation(const QueueImplementation&) noexcept; + auto operator=(const QueueImplementation&) noexcept -> QueueImplementation&; + + QueueImplementation(QueueImplementation&&) noexcept; + auto operator=(QueueImplementation&&) noexcept -> QueueImplementation&; + + protected: + QueueEntry m_entry; }; } // namespace view - class STORMKIT_GPU_API CommandPool: public OwnedByDevice { + class STORMKIT_GPU_API CommandBufferImplementation: public GpuObjectImplementation { public: - ~CommandPool() noexcept; + using RecordClosure = CommandBufferInterfaceBase::RecordClosure; + using State = CommandBufferInterfaceBase::State; + + using Deleter = std::function; - CommandPool(const CommandPool&) = delete; - auto operator=(const CommandPool&) = delete; + CommandBufferImplementation(PrivateTag, view::Device&&) noexcept; + auto do_init(PrivateTag, CommandBufferLevel, VkCommandBuffer&&, Deleter&&) noexcept -> void; + ~CommandBufferImplementation() noexcept; - CommandPool(CommandPool&&) noexcept; - auto operator=(CommandPool&&) noexcept -> CommandPool&; + CommandBufferImplementation(const CommandBufferImplementation&) = delete; + auto operator=(const CommandBufferImplementation&) -> CommandBufferImplementation& = delete; - auto create_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected; - auto create_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>; + CommandBufferImplementation(CommandBufferImplementation&&) noexcept; + auto operator=(CommandBufferImplementation&&) noexcept -> CommandBufferImplementation&; - auto allocate_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>; - auto allocate_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>>; + protected: + using UseNamedConstructors::allocate; + using UseNamedConstructors::create; - // clang-format off - // private: - // clang-format on - CommandPool(PrivateTag, view::Device&& device) noexcept; - auto do_init(PrivateTag) noexcept -> Expected; + Heap m_state; + CommandBufferLevel m_level = CommandBufferLevel::PRIMARY; - private: - auto create_vk_command_buffers(usize, CommandBufferLevel) const noexcept -> Expected>; + Deleter m_deleter; - static auto delete_vk_command_buffers(view::Device, view::CommandPool, VkCommandBuffer) noexcept -> void; + friend class CommandPoolInterface; + friend class CommandPoolInterface; + friend class view::CommandBufferImplementation; }; namespace view { - class CommandPool: public DeviceObject { + class CommandBufferImplementation: public GpuObjectViewImplementation { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; + using RecordClosure = CommandBufferInterfaceBase::RecordClosure; + using State = CommandBufferInterfaceBase::State; - using DeviceObject::DeviceObject; - ~CommandPool() noexcept; + CommandBufferImplementation(const gpu::CommandBuffer& of) noexcept; + template TContainerOrPointer> + CommandBufferImplementation(const TContainerOrPointer&) noexcept; + ~CommandBufferImplementation() noexcept; - CommandPool(const CommandPool&) noexcept; - auto operator=(const CommandPool&) noexcept -> CommandPool&; + CommandBufferImplementation(const CommandBufferImplementation&) noexcept; + auto operator=(const CommandBufferImplementation&) noexcept -> CommandBufferImplementation&; - CommandPool(CommandPool&&) noexcept; - auto operator=(CommandPool&&) noexcept -> CommandPool&; + CommandBufferImplementation(CommandBufferImplementation&&) noexcept; + auto operator=(CommandBufferImplementation&&) noexcept -> CommandBufferImplementation&; - auto create_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected; - auto create_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>; + protected: + ref m_state; + CommandBufferLevel m_level; + }; + } // namespace view - auto allocate_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>; - auto allocate_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>>; + class STORMKIT_GPU_API CommandPoolImplementation: public GpuObjectImplementation { + public: + CommandPoolImplementation(PrivateTag, view::Device&& device) noexcept; + auto do_init(PrivateTag) noexcept -> Expected; + ~CommandPoolImplementation() noexcept; - private: - auto create_vk_command_buffers(usize, CommandBufferLevel) const noexcept -> Expected>; + CommandPoolImplementation(const CommandPoolImplementation&) = delete; + auto operator=(const CommandPoolImplementation&) = delete; - static auto delete_vk_command_buffers(Device, CommandPool, VkCommandBuffer) noexcept -> void; + CommandPoolImplementation(CommandPoolImplementation&&) noexcept; + auto operator=(CommandPoolImplementation&&) noexcept -> CommandPoolImplementation&; + }; + + namespace view { + class CommandPoolImplementation: public GpuObjectViewImplementation { + public: + using GpuObjectViewImplementation::GpuObjectViewImplementation; + using GpuObjectViewImplementation::operator=; }; } // namespace view - } // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// @@ -568,383 +411,280 @@ export namespace stormkit::gpu { namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline Queue::Queue(PrivateTag, view::Device&& device) noexcept - : OwnedByDevice { std::move(device), cmonadic::noop() } { + inline auto QueueInterface::submit(const SubmitInfo& submit_info, std::optional fence) const noexcept + -> Expected { + return submit({ &submit_info, 1 }, std::move(fence)); } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline Queue::~Queue() noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Queue::Queue(Queue&&) noexcept = default; + inline auto QueueInterface::entry() const noexcept -> const QueueEntry& { + return Base::m_entry; + } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto Queue::operator=(Queue&&) noexcept -> Queue& = default; + inline auto CommandBufferInterface::submit(this const auto& self, + view::Queue queue, + std::span wait_semaphores, + std::span wait_dst_stages, + std::span signal_semaphores, + std::optional fence) noexcept -> Expected { + auto cmbs = as_views(self); + auto submit_infos = std::array { + Queue::SubmitInfo { .wait_semaphores = wait_semaphores, + .wait_dst_stages = wait_dst_stages, + .command_buffers = cmbs, + .signal_semaphores = signal_semaphores } + }; - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Queue::submit(const SubmitInfo& submit_info, std::optional fence) const noexcept -> Expected { - return submit({ &submit_info, 1 }, std::move(fence)); + return queue.submit(submit_infos, std::move(fence)); } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto Queue::entry() const noexcept -> const Device::QueueEntry& { - return m_entry; + inline auto CommandBufferInterface::state() const noexcept -> State { + EXPECTS(Base::m_state != nullptr); + return *Base::m_state; } - namespace view { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Queue::Queue(const gpu::Queue& of) noexcept - : DeviceObject { of }, m_entry { of.entry() } { - } - - /////////////////////////////////// - /////////////////////////////////// - template T> - STORMKIT_FORCE_INLINE - inline Queue::Queue(const T& of) noexcept - : DeviceObject { of }, m_entry { of->entry() } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Queue::~Queue() noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Queue::Queue(const Queue&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Queue::operator=(const Queue&) noexcept -> Queue& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Queue::Queue(Queue&&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Queue::operator=(Queue&&) noexcept -> Queue& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Queue::submit(const gpu::Queue::SubmitInfo& submit_info, std::optional fence) const noexcept - -> Expected { - return submit({ &submit_info, 1 }, std::move(fence)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Queue::entry() const noexcept -> const gpu::Device::QueueEntry& { - return m_entry; - } - } // namespace view - ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline CommandBuffer::CommandBuffer(PrivateTag, view::Device&& device) noexcept - : OwnedByDevice { std::move(device), cmonadic::noop() } { + inline auto CommandBufferInterface::level() const noexcept -> CommandBufferLevel { + return Base::m_level; } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto CommandBuffer::create(view::Device&& device, - CommandBufferLevel level, - VkCommandBuffer&& cmb, - Deleter&& deleter) noexcept -> CommandBuffer { - auto out = CommandBuffer { PRIVATE, std::move(device) }; - out.do_init(PRIVATE, level, std::move(cmb), std::move(deleter)); - return out; + inline auto CommandBufferInterface::record(this auto& self, + RecordClosure record_closure, + bool one_time_submit, + InheritanceInfo inheritance_info) noexcept -> Expected { + Try(self.begin(one_time_submit, std::move(inheritance_info))); + record_closure(gpu::as_view(self)); + Try(self.end()); + Return {}; } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto CommandBuffer::allocate(view::Device&& device, - CommandBufferLevel level, - VkCommandBuffer&& cmb, - Deleter&& deleter) noexcept -> Heap { - auto out = core::allocate_unsafe(PRIVATE, std::move(device)); - out->do_init(PRIVATE, level, std::move(cmb), std::move(deleter)); - return out; + inline auto CommandPoolInterface::create_command_buffer(CommandBufferLevel level) const noexcept + -> Expected { + auto device = Base::owner(); + auto vk_handle = Try(create_vk_command_buffers(1, level)).front(); + Return CommandBuffer::create(std::move(device), level, std::move(vk_handle), delete_vk_command_buffers); } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline CommandBuffer::~CommandBuffer() noexcept = default; + inline auto CommandPoolInterface::create_command_buffers(usize count, CommandBufferLevel level) const noexcept + -> Expected> { + Return transform(Try(create_vk_command_buffers(count, level)), [this, &level](auto vk_handle) noexcept { + auto device = Base::owner(); + return CommandBuffer::create(std::move(device), level, std::move(vk_handle), delete_vk_command_buffers); + }); + } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline CommandBuffer::CommandBuffer(CommandBuffer&&) noexcept = default; + inline auto CommandPoolInterface::allocate_command_buffer(CommandBufferLevel level) const noexcept + -> Expected> { + auto device = Base::owner(); + auto vk_handle = Try(create_vk_command_buffers(1, level)).front(); + Return CommandBuffer::allocate(std::move(device), level, std::move(vk_handle), delete_vk_command_buffers); + } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto CommandBuffer::operator=(CommandBuffer&&) noexcept -> CommandBuffer& = default; + inline auto CommandPoolInterface::allocate_command_buffers(usize count, CommandBufferLevel level) const noexcept + -> Expected>> { + Return transform(Try(create_vk_command_buffers(count, level)), [this, &level](auto vk_handle) noexcept { + auto device = Base::owner(); + return CommandBuffer::allocate(std::move(device), level, std::move(vk_handle), delete_vk_command_buffers); + }); + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::submit(view::Queue queue, - std::span wait_semaphores, - std::span wait_dst_stages, - std::span signal_semaphores, - std::optional fence) const noexcept -> Expected { - auto cmbs = as_views(*this); - auto submit_infos = std::array { - Queue::SubmitInfo { .wait_semaphores = wait_semaphores, - .wait_dst_stages = wait_dst_stages, - .command_buffers = cmbs, - .signal_semaphores = signal_semaphores } - }; - - return queue.submit(submit_infos, std::move(fence)); + inline QueueImplementation::QueueImplementation(PrivateTag, view::Device&& device) noexcept + : GpuObjectImplementation { std::move(device), cmonadic::noop() } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::state() const noexcept -> State { - return m_state; - } + inline QueueImplementation::~QueueImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::level() const noexcept -> CommandBufferLevel { - return m_level; - } + inline QueueImplementation::QueueImplementation(QueueImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::record(RecordClosure record_closure, - bool one_time_submit, - InheritanceInfo inheritance_info) noexcept -> Expected { - Try(begin(one_time_submit, std::move(inheritance_info))); - record_closure(*this); - Try(end()); - Return {}; - } + inline auto QueueImplementation::operator=(QueueImplementation&&) noexcept -> QueueImplementation& = default; namespace view { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline CommandBuffer::CommandBuffer(const gpu::CommandBuffer& of) noexcept - : DeviceObject { of }, m_state { of.state() }, m_level { of.level() } { - } - - /////////////////////////////////// - /////////////////////////////////// - template T> - STORMKIT_FORCE_INLINE - inline CommandBuffer::CommandBuffer(const T& of) noexcept - : DeviceObject { of }, m_state { of->state() }, m_level { of->level() } { + inline QueueImplementation::QueueImplementation(const gpu::Queue& of) noexcept + : GpuObjectViewImplementation { of }, m_entry { of.entry() } { } ///////////////////////////////////// ///////////////////////////////////// + template TContainerOrPointer> STORMKIT_FORCE_INLINE - inline CommandBuffer::~CommandBuffer() noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline CommandBuffer::CommandBuffer(const CommandBuffer&) noexcept = default; + inline QueueImplementation::QueueImplementation(const TContainerOrPointer& of) noexcept + : QueueImplementation { *of } { + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::operator=(const CommandBuffer&) noexcept -> CommandBuffer& = default; + inline QueueImplementation::~QueueImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline CommandBuffer::CommandBuffer(CommandBuffer&&) noexcept = default; + inline QueueImplementation::QueueImplementation(const QueueImplementation&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::operator=(CommandBuffer&&) noexcept -> CommandBuffer& = default; + inline auto QueueImplementation::operator=(const QueueImplementation&) noexcept -> QueueImplementation& = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::submit(Queue queue, - std::span wait_semaphores, - std::span wait_dst_stages, - std::span signal_semaphores, - std::optional fence) const noexcept -> Expected { - auto cmbs = as_views(*this); - auto submit_infos = std::array { - gpu::Queue::SubmitInfo { .wait_semaphores = wait_semaphores, - .wait_dst_stages = wait_dst_stages, - .command_buffers = cmbs, - .signal_semaphores = signal_semaphores } - }; - - return queue.submit(submit_infos, std::move(fence)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandBuffer::state() const noexcept -> gpu::CommandBuffer::State { - return m_state; - } + inline QueueImplementation::QueueImplementation(QueueImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandBuffer::level() const noexcept -> CommandBufferLevel { - return m_level; - } + inline auto QueueImplementation::operator=(QueueImplementation&&) noexcept -> QueueImplementation& = default; } // namespace view ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline CommandPool::CommandPool(PrivateTag, view::Device&& device) noexcept - : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyCommandPool } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline CommandPool::~CommandPool() noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline CommandPool::CommandPool(CommandPool&&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandPool::operator=(CommandPool&&) noexcept -> CommandPool& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandPool::create_command_buffer(CommandBufferLevel level) const noexcept -> Expected { - auto vk_handle = Try(create_vk_command_buffers(1, level)).front(); - Return CommandBuffer::create(auto(device()), level, std::move(vk_handle), delete_vk_command_buffers); + inline CommandBufferImplementation::CommandBufferImplementation(PrivateTag, view::Device&& device) noexcept + : GpuObjectImplementation { std::move(device), cmonadic::noop() } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandPool::create_command_buffers(usize count, CommandBufferLevel level) const noexcept - -> Expected> { - Return transform(Try(create_vk_command_buffers(count, level)), [this, &level](auto vk_handle) noexcept { - return CommandBuffer::create(auto(device()), level, std::move(vk_handle), delete_vk_command_buffers); - }); - } + inline CommandBufferImplementation::~CommandBufferImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandPool::allocate_command_buffer(CommandBufferLevel level) const noexcept -> Expected> { - auto vk_handle = Try(create_vk_command_buffers(1, level)).front(); - Return CommandBuffer::allocate(auto(device()), level, std::move(vk_handle), delete_vk_command_buffers); - } + inline CommandBufferImplementation::CommandBufferImplementation(CommandBufferImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandPool::allocate_command_buffers(usize count, CommandBufferLevel level) const noexcept - -> Expected>> { - Return transform(Try(create_vk_command_buffers(count, level)), [this, &level](auto vk_handle) noexcept { - return CommandBuffer::allocate(auto(device()), level, std::move(vk_handle), delete_vk_command_buffers); - }); - } + inline auto CommandBufferImplementation::operator=(CommandBufferImplementation&&) noexcept + -> CommandBufferImplementation& = default; namespace view { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline CommandPool::~CommandPool() noexcept = default; + inline CommandBufferImplementation::CommandBufferImplementation(const gpu::CommandBuffer& of) noexcept + : GpuObjectViewImplementation { of }, m_state { as_ref_mut(of.m_state) }, m_level { of.level() } { + } ///////////////////////////////////// ///////////////////////////////////// + template TContainerOrPointer> STORMKIT_FORCE_INLINE - inline CommandPool::CommandPool(const CommandPool&) noexcept = default; + inline CommandBufferImplementation::CommandBufferImplementation(const TContainerOrPointer& of) noexcept + : CommandBufferImplementation { *of } { + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandPool::operator=(const CommandPool&) noexcept -> CommandPool& = default; + inline CommandBufferImplementation::~CommandBufferImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline CommandPool::CommandPool(CommandPool&&) noexcept = default; + inline CommandBufferImplementation::CommandBufferImplementation(const CommandBufferImplementation&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandPool::operator=(CommandPool&&) noexcept -> CommandPool& = default; + inline auto CommandBufferImplementation::operator=(const CommandBufferImplementation& other) noexcept + -> CommandBufferImplementation& { + if (&other == this) [[unlikely]] + return *this; - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandPool::create_command_buffer(CommandBufferLevel level) const noexcept -> Expected { - auto vk_handle = Try(create_vk_command_buffers(1, level)).front(); - Return gpu::CommandBuffer::create(auto(device()), level, std::move(vk_handle), delete_vk_command_buffers); - } + GpuObjectViewImplementation::operator=(other); - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto CommandPool::create_command_buffers(usize count, CommandBufferLevel level) const noexcept - -> Expected> { - Return transform(Try(create_vk_command_buffers(count, level)), [this, &level](auto vk_handle) noexcept { - return gpu::CommandBuffer::create(auto(device()), level, std::move(vk_handle), delete_vk_command_buffers); - }); + m_level = other.m_level; + m_state = as_ref_mut(other.m_state); + + return *this; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandPool::allocate_command_buffer(CommandBufferLevel level) const noexcept - -> Expected> { - auto vk_handle = Try(create_vk_command_buffers(1, level)).front(); - Return gpu::CommandBuffer::allocate(auto(device()), level, std::move(vk_handle), delete_vk_command_buffers); - } + inline CommandBufferImplementation::CommandBufferImplementation(CommandBufferImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto CommandPool::allocate_command_buffers(usize count, CommandBufferLevel level) const noexcept - -> Expected>> { - Return transform(Try(create_vk_command_buffers(count, level)), [this, &level](auto vk_handle) noexcept { - return gpu::CommandBuffer::allocate(auto(device()), level, std::move(vk_handle), delete_vk_command_buffers); - }); - } - + inline auto CommandBufferImplementation::operator=(CommandBufferImplementation&&) noexcept + -> CommandBufferImplementation& = default; } // namespace view + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline CommandPoolImplementation::CommandPoolImplementation(PrivateTag, view::Device&& device) noexcept + : GpuObjectImplementation { std::move(device), &VolkDeviceTable::vkDestroyCommandPool } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline CommandPoolImplementation::~CommandPoolImplementation() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline CommandPoolImplementation::CommandPoolImplementation(CommandPoolImplementation&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto CommandPoolImplementation::operator=(CommandPoolImplementation&&) noexcept + -> CommandPoolImplementation& = default; } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/execution/descriptors.cppm b/modules/stormkit/gpu/execution/descriptors.cppm index e1092a5ee..88cc542df 100644 --- a/modules/stormkit/gpu/execution/descriptors.cppm +++ b/modules/stormkit/gpu/execution/descriptors.cppm @@ -19,247 +19,184 @@ import stormkit.core; import stormkit.gpu.core; import stormkit.gpu.resource; +import :objects; + namespace stdr = std::ranges; namespace stdv = std::views; namespace cmonadic = stormkit::core::monadic; namespace cmeta = stormkit::core::meta; -export namespace stormkit::gpu { - class DescriptorSet; - class DescriptorSetLayout; - class DescriptorPool; - - namespace view { - class DescriptorSet; - class DescriptorSetLayout; - class DescriptorPool; - } // namespace view +namespace stormkit::gpu { + export { + struct BufferDescriptor { + DescriptorType type = DescriptorType::UNIFORM_BUFFER; + u32 binding; + view::Buffer buffer; + std::optional range = std::nullopt; + u32 offset = 0; + }; - namespace meta { - template<> - struct ObjectInfo { - using Of = DescriptorSet; - using ValueType = VkDescriptorSet; - using DeleterType = decltype(cmonadic::noop()); - using ViewType = view::DescriptorSet; - using OwnedBy = Device; - - static constexpr auto DISABLE_CREATE_ALLOCATE = true; - static constexpr auto DEBUG_TYPE = DebugObjectType::DESCRIPTOR_SET; + struct ImageDescriptor { + DescriptorType type = DescriptorType::COMBINED_IMAGE_SAMPLER; + u32 binding; + ImageLayout layout; + view::ImageView image_view; + view::Sampler sampler; }; - template<> - struct ObjectInfo { - using Of = DescriptorSetLayout; - using ValueType = VkDescriptorSetLayout; - using DeleterType = PFN_vkDestroyDescriptorSetLayout VolkDeviceTable::*; - using ViewType = view::DescriptorSetLayout; - using OwnedBy = Device; + using Descriptor = std::variant; - static constexpr auto DEBUG_TYPE = DebugObjectType::DESCRIPTOR_SET_LAYOUT; + struct DescriptorSetLayoutBinding { + u32 binding; + DescriptorType type; + ShaderStageFlag stages; + usize descriptor_count; }; - template<> - struct ObjectInfo { - using Of = DescriptorPool; - using ValueType = VkDescriptorPool; - using DeleterType = PFN_vkDestroyDescriptorPool VolkDeviceTable::*; - using ViewType = view::DescriptorPool; - using OwnedBy = Device; + template + class DescriptorSetInterface: public Base { + public: + using Base::Base; + using Base::operator=; + using TagType = DescriptorSetTag; - static constexpr auto DEBUG_TYPE = DebugObjectType::DESCRIPTOR_POOL; + auto update(std::span descriptors) const noexcept -> void; }; - } // namespace meta - - struct BufferDescriptor { - DescriptorType type = DescriptorType::UNIFORM_BUFFER; - u32 binding; - view::Buffer buffer; - std::optional range = std::nullopt; - u32 offset = 0; - }; + } - struct ImageDescriptor { - DescriptorType type = DescriptorType::COMBINED_IMAGE_SAMPLER; - u32 binding; - ImageLayout layout; - view::ImageView image_view; - view::Sampler sampler; + struct DescriptorSetLayoutInterfaceBase { + struct Size { + DescriptorType type; + u32 descriptor_count; + }; }; - using Descriptor = std::variant; + export { + template + class DescriptorSetLayoutInterface: public Base, public DescriptorSetLayoutInterfaceBase { + public: + using Base::Base; + using Base::operator=; + using TagType = DescriptorSetLayoutTag; - class STORMKIT_GPU_API DescriptorSet: public OwnedByDevice { - public: - using Deleter = std::function; - ~DescriptorSet() noexcept; + using DescriptorSetLayoutInterfaceBase::Size; + + [[nodiscard]] + auto bindings() const noexcept -> std::span; + }; + + template + class DescriptorPoolInterface: public Base { + public: + using Base::Base; + using Base::operator=; + using TagType = DescriptorPoolTag; + + auto create_descriptor_set(this const auto&, view::DescriptorSetLayout layout) noexcept -> Expected; + auto create_descriptor_sets(this const auto&, usize count, view::DescriptorSetLayout layout) noexcept + -> Expected>; - DescriptorSet(const DescriptorSet&) = delete; - auto operator=(const DescriptorSet&) -> DescriptorSet& = delete; + auto allocate_descriptor_set(this const auto&, view::DescriptorSetLayout layout) noexcept + -> Expected>; + auto allocate_descriptor_sets(this const auto&, usize count, view::DescriptorSetLayout layout) noexcept + -> Expected>>; - DescriptorSet(DescriptorSet&&) noexcept; - auto operator=(DescriptorSet&&) noexcept -> DescriptorSet&; + private: + auto create_vk_descriptor_sets(usize, view::DescriptorSetLayout&&) const noexcept + -> Expected>; + + static auto delete_vk_descriptor_set(view::Device, view::DescriptorPool, VkDescriptorSet) noexcept -> void; + }; + } - auto update(std::span descriptors) const noexcept -> void; + class STORMKIT_GPU_API DescriptorSetImplementation: public GpuObjectImplementation { + public: + using Deleter = std::function; - // clang-format off - // private: - // clang-format on - DescriptorSet(PrivateTag, view::Device&&) noexcept; + DescriptorSetImplementation(PrivateTag, view::Device&&) noexcept; + auto do_init(PrivateTag, VkDescriptorSet&&, Deleter&&) noexcept -> void; + ~DescriptorSetImplementation() noexcept; - private: - auto do_init(VkDescriptorSet&&, Deleter&&) noexcept -> void; + DescriptorSetImplementation(const DescriptorSetImplementation&) = delete; + auto operator=(const DescriptorSetImplementation&) -> DescriptorSetImplementation& = delete; - static auto create(view::Device&&, VkDescriptorSet&&, Deleter&&) noexcept -> DescriptorSet; - static auto allocate(view::Device&&, VkDescriptorSet&&, Deleter&&) noexcept -> Heap; + DescriptorSetImplementation(DescriptorSetImplementation&&) noexcept; + auto operator=(DescriptorSetImplementation&&) noexcept -> DescriptorSetImplementation&; + + protected: + using UseNamedConstructors::allocate; + using UseNamedConstructors::create; Deleter m_deleter; - friend class DescriptorPool; - friend class view::DescriptorPool; - }; - struct DescriptorSetLayoutBinding { - u32 binding; - DescriptorType type; - ShaderStageFlag stages; - usize descriptor_count; + friend class DescriptorPoolInterface; + friend class DescriptorPoolInterface; }; namespace view { - class DescriptorSet: public DeviceObject { + class DescriptorSetImplementation: public GpuObjectViewImplementation { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; - - using DeviceObject::DeviceObject; - ~DescriptorSet() noexcept; - - DescriptorSet(const DescriptorSet&) noexcept; - auto operator=(const DescriptorSet&) noexcept -> DescriptorSet&; - - DescriptorSet(DescriptorSet&&) noexcept; - auto operator=(DescriptorSet&&) noexcept -> DescriptorSet&; - - auto update(std::span descriptors) const noexcept -> void; + using GpuObjectViewImplementation::GpuObjectViewImplementation; + using GpuObjectViewImplementation::operator=; }; } // namespace view - class STORMKIT_GPU_API DescriptorSetLayout: public OwnedByDevice { + class STORMKIT_GPU_API DescriptorSetLayoutImplementation: public GpuObjectImplementation { public: - ~DescriptorSetLayout() noexcept; - - DescriptorSetLayout(const DescriptorSetLayout&) = delete; - auto operator=(const DescriptorSetLayout&) -> DescriptorSetLayout& = delete; - - DescriptorSetLayout(DescriptorSetLayout&&) noexcept; - auto operator=(DescriptorSetLayout&&) noexcept -> DescriptorSetLayout&; + DescriptorSetLayoutImplementation(PrivateTag, view::Device&&) noexcept; + auto do_init(PrivateTag, std::vector&&) noexcept -> Expected; + ~DescriptorSetLayoutImplementation() noexcept; - [[nodiscard]] - auto bindings() const noexcept -> std::span; + DescriptorSetLayoutImplementation(const DescriptorSetLayoutImplementation&) = delete; + auto operator=(const DescriptorSetLayoutImplementation&) -> DescriptorSetLayoutImplementation& = delete; - // clang-format off - // private: - // clang-format on - DescriptorSetLayout(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, std::vector&&) noexcept -> Expected; + DescriptorSetLayoutImplementation(DescriptorSetLayoutImplementation&&) noexcept; + auto operator=(DescriptorSetLayoutImplementation&&) noexcept -> DescriptorSetLayoutImplementation&; - private: + protected: std::vector m_bindings; }; namespace view { - class DescriptorSetLayout: public DeviceObject { + class DescriptorSetLayoutImplementation: public GpuObjectViewImplementation { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; + DescriptorSetLayoutImplementation(const gpu::DescriptorSetLayout& of) noexcept; + template TContainerOrPointer> + DescriptorSetLayoutImplementation(const TContainerOrPointer&) noexcept; + ~DescriptorSetLayoutImplementation() noexcept; - DescriptorSetLayout(const gpu::DescriptorSetLayout& of) noexcept; - template T> - DescriptorSetLayout(const T& of) noexcept; - ~DescriptorSetLayout() noexcept; + DescriptorSetLayoutImplementation(const DescriptorSetLayoutImplementation&) noexcept; + auto operator=(const DescriptorSetLayoutImplementation&) noexcept -> DescriptorSetLayoutImplementation&; - DescriptorSetLayout(const DescriptorSetLayout&) noexcept; - auto operator=(const DescriptorSetLayout&) noexcept -> DescriptorSetLayout&; + DescriptorSetLayoutImplementation(DescriptorSetLayoutImplementation&&) noexcept; + auto operator=(DescriptorSetLayoutImplementation&&) noexcept -> DescriptorSetLayoutImplementation&; - DescriptorSetLayout(DescriptorSetLayout&&) noexcept; - auto operator=(DescriptorSetLayout&&) noexcept -> DescriptorSetLayout&; - - auto bindings() const noexcept -> std::span; - - private: - std::span m_bindings; + protected: + std::span m_bindings; }; } // namespace view - class STORMKIT_GPU_API DescriptorPool: public OwnedByDevice { + class STORMKIT_GPU_API DescriptorPoolImplementation: public GpuObjectImplementation { public: - struct Size { - DescriptorType type; - u32 descriptor_count; - }; - - ~DescriptorPool() noexcept; - - DescriptorPool(const DescriptorPool&) = delete; - auto operator=(const DescriptorPool&) -> DescriptorPool& = delete; - - DescriptorPool(DescriptorPool&&) noexcept; - auto operator=(DescriptorPool&&) noexcept -> DescriptorPool&; - - auto create_descriptor_set(view::DescriptorSetLayout layout) const noexcept -> Expected; - auto create_descriptor_sets(usize count, view::DescriptorSetLayout layout) const noexcept - -> Expected>; + using Size = DescriptorSetLayoutInterfaceBase::Size; - auto allocate_descriptor_set(view::DescriptorSetLayout layout) const noexcept -> Expected>; - auto allocate_descriptor_sets(usize count, view::DescriptorSetLayout layout) const noexcept - -> Expected>>; - - // clang-format off - // private: - // clang-format on - DescriptorPool(PrivateTag, view::Device&&) noexcept; + DescriptorPoolImplementation(PrivateTag, view::Device&&) noexcept; auto do_init(PrivateTag, std::span&&, u32) noexcept -> Expected; + ~DescriptorPoolImplementation() noexcept; - private: - auto create_vk_descriptor_sets(usize, view::DescriptorSetLayout&&) const noexcept - -> Expected>; - - static auto delete_vk_descriptor_set(view::Device, view::DescriptorPool, VkDescriptorSet) noexcept -> void; + DescriptorPoolImplementation(const DescriptorPoolImplementation&) = delete; + auto operator=(const DescriptorPoolImplementation&) -> DescriptorPoolImplementation& = delete; - friend class view::DescriptorPool; + DescriptorPoolImplementation(DescriptorPoolImplementation&&) noexcept; + auto operator=(DescriptorPoolImplementation&&) noexcept -> DescriptorPoolImplementation&; }; namespace view { - class DescriptorPool: public DeviceObject { + class DescriptorPoolImplementation: public GpuObjectViewImplementation { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; - - using DeviceObject::DeviceObject; - ~DescriptorPool() noexcept; - - DescriptorPool(const DescriptorPool&) noexcept; - auto operator=(const DescriptorPool&) noexcept -> DescriptorPool&; - - DescriptorPool(DescriptorPool&&) noexcept; - auto operator=(DescriptorPool&&) noexcept -> DescriptorPool&; - - auto create_descriptor_set(DescriptorSetLayout layout) const noexcept -> Expected; - auto create_descriptor_sets(usize count, DescriptorSetLayout layout) const noexcept - -> Expected>; - - auto allocate_descriptor_set(DescriptorSetLayout layout) const noexcept -> Expected>; - auto allocate_descriptor_sets(usize count, DescriptorSetLayout layout) const noexcept - -> Expected>>; - - private: - auto create_vk_descriptor_sets(usize, DescriptorSetLayout&&) const noexcept -> Expected>; - - static auto delete_vk_descriptor_set(Device, DescriptorPool, VkDescriptorSet) noexcept -> void; + using GpuObjectViewImplementation::GpuObjectViewImplementation; + using GpuObjectViewImplementation::operator=; }; } // namespace view @@ -282,290 +219,191 @@ export namespace stormkit::gpu { namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline DescriptorSet::DescriptorSet(PrivateTag, view::Device&& device) noexcept - : OwnedByDevice { std::move(device), cmonadic::noop() } { + inline auto DescriptorSetLayoutInterface::bindings() const noexcept -> std::span { + return Base::m_bindings; } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline DescriptorSet::~DescriptorSet() noexcept { - if (m_vk_handle != VK_NULL_HANDLE) { - m_deleter(m_vk_handle); - m_vk_handle = VK_NULL_HANDLE; - } + inline auto DescriptorPoolInterface::create_descriptor_set(this const auto& self, + view::DescriptorSetLayout layout) noexcept + -> Expected { + auto device = self.owner(); + auto vk_handle = Try(self.create_vk_descriptor_sets(1, std::move(layout))).front(); + Return DescriptorSet::create(device, + std::move(vk_handle), + bind_front(self.delete_vk_descriptor_set, std::move(device), gpu::as_view(self))); } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline DescriptorSet::DescriptorSet(DescriptorSet&& other) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DescriptorSet::operator=(DescriptorSet&& other) noexcept -> DescriptorSet& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DescriptorSet::create(view::Device&& device, VkDescriptorSet&& handle, Deleter&& deleter) noexcept - -> DescriptorSet { - auto out = DescriptorSet { PRIVATE, std::move(device) }; - out.do_init(std::move(handle), std::move(deleter)); - return out; + inline auto DescriptorPoolInterface::create_descriptor_sets(this const auto& self, + usize count, + view::DescriptorSetLayout layout) noexcept + -> Expected> { + auto device = self.owner(); + Return transform(Try(self.create_vk_descriptor_sets(count, std::move(layout))), [&self, device](auto vk_handle) noexcept { + return DescriptorSet::create(device, + std::move(vk_handle), + bind_front(self.delete_vk_descriptor_set, std::move(device), gpu::as_view(self))); + }); } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto DescriptorSet::allocate(view::Device&& device, VkDescriptorSet&& handle, Deleter&& deleter) noexcept - -> Heap { - auto out = core::allocate_unsafe(PRIVATE, std::move(device)); - out->do_init(std::move(handle), std::move(deleter)); - return out; + inline auto DescriptorPoolInterface::allocate_descriptor_set(this const auto& self, + view::DescriptorSetLayout layout) noexcept + -> Expected> { + auto device = self.owner(); + auto vk_handle = Try(self.create_vk_descriptor_sets(1, std::move(layout))).front(); + Return DescriptorSet::allocate(device, + std::move(vk_handle), + bind_front(self.delete_vk_descriptor_set, std::move(device), gpu::as_view(self))); } - namespace view { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline DescriptorSet::~DescriptorSet() noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline DescriptorSet::DescriptorSet(const DescriptorSet&) noexcept = default; - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DescriptorSet::operator=(const DescriptorSet&) noexcept -> DescriptorSet& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline DescriptorSet::DescriptorSet(DescriptorSet&&) noexcept = default; - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DescriptorSet::operator=(DescriptorSet&&) noexcept -> DescriptorSet& = default; - } // namespace view - ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline DescriptorSetLayout::DescriptorSetLayout(PrivateTag, view::Device&& device) noexcept - : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyDescriptorSetLayout } { + inline auto DescriptorPoolInterface::allocate_descriptor_sets(this const auto& self, + usize count, + view::DescriptorSetLayout layout) noexcept + -> Expected>> { + auto device = self.owner(); + Return transform(Try(self.create_vk_descriptor_sets(count, std::move(layout))), [&self, device](auto vk_handle) noexcept { + return DescriptorSet::allocate(device, + std::move(vk_handle), + bind_front(self.delete_vk_descriptor_set, std::move(device), gpu::as_view(self))); + }); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorSetLayout::~DescriptorSetLayout() noexcept = default; + inline DescriptorSetLayoutImplementation::DescriptorSetLayoutImplementation(PrivateTag, view::Device&& device) noexcept + : GpuObjectImplementation { std::move(device), &VolkDeviceTable::vkDestroyDescriptorSetLayout } { + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorSetLayout::DescriptorSetLayout(DescriptorSetLayout&& other) noexcept = default; + inline DescriptorSetLayoutImplementation::~DescriptorSetLayoutImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorSetLayout::operator=(DescriptorSetLayout&& other) noexcept -> DescriptorSetLayout& = default; + inline DescriptorSetLayoutImplementation::DescriptorSetLayoutImplementation(DescriptorSetLayoutImplementation&& + other) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorSetLayout::bindings() const noexcept -> std::span { - return m_bindings; - } + inline auto DescriptorSetLayoutImplementation::operator=(DescriptorSetLayoutImplementation&& other) noexcept + -> DescriptorSetLayoutImplementation& = default; namespace view { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorSetLayout::DescriptorSetLayout(const gpu::DescriptorSetLayout& of) noexcept - : DeviceObject { of }, m_bindings { of.bindings() } { + inline DescriptorSetLayoutImplementation ::DescriptorSetLayoutImplementation(const gpu::DescriptorSetLayout& of) noexcept + : GpuObjectViewImplementation { of }, m_bindings { of.bindings() } { } - /////////////////////////////////// - /////////////////////////////////// - template T> + ///////////////////////////////////// + ///////////////////////////////////// + template TContainerOrPointer> STORMKIT_FORCE_INLINE - inline DescriptorSetLayout::DescriptorSetLayout(const T& of) noexcept - : DeviceObject { of }, m_bindings { of->bindings() } { + inline DescriptorSetLayoutImplementation::DescriptorSetLayoutImplementation(const TContainerOrPointer& of) noexcept + : DescriptorSetLayoutImplementation { *of } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorSetLayout::~DescriptorSetLayout() noexcept = default; + inline DescriptorSetLayoutImplementation ::~DescriptorSetLayoutImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorSetLayout::DescriptorSetLayout(const DescriptorSetLayout&) noexcept = default; + inline DescriptorSetLayoutImplementation :: + DescriptorSetLayoutImplementation(const DescriptorSetLayoutImplementation&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorSetLayout::operator=(const DescriptorSetLayout&) noexcept -> DescriptorSetLayout& = default; + inline auto DescriptorSetLayoutImplementation ::operator=(const DescriptorSetLayoutImplementation&) noexcept + -> DescriptorSetLayoutImplementation& = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorSetLayout::DescriptorSetLayout(DescriptorSetLayout&&) noexcept = default; - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DescriptorSetLayout::operator=(DescriptorSetLayout&&) noexcept -> DescriptorSetLayout& = default; + inline DescriptorSetLayoutImplementation :: + DescriptorSetLayoutImplementation(DescriptorSetLayoutImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorSetLayout::bindings() const noexcept -> std::span { - return m_bindings; - } + inline auto DescriptorSetLayoutImplementation ::operator=(DescriptorSetLayoutImplementation&&) noexcept + -> DescriptorSetLayoutImplementation& = default; } // namespace view ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorPool::DescriptorPool(PrivateTag, view::Device&& device) noexcept - : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyDescriptorPool } { + inline DescriptorSetImplementation::DescriptorSetImplementation(PrivateTag, view::Device&& device) noexcept + : GpuObjectImplementation { std::move(device), cmonadic::noop() } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorPool::~DescriptorPool() noexcept = default; + inline DescriptorSetImplementation::~DescriptorSetImplementation() noexcept { + if (m_vk_handle != VK_NULL_HANDLE) { + m_deleter(m_vk_handle); + m_vk_handle = VK_NULL_HANDLE; + } + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline DescriptorPool::DescriptorPool(DescriptorPool&& other) noexcept = default; + inline DescriptorSetImplementation::DescriptorSetImplementation(DescriptorSetImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorPool::operator=(DescriptorPool&& other) noexcept -> DescriptorPool& = default; + inline auto DescriptorSetImplementation::operator=(DescriptorSetImplementation&&) noexcept + -> DescriptorSetImplementation& = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorPool::create_descriptor_set(view::DescriptorSetLayout layout) const noexcept - -> Expected { - auto vk_handle = Try(create_vk_descriptor_sets(1, std::move(layout))).front(); - Return DescriptorSet::create(auto(device()), - std::move(vk_handle), - bind_front(delete_vk_descriptor_set, device(), as_view(*this))); + inline DescriptorPoolImplementation::DescriptorPoolImplementation(PrivateTag, view::Device&& device) noexcept + : GpuObjectImplementation { std::move(device), &VolkDeviceTable::vkDestroyDescriptorPool } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorPool::create_descriptor_sets(usize count, view::DescriptorSetLayout layout) const noexcept - -> Expected> { - Return transform(Try(create_vk_descriptor_sets(count, std::move(layout))), [this](auto vk_handle) noexcept { - return DescriptorSet::create(auto(device()), - std::move(vk_handle), - bind_front(delete_vk_descriptor_set, device(), as_view(*this))); - }); - } + inline DescriptorPoolImplementation::~DescriptorPoolImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorPool::allocate_descriptor_set(view::DescriptorSetLayout layout) const noexcept - -> Expected> { - auto vk_handle = Try(create_vk_descriptor_sets(1, std::move(layout))).front(); - Return DescriptorSet::allocate(auto(device()), - std::move(vk_handle), - bind_front(delete_vk_descriptor_set, device(), as_view(*this))); - } + inline DescriptorPoolImplementation::DescriptorPoolImplementation(DescriptorPoolImplementation&& other) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto DescriptorPool::allocate_descriptor_sets(usize count, view::DescriptorSetLayout layout) const noexcept - -> Expected>> { - Return transform(Try(create_vk_descriptor_sets(count, std::move(layout))), [this](auto vk_handle) noexcept { - return DescriptorSet::allocate(auto(device()), - std::move(vk_handle), - bind_front(delete_vk_descriptor_set, device(), as_view(*this))); - }); - } - - namespace view { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline DescriptorPool::~DescriptorPool() noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline DescriptorPool::DescriptorPool(const DescriptorPool&) noexcept = default; - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DescriptorPool::operator=(const DescriptorPool&) noexcept -> DescriptorPool& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline DescriptorPool::DescriptorPool(DescriptorPool&&) noexcept = default; - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DescriptorPool::operator=(DescriptorPool&&) noexcept -> DescriptorPool& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DescriptorPool::create_descriptor_set(DescriptorSetLayout layout) const noexcept - -> Expected { - auto vk_handle = Try(create_vk_descriptor_sets(1, std::move(layout))).front(); - Return gpu::DescriptorSet::create(auto(device()), - std::move(vk_handle), - bind_front(delete_vk_descriptor_set, device(), as_view(*this))); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DescriptorPool::create_descriptor_sets(usize count, DescriptorSetLayout layout) const noexcept - -> Expected> { - Return transform(Try(create_vk_descriptor_sets(count, std::move(layout))), [this](auto vk_handle) noexcept { - return gpu::DescriptorSet::create(auto(device()), - std::move(vk_handle), - bind_front(delete_vk_descriptor_set, device(), as_view(*this))); - }); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DescriptorPool::allocate_descriptor_set(DescriptorSetLayout layout) const noexcept - -> Expected> { - auto vk_handle = Try(create_vk_descriptor_sets(1, std::move(layout))).front(); - Return gpu::DescriptorSet::allocate(auto(device()), - std::move(vk_handle), - bind_front(delete_vk_descriptor_set, device(), as_view(*this))); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto DescriptorPool::allocate_descriptor_sets(usize count, DescriptorSetLayout layout) const noexcept - -> Expected>> { - Return transform(Try(create_vk_descriptor_sets(count, std::move(layout))), [this](auto vk_handle) noexcept { - return gpu::DescriptorSet::allocate(auto(device()), - std::move(vk_handle), - bind_front(delete_vk_descriptor_set, device(), as_view(*this))); - }); - } - } // namespace view + inline auto DescriptorPoolImplementation::operator=(DescriptorPoolImplementation&& other) noexcept + -> DescriptorPoolImplementation& = default; ///////////////////////////////////// ///////////////////////////////////// diff --git a/modules/stormkit/gpu/execution/objects.cppm b/modules/stormkit/gpu/execution/objects.cppm new file mode 100644 index 000000000..75ab3e3ea --- /dev/null +++ b/modules/stormkit/gpu/execution/objects.cppm @@ -0,0 +1,267 @@ +// Copyright (C) 2023 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.gpu.execution:objects; + +import std; + +import stormkit.core; +import stormkit.gpu.core; + +namespace cmonadic = stormkit::core::monadic; + +namespace stormkit::gpu { + class SwapChainImplementation; + class FrameBufferImplementation; + class RenderPassImplementation; + class PipelineCacheImplementation; + class PipelineLayoutImplementation; + class PipelineImplementation; + class DescriptorSetImplementation; + class DescriptorSetLayoutImplementation; + class DescriptorPoolImplementation; + class QueueImplementation; + class CommandPoolImplementation; + class CommandBufferImplementation; + + namespace view { + class SwapChainImplementation; + class FrameBufferImplementation; + class RenderPassImplementation; + class PipelineCacheImplementation; + class PipelineLayoutImplementation; + class PipelineImplementation; + class DescriptorSetImplementation; + class DescriptorSetLayoutImplementation; + class DescriptorPoolImplementation; + class QueueImplementation; + class CommandPoolImplementation; + class CommandBufferImplementation; + } // namespace view + + export { + class SwapChainTag; + template + class SwapChainInterface; + + class FrameBufferTag; + template + class FrameBufferInterface; + + class RenderPassTag; + template + class RenderPassInterface; + + class PipelineCacheTag; + template + class PipelineCacheInterface; + + class PipelineLayoutTag; + template + class PipelineLayoutInterface; + + class PipelineTag; + template + class PipelineInterface; + + class DescriptorSetTag; + template + class DescriptorSetInterface; + + class DescriptorSetLayoutTag; + template + class DescriptorSetLayoutInterface; + + class DescriptorPoolTag; + template + class DescriptorPoolInterface; + + class QueueTag; + template + class QueueInterface; + + class CommandBufferTag; + template + class CommandBufferInterface; + + class CommandPoolTag; + template + class CommandPoolInterface; + + using LoadSaveError = DecoratedError>; + template + using LoadSaveExpected = core::Expected; + + using SwapChain = SwapChainInterface; + using FrameBuffer = FrameBufferInterface; + using RenderPass = RenderPassInterface; + using PipelineCache = PipelineCacheInterface; + using PipelineLayout = PipelineLayoutInterface; + using Pipeline = PipelineInterface; + using DescriptorSet = DescriptorSetInterface; + using DescriptorSetLayout = DescriptorSetLayoutInterface; + using DescriptorPool = DescriptorPoolInterface; + using Queue = QueueInterface; + using CommandBuffer = CommandBufferInterface; + using CommandPool = CommandPoolInterface; + + namespace view { + using SwapChain = SwapChainInterface; + using FrameBuffer = FrameBufferInterface; + using RenderPass = RenderPassInterface; + using PipelineCache = PipelineCacheInterface; + using PipelineLayout = PipelineLayoutInterface; + using Pipeline = PipelineInterface; + using DescriptorSet = DescriptorSetInterface; + using DescriptorSetLayout = DescriptorSetLayoutInterface; + using DescriptorPool = DescriptorPoolInterface; + using Queue = QueueInterface; + using CommandBuffer = CommandBufferInterface; + using CommandPool = CommandPoolInterface; + } // namespace view + + namespace trait { + template<> + struct GpuObject { + using ValueType = VkSwapchainKHR; + using DeleterType = PFN_vkDestroySwapchainKHR VolkDeviceTable::*; + using ObjectType = SwapChain; + using ViewType = view::SwapChain; + using OwnerType = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::SWAPCHAIN; + }; + + template<> + struct GpuObject { + using ValueType = VkFramebuffer; + using DeleterType = PFN_vkDestroyFramebuffer VolkDeviceTable::*; + using ObjectType = FrameBuffer; + using ViewType = view::FrameBuffer; + using OwnerType = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::FRAMEBUFFER; + }; + + template<> + struct GpuObject { + using ValueType = VkRenderPass; + using DeleterType = PFN_vkDestroyRenderPass VolkDeviceTable::*; + using ObjectType = RenderPass; + using ViewType = view::RenderPass; + using OwnerType = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::RENDER_PASS; + }; + + template<> + struct GpuObject { + using ValueType = VkPipelineCache; + using DeleterType = PFN_vkDestroyPipelineCache VolkDeviceTable::*; + using ObjectType = PipelineCache; + using ViewType = view::PipelineCache; + using OwnerType = Device; + using DoInitReturnType = LoadSaveExpected; + + static constexpr auto DEBUG_TYPE = DebugObjectType::PIPELINE_CACHE; + }; + + template<> + struct GpuObject { + using ValueType = VkPipelineLayout; + using DeleterType = PFN_vkDestroyPipelineLayout VolkDeviceTable::*; + using ObjectType = PipelineLayout; + using ViewType = view::PipelineLayout; + using OwnerType = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::PIPELINE_LAYOUT; + }; + + template<> + struct GpuObject { + using ValueType = VkPipeline; + using DeleterType = PFN_vkDestroyPipeline VolkDeviceTable::*; + using ObjectType = Pipeline; + using ViewType = view::Pipeline; + using OwnerType = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::PIPELINE; + }; + + template<> + struct GpuObject { + using ValueType = VkDescriptorSet; + using DeleterType = decltype(cmonadic::noop()); + using ObjectType = DescriptorSet; + using ViewType = view::DescriptorSet; + using OwnerType = Device; + using DoInitReturnType = void; + + static constexpr auto DEBUG_TYPE = DebugObjectType::DESCRIPTOR_SET; + }; + + template<> + struct GpuObject { + using ValueType = VkDescriptorSetLayout; + using DeleterType = PFN_vkDestroyDescriptorSetLayout VolkDeviceTable::*; + using ObjectType = DescriptorSetLayout; + using ViewType = view::DescriptorSetLayout; + using OwnerType = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::DESCRIPTOR_SET_LAYOUT; + }; + + template<> + struct GpuObject { + using ValueType = VkDescriptorPool; + using DeleterType = PFN_vkDestroyDescriptorPool VolkDeviceTable::*; + using ObjectType = DescriptorPool; + using ViewType = view::DescriptorPool; + using OwnerType = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::DESCRIPTOR_POOL; + }; + + template<> + struct GpuObject { + using ValueType = VkQueue; + using DeleterType = decltype(cmonadic::noop()); + using ObjectType = Queue; + using ViewType = view::Queue; + using OwnerType = Device; + using DoInitReturnType = void; + + static constexpr auto DEBUG_TYPE = DebugObjectType::QUEUE; + }; + + template<> + struct GpuObject { + using ValueType = VkCommandBuffer; + using DeleterType = decltype(cmonadic::noop()); + using ObjectType = CommandBuffer; + using ViewType = view::CommandBuffer; + using OwnerType = Device; + using DoInitReturnType = void; + + static constexpr auto DEBUG_TYPE = DebugObjectType::COMMAND_BUFFER; + }; + + template<> + struct GpuObject { + using ValueType = VkCommandPool; + using DeleterType = PFN_vkDestroyCommandPool VolkDeviceTable::*; + using ObjectType = CommandPool; + using ViewType = view::CommandPool; + using OwnerType = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::COMMAND_POOL; + }; + + } // namespace trait + } +} // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/execution/pipeline.cppm b/modules/stormkit/gpu/execution/pipeline.cppm index 098652b1c..b58853939 100644 --- a/modules/stormkit/gpu/execution/pipeline.cppm +++ b/modules/stormkit/gpu/execution/pipeline.cppm @@ -19,6 +19,7 @@ import std; import stormkit.core; import stormkit.gpu.core; +import :objects; import :raster_pipeline; import :render_pass; @@ -26,77 +27,71 @@ namespace stdfs = std::filesystem; namespace cmeta = stormkit::core::meta; -export namespace stormkit::gpu { - class PipelineCache; - class Pipeline; - class PipelineLayout; +namespace stormkit::gpu { + export template + class PipelineCacheInterface final: public DeviceObject { + public: + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = PipelineCacheTag; + }; - namespace view { - using PipelineCache = DeviceObject; - using PipelineLayout = DeviceObject; - class Pipeline; - } // namespace view + export template + class PipelineLayoutInterface final: public DeviceObject { + public: + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = PipelineLayoutTag; - namespace meta { - template<> - struct ObjectInfo { - using Of = PipelineCache; - using ValueType = VkPipelineCache; - using DeleterType = PFN_vkDestroyPipelineCache VolkDeviceTable::*; - using ViewType = view::PipelineCache; - using OwnedBy = Device; - - static constexpr auto DISABLE_CREATE_ALLOCATE = true; - static constexpr auto DEBUG_TYPE = DebugObjectType::PIPELINE_CACHE; - }; + [[nodiscard]] + auto raster_layout() const noexcept -> const RasterPipelineLayout&; + }; - template<> - struct ObjectInfo { - using Of = Pipeline; - using ValueType = VkPipeline; - using DeleterType = PFN_vkDestroyPipeline VolkDeviceTable::*; - using ViewType = view::Pipeline; - using OwnedBy = Device; + struct PipelineInterfaceBase { + using StateVariant = std::variant; - static constexpr auto DEBUG_TYPE = DebugObjectType::PIPELINE; + enum class Type { + RASTER, + COMPUTE, + RAYTRACING, }; + }; - template<> - struct ObjectInfo { - using Of = PipelineLayout; - using ValueType = VkPipelineLayout; - using DeleterType = PFN_vkDestroyPipelineLayout VolkDeviceTable::*; - using ViewType = view::PipelineLayout; - using OwnedBy = Device; + export template + class PipelineInterface final: public DeviceObject, protected PipelineInterfaceBase { + public: + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = PipelineTag; - static constexpr auto DEBUG_TYPE = DebugObjectType::PIPELINE_LAYOUT; - }; - } // namespace meta + using PipelineInterfaceBase::Type; + + [[nodiscard]] + auto type() const noexcept -> Type; + [[nodiscard]] + auto raster_state() const noexcept -> const RasterPipelineState&; + }; - class STORMKIT_GPU_API PipelineCache: public OwnedByDevice { + class STORMKIT_GPU_API PipelineCacheImplementation: public GpuObjectImplementation { public: - using LoadSaveError = DecoratedError>; - template - using LoadSaveExpected = core::Expected; + PipelineCacheImplementation(PrivateTag, view::Device&&) noexcept; + auto do_init(PrivateTag, stdfs::path&&) noexcept -> LoadSaveExpected; + ~PipelineCacheImplementation() noexcept; + + PipelineCacheImplementation(const PipelineCacheImplementation&) = delete; + auto operator=(const PipelineCacheImplementation&) -> PipelineCacheImplementation& = delete; + + PipelineCacheImplementation(PipelineCacheImplementation&&) noexcept; + auto operator=(PipelineCacheImplementation&&) noexcept -> PipelineCacheImplementation&; static auto load_from_file(view::Device device, stdfs::path cache_path) noexcept -> LoadSaveExpected; static auto allocate_load_from_file(view::Device device, stdfs::path cache_path) noexcept -> LoadSaveExpected>; - ~PipelineCache() noexcept; - PipelineCache(const PipelineCache&) = delete; - auto operator=(const PipelineCache&) -> PipelineCache& = delete; + protected: + using UseNamedConstructors::allocate; + using UseNamedConstructors::create; - PipelineCache(PipelineCache&&) noexcept; - auto operator=(PipelineCache&&) noexcept -> PipelineCache&; - - // clang-format off - // private: - // clang-format on - PipelineCache(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, stdfs::path&&) noexcept -> LoadSaveExpected; - - private: auto create_new_pipeline_cache() noexcept -> LoadSaveExpected; auto read_pipeline_cache() noexcept -> LoadSaveExpected; auto save_cache() noexcept -> LoadSaveExpected; @@ -125,96 +120,106 @@ export namespace stormkit::gpu { stdfs::path m_path; }; - class STORMKIT_GPU_API PipelineLayout: public OwnedByDevice { - public: - ~PipelineLayout() noexcept; + namespace view { + class PipelineCacheImplementation: public GpuObjectViewImplementation { + public: + using GpuObjectViewImplementation::GpuObjectViewImplementation; + using GpuObjectViewImplementation::operator=; + }; + } // namespace view - PipelineLayout(const PipelineLayout&) = delete; - auto operator=(const PipelineLayout&) -> PipelineLayout& = delete; + class STORMKIT_GPU_API PipelineLayoutImplementation: public GpuObjectImplementation { + public: + PipelineLayoutImplementation(PrivateTag, view::Device&& device) noexcept; + auto do_init(PrivateTag, const RasterPipelineLayout&) noexcept -> Expected; + ~PipelineLayoutImplementation() noexcept; - PipelineLayout(PipelineLayout&&) noexcept; - auto operator=(PipelineLayout&&) noexcept -> PipelineLayout&; + PipelineLayoutImplementation(const PipelineLayoutImplementation&) = delete; + auto operator=(const PipelineLayoutImplementation&) -> PipelineLayoutImplementation& = delete; - [[nodiscard]] - auto raster_layout() const noexcept -> const RasterPipelineLayout&; + PipelineLayoutImplementation(PipelineLayoutImplementation&&) noexcept; + auto operator=(PipelineLayoutImplementation&&) noexcept -> PipelineLayoutImplementation&; - // clang-format off - // private: - // clang-format on - PipelineLayout(PrivateTag, view::Device&& device) noexcept; - auto do_init(PrivateTag, const RasterPipelineLayout&) noexcept -> Expected; + protected: + Heap m_layout; - private: - RasterPipelineLayout m_layout; + friend class view::PipelineLayoutImplementation; }; - class STORMKIT_GPU_API Pipeline: public OwnedByDevice { - public: - enum class Type { - RASTER, - COMPUTE, - RAYTRACING, - }; + namespace view { + class PipelineLayoutImplementation: public GpuObjectViewImplementation { + public: + PipelineLayoutImplementation(const gpu::PipelineLayout& of) noexcept; + template TContainerOrPointer> + PipelineLayoutImplementation(const TContainerOrPointer&) noexcept; + ~PipelineLayoutImplementation() noexcept; - ~Pipeline() noexcept; + PipelineLayoutImplementation(const PipelineLayoutImplementation&) noexcept; + auto operator=(const PipelineLayoutImplementation&) noexcept -> PipelineLayoutImplementation&; - Pipeline(const Pipeline&) = delete; - auto operator=(const Pipeline&) -> Pipeline& = delete; + PipelineLayoutImplementation(PipelineLayoutImplementation&&) noexcept; + auto operator=(PipelineLayoutImplementation&&) noexcept -> PipelineLayoutImplementation&; - Pipeline(Pipeline&&) noexcept; - auto operator=(Pipeline&&) noexcept -> Pipeline&; + protected: + ref m_layout; + }; + } // namespace view - [[nodiscard]] - auto type() const noexcept -> Type; - [[nodiscard]] - auto raster_state() const noexcept -> const RasterPipelineState&; + class STORMKIT_GPU_API PipelineImplementation: public GpuObjectImplementation { + using StateVariant = PipelineInterfaceBase::StateVariant; - // clang-format off - // private: - // clang-format on - Pipeline(PrivateTag, view::Device&&) noexcept; + public: + using Type = PipelineInterfaceBase::Type; + + PipelineImplementation(PrivateTag, view::Device&&) noexcept; auto do_init(PrivateTag, const RasterPipelineState&, - view::PipelineLayout&&, + view::PipelineLayout, const RasterPipelineRenderingInfo&, std::optional&& = std::nullopt) noexcept -> Expected; auto do_init(PrivateTag, const RasterPipelineState&, - view::PipelineLayout&&, - view::RenderPass&&, + view::PipelineLayout, + view::RenderPass, std::optional&& = std::nullopt) noexcept -> Expected; + ~PipelineImplementation() noexcept; + + PipelineImplementation(const PipelineImplementation&) = delete; + auto operator=(const PipelineImplementation&) -> PipelineImplementation& = delete; + + PipelineImplementation(PipelineImplementation&&) noexcept; + auto operator=(PipelineImplementation&&) noexcept -> PipelineImplementation&; + + protected: + Type m_type; + Heap m_state; - private: - Type m_type; - std::variant m_state; + friend class view::PipelineImplementation; }; namespace view { - class STORMKIT_GPU_API Pipeline: public DeviceObject { - public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; + class PipelineImplementation: public GpuObjectViewImplementation { + using StateVariant = PipelineInterfaceBase::StateVariant; - Pipeline(const gpu::Pipeline& of) noexcept; - template T> - Pipeline(const T& of) noexcept; - ~Pipeline() noexcept; + public: + using Type = PipelineInterfaceBase::Type; - Pipeline(const Pipeline&) noexcept; - auto operator=(const Pipeline&) noexcept -> Pipeline&; + PipelineImplementation(const gpu::Pipeline& of) noexcept; + template TContainerOrPointer> + PipelineImplementation(const TContainerOrPointer&) noexcept; + ~PipelineImplementation() noexcept; - Pipeline(Pipeline&&) noexcept; - auto operator=(Pipeline&&) noexcept -> Pipeline&; + PipelineImplementation(const PipelineImplementation&) noexcept; + auto operator=(const PipelineImplementation&) noexcept -> PipelineImplementation&; - [[nodiscard]] - auto type() const noexcept -> gpu::Pipeline::Type; + PipelineImplementation(PipelineImplementation&&) noexcept; + auto operator=(PipelineImplementation&&) noexcept -> PipelineImplementation&; - private: - gpu::Pipeline::Type m_type; + protected: + Type m_type; + ref m_state; }; } // namespace view - } // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// @@ -224,147 +229,211 @@ export namespace stormkit::gpu { namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline PipelineCache::PipelineCache(PrivateTag, view::Device&& device) noexcept - : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyPipelineCache } { + inline auto PipelineLayoutInterface::raster_layout() const noexcept -> const RasterPipelineLayout& { + EXPECTS(Base::m_layout != nullptr); + return *Base::m_layout; } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline PipelineCache::PipelineCache(PipelineCache&& other) noexcept = default; + inline auto PipelineInterface::type() const noexcept -> Type { + return Base::m_type; + } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto PipelineCache::operator=(PipelineCache&& other) noexcept -> PipelineCache& = default; + inline auto PipelineInterface::raster_state() const noexcept -> const RasterPipelineState& { + EXPECTS(Base::m_type == Type::RASTER); + EXPECTS(Base::m_state != nullptr); + EXPECTS(is(*Base::m_state)); + return as(*Base::m_state); + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto PipelineCache::load_from_file(view::Device device, stdfs::path cache_path) noexcept - -> LoadSaveExpected { - auto cache = PipelineCache { PRIVATE, std::move(device) }; - Try(cache.do_init(PRIVATE, std::move(cache_path))); - Return cache; + inline PipelineCacheImplementation::PipelineCacheImplementation(PrivateTag, view::Device&& device) noexcept + : GpuObjectImplementation { std::move(device), &VolkDeviceTable::vkDestroyPipelineCache } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto PipelineCache::allocate_load_from_file(view::Device device, stdfs::path cache_path) noexcept - -> LoadSaveExpected> { - auto cache = core::allocate_unsafe(PRIVATE, std::move(device)); - Try(cache->do_init(PRIVATE, std::move(cache_path))); - Return cache; - } + inline PipelineCacheImplementation::PipelineCacheImplementation(PipelineCacheImplementation&& other) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto PipelineCacheImplementation::operator=(PipelineCacheImplementation&& other) noexcept + -> PipelineCacheImplementation& = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline PipelineLayout::PipelineLayout(PrivateTag, view::Device&& device) noexcept - : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyPipelineLayout } { + inline auto PipelineCacheImplementation::load_from_file(view::Device device, stdfs::path cache_path) noexcept + -> LoadSaveExpected { + Return UseNamedConstructors::create(std::move(device), std::move(cache_path)); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline PipelineLayout::~PipelineLayout() noexcept = default; + inline auto PipelineCacheImplementation::allocate_load_from_file(view::Device device, stdfs::path cache_path) noexcept + -> LoadSaveExpected> { + Return UseNamedConstructors::allocate(std::move(device), std::move(cache_path)); + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline PipelineLayout::PipelineLayout(PipelineLayout&&) noexcept = default; + inline PipelineLayoutImplementation::PipelineLayoutImplementation(PrivateTag, view::Device&& device) noexcept + : GpuObjectImplementation { std::move(device), &VolkDeviceTable::vkDestroyPipelineLayout } { + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto PipelineLayout::operator=(PipelineLayout&&) noexcept -> PipelineLayout& = default; + inline PipelineLayoutImplementation::~PipelineLayoutImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Pipeline::Pipeline(PrivateTag, view::Device&& device) noexcept - : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyPipeline } { - } + inline PipelineLayoutImplementation::PipelineLayoutImplementation(PipelineLayoutImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Pipeline::~Pipeline() noexcept = default; + inline auto PipelineLayoutImplementation::operator=(PipelineLayoutImplementation&&) noexcept + -> PipelineLayoutImplementation& = default; + + namespace view { + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline PipelineLayoutImplementation::PipelineLayoutImplementation(const gpu::PipelineLayout& of) noexcept + : GpuObjectViewImplementation { of }, m_layout { as_ref(of.raster_layout()) } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + template TContainerOrPointer> + STORMKIT_FORCE_INLINE + inline PipelineLayoutImplementation::PipelineLayoutImplementation(const TContainerOrPointer& of) noexcept + : PipelineLayoutImplementation { *of } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline PipelineLayoutImplementation::~PipelineLayoutImplementation() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline PipelineLayoutImplementation::PipelineLayoutImplementation(const PipelineLayoutImplementation&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto PipelineLayoutImplementation::operator=(const PipelineLayoutImplementation& other) noexcept + -> PipelineLayoutImplementation& { + if (&other == this) [[unlikely]] + return *this; + + m_layout = as_ref(other.m_layout); + + return *this; + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline PipelineLayoutImplementation::PipelineLayoutImplementation(PipelineLayoutImplementation&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto PipelineLayoutImplementation::operator=(PipelineLayoutImplementation&&) noexcept + -> PipelineLayoutImplementation& = default; + } // namespace view ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Pipeline::Pipeline(Pipeline&& other) noexcept = default; + inline PipelineImplementation::PipelineImplementation(PrivateTag, view::Device&& device) noexcept + : GpuObjectImplementation { std::move(device), &VolkDeviceTable::vkDestroyPipeline } { + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Pipeline::operator=(Pipeline&& other) noexcept -> Pipeline& = default; + inline PipelineImplementation::~PipelineImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Pipeline::type() const noexcept -> Type { - return m_type; - } + inline PipelineImplementation::PipelineImplementation(PipelineImplementation&& other) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Pipeline::raster_state() const noexcept -> const RasterPipelineState& { - EXPECTS(m_type == Type::RASTER); - EXPECTS(is(m_state)); - return as(m_state); - } + inline auto PipelineImplementation::operator=(PipelineImplementation&& other) noexcept -> PipelineImplementation& = default; namespace view { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Pipeline::Pipeline(const gpu::Pipeline& of) noexcept - : DeviceObject { of }, m_type { of.type() } { - } - - /////////////////////////////////// - /////////////////////////////////// - template T> - STORMKIT_FORCE_INLINE - inline Pipeline::Pipeline(const T& of) noexcept - : DeviceObject { of }, m_type { of->type() } { + inline PipelineImplementation::PipelineImplementation(const gpu::Pipeline& of) noexcept + : GpuObjectViewImplementation { of }, m_type { of.type() }, m_state { as_ref(of.m_state) } { } ///////////////////////////////////// ///////////////////////////////////// + template TContainerOrPointer> STORMKIT_FORCE_INLINE - inline Pipeline::~Pipeline() noexcept = default; + inline PipelineImplementation::PipelineImplementation(const TContainerOrPointer& of) noexcept + : PipelineImplementation { *of } { + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Pipeline::Pipeline(const Pipeline& other) noexcept = default; + inline PipelineImplementation::~PipelineImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Pipeline::operator=(const Pipeline& other) noexcept -> Pipeline& = default; + inline PipelineImplementation::PipelineImplementation(const PipelineImplementation&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Pipeline::Pipeline(Pipeline&&) noexcept = default; + inline auto PipelineImplementation::operator=(const PipelineImplementation& other) noexcept -> PipelineImplementation& { + if (&other == this) [[unlikely]] + return *this; + + GpuObjectViewImplementation::operator=(other); + + m_type = other.m_type; + m_state = as_ref(other.m_state); + + return *this; + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Pipeline::operator=(Pipeline&&) noexcept -> Pipeline& = default; + inline PipelineImplementation::PipelineImplementation(PipelineImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Pipeline::type() const noexcept -> gpu::Pipeline::Type { - return m_type; - } + inline auto PipelineImplementation::operator=(PipelineImplementation&&) noexcept -> PipelineImplementation& = default; } // namespace view } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/execution/render_pass.cppm b/modules/stormkit/gpu/execution/render_pass.cppm index 34316eb71..c286bbb0f 100644 --- a/modules/stormkit/gpu/execution/render_pass.cppm +++ b/modules/stormkit/gpu/execution/render_pass.cppm @@ -19,209 +19,169 @@ import stormkit.core; import stormkit.gpu.core; import stormkit.gpu.resource; +import :objects; + namespace cmeta = stormkit::core::meta; -export namespace stormkit::gpu { - class FrameBuffer; - class RenderPass; +namespace stormkit::gpu { + export { + struct AttachmentDescription { + PixelFormat format; + SampleCountFlag samples = SampleCountFlag::C1; - namespace view { - class FrameBuffer; - class RenderPass; - } // namespace view + AttachmentLoadOperation load_op = AttachmentLoadOperation::CLEAR; + AttachmentStoreOperation store_op = AttachmentStoreOperation::STORE; - namespace meta { - template<> - struct ObjectInfo { - using Of = FrameBuffer; - using ValueType = VkFramebuffer; - using DeleterType = PFN_vkDestroyFramebuffer VolkDeviceTable::*; - using ViewType = view::FrameBuffer; - using OwnedBy = Device; - - static constexpr auto DISABLE_CREATE_ALLOCATE = true; - static constexpr auto DEBUG_TYPE = DebugObjectType::FRAMEBUFFER; - }; + AttachmentLoadOperation stencil_load_op = AttachmentLoadOperation::DONT_CARE; + AttachmentStoreOperation stencil_store_op = AttachmentStoreOperation::DONT_CARE; - template<> - struct ObjectInfo { - using Of = RenderPass; - using ValueType = VkRenderPass; - using DeleterType = PFN_vkDestroyRenderPass VolkDeviceTable::*; - using ViewType = view::RenderPass; - using OwnedBy = Device; + ImageLayout source_layout = ImageLayout::UNDEFINED; + ImageLayout destination_layout = ImageLayout::PRESENT_SRC; - static constexpr auto DEBUG_TYPE = DebugObjectType::RENDER_PASS; + bool resolve = false; }; - } // namespace meta - - class RenderPass; - - class STORMKIT_GPU_API FrameBuffer: public OwnedByDevice { - public: - ~FrameBuffer() noexcept; - FrameBuffer(const FrameBuffer&) = delete; - auto operator=(const FrameBuffer&) -> FrameBuffer& = delete; + using AttachmentDescriptions = std::vector; - FrameBuffer(FrameBuffer&&) noexcept; - auto operator=(FrameBuffer&&) noexcept -> FrameBuffer&; + struct Subpass { + struct Ref { + u32 attachment_id; - [[nodiscard]] - auto extent() const noexcept -> const math::uextent2&; - [[nodiscard]] - auto attachments() const noexcept -> std::span; + ImageLayout layout = ImageLayout::COLOR_ATTACHMENT_OPTIMAL; + }; - FrameBuffer(PrivateTag, view::Device&&) noexcept; + PipelineBindPoint bind_point; + std::vector color_attachment_refs = {}; + std::vector resolve_attachment_refs = {}; + std::optional depth_attachment_ref = {}; + }; - private: - static auto create(view::Device&& device, - view::RenderPass render_pass, - const math::uextent2& extent, - std::vector&& attachments) noexcept -> Expected; - static auto allocate(view::Device&& device, - view::RenderPass render_pass, - const math::uextent2& extent, - std::vector&& attachments) noexcept -> Expected>; + using Subpasses = std::vector; - auto do_init(view::RenderPass&&, const math::uextent2&, std::vector&&) noexcept -> Expected; + struct RenderPassDescription { + AttachmentDescriptions attachments; + Subpasses subpasses; - math::uextent2 m_extent = { 0, 0 }; - std::vector m_attachments; - - friend class RenderPass; - friend class view::RenderPass; - }; + auto is_compatible(const RenderPassDescription& description) const noexcept -> bool; + }; - namespace view { - class STORMKIT_GPU_API FrameBuffer: public DeviceObject { + template + class FrameBufferInterface final: public DeviceObject { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; - - FrameBuffer(const gpu::FrameBuffer& of) noexcept; - template T> - FrameBuffer(const T& of) noexcept; - ~FrameBuffer() noexcept; - - FrameBuffer(const FrameBuffer&) noexcept; - auto operator=(const FrameBuffer&) noexcept -> FrameBuffer&; - - FrameBuffer(FrameBuffer&&) noexcept; - auto operator=(FrameBuffer&&) noexcept -> FrameBuffer&; + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = FrameBufferTag; [[nodiscard]] auto extent() const noexcept -> const math::uextent2&; [[nodiscard]] auto attachments() const noexcept -> std::span; - - private: - math::uextent2 m_extent = { 0, 0 }; - std::span m_attachments; }; - } // namespace view - struct AttachmentDescription { - PixelFormat format; - SampleCountFlag samples = SampleCountFlag::C1; + template + class RenderPassInterface final: public DeviceObject { + public: + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = RenderPassTag; + + auto create_framebuffer(this const auto&, + view::Device device, + const math::uextent2& extent, + std::vector attachments) noexcept -> Expected; + auto allocate_framebuffer(this const auto&, + view::Device device, + const math::uextent2& extent, + std::vector attachments) noexcept -> Expected>; - AttachmentLoadOperation load_op = AttachmentLoadOperation::CLEAR; - AttachmentStoreOperation store_op = AttachmentStoreOperation::STORE; + [[nodiscard]] + auto is_compatible(view::RenderPass render_pass) const noexcept -> bool; + [[nodiscard]] + auto is_compatible(const RenderPassDescription& description) const noexcept -> bool; - AttachmentLoadOperation stencil_load_op = AttachmentLoadOperation::DONT_CARE; - AttachmentStoreOperation stencil_store_op = AttachmentStoreOperation::DONT_CARE; + [[nodiscard]] + auto description() const noexcept -> const RenderPassDescription&; + }; + } - ImageLayout source_layout = ImageLayout::UNDEFINED; - ImageLayout destination_layout = ImageLayout::PRESENT_SRC; + class STORMKIT_GPU_API FrameBufferImplementation: public GpuObjectImplementation { + public: + FrameBufferImplementation(PrivateTag, view::Device&&) noexcept; + auto do_init(PrivateTag, view::RenderPass&&, const math::uextent2&, std::vector&&) noexcept + -> Expected; + ~FrameBufferImplementation() noexcept; - bool resolve = false; - }; + FrameBufferImplementation(const FrameBufferImplementation&) = delete; + auto operator=(const FrameBufferImplementation&) -> FrameBufferImplementation& = delete; - using AttachmentDescriptions = std::vector; + FrameBufferImplementation(FrameBufferImplementation&&) noexcept; + auto operator=(FrameBufferImplementation&&) noexcept -> FrameBufferImplementation&; - struct Subpass { - struct Ref { - u32 attachment_id; + protected: + using UseNamedConstructors::allocate; + using UseNamedConstructors::create; - ImageLayout layout = ImageLayout::COLOR_ATTACHMENT_OPTIMAL; - }; + math::uextent2 m_extent = { 0, 0 }; + std::vector m_attachments; - PipelineBindPoint bind_point; - std::vector color_attachment_refs = {}; - std::vector resolve_attachment_refs = {}; - std::optional depth_attachment_ref = {}; + friend class RenderPassInterface; + friend class RenderPassInterface; }; - using Subpasses = std::vector; + namespace view { + class FrameBufferImplementation: public GpuObjectViewImplementation { + public: + FrameBufferImplementation(const gpu::FrameBuffer& of) noexcept; + template TContainerOrPointer> + FrameBufferImplementation(const TContainerOrPointer&) noexcept; + ~FrameBufferImplementation() noexcept; + + FrameBufferImplementation(const FrameBufferImplementation&) noexcept; + auto operator=(const FrameBufferImplementation&) noexcept -> FrameBufferImplementation&; - struct RenderPassDescription { - AttachmentDescriptions attachments; - Subpasses subpasses; + FrameBufferImplementation(FrameBufferImplementation&&) noexcept; + auto operator=(FrameBufferImplementation&&) noexcept -> FrameBufferImplementation&; - auto is_compatible(const RenderPassDescription& description) const noexcept -> bool; - }; + protected: + math::uextent2 m_extent; + std::span m_attachments; + }; + } // namespace view - class STORMKIT_GPU_API RenderPass: public OwnedByDevice { + class STORMKIT_GPU_API RenderPassImplementation: public GpuObjectImplementation { public: - ~RenderPass() noexcept; + RenderPassImplementation(PrivateTag, view::Device&&) noexcept; + auto do_init(PrivateTag, const RenderPassDescription&) noexcept -> Expected; + ~RenderPassImplementation() noexcept; - RenderPass(const RenderPass&) = delete; - auto operator=(const RenderPass&) -> RenderPass& = delete; + RenderPassImplementation(const RenderPassImplementation&) = delete; + auto operator=(const RenderPassImplementation&) -> RenderPassImplementation& = delete; - RenderPass(RenderPass&&) noexcept; - auto operator=(RenderPass&&) noexcept -> RenderPass&; + RenderPassImplementation(RenderPassImplementation&&) noexcept; + auto operator=(RenderPassImplementation&&) noexcept -> RenderPassImplementation&; - auto create_framebuffer(view::Device device, - const math::uextent2& extent, - std::vector attachments) const noexcept -> Expected; - auto allocate_framebuffer(view::Device device, - const math::uextent2& extent, - std::vector attachments) const noexcept -> Expected>; + protected: + Heap m_description = {}; + }; - [[nodiscard]] - auto is_compatible(view::RenderPass render_pass) const noexcept -> bool; - [[nodiscard]] - auto is_compatible(const RenderPassDescription& description) const noexcept -> bool; + namespace view { + class RenderPassImplementation: public GpuObjectViewImplementation { + public: + RenderPassImplementation(const gpu::RenderPass& of) noexcept; + template TContainerOrPointer> + RenderPassImplementation(const TContainerOrPointer&) noexcept; + ~RenderPassImplementation() noexcept; - [[nodiscard]] - auto description() const noexcept -> const RenderPassDescription&; + RenderPassImplementation(const RenderPassImplementation&) noexcept; + auto operator=(const RenderPassImplementation&) noexcept -> RenderPassImplementation&; - // clang-format off - // private: - // clang-format on - RenderPass(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, const RenderPassDescription&) noexcept -> Expected; + RenderPassImplementation(RenderPassImplementation&&) noexcept; + auto operator=(RenderPassImplementation&&) noexcept -> RenderPassImplementation&; - private: - RenderPassDescription m_description = {}; - }; + protected: + ref m_description; - namespace view { - class STORMKIT_GPU_API RenderPass: public DeviceObject { - public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; - - // RenderPass(const gpu::RenderPass& of) noexcept; - // template T> - // RenderPass(const T& of) noexcept; - using DeviceObject::DeviceObject; - ~RenderPass() noexcept; - - RenderPass(const RenderPass&) noexcept; - auto operator=(const RenderPass&) noexcept -> RenderPass&; - - RenderPass(RenderPass&&) noexcept; - auto operator=(RenderPass&&) noexcept -> RenderPass&; - - auto create_framebuffer(Device device, - const math::uextent2& extent, - std::vector attachments) const noexcept -> Expected; - auto allocate_framebuffer(view::Device device, - const math::uextent2& extent, - std::vector attachments) const noexcept -> Expected>; + friend class RenderPassInterface; }; } // namespace view @@ -242,223 +202,202 @@ export namespace stormkit::gpu { namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline FrameBuffer::FrameBuffer(PrivateTag, view::Device&& device) noexcept - : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyFramebuffer } { + inline auto FrameBufferInterface::extent() const noexcept -> const math::uextent2& { + return Base::m_extent; } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto FrameBuffer::create(view::Device&& device, - view::RenderPass render_pass, - const math::uextent2& extent, - std::vector&& attachments) noexcept -> Expected { - auto frame_buffer = FrameBuffer { PRIVATE, std::move(device) }; - Try(frame_buffer.do_init(std::move(render_pass), extent, std::move(attachments))); - Return frame_buffer; + inline auto FrameBufferInterface::attachments() const noexcept -> std::span { + return Base::m_attachments; } - ////////////////////////////////////p/ ///////////////////////////////////// + ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto FrameBuffer::allocate(view::Device&& device, - view::RenderPass render_pass, - const math::uextent2& extent, - std::vector&& attachments) noexcept -> Expected> { - auto frame_buffer = core::allocate_unsafe(PRIVATE, std::move(device)); - Try(frame_buffer->do_init(std::move(render_pass), extent, std::move(attachments))); - Return frame_buffer; + inline auto RenderPassInterface::create_framebuffer(this const auto& self, + view::Device device, + const math::uextent2& extent, + std::vector attachments) noexcept + -> Expected { + return FrameBuffer::create(std::move(device), gpu::as_view(self), extent, std::move(attachments)); } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline FrameBuffer::~FrameBuffer() noexcept = default; + inline auto RenderPassInterface::allocate_framebuffer(this const auto& self, + view::Device device, + const math::uextent2& extent, + std::vector attachments) noexcept + -> Expected> { + return FrameBuffer::allocate(std::move(device), gpu::as_view(self), extent, std::move(attachments)); + } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline FrameBuffer::FrameBuffer(FrameBuffer&&) noexcept = default; + inline auto RenderPassInterface::is_compatible(view::RenderPass) const noexcept -> bool { + // TODO implement proper compatibility check + // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/chap7.html#renderpass-compatibility + + return false; + } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto FrameBuffer::operator=(FrameBuffer&&) noexcept -> FrameBuffer& = default; + inline auto RenderPassInterface::description() const noexcept -> const RenderPassDescription& { + EXPECTS(Base::m_description != nullptr); + return *Base::m_description; + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto FrameBuffer::extent() const noexcept -> const math::uextent2& { - return m_extent; + inline FrameBufferImplementation::FrameBufferImplementation(PrivateTag, view::Device&& device) noexcept + : GpuObjectImplementation { std::move(device), &VolkDeviceTable::vkDestroyFramebuffer } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto FrameBuffer::attachments() const noexcept -> std::span { - return m_attachments; - } + inline FrameBufferImplementation::~FrameBufferImplementation() noexcept = default; - namespace view { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline FrameBuffer::FrameBuffer(const gpu::FrameBuffer& of) noexcept - : DeviceObject { of }, m_extent { of.extent() }, m_attachments { of.attachments() } { - } + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline FrameBufferImplementation::FrameBufferImplementation(FrameBufferImplementation&&) noexcept = default; - /////////////////////////////////// - /////////////////////////////////// - template T> - STORMKIT_FORCE_INLINE - inline FrameBuffer::FrameBuffer(const T& of) noexcept - : DeviceObject { of }, m_extent { of->extent() }, m_attachments { of->attachments() } { - } + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto FrameBufferImplementation::operator=(FrameBufferImplementation&&) noexcept + -> FrameBufferImplementation& = default; + namespace view { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline FrameBuffer::~FrameBuffer() noexcept = default; + inline FrameBufferImplementation::FrameBufferImplementation(const gpu::FrameBuffer& of) noexcept + : GpuObjectViewImplementation { of }, m_extent { of.extent() }, m_attachments { of.attachments() } { + } ///////////////////////////////////// ///////////////////////////////////// + template TContainerOrPointer> STORMKIT_FORCE_INLINE - inline FrameBuffer::FrameBuffer(const FrameBuffer&) noexcept = default; + inline FrameBufferImplementation::FrameBufferImplementation(const TContainerOrPointer& of) noexcept + : FrameBufferImplementation { *of } { + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto FrameBuffer::operator=(const FrameBuffer&) noexcept -> FrameBuffer& = default; + inline FrameBufferImplementation::~FrameBufferImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline FrameBuffer::FrameBuffer(FrameBuffer&&) noexcept = default; + inline FrameBufferImplementation::FrameBufferImplementation(const FrameBufferImplementation&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto FrameBuffer::operator=(FrameBuffer&&) noexcept -> FrameBuffer& = default; + inline auto FrameBufferImplementation::operator=(const FrameBufferImplementation&) noexcept + -> FrameBufferImplementation& = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto FrameBuffer::extent() const noexcept -> const math::uextent2& { - return m_extent; - } + inline FrameBufferImplementation::FrameBufferImplementation(FrameBufferImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto FrameBuffer::attachments() const noexcept -> std::span { - return m_attachments; - } + inline auto FrameBufferImplementation::operator=(FrameBufferImplementation&&) noexcept + -> FrameBufferImplementation& = default; } // namespace view ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline RenderPass::RenderPass(PrivateTag, view::Device&& device) noexcept - : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyRenderPass } { + inline RenderPassImplementation::RenderPassImplementation(PrivateTag, view::Device&& device) noexcept + : GpuObjectImplementation { std::move(device), &VolkDeviceTable::vkDestroyRenderPass } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline RenderPass::~RenderPass() noexcept = default; + inline RenderPassImplementation::~RenderPassImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline RenderPass::RenderPass(RenderPass&&) noexcept = default; + inline RenderPassImplementation::RenderPassImplementation(RenderPassImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto RenderPass::operator=(RenderPass&&) noexcept -> RenderPass& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto RenderPass::create_framebuffer(view::Device device, - const math::uextent2& extent, - std::vector attachments) const noexcept -> Expected { - return FrameBuffer::create(std::move(device), *this, extent, std::move(attachments)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto RenderPass::allocate_framebuffer(view::Device device, - const math::uextent2& extent, - std::vector attachments) const noexcept - -> Expected> { - return FrameBuffer::allocate(std::move(device), *this, extent, std::move(attachments)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto RenderPass::is_compatible(view::RenderPass) const noexcept -> bool { - // TODO implement proper compatibility check - // https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/chap7.html#renderpass-compatibility - - return false; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto RenderPass::description() const noexcept -> const RenderPassDescription& { - return m_description; - } + inline auto RenderPassImplementation::operator=(RenderPassImplementation&&) noexcept -> RenderPassImplementation& = default; namespace view { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline RenderPass::~RenderPass() noexcept = default; + inline RenderPassImplementation::RenderPassImplementation(const gpu::RenderPass& of) noexcept + : GpuObjectViewImplementation { of }, m_description { as_ref(of.description()) } { + } ///////////////////////////////////// ///////////////////////////////////// + template TContainerOrPointer> STORMKIT_FORCE_INLINE - inline RenderPass::RenderPass(const RenderPass&) noexcept = default; + inline RenderPassImplementation::RenderPassImplementation(const TContainerOrPointer& of) noexcept + : RenderPassImplementation { *of } { + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto RenderPass::operator=(const RenderPass&) noexcept -> RenderPass& = default; + inline RenderPassImplementation::~RenderPassImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline RenderPass::RenderPass(RenderPass&&) noexcept = default; + inline RenderPassImplementation::RenderPassImplementation(const RenderPassImplementation&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto RenderPass::operator=(RenderPass&&) noexcept -> RenderPass& = default; + inline auto RenderPassImplementation::operator=(const RenderPassImplementation& other) noexcept + -> RenderPassImplementation& { + if (&other == this) [[unlikely]] + return *this; + + m_description = as_ref(other.m_description); + + return *this; + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto RenderPass::create_framebuffer(Device device, - const math::uextent2& extent, - std::vector attachments) const noexcept - -> Expected { - return gpu::FrameBuffer::create(std::move(device), *this, extent, std::move(attachments)); - } + inline RenderPassImplementation::RenderPassImplementation(RenderPassImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto RenderPass::allocate_framebuffer(Device device, - const math::uextent2& extent, - std::vector attachments) const noexcept - -> Expected> { - return gpu::FrameBuffer::allocate(std::move(device), *this, extent, std::move(attachments)); - } + inline auto RenderPassImplementation::operator=(RenderPassImplementation&&) noexcept + -> RenderPassImplementation& = default; } // namespace view ///////////////////////////////////// diff --git a/modules/stormkit/gpu/execution/swapchain.cppm b/modules/stormkit/gpu/execution/swapchain.cppm index 5cb2315c0..44f58587d 100644 --- a/modules/stormkit/gpu/execution/swapchain.cppm +++ b/modules/stormkit/gpu/execution/swapchain.cppm @@ -17,44 +17,29 @@ import stormkit.core; import stormkit.gpu.core; import stormkit.gpu.resource; -namespace cmeta = stormkit::core::meta; - -export namespace stormkit::gpu { - class SwapChain; - - namespace view { - class SwapChain; - } // namespace view +import :objects; - namespace meta { - template<> - struct ObjectInfo { - using Of = SwapChain; - using ValueType = VkSwapchainKHR; - using DeleterType = PFN_vkDestroySwapchainKHR VolkDeviceTable::*; - using ViewType = view::SwapChain; - using OwnedBy = Device; - - static constexpr auto DEBUG_TYPE = DebugObjectType::SWAPCHAIN; - }; - } // namespace meta +namespace cmeta = stormkit::core::meta; - class STORMKIT_GPU_API SwapChain: public OwnedByDevice { - public: +namespace stormkit::gpu { + struct SwapChainInterfaceBase { using ImageID = u32; struct NextImage { Result result; ImageID id; }; + }; - ~SwapChain() noexcept; - - SwapChain(const SwapChain&) = delete; - auto operator=(const SwapChain&) -> SwapChain& = delete; + export template + class STORMKIT_GPU_API SwapChainInterface final: public DeviceObject, public SwapChainInterfaceBase { + public: + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = SwapChainTag; - SwapChain(SwapChain&&) noexcept; - auto operator=(SwapChain&&) noexcept -> SwapChain&; + using SwapChainInterfaceBase::ImageID; + using SwapChainInterfaceBase::NextImage; [[nodiscard]] auto pixel_format() const noexcept -> PixelFormat; @@ -62,15 +47,25 @@ export namespace stormkit::gpu { auto images() const noexcept -> std::span; auto acquire_next_image(std::chrono::nanoseconds wait, view::Semaphore image_available) const noexcept -> Expected; + }; - // clang-format off - // private: - // clang-format on - SwapChain(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, view::Surface&&, const math::uextent2&, VkSwapchainKHR = VK_NULL_HANDLE) noexcept + class STORMKIT_GPU_API SwapChainImplementation: public GpuObjectImplementation { + public: + using ImageID = SwapChainInterfaceBase::ImageID; + using NextImage = SwapChainInterfaceBase::NextImage; + + SwapChainImplementation(PrivateTag, view::Device&&) noexcept; + auto do_init(PrivateTag, view::Surface, const math::uextent2&, VkSwapchainKHR = VK_NULL_HANDLE) noexcept -> Expected; + ~SwapChainImplementation() noexcept; + + SwapChainImplementation(const SwapChainImplementation&) = delete; + auto operator=(const SwapChainImplementation&) -> SwapChainImplementation& = delete; - private: + SwapChainImplementation(SwapChainImplementation&&) noexcept; + auto operator=(SwapChainImplementation&&) noexcept -> SwapChainImplementation&; + + protected: math::uextent2 m_extent; PixelFormat m_pixel_format; u32 m_image_count; @@ -79,31 +74,23 @@ export namespace stormkit::gpu { }; namespace view { - class STORMKIT_GPU_API SwapChain: public DeviceObject { + class SwapChainImplementation: public GpuObjectViewImplementation { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; - - SwapChain(const gpu::SwapChain& of) noexcept; - template T> - SwapChain(const T& of) noexcept; - ~SwapChain() noexcept; + using ImageID = SwapChainInterfaceBase::ImageID; + using NextImage = SwapChainInterfaceBase::NextImage; - SwapChain(const SwapChain&) noexcept; - auto operator=(const SwapChain&) noexcept -> SwapChain&; + SwapChainImplementation(const gpu::SwapChain& of) noexcept; + template TContainerOrPointer> + SwapChainImplementation(const TContainerOrPointer&) noexcept; + ~SwapChainImplementation() noexcept; - SwapChain(SwapChain&&) noexcept; - auto operator=(SwapChain&&) noexcept -> SwapChain&; + SwapChainImplementation(const SwapChainImplementation&) noexcept; + auto operator=(const SwapChainImplementation&) noexcept -> SwapChainImplementation&; - [[nodiscard]] - auto pixel_format() const noexcept -> PixelFormat; - [[nodiscard]] - auto images() const noexcept -> std::span; - auto acquire_next_image(std::chrono::nanoseconds wait, Semaphore image_available) const noexcept - -> Expected; + SwapChainImplementation(SwapChainImplementation&&) noexcept; + auto operator=(SwapChainImplementation&&) noexcept -> SwapChainImplementation&; - private: + protected: math::uextent2 m_extent; PixelFormat m_pixel_format; u32 m_image_count; @@ -118,93 +105,82 @@ export namespace stormkit::gpu { //////////////////////////////////////////////////////////////////// namespace stormkit::gpu { + ///////////////////////////////////// + ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline SwapChain::SwapChain(PrivateTag, view::Device&& device) noexcept - : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroySwapchainKHR } { + inline auto SwapChainInterface::pixel_format() const noexcept -> PixelFormat { + return Base::m_pixel_format; } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline SwapChain::~SwapChain() noexcept = default; + inline auto SwapChainInterface::images() const noexcept -> std::span { + return Base::m_images; + } - ///////////////////////////////////// - ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline SwapChain::SwapChain(SwapChain&&) noexcept = default; + inline SwapChainImplementation::SwapChainImplementation(PrivateTag, view::Device&& device) noexcept + : GpuObjectImplementation { std::move(device), &VolkDeviceTable::vkDestroySwapchainKHR } { + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto SwapChain::operator=(SwapChain&&) noexcept -> SwapChain& = default; + inline SwapChainImplementation::~SwapChainImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto SwapChain::pixel_format() const noexcept -> PixelFormat { - return m_pixel_format; - } + inline SwapChainImplementation::SwapChainImplementation(SwapChainImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto SwapChain::images() const noexcept -> std::span { - return m_images; - } + inline auto SwapChainImplementation::operator=(SwapChainImplementation&&) noexcept -> SwapChainImplementation& = default; namespace view { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline SwapChain::SwapChain(const gpu::SwapChain& of) noexcept - : view::DeviceObject { of }, m_pixel_format { of.pixel_format() }, m_images { of.images() } { - } - - /////////////////////////////////// - /////////////////////////////////// - template T> - STORMKIT_FORCE_INLINE - inline SwapChain::SwapChain(const T& of) noexcept - : view::DeviceObject { of }, m_pixel_format { of->pixel_format() }, m_images { of->images() } { + inline SwapChainImplementation::SwapChainImplementation(const gpu::SwapChain& of) noexcept + : GpuObjectViewImplementation { of }, m_pixel_format { of.pixel_format() }, m_images { of.images() } { } ///////////////////////////////////// ///////////////////////////////////// + template TContainerOrPointer> STORMKIT_FORCE_INLINE - inline SwapChain::~SwapChain() noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline SwapChain::SwapChain(const SwapChain&) noexcept = default; + inline SwapChainImplementation::SwapChainImplementation(const TContainerOrPointer& of) noexcept + : SwapChainImplementation { *of } { + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto SwapChain::operator=(const SwapChain&) noexcept -> SwapChain& = default; + inline SwapChainImplementation::~SwapChainImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline SwapChain::SwapChain(SwapChain&&) noexcept = default; + inline SwapChainImplementation::SwapChainImplementation(const SwapChainImplementation&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto SwapChain::operator=(SwapChain&&) noexcept -> SwapChain& = default; + inline auto SwapChainImplementation::operator=(const SwapChainImplementation&) noexcept + -> SwapChainImplementation& = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto SwapChain::pixel_format() const noexcept -> PixelFormat { - return m_pixel_format; - } + inline SwapChainImplementation::SwapChainImplementation(SwapChainImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto SwapChain::images() const noexcept -> std::span { - return m_images; - } + inline auto SwapChainImplementation::operator=(SwapChainImplementation&&) noexcept -> SwapChainImplementation& = default; } // namespace view } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/resource.cppm b/modules/stormkit/gpu/resource.cppm index 53629a51b..ac97f86dc 100644 --- a/modules/stormkit/gpu/resource.cppm +++ b/modules/stormkit/gpu/resource.cppm @@ -4,6 +4,7 @@ export module stormkit.gpu.resource; +export import :objects; export import :buffer; export import :image; export import :shader; diff --git a/modules/stormkit/gpu/resource/buffer.cppm b/modules/stormkit/gpu/resource/buffer.cppm index a89a7af58..b9a207940 100644 --- a/modules/stormkit/gpu/resource/buffer.cppm +++ b/modules/stormkit/gpu/resource/buffer.cppm @@ -18,52 +18,29 @@ import std; import stormkit.core; import stormkit.gpu.core; +import :objects; + namespace stdr = std::ranges; namespace cmeta = stormkit::core::meta; namespace cmonadic = stormkit::core::monadic; namespace stormkit::gpu { - struct BufferAPI; -} - -export namespace stormkit::gpu { - class Buffer; - - namespace view { - class Buffer; - } // namespace view - - namespace meta { - template<> - struct ObjectInfo { - using Of = Buffer; - using ValueType = VkBuffer; - using DeleterType = PFN_vkDestroyBuffer VolkDeviceTable::*; - using ViewType = view::Buffer; - using OwnedBy = Device; - - static constexpr auto DEBUG_TYPE = DebugObjectType::BUFFER; - }; - } // namespace meta - - class STORMKIT_GPU_API Buffer: public OwnedByDevice { + export template + class STORMKIT_GPU_API BufferInterface final: public DeviceObject { public: - struct CreateInfo { - BufferUsageFlag usages; - usize size; - MemoryPropertyFlag properties = MemoryPropertyFlag::HOST_VISIBLE | MemoryPropertyFlag::HOST_COHERENT; + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = BufferTag; - bool persistently_mapped = false; - }; + BufferInterface(const BufferInterface&) noexcept + requires(cmeta::IsCopyConstructible>); + auto operator=(const BufferInterface&) noexcept -> BufferInterface& + requires(cmeta::IsCopyAssignable>); - ~Buffer(); - - Buffer(const Buffer&) = delete; - auto operator=(const Buffer&) -> Buffer& = delete; - - Buffer(Buffer&&) noexcept; - auto operator=(Buffer&&) noexcept -> Buffer&; + BufferInterface(BufferInterface&&) noexcept; + auto operator=(BufferInterface&&) noexcept -> BufferInterface&; + ~BufferInterface() noexcept; [[nodiscard]] auto usages() const noexcept -> BufferUsageFlag; @@ -94,7 +71,7 @@ export namespace stormkit::gpu { [[nodiscard]] auto data_as(this auto& self) noexcept -> ref; - auto flush(ioffset offset, usize size) noexcept -> Expected; + auto flush(ioffset offset, usize size) const noexcept -> Expected; auto unmap() noexcept -> void; auto upload(std::span data, ioffset offset = 0) noexcept -> Expected; @@ -105,19 +82,29 @@ export namespace stormkit::gpu { [[nodiscard]] auto allocation() const noexcept -> vk::Observer; + }; - // clang-format off - // private: - // clang-format on - Buffer(PrivateTag, view::Device) noexcept; + class STORMKIT_GPU_API BufferImplementation: public GpuObjectImplementation { + public: + struct CreateInfo { + BufferUsageFlag usages; + usize size; + MemoryPropertyFlag properties = MemoryPropertyFlag::HOST_VISIBLE | MemoryPropertyFlag::HOST_COHERENT; + + bool persistently_mapped = false; + }; + + BufferImplementation(PrivateTag, view::Device&&) noexcept; auto do_init(PrivateTag, const CreateInfo&) noexcept -> Expected; + ~BufferImplementation() noexcept; + + BufferImplementation(const BufferImplementation&) noexcept = delete; + auto operator=(const BufferImplementation&) noexcept -> BufferImplementation& = delete; - private: - static auto find_memory_type(u32, - VkMemoryPropertyFlagBits, - const VkPhysicalDeviceMemoryProperties&, - const VkMemoryRequirements&) noexcept -> u32; + BufferImplementation(BufferImplementation&&) noexcept; + auto operator=(BufferImplementation&&) noexcept -> BufferImplementation&; + protected: BufferUsageFlag m_usages = {}; usize m_size = 0; MemoryPropertyFlag m_memory_properties = {}; @@ -126,70 +113,23 @@ export namespace stormkit::gpu { byte* m_mapped_pointer = nullptr; vk::Owned m_vma_allocation = { cmonadic::discard() }; - - friend struct BufferAPI; }; namespace view { - class STORMKIT_GPU_API Buffer: public DeviceObject { + class BufferImplementation: public GpuObjectViewImplementation { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; - - Buffer(const gpu::Buffer& of) noexcept; - template T> - Buffer(const T& of) noexcept; - ~Buffer() noexcept; - - Buffer(const Buffer&) noexcept; - auto operator=(const Buffer&) noexcept -> Buffer&; - - Buffer(Buffer&&) noexcept; - auto operator=(Buffer&&) noexcept -> Buffer&; - - [[nodiscard]] - auto usages() const noexcept -> BufferUsageFlag; - [[nodiscard]] - auto size() const noexcept -> usize; - [[nodiscard]] - auto memory_properties() const noexcept -> MemoryPropertyFlag; - [[nodiscard]] - auto is_persistently_mapped() const noexcept -> bool; - - auto map(ioffset offset) noexcept -> Expected; - auto map(ioffset offset, usize size) noexcept -> Expected>; - - template - auto map_as(ioffset offset) noexcept -> Expected>; - - bool mapped() const noexcept; - - template - [[nodiscard]] - auto data(this Self& self) noexcept -> cmeta::ForwardConst*; - template - [[nodiscard]] - auto data(this Self& self, usize size) noexcept - -> cmeta::If, std::span, std::span>; + BufferImplementation(const gpu::Buffer&) noexcept; + template TContainerOrPointer> + BufferImplementation(const TContainerOrPointer&) noexcept; + ~BufferImplementation() noexcept; - template - [[nodiscard]] - auto data_as(this auto& self) noexcept -> ref; + BufferImplementation(const BufferImplementation&) noexcept; + auto operator=(const BufferImplementation&) noexcept -> BufferImplementation&; - auto flush(ioffset offset, usize size) noexcept -> Expected; - auto unmap() noexcept -> void; + BufferImplementation(BufferImplementation&&) noexcept; + auto operator=(BufferImplementation&&) noexcept -> BufferImplementation&; - auto upload(std::span data, ioffset offset = 0) noexcept -> Expected; - - template - requires(not stormkit::meta::IsSpecializationWithNTTPOf) - auto upload(const T& data, ioffset offset = 0) noexcept -> Expected; - - [[nodiscard]] - auto allocation() const noexcept -> vk::Observer; - - private: + protected: BufferUsageFlag m_usages = {}; usize m_size = 0; MemoryPropertyFlag m_memory_properties = {}; @@ -198,25 +138,20 @@ export namespace stormkit::gpu { byte* m_mapped_pointer = nullptr; vk::Observer m_vma_allocation; - - friend struct gpu::BufferAPI; }; } // namespace view - struct BufferMemoryBarrier { + export struct BufferMemoryBarrier { AccessFlag src; AccessFlag dst; u32 src_queue_family_index = QUEUE_FAMILY_IGNORED; u32 dst_queue_family_index = QUEUE_FAMILY_IGNORED; - const Buffer& buffer; - usize size; - u64 offset = 0; + view::Buffer buffer; + usize size; + u64 offset = 0; }; - - template - constexpr auto hasher(const Buffer::CreateInfo& create_info) noexcept -> Ret; } // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// @@ -226,95 +161,108 @@ export namespace stormkit::gpu { namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - inline Buffer::Buffer(PrivateTag, view::Device device) noexcept - : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyBuffer } { + template + STORMKIT_FORCE_INLINE + inline BufferInterface::BufferInterface(const BufferInterface& other) noexcept + requires(cmeta::IsCopyConstructible>) + : DeviceObject { other } { } ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Buffer::~Buffer() { - if (m_mapped_pointer != nullptr and m_vma_allocation) { - const auto& allocator = device().allocator(); - - vk::call(vmaUnmapMemory, allocator, m_vma_allocation); - - m_mapped_pointer = nullptr; - } - } + template + STORMKIT_FORCE_INLINE + inline auto BufferInterface::operator=(const BufferInterface& other) noexcept -> BufferInterface& + requires(cmeta::IsCopyAssignable>) + = default; ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline Buffer::Buffer(Buffer&& other) noexcept = default; + inline BufferInterface::BufferInterface(BufferInterface&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto BufferInterface::operator=(BufferInterface&&) noexcept -> BufferInterface& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto Buffer::operator=(Buffer&& other) noexcept -> Buffer& = default; + inline BufferInterface::~BufferInterface() noexcept { + if (allocation()) unmap(); + } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto Buffer::usages() const noexcept -> BufferUsageFlag { - EXPECTS(m_vma_allocation and m_vk_handle); - return m_usages; + inline auto BufferInterface::usages() const noexcept -> BufferUsageFlag { + EXPECTS(Base::m_vma_allocation and Base::m_vk_handle); + return Base::m_usages; } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto Buffer::size() const noexcept -> usize { - EXPECTS(m_vma_allocation and m_vk_handle); - return m_size; + inline auto BufferInterface::size() const noexcept -> usize { + EXPECTS(Base::m_vma_allocation and Base::m_vk_handle); + return Base::m_size; } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto Buffer::memory_properties() const noexcept -> MemoryPropertyFlag { - return m_memory_properties; + inline auto BufferInterface::memory_properties() const noexcept -> MemoryPropertyFlag { + return Base::m_memory_properties; } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto Buffer::is_persistently_mapped() const noexcept -> bool { - return m_is_persistently_mapped; + inline auto BufferInterface::is_persistently_mapped() const noexcept -> bool { + return Base::m_is_persistently_mapped; } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto Buffer::map(ioffset offset, usize size) noexcept -> Expected> { - EXPECTS(m_vma_allocation and m_vk_handle); + inline auto BufferInterface::map(ioffset offset, usize size) noexcept -> Expected> { auto ptr = Try(map(offset)); Return as_bytes_mut(ptr, size); } ///////////////////////////////////// ///////////////////////////////////// + template template STORMKIT_FORCE_INLINE - inline auto Buffer::map_as(ioffset offset) noexcept -> Expected> { - EXPECTS(m_vma_allocation and m_vk_handle); - + inline auto BufferInterface::map_as(ioffset offset) noexcept -> Expected> { const auto ptr = Try(map(offset)); Return from_bytes_mut(ptr); } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto Buffer::mapped() const noexcept -> bool { - return m_mapped_pointer != nullptr; + inline auto BufferInterface::mapped() const noexcept -> bool { + return Base::m_mapped_pointer != nullptr; } ///////////////////////////////////// ///////////////////////////////////// + template template STORMKIT_FORCE_INLINE - inline auto Buffer::data(this Self& self) noexcept -> cmeta::ForwardConst* { + inline auto BufferInterface::data(this Self& self) noexcept -> cmeta::ForwardConst* { EXPECTS(self.m_vma_allocation and self.m_vk_handle); EXPECTS(self.m_mapped_pointer); @@ -324,52 +272,71 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// + template template STORMKIT_FORCE_INLINE - inline auto Buffer::data(this Self& self, usize size) noexcept + inline auto BufferInterface::data(this Self& self, usize size) noexcept -> cmeta::If, std::span, std::span> { - EXPECTS(self.m_vma_allocation and self.m_vk_handle); - EXPECTS(self.m_mapped_pointer); - using Out = std::span>; - return Out { std::bit_cast(self.m_mapped_pointer), size }; + return Out { std::bit_cast(self.data()), size }; } ///////////////////////////////////// ///////////////////////////////////// + template template STORMKIT_FORCE_INLINE - inline auto Buffer::data_as(this Self& self) noexcept -> ref { - EXPECTS(self.m_vma_allocation and self.m_vk_handle); - EXPECTS(self.m_mapped_pointer); - + inline auto BufferInterface::data_as(this Self& self) noexcept -> ref { using Type = cmeta::ForwardConst*; return as_ref_like(std::bit_cast(self.data())); } ///////////////////////////////////// ///////////////////////////////////// + template + template + requires(not stormkit::meta::IsSpecializationWithNTTPOf) STORMKIT_FORCE_INLINE - inline auto Buffer::allocation() const noexcept -> vk::Observer { - return m_vma_allocation; + inline auto BufferInterface::upload(const T& data, ioffset offset) noexcept -> Expected { + const auto bytes = as_bytes(data); + return upload(bytes, offset); } ///////////////////////////////////// ///////////////////////////////////// - template - requires(not stormkit::meta::IsSpecializationWithNTTPOf) + template STORMKIT_FORCE_INLINE - inline auto Buffer::upload(const T& data, ioffset offset) noexcept -> Expected { - const auto bytes = as_bytes(data); - return upload(bytes, offset); + inline auto BufferInterface::allocation() const noexcept -> vk::Observer { + return Base::m_vma_allocation; } + ///////////////////////////////////// + ///////////////////////////////////// + inline BufferImplementation::BufferImplementation(PrivateTag, view::Device&& device) noexcept + : GpuObjectImplementation { std::move(device), &VolkDeviceTable::vkDestroyBuffer } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline BufferImplementation::~BufferImplementation() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline BufferImplementation::BufferImplementation(BufferImplementation&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto BufferImplementation::operator=(BufferImplementation&&) noexcept -> BufferImplementation& = default; + namespace view { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Buffer::Buffer(const gpu::Buffer& of) noexcept - : DeviceObject { of }, + inline BufferImplementation::BufferImplementation(const gpu::Buffer& of) noexcept + : GpuObjectViewImplementation { of }, m_usages { of.usages() }, m_size { of.size() }, m_memory_properties { of.memory_properties() }, @@ -379,150 +346,44 @@ namespace stormkit::gpu { if (of.is_persistently_mapped()) m_mapped_pointer = std::bit_cast(of.data()); } - /////////////////////////////////// - /////////////////////////////////// - template T> - STORMKIT_FORCE_INLINE - inline Buffer::Buffer(const T& of) noexcept - : DeviceObject { of }, - m_usages { of->usages() }, - m_size { of->size() }, - m_memory_properties { of->memory_properties() }, - m_is_persistently_mapped { of->is_persistently_mapped() }, - m_mapped_pointer { nullptr }, - m_vma_allocation { of->allocation() } { - if (of->is_persistently_mapped()) m_mapped_pointer = std::bit_cast(of->data()); - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Buffer::~Buffer() noexcept = default; - ///////////////////////////////////// ///////////////////////////////////// + template TContainerOrPointer> STORMKIT_FORCE_INLINE - inline Buffer::Buffer(const Buffer& other) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Buffer::operator=(const Buffer& other) noexcept -> Buffer& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Buffer::Buffer(Buffer&&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Buffer::operator=(Buffer&&) noexcept -> Buffer& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Buffer::usages() const noexcept -> BufferUsageFlag { - return m_usages; + inline BufferImplementation::BufferImplementation(const TContainerOrPointer& of) noexcept + : BufferImplementation { *of } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Buffer::size() const noexcept -> usize { - return m_size; - } + inline BufferImplementation::~BufferImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Buffer::memory_properties() const noexcept -> MemoryPropertyFlag { - return m_memory_properties; - } + inline BufferImplementation::BufferImplementation(const BufferImplementation&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Buffer::is_persistently_mapped() const noexcept -> bool { - return m_is_persistently_mapped; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Buffer::map(ioffset offset, usize size) noexcept -> Expected> { - EXPECTS(m_vma_allocation and m_vk_handle); - auto ptr = Try(map(offset)); - Return as_bytes_mut(ptr, size); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Buffer::map_as(ioffset offset) noexcept -> Expected> { - EXPECTS(m_vma_allocation and m_vk_handle); - - const auto ptr = Try(map(offset)); - Return from_bytes_mut(ptr); - } + inline auto BufferImplementation::operator=(const BufferImplementation&) noexcept -> BufferImplementation& = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Buffer::mapped() const noexcept -> bool { - return m_mapped_pointer != nullptr; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Buffer::data(this Self& self) noexcept -> cmeta::ForwardConst* { - EXPECTS(self.m_vma_allocation and self.m_vk_handle); - EXPECTS(self.m_mapped_pointer); - - using Out = cmeta::ForwardConst*; - return std::bit_cast(self.m_mapped_pointer); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Buffer::data(this Self& self, usize size) noexcept - -> cmeta::If, std::span, std::span> { - EXPECTS(self.m_vma_allocation and self.m_vk_handle); - EXPECTS(self.m_mapped_pointer); - - using Out = std::span>; - return Out { std::bit_cast(self.m_mapped_pointer), size }; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline auto Buffer::data_as(this Self& self) noexcept -> ref { - EXPECTS(self.m_vma_allocation and self.m_vk_handle); - EXPECTS(self.m_mapped_pointer); - - using Type = cmeta::ForwardConst*; - return as_ref_like(std::bit_cast(self.data())); - } + inline BufferImplementation::BufferImplementation(BufferImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Buffer::allocation() const noexcept -> vk::Observer { - return m_vma_allocation; - } + inline auto BufferImplementation::operator=(BufferImplementation&&) noexcept -> BufferImplementation& = default; } // namespace view ///////////////////////////////////// ///////////////////////////////////// - template - constexpr auto hasher(const Buffer::CreateInfo& create_info) noexcept -> Ret { - return hash(create_info.usages, create_info.size, create_info.properties); - } + // template + // constexpr auto hasher(const Buffer::CreateInfo& create_info) noexcept -> Ret { + // return hash(create_info.usages, create_info.size, create_info.properties); + // } } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/resource/image.cppm b/modules/stormkit/gpu/resource/image.cppm index 40b87200d..f4dc99da3 100644 --- a/modules/stormkit/gpu/resource/image.cppm +++ b/modules/stormkit/gpu/resource/image.cppm @@ -18,57 +18,13 @@ import stormkit.core; import stormkit.image; import stormkit.gpu.core; +import :objects; + namespace cmeta = stormkit::core::meta; namespace cmonadic = stormkit::core::monadic; -export namespace stormkit::gpu { - class Sampler; - class ImageView; - class Image; - - namespace view { - class Sampler; - class ImageView; - class Image; - } // namespace view - - namespace meta { - template<> - struct ObjectInfo { - using Of = Sampler; - using ValueType = VkSampler; - using DeleterType = PFN_vkDestroySampler VolkDeviceTable::*; - using ViewType = view::Sampler; - using OwnedBy = Device; - - static constexpr auto DEBUG_TYPE = DebugObjectType::SAMPLER; - }; - - template<> - struct ObjectInfo { - using Of = ImageView; - using ValueType = VkImageView; - using DeleterType = PFN_vkDestroyImageView VolkDeviceTable::*; - using ViewType = view::ImageView; - using OwnedBy = Device; - - static constexpr auto DEBUG_TYPE = DebugObjectType::IMAGE_VIEW; - }; - - template<> - struct ObjectInfo { - using Of = Image; - using ValueType = VkImage; - using DeleterType = PFN_vkDestroyImage VolkDeviceTable::*; - using ViewType = view::Image; - using OwnedBy = Device; - - static constexpr auto DEBUG_TYPE = DebugObjectType::IMAGE; - }; - } // namespace meta - - class STORMKIT_GPU_API Sampler: public OwnedByDevice { - public: +namespace stormkit::gpu { + struct SamplerInterfaceBase { struct Settings { Filter mag_filter = Filter::LINEAR; Filter min_filter = Filter::LINEAR; @@ -93,111 +49,101 @@ export namespace stormkit::gpu { f32 min_lod = 0.f; f32 max_lod = 0.f; }; - - ~Sampler(); - - Sampler(const Sampler&) = delete; - auto operator=(const Sampler&) -> Sampler& = delete; - - Sampler(Sampler&&) noexcept; - auto operator=(Sampler&&) noexcept -> Sampler&; - - [[nodiscard]] - auto settings() const noexcept -> const Settings&; - - // clang-format off - // private: - // clang-format on - Sampler(PrivateTag, view::Device) noexcept; - auto do_init(PrivateTag, const Settings&) noexcept -> Expected; - - private: - Settings m_settings = {}; }; - namespace view { - class STORMKIT_GPU_API Sampler: public view::DeviceObject { + export { + template + class SamplerInterface: public DeviceObject, public SamplerInterfaceBase { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = SamplerTag; - Sampler(const gpu::Sampler& of) noexcept; - template T> - Sampler(const T& of) noexcept; - ~Sampler() noexcept; - - Sampler(const Sampler&) noexcept; - auto operator=(const Sampler&) noexcept -> Sampler&; + [[nodiscard]] + auto settings() const noexcept -> const Settings&; + }; - Sampler(Sampler&&) noexcept; - auto operator=(Sampler&&) noexcept -> Sampler&; + template + class ImageInterface: public DeviceObject { + public: + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = ImageTag; [[nodiscard]] - auto settings() const noexcept -> const gpu::Sampler::Settings&; + auto extent() const noexcept -> const math::uextent3&; + [[nodiscard]] + auto format() const noexcept -> PixelFormat; + [[nodiscard]] + auto type() const noexcept -> ImageType; + [[nodiscard]] + auto samples() const noexcept -> SampleCountFlag; + [[nodiscard]] + auto layers() const noexcept -> u32; + [[nodiscard]] + auto faces() const noexcept -> u32; + [[nodiscard]] + auto mip_levels() const noexcept -> u32; + [[nodiscard]] + auto usages() const noexcept -> ImageUsageFlag; + [[nodiscard]] + auto allocation() const noexcept -> vk::Observer; + }; + + template + class ImageViewInterface: public DeviceObject { + public: + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = ImageViewTag; - private: - gpu::Sampler::Settings m_settings; + [[nodiscard]] + auto type() const noexcept -> ImageViewType; + [[nodiscard]] + auto subresource_range() const noexcept -> const ImageSubresourceRange&; }; - } // namespace view + } - class STORMKIT_GPU_API ImageView: public OwnedByDevice { + class STORMKIT_GPU_API SamplerImplementation: public GpuObjectImplementation { public: - ~ImageView(); + using Settings = SamplerInterfaceBase::Settings; - ImageView(const ImageView&) = delete; - auto operator=(const ImageView&) -> ImageView& = delete; - - ImageView(ImageView&&) noexcept; - auto operator=(ImageView&&) noexcept -> ImageView&; + SamplerImplementation(PrivateTag, view::Device&&) noexcept; + auto do_init(PrivateTag, const Settings&) noexcept -> Expected; + ~SamplerImplementation() noexcept; - [[nodiscard]] - auto type() const noexcept -> ImageViewType; - [[nodiscard]] - auto subresource_range() const noexcept -> const ImageSubresourceRange&; + SamplerImplementation(const SamplerImplementation&) noexcept = delete; + auto operator=(const SamplerImplementation&) noexcept -> SamplerImplementation& = delete; - // clang-format off - // private: - // clang-format on - ImageView(PrivateTag, view::Device) noexcept; - auto do_init(PrivateTag, view::Image, ImageViewType = ImageViewType::T2D, const ImageSubresourceRange& = {}) noexcept - -> Expected; + SamplerImplementation(SamplerImplementation&&) noexcept; + auto operator=(SamplerImplementation&&) noexcept -> SamplerImplementation&; - private: - ImageViewType m_type = {}; - ImageSubresourceRange m_subresource_range = {}; + protected: + Settings m_settings = {}; }; namespace view { - class STORMKIT_GPU_API ImageView: public view::DeviceObject { + class SamplerImplementation: public GpuObjectViewImplementation { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; + using Settings = SamplerInterfaceBase::Settings; - ImageView(const gpu::ImageView& of) noexcept; - template T> - ImageView(const T& of) noexcept; - ~ImageView() noexcept; + SamplerImplementation(const gpu::Sampler&) noexcept; + template TContainerOrPointer> + SamplerImplementation(const TContainerOrPointer&) noexcept; + ~SamplerImplementation() noexcept; - ImageView(const ImageView&) noexcept; - auto operator=(const ImageView&) noexcept -> ImageView&; + SamplerImplementation(const SamplerImplementation&) noexcept; + auto operator=(const SamplerImplementation&) noexcept -> SamplerImplementation&; - ImageView(ImageView&&) noexcept; - auto operator=(ImageView&&) noexcept -> ImageView&; + SamplerImplementation(SamplerImplementation&&) noexcept; + auto operator=(SamplerImplementation&&) noexcept -> SamplerImplementation&; - [[nodiscard]] - auto type() const noexcept -> ImageViewType; - [[nodiscard]] - auto subresource_range() const noexcept -> const ImageSubresourceRange&; - - private: - ImageViewType m_type = {}; - ImageSubresourceRange m_subresource_range = {}; + protected: + Settings m_settings; }; } // namespace view - class STORMKIT_GPU_API Image: public OwnedByDevice { + class STORMKIT_GPU_API ImageImplementation: public GpuObjectImplementation { public: struct CreateInfo { math::uextent3 extent; @@ -212,41 +158,19 @@ export namespace stormkit::gpu { MemoryPropertyFlag properties = MemoryPropertyFlag::DEVICE_LOCAL; }; - static auto from_existing(view::Device device, const CreateInfo& create_info, VkImage image) noexcept -> Image; - ~Image(); - - Image(const Image&) = delete; - auto operator=(const Image&) -> Image& = delete; - - Image(Image&&) noexcept; - auto operator=(Image&&) noexcept -> Image&; - - [[nodiscard]] - auto extent() const noexcept -> const math::uextent3&; - [[nodiscard]] - auto format() const noexcept -> PixelFormat; - [[nodiscard]] - auto type() const noexcept -> ImageType; - [[nodiscard]] - auto samples() const noexcept -> SampleCountFlag; - [[nodiscard]] - auto layers() const noexcept -> u32; - [[nodiscard]] - auto faces() const noexcept -> u32; - [[nodiscard]] - auto mip_levels() const noexcept -> u32; - [[nodiscard]] - auto usages() const noexcept -> ImageUsageFlag; - [[nodiscard]] - auto allocation() const noexcept -> vk::Observer; - - // clang-format off - // private: - // clang-format on - Image(PrivateTag, view::Device) noexcept; + ImageImplementation(PrivateTag, view::Device&&) noexcept; auto do_init(PrivateTag, const CreateInfo&) noexcept -> Expected; + ~ImageImplementation() noexcept; + + ImageImplementation(const ImageImplementation&) noexcept = delete; + auto operator=(const ImageImplementation&) noexcept -> ImageImplementation& = delete; + + ImageImplementation(ImageImplementation&&) noexcept; + auto operator=(ImageImplementation&&) noexcept -> ImageImplementation&; + + static auto from_existing(view::Device device, const CreateInfo& create_info, VkImage image) noexcept -> Image; - private: + protected: bool m_no_delete = false; math::uextent3 m_extent = { 0, 0, 0 }; @@ -261,47 +185,24 @@ export namespace stormkit::gpu { vk::Owned m_vma_allocation = { cmonadic::discard() }; - friend class view::Image; + friend class view::ImageImplementation; }; namespace view { - class STORMKIT_GPU_API Image: public view::DeviceObject { + class ImageImplementation: public GpuObjectViewImplementation { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; - - Image(const gpu::Image& of) noexcept; - template T> - Image(const T& of) noexcept; - ~Image() noexcept; + ImageImplementation(const gpu::Image&) noexcept; + template TContainerOrPointer> + ImageImplementation(const TContainerOrPointer&) noexcept; + ~ImageImplementation() noexcept; - Image(const Image&) noexcept; - auto operator=(const Image&) noexcept -> Image&; + ImageImplementation(const ImageImplementation&) noexcept; + auto operator=(const ImageImplementation&) noexcept -> ImageImplementation&; - Image(Image&&) noexcept; - auto operator=(Image&&) noexcept -> Image&; - - [[nodiscard]] - auto extent() const noexcept -> const math::uextent3&; - [[nodiscard]] - auto format() const noexcept -> PixelFormat; - [[nodiscard]] - auto type() const noexcept -> ImageType; - [[nodiscard]] - auto samples() const noexcept -> SampleCountFlag; - [[nodiscard]] - auto layers() const noexcept -> u32; - [[nodiscard]] - auto faces() const noexcept -> u32; - [[nodiscard]] - auto mip_levels() const noexcept -> u32; - [[nodiscard]] - auto usages() const noexcept -> ImageUsageFlag; - [[nodiscard]] - auto allocation() const noexcept -> vk::Observer; + ImageImplementation(ImageImplementation&&) noexcept; + auto operator=(ImageImplementation&&) noexcept -> ImageImplementation&; - private: + protected: math::uextent3 m_extent = { 0, 0, 0 }; PixelFormat m_format = {}; u32 m_layers = 0; @@ -319,7 +220,45 @@ export namespace stormkit::gpu { }; } // namespace view - struct ImageMemoryBarrier { + class STORMKIT_GPU_API ImageViewImplementation: public GpuObjectImplementation { + public: + ImageViewImplementation(PrivateTag, view::Device&&) noexcept; + auto do_init(PrivateTag, view::Image, ImageViewType = ImageViewType::T2D, const ImageSubresourceRange& = {}) noexcept + -> Expected; + ~ImageViewImplementation() noexcept; + + ImageViewImplementation(const ImageViewImplementation&) noexcept = delete; + auto operator=(const ImageViewImplementation&) noexcept -> ImageViewImplementation& = delete; + + ImageViewImplementation(ImageViewImplementation&&) noexcept; + auto operator=(ImageViewImplementation&&) noexcept -> ImageViewImplementation&; + + protected: + ImageViewType m_type = {}; + ImageSubresourceRange m_subresource_range = {}; + }; + + namespace view { + class ImageViewImplementation: public GpuObjectViewImplementation { + public: + ImageViewImplementation(const gpu::ImageView&) noexcept; + template TContainerOrPointer> + ImageViewImplementation(const TContainerOrPointer&) noexcept; + ~ImageViewImplementation() noexcept; + + ImageViewImplementation(const ImageViewImplementation&) noexcept; + auto operator=(const ImageViewImplementation&) noexcept -> ImageViewImplementation&; + + ImageViewImplementation(ImageViewImplementation&&) noexcept; + auto operator=(ImageViewImplementation&&) noexcept -> ImageViewImplementation&; + + protected: + ImageViewType m_type = {}; + ImageSubresourceRange m_subresource_range = {}; + }; + } // namespace view + + export struct ImageMemoryBarrier { AccessFlag src; AccessFlag dst; @@ -329,7 +268,7 @@ export namespace stormkit::gpu { u32 src_queue_family_index = QUEUE_FAMILY_IGNORED; u32 dst_queue_family_index = QUEUE_FAMILY_IGNORED; - const Image& image; + view::Image image; ImageSubresourceRange range; }; @@ -344,272 +283,195 @@ export namespace stormkit::gpu { namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline Sampler::Sampler(PrivateTag, view::Device device) noexcept - : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroySampler } { + inline auto SamplerInterface::settings() const noexcept -> const Settings& { + return Base::m_settings; } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline Sampler::~Sampler() = default; + inline auto ImageInterface::extent() const noexcept -> const math::uextent3& { + return Base::m_extent; + } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline Sampler::Sampler(Sampler&&) noexcept = default; + inline auto ImageInterface::format() const noexcept -> PixelFormat { + return Base::m_format; + } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto Sampler::operator=(Sampler&&) noexcept -> Sampler& = default; + inline auto ImageInterface::type() const noexcept -> ImageType { + return Base::m_type; + } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline auto Sampler::settings() const noexcept -> const Settings& { - return m_settings; + inline auto ImageInterface::samples() const noexcept -> SampleCountFlag { + return Base::m_samples; } - namespace view { - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Sampler::Sampler(const gpu::Sampler& of) noexcept - : view::DeviceObject { of }, m_settings { of.settings() } { - } - - /////////////////////////////////// - /////////////////////////////////// - template T> - STORMKIT_FORCE_INLINE - inline Sampler::Sampler(const T& of) noexcept - : view::DeviceObject { of }, m_settings { of->settings() } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Sampler::~Sampler() noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Sampler::Sampler(const Sampler&) noexcept = default; + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto ImageInterface::layers() const noexcept -> u32 { + return Base::m_layers; + } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Sampler::operator=(const Sampler&) noexcept -> Sampler& = default; + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto ImageInterface::faces() const noexcept -> u32 { + return Base::m_faces; + } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline Sampler::Sampler(Sampler&&) noexcept = default; + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto ImageInterface::mip_levels() const noexcept -> u32 { + return Base::m_mip_levels; + } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Sampler::operator=(Sampler&&) noexcept -> Sampler& = default; + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto ImageInterface::usages() const noexcept -> ImageUsageFlag { + return Base::m_usages; + } - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Sampler::settings() const noexcept -> const gpu::Sampler::Settings& { - return m_settings; - } - } // namespace view + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto ImageInterface::allocation() const noexcept -> vk::Observer { + EXPECTS(Base::m_vma_allocation != VK_NULL_HANDLE); + return Base::m_vma_allocation; + } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline ImageView::ImageView(PrivateTag, view::Device device) noexcept - : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyImageView } { + inline auto ImageViewInterface::type() const noexcept -> ImageViewType { + return Base::m_type; } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline ImageView::~ImageView() = default; + inline auto ImageViewInterface::subresource_range() const noexcept -> const ImageSubresourceRange& { + return Base::m_subresource_range; + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline ImageView::ImageView(ImageView&&) noexcept = default; + inline SamplerImplementation::SamplerImplementation(PrivateTag, view::Device&& device) noexcept + : GpuObjectImplementation { std::move(device), &VolkDeviceTable::vkDestroySampler } { + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto ImageView::operator=(ImageView&&) noexcept -> ImageView& = default; + inline SamplerImplementation::~SamplerImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto ImageView::type() const noexcept -> ImageViewType { - return m_type; - } + inline SamplerImplementation::SamplerImplementation(SamplerImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto ImageView::subresource_range() const noexcept -> const ImageSubresourceRange& { - return m_subresource_range; - } + inline auto SamplerImplementation::operator=(SamplerImplementation&&) noexcept -> SamplerImplementation& = default; namespace view { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline ImageView::ImageView(const gpu::ImageView& of) noexcept - : view::DeviceObject { of }, m_type { of.type() }, m_subresource_range { of.subresource_range() } { - } - - /////////////////////////////////// - /////////////////////////////////// - template T> - STORMKIT_FORCE_INLINE - inline ImageView::ImageView(const T& of) noexcept - : view::DeviceObject { of }, m_type { of.type() }, m_subresource_range { of.subresource_range() } { + inline SamplerImplementation::SamplerImplementation(const gpu::Sampler& of) noexcept + : GpuObjectViewImplementation { of }, m_settings { of.settings() } { } ///////////////////////////////////// ///////////////////////////////////// + template TContainerOrPointer> STORMKIT_FORCE_INLINE - inline ImageView::~ImageView() noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline ImageView::ImageView(const ImageView&) noexcept = default; + inline SamplerImplementation::SamplerImplementation(const TContainerOrPointer& of) noexcept + : SamplerImplementation { *of } { + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto ImageView::operator=(const ImageView&) noexcept -> ImageView& = default; + inline SamplerImplementation::~SamplerImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline ImageView::ImageView(ImageView&&) noexcept = default; + inline SamplerImplementation::SamplerImplementation(const SamplerImplementation&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto ImageView::operator=(ImageView&&) noexcept -> ImageView& = default; + inline auto SamplerImplementation::operator=(const SamplerImplementation&) noexcept -> SamplerImplementation& = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto ImageView::type() const noexcept -> ImageViewType { - return m_type; - } + inline SamplerImplementation::SamplerImplementation(SamplerImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto ImageView::subresource_range() const noexcept -> const ImageSubresourceRange& { - return m_subresource_range; - } + inline auto SamplerImplementation::operator=(SamplerImplementation&&) noexcept -> SamplerImplementation& = default; } // namespace view ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Image::Image(PrivateTag, view::Device device) noexcept - : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyImage } { + inline ImageImplementation::ImageImplementation(PrivateTag, view::Device&& device) noexcept + : GpuObjectImplementation { std::move(device), &VolkDeviceTable::vkDestroyImage } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Image::~Image() { - if (not m_no_delete) [[unlikely]] - if (m_vk_handle != VK_NULL_HANDLE) { - const auto& device = this->device(); - vk::call(device.device_table().*m_deleter_ptr, device, m_vk_handle, nullptr); - } - - m_vk_handle = VK_NULL_HANDLE; + inline ImageImplementation::~ImageImplementation() noexcept { + if (m_no_delete) [[unlikely]] + m_vk_handle = VK_NULL_HANDLE; } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Image::Image(Image&&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::operator=(Image&&) noexcept -> Image& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::extent() const noexcept -> const math::uextent3& { - return m_extent; - } + inline ImageImplementation::ImageImplementation(ImageImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Image::format() const noexcept -> PixelFormat { - return m_format; - } + inline auto ImageImplementation::operator=(ImageImplementation&&) noexcept -> ImageImplementation& = default; ///////////////////////////////////// ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::type() const noexcept -> ImageType { - return m_type; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::samples() const noexcept -> SampleCountFlag { - return m_samples; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::layers() const noexcept -> u32 { - return m_layers; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::faces() const noexcept -> u32 { - return m_faces; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::mip_levels() const noexcept -> u32 { - return m_mip_levels; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::usages() const noexcept -> ImageUsageFlag { - return m_usages; - } - - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::allocation() const noexcept -> vk::Observer { - EXPECTS(m_vma_allocation != VK_NULL_HANDLE); - return m_vma_allocation; - } - - ///////////////////////////////////// - ///////////////////////////////////// - inline auto Image::from_existing(view::Device device, const CreateInfo& create_info, VkImage vk_image) noexcept -> Image { - auto image = Image { PrivateTag {}, std::move(device) }; + inline auto ImageImplementation::from_existing(view::Device device, const CreateInfo& create_info, VkImage vk_image) noexcept + -> Image { + auto image = Image { UseNamedConstructors::PRIVATE, std::move(device) }; image.m_extent = create_info.extent; image.m_format = create_info.format; image.m_layers = create_info.layers; @@ -631,8 +493,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Image::Image(const gpu::Image& of) noexcept - : view::DeviceObject { of }, + inline ImageImplementation::ImageImplementation(const gpu::Image& of) noexcept + : GpuObjectViewImplementation { of }, m_extent { of.extent() }, m_format { of.format() }, m_layers { of.layers() }, @@ -645,113 +507,103 @@ namespace stormkit::gpu { if (not of.m_no_delete) m_vma_allocation = of.allocation(); } - /////////////////////////////////// - /////////////////////////////////// - template T> - STORMKIT_FORCE_INLINE - inline Image::Image(const T& of) noexcept - : view::DeviceObject { of }, - m_extent { of->extent() }, - m_format { of->format() }, - m_layers { of->layers() }, - m_faces { of->faces() }, - m_mip_levels { of->mip_levels() }, - m_type { of->type() }, - m_flags { of->m_flags }, - m_samples { of->samples() }, - m_usages { of->usages() }, - m_vma_allocation { of->allocation() } { - if (not of->m_no_delete) m_vma_allocation = of->allocation(); - } - ///////////////////////////////////// ///////////////////////////////////// + template TContainerOrPointer> STORMKIT_FORCE_INLINE - inline Image::~Image() noexcept = default; + inline ImageImplementation::ImageImplementation(const TContainerOrPointer& of) noexcept + : ImageImplementation { *of } { + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Image::Image(const Image&) noexcept = default; + inline ImageImplementation::~ImageImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Image::operator=(const Image&) noexcept -> Image& = default; + inline ImageImplementation::ImageImplementation(const ImageImplementation&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Image::Image(Image&&) noexcept = default; + inline auto ImageImplementation::operator=(const ImageImplementation&) noexcept -> ImageImplementation& = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Image::operator=(Image&&) noexcept -> Image& = default; + inline ImageImplementation::ImageImplementation(ImageImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Image::extent() const noexcept -> const math::uextent3& { - return m_extent; - } + inline auto ImageImplementation::operator=(ImageImplementation&&) noexcept -> ImageImplementation& = default; + } // namespace view - ///////////////////////////////////// - ///////////////////////////////////// - STORMKIT_FORCE_INLINE - inline auto Image::format() const noexcept -> PixelFormat { - return m_format; - } + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline ImageViewImplementation::ImageViewImplementation(PrivateTag, view::Device&& device) noexcept + : GpuObjectImplementation { std::move(device), &VolkDeviceTable::vkDestroyImageView } { + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline ImageViewImplementation::~ImageViewImplementation() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline ImageViewImplementation::ImageViewImplementation(ImageViewImplementation&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto ImageViewImplementation::operator=(ImageViewImplementation&&) noexcept -> ImageViewImplementation& = default; + namespace view { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Image::type() const noexcept -> ImageType { - return m_type; + inline ImageViewImplementation::ImageViewImplementation(const gpu::ImageView& of) noexcept + : GpuObjectViewImplementation { of }, m_type { of.type() }, m_subresource_range { of.subresource_range() } { } ///////////////////////////////////// ///////////////////////////////////// + template TContainerOrPointer> STORMKIT_FORCE_INLINE - inline auto Image::samples() const noexcept -> SampleCountFlag { - return m_samples; + inline ImageViewImplementation::ImageViewImplementation(const TContainerOrPointer& of) noexcept + : ImageViewImplementation { *of } { } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Image::layers() const noexcept -> u32 { - return m_layers; - } + inline ImageViewImplementation::~ImageViewImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Image::faces() const noexcept -> u32 { - return m_faces; - } + inline ImageViewImplementation::ImageViewImplementation(const ImageViewImplementation&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Image::mip_levels() const noexcept -> u32 { - return m_mip_levels; - } + inline auto ImageViewImplementation::operator=(const ImageViewImplementation&) noexcept + -> ImageViewImplementation& = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Image::usages() const noexcept -> ImageUsageFlag { - return m_usages; - } + inline ImageViewImplementation::ImageViewImplementation(ImageViewImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Image::allocation() const noexcept -> vk::Observer { - EXPECTS(m_vma_allocation != VK_NULL_HANDLE); - return m_vma_allocation; - } + inline auto ImageViewImplementation::operator=(ImageViewImplementation&&) noexcept -> ImageViewImplementation& = default; } // namespace view ///////////////////////////////////// diff --git a/modules/stormkit/gpu/resource/objects.cppm b/modules/stormkit/gpu/resource/objects.cppm new file mode 100644 index 000000000..ea5c351a0 --- /dev/null +++ b/modules/stormkit/gpu/resource/objects.cppm @@ -0,0 +1,123 @@ +// Copyright (C) 2023 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +module; + +#include + +export module stormkit.gpu.resource:objects; + +import std; + +import stormkit.core; +import stormkit.gpu.core; + +namespace stormkit::gpu { + class ShaderImplementation; + class BufferImplementation; + class ImageImplementation; + class ImageViewImplementation; + class SamplerImplementation; + + namespace view { + class ShaderImplementation; + class BufferImplementation; + class ImageImplementation; + class ImageViewImplementation; + class SamplerImplementation; + } // namespace view + + export { + class ShaderTag; + template + class ShaderInterface; + + class BufferTag; + template + class BufferInterface; + + class ImageTag; + template + class ImageInterface; + + class ImageViewTag; + template + class ImageViewInterface; + + class SamplerTag; + template + class SamplerInterface; + + using Shader = ShaderInterface; + using Buffer = BufferInterface; + using Image = ImageInterface; + using ImageView = ImageViewInterface; + using Sampler = SamplerInterface; + + namespace view { + using Shader = ShaderInterface; + using Buffer = BufferInterface; + using Image = ImageInterface; + using ImageView = ImageViewInterface; + using Sampler = SamplerInterface; + } // namespace view + + namespace trait { + template<> + struct GpuObject { + using ValueType = VkShaderModule; + using DeleterType = PFN_vkDestroyShaderModule VolkDeviceTable::*; + using ObjectType = Shader; + using ViewType = view::Shader; + using OwnerType = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::SHADER_MODULE; + }; + + template<> + struct GpuObject { + using ValueType = VkBuffer; + using DeleterType = PFN_vkDestroyBuffer VolkDeviceTable::*; + using ObjectType = Buffer; + using ViewType = view::Buffer; + using OwnerType = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::BUFFER; + }; + + template<> + struct GpuObject { + using ValueType = VkImage; + using DeleterType = PFN_vkDestroyImage VolkDeviceTable::*; + using ObjectType = Image; + using ViewType = view::Image; + using OwnerType = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::IMAGE; + }; + + template<> + struct GpuObject { + using ValueType = VkImageView; + using DeleterType = PFN_vkDestroyImageView VolkDeviceTable::*; + using ObjectType = ImageView; + using ViewType = view::ImageView; + using OwnerType = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::IMAGE_VIEW; + }; + + template<> + struct GpuObject { + using ValueType = VkSampler; + using DeleterType = PFN_vkDestroySampler VolkDeviceTable::*; + using ObjectType = Sampler; + using ViewType = view::Sampler; + using OwnerType = Device; + + static constexpr auto DEBUG_TYPE = DebugObjectType::SAMPLER; + }; + } // namespace trait + } +} // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/resource/shader.cppm b/modules/stormkit/gpu/resource/shader.cppm index 3f5b4854a..ce126e8a8 100644 --- a/modules/stormkit/gpu/resource/shader.cppm +++ b/modules/stormkit/gpu/resource/shader.cppm @@ -18,32 +18,30 @@ import std; import stormkit.core; import stormkit.gpu.core; +import :objects; + namespace stdr = std::ranges; namespace stdv = std::views; namespace cmeta = stormkit::core::meta; -export namespace stormkit::gpu { - class Shader; - - namespace view { - class Shader; - } // namespace view - - namespace meta { - template<> - struct ObjectInfo { - using Of = Shader; - using ValueType = VkShaderModule; - using DeleterType = PFN_vkDestroyShaderModule VolkDeviceTable::*; - using ViewType = view::Shader; - using OwnedBy = Device; +namespace stormkit::gpu { + export template + class STORMKIT_GPU_API ShaderInterface: public DeviceObject { + public: + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = ShaderTag; - static constexpr auto DEBUG_TYPE = DebugObjectType::SHADER_MODULE; - }; - } // namespace meta + [[nodiscard]] + auto type() const noexcept -> ShaderStageFlag; + [[nodiscard]] + auto source() const noexcept -> std::span; + [[nodiscard]] + auto source_as_bytes() const noexcept -> std::span; + }; - class STORMKIT_GPU_API Shader: public OwnedByDevice { + class STORMKIT_GPU_API ShaderImplementation: public GpuObjectImplementation { public: enum class Error { INVALID_SPIRV, @@ -53,6 +51,16 @@ export namespace stormkit::gpu { template using LoadExpected = std::expected; + ShaderImplementation(PrivateTag, view::Device&&) noexcept; + auto do_init(PrivateTag, std::vector&&, ShaderStageFlag) -> Expected; + ~ShaderImplementation() noexcept; + + ShaderImplementation(const ShaderImplementation&) noexcept = delete; + auto operator=(const ShaderImplementation&) noexcept -> ShaderImplementation& = delete; + + ShaderImplementation(ShaderImplementation&&) noexcept; + auto operator=(ShaderImplementation&&) noexcept -> ShaderImplementation&; + static auto load_from_file(view::Device device, const std::filesystem::path& filepath, ShaderStageFlag type) noexcept -> LoadExpected; static auto load_from_bytes(view::Device device, std::span data, ShaderStageFlag type) noexcept @@ -68,57 +76,32 @@ export namespace stormkit::gpu { static auto allocate_and_load_from_spirv(view::Device device, std::span data, ShaderStageFlag type) noexcept -> Expected>; - ~Shader(); - - Shader(const Shader&) = delete; - auto operator=(const Shader&) -> Shader& = delete; - Shader(Shader&&) noexcept; - auto operator=(Shader&&) noexcept -> Shader&; - - [[nodiscard]] - auto type() const noexcept -> ShaderStageFlag; - [[nodiscard]] - auto source() const noexcept -> const std::vector&; - [[nodiscard]] - auto source_as_bytes() const noexcept -> std::span; - - // clang-format off - // private: - // clang-format on - Shader(PrivateTag, view::Device) noexcept; - auto do_init(PrivateTag, std::vector, ShaderStageFlag) -> Expected; - - private: - auto reflect() noexcept -> void; + protected: + using UseNamedConstructors::allocate; + using UseNamedConstructors::create; ShaderStageFlag m_type = ShaderStageFlag::NONE; std::vector m_source = {}; }; namespace view { - class STORMKIT_GPU_API Shader: public view::DeviceObject { + class ShaderImplementation: public GpuObjectViewImplementation { public: - using ObjectInfo = typename meta::ObjectInfo; - using ValueType = ObjectInfo::ValueType; - using ViewType = ObjectInfo::ViewType; + ShaderImplementation(const gpu::Shader&) noexcept; + template TContainerOrPointer> + ShaderImplementation(const TContainerOrPointer&) noexcept; + ~ShaderImplementation() noexcept; - Shader(const gpu::Shader& of) noexcept; - template T> - Shader(const T& of) noexcept; - ~Shader() noexcept; + ShaderImplementation(const ShaderImplementation&) noexcept; + auto operator=(const ShaderImplementation&) noexcept -> ShaderImplementation&; - Shader(const Shader&) noexcept; - auto operator=(const Shader&) noexcept -> Shader&; + ShaderImplementation(ShaderImplementation&&) noexcept; + auto operator=(ShaderImplementation&&) noexcept -> ShaderImplementation&; - Shader(Shader&&) noexcept; - auto operator=(Shader&&) noexcept -> Shader&; - - [[nodiscard]] - auto type() const noexcept -> ShaderStageFlag; - - private: - ShaderStageFlag m_type = ShaderStageFlag::NONE; + protected: + ShaderStageFlag m_type; + std::span m_source; }; } // namespace view } // namespace stormkit::gpu @@ -144,156 +127,155 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline Shader::Shader(PrivateTag, view::Device device) noexcept - : OwnedByDevice { std::move(device), &VolkDeviceTable::vkDestroyShaderModule } { + inline auto ShaderInterface::type() const noexcept -> ShaderStageFlag { + return Base::m_type; } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline Shader::~Shader() = default; + inline auto ShaderInterface::source() const noexcept -> std::span { + return Base::m_source; + } ///////////////////////////////////// ///////////////////////////////////// + template STORMKIT_FORCE_INLINE - inline Shader::Shader(Shader&&) noexcept = default; + inline auto ShaderInterface::source_as_bytes() const noexcept -> std::span { + return as_bytes(Base::m_source); + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::operator=(Shader&&) noexcept -> Shader& = default; + inline ShaderImplementation::ShaderImplementation(PrivateTag, view::Device&& device) noexcept + : GpuObjectImplementation { std::move(device), &VolkDeviceTable::vkDestroyShaderModule } { + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::load_from_file(view::Device device, const std::filesystem::path& filepath, ShaderStageFlag type) noexcept - -> LoadExpected { - expects(std::filesystem::is_regular_file(filepath), std::format("{} is not a file", filepath.string())); - - const auto data = TryTransformError(io::read(filepath), sys_to_load_error); - const auto spirv = std::vector { std::from_range, bytes_as_span(data) }; - Return TryTransformError(create(std::move(device), std::move(spirv), type), result_to_load_error); - } + inline ShaderImplementation::~ShaderImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::load_from_bytes(view::Device device, std::span data, ShaderStageFlag type) noexcept - -> Expected { - const auto spirv = std::vector { std::from_range, bytes_as_span(data) }; - return create(std::move(device), std::move(spirv), type); - } + inline ShaderImplementation::ShaderImplementation(ShaderImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::load_from_spirv(view::Device device, std::span data, ShaderStageFlag type) noexcept - -> Expected { - const auto spirv = std::vector { std::from_range, data }; - return create(std::move(device), std::move(spirv), type); - } + inline auto ShaderImplementation::operator=(ShaderImplementation&&) noexcept -> ShaderImplementation& = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::allocate_and_load_from_file(view::Device device, - const std::filesystem::path& filepath, - ShaderStageFlag type) noexcept -> LoadExpected> { + inline auto ShaderImplementation::load_from_file(view::Device device, + const std::filesystem::path& filepath, + ShaderStageFlag type) noexcept -> LoadExpected { expects(std::filesystem::is_regular_file(filepath), std::format("{} is not a file", filepath.string())); const auto data = TryTransformError(io::read(filepath), sys_to_load_error); - const auto spirv = std::vector { std::from_range, bytes_as_span(data) }; - Return TryTransformError(allocate(std::move(device), std::move(spirv), type), result_to_load_error); + auto spirv = std::vector { std::from_range, bytes_as_span(data) }; + Return TryTransformError(UseNamedConstructors::create(std::move(device), std::move(spirv), type), result_to_load_error); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::allocate_and_load_from_bytes(view::Device device, - std::span data, - ShaderStageFlag type) noexcept -> Expected> { - const auto spirv = std::vector { std::from_range, bytes_as_span(data) }; - return allocate(std::move(device), std::move(spirv), type); + inline auto ShaderImplementation::load_from_bytes(view::Device device, + std::span data, + ShaderStageFlag type) noexcept -> Expected { + auto spirv = std::vector { std::from_range, bytes_as_span(data) }; + return UseNamedConstructors::create(std::move(device), std::move(spirv), type); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::allocate_and_load_from_spirv(view::Device device, - std::span data, - ShaderStageFlag type) noexcept -> Expected> { - const auto spirv = std::vector { std::from_range, data }; - return allocate(std::move(device), std::move(spirv), type); + inline auto ShaderImplementation::load_from_spirv(view::Device device, + std::span data, + ShaderStageFlag type) noexcept -> Expected { + auto spirv = std::vector { std::from_range, data }; + return UseNamedConstructors::create(std::move(device), std::move(spirv), type); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::type() const noexcept -> ShaderStageFlag { - return m_type; + inline auto ShaderImplementation::allocate_and_load_from_file(view::Device device, + const std::filesystem::path& filepath, + ShaderStageFlag type) noexcept -> LoadExpected> { + expects(std::filesystem::is_regular_file(filepath), std::format("{} is not a file", filepath.string())); + + const auto data = TryTransformError(io::read(filepath), sys_to_load_error); + auto spirv = std::vector { std::from_range, bytes_as_span(data) }; + Return TryTransformError(UseNamedConstructors::allocate(std::move(device), std::move(spirv), type), result_to_load_error); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::source() const noexcept -> const std::vector& { - return m_source; + inline auto ShaderImplementation::allocate_and_load_from_bytes(view::Device device, + std::span data, + ShaderStageFlag type) noexcept -> Expected> { + auto spirv = std::vector { std::from_range, bytes_as_span(data) }; + return UseNamedConstructors::allocate(std::move(device), std::move(spirv), type); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::source_as_bytes() const noexcept -> std::span { - return as_bytes(m_source); + inline auto ShaderImplementation::allocate_and_load_from_spirv(view::Device device, + std::span data, + ShaderStageFlag type) noexcept -> Expected> { + auto spirv = std::vector { std::from_range, data }; + return UseNamedConstructors::allocate(std::move(device), std::move(spirv), type); } namespace view { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Shader::Shader(const gpu::Shader& of) noexcept - : view::DeviceObject { of }, m_type { of.type() } { - } - - /////////////////////////////////// - /////////////////////////////////// - template T> - STORMKIT_FORCE_INLINE - inline Shader::Shader(const T& of) noexcept - : view::DeviceObject { of }, m_type { of->type() } { + inline ShaderImplementation::ShaderImplementation(const gpu::Shader& of) noexcept + : GpuObjectViewImplementation { of }, m_type { of.type() }, m_source { of.source() } { } ///////////////////////////////////// ///////////////////////////////////// + template TContainerOrPointer> STORMKIT_FORCE_INLINE - inline Shader::~Shader() noexcept = default; + inline ShaderImplementation::ShaderImplementation(const TContainerOrPointer& of) noexcept + : ShaderImplementation { *of } { + } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Shader::Shader(const Shader& other) noexcept = default; + inline ShaderImplementation::~ShaderImplementation() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::operator=(const Shader& other) noexcept -> Shader& = default; + inline ShaderImplementation::ShaderImplementation(const ShaderImplementation&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline Shader::Shader(Shader&&) noexcept = default; + inline auto ShaderImplementation::operator=(const ShaderImplementation&) noexcept -> ShaderImplementation& = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::operator=(Shader&&) noexcept -> Shader& = default; + inline ShaderImplementation::ShaderImplementation(ShaderImplementation&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Shader::type() const noexcept -> ShaderStageFlag { - return m_type; - } + inline auto ShaderImplementation::operator=(ShaderImplementation&&) noexcept -> ShaderImplementation& = default; } // namespace view } // namespace stormkit::gpu diff --git a/src/gpu/core/debug_callback.cpp b/src/gpu/core/debug_callback.cpp index 02167c3c5..2f51209ef 100644 --- a/src/gpu/core/debug_callback.cpp +++ b/src/gpu/core/debug_callback.cpp @@ -6,6 +6,7 @@ module; #include +#include #include module stormkit.gpu.core; @@ -19,9 +20,12 @@ namespace stdr = std::ranges; namespace stdv = std::views; namespace stormkit::gpu { + template class DebugCallbackInterface; + template class DebugCallbackInterface; + ///////////////////////////////////// ///////////////////////////////////// - auto DebugCallback::do_init(PrivateTag, Closure closure, void* user_data) noexcept -> Expected { + auto DebugCallbackImplementation::do_init(PrivateTag, Closure closure, void* user_data) noexcept -> Expected { constexpr auto severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; @@ -41,7 +45,7 @@ namespace stormkit::gpu { }; m_vk_handle = Try(vk::call_checked(vkCreateDebugUtilsMessengerEXT, - instance(), + owner(), &create_info, nullptr)); Return {}; diff --git a/src/gpu/core/device.cpp b/src/gpu/core/device.cpp index d50101080..a31b3e4e7 100644 --- a/src/gpu/core/device.cpp +++ b/src/gpu/core/device.cpp @@ -10,6 +10,7 @@ module; #include +#include #include module stormkit.gpu.core; @@ -197,124 +198,73 @@ namespace { } // namespace namespace stormkit::gpu { - namespace { - struct DeviceAPI { - template - static auto wait_idle(const DeviceType& device) noexcept -> Expected { - const auto& table = device.device_table(); - const auto& handle = device.native_handle(); - Try(vk::call_checked(table.vkDeviceWaitIdle, handle)); - Return {}; - } - - template - static auto wait_for_fences(const DeviceType& device, - std::span fences, - bool wait_all = true, - const std::chrono::milliseconds& timeout = std::chrono::milliseconds::max()) noexcept - -> Expected { - const auto& device_table = device.device_table(); - const auto _fences = transform(fences, vk::monadic::to_vk()); - - const auto result = Try((vk::call_checked(device_table.vkWaitForFences, - device, - stdr::size(_fences), - stdr::data(_fences), - wait_all, - std::chrono::duration_cast< - std::chrono::nanoseconds>(timeout) - .count()))); - return vk::from_vk(result); - } - - template - static auto reset_fences(const DeviceType& device, std::span fences) noexcept -> Expected { - const auto& device_table = device.device_table(); - - const auto _fences = transform(fences, vk::monadic::to_vk()); - Try(vk::call_checked(device_table.vkResetFences, device, stdr::size(_fences), stdr::data(_fences))); - Return {}; - } - - template - static auto set_object_name(const DeviceType& device, - u64 object, - DebugObjectType type, - std::string_view name) noexcept -> Expected { - if (not vkSetDebugUtilsObjectNameEXT) return {}; - - const auto info = VkDebugUtilsObjectNameInfoEXT { - .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, - .pNext = nullptr, - .objectType = vk::to_vk(type), - .objectHandle = object, - .pObjectName = stdr::data(name), - }; - - Try(vk::call_checked(vkSetDebugUtilsObjectNameEXT, device, &info)); - Return {}; - } - }; - } // namespace - ///////////////////////////////////// ///////////////////////////////////// - auto Device::wait_idle() const noexcept -> Expected { - return DeviceAPI::wait_idle(*this); + template + auto DeviceInterface::wait_idle() const noexcept -> Expected { + const auto device_table = this->device_table(); + Try(vk::call_checked(device_table.vkDeviceWaitIdle, *this)); + Return {}; } ///////////////////////////////////// ///////////////////////////////////// - auto Device::wait_for_fences(std::span fences, - bool wait_all, - const std::chrono::milliseconds& timeout) const noexcept -> Expected { - return DeviceAPI::wait_for_fences(*this, std::move(fences), wait_all, timeout); + template + auto DeviceInterface::wait_for_fences(std::span fences, + bool wait_all, + const std::chrono::milliseconds& timeout) const noexcept -> Expected { + const auto device_table = this->device_table(); + const auto _fences = transform(fences, vk::monadic::to_vk()); + + const auto result = Try((vk::call_checked(device_table.vkWaitForFences, + *this, + stdr::size(_fences), + stdr::data(_fences), + wait_all, + std::chrono::duration_cast< + std::chrono::nanoseconds>(timeout) + .count()))); + return vk::from_vk(result); } ///////////////////////////////////// ///////////////////////////////////// - auto Device::reset_fences(std::span fences) const noexcept -> Expected { - return DeviceAPI::reset_fences(*this, std::move(fences)); + template + auto DeviceInterface::reset_fences(std::span fences) const noexcept -> Expected { + const auto device_table = this->device_table(); + + const auto _fences = transform(fences, vk::monadic::to_vk()); + Try(vk::call_checked(device_table.vkResetFences, *this, stdr::size(_fences), stdr::data(_fences))); + Return {}; } ///////////////////////////////////// ///////////////////////////////////// - auto Device::set_object_name(u64 object, DebugObjectType type, std::string_view name) const -> Expected { - return DeviceAPI::set_object_name(*this, object, type, std::move(name)); - } - - namespace view { - ///////////////////////////////////// - ///////////////////////////////////// - auto Device::wait_idle() const noexcept -> Expected { - return DeviceAPI::wait_idle(*this); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto Device::wait_for_fences(std::span fences, - bool wait_all, - const std::chrono::milliseconds& timeout) const noexcept -> Expected { - return DeviceAPI::wait_for_fences(*this, std::move(fences), wait_all, timeout); - } + template + auto DeviceInterface::set_object_name(u64 object, DebugObjectType type, std::string_view name) const noexcept + -> Expected { + if (not vkSetDebugUtilsObjectNameEXT) return {}; + + const auto info = VkDebugUtilsObjectNameInfoEXT { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, + .pNext = nullptr, + .objectType = vk::to_vk(type), + .objectHandle = object, + .pObjectName = stdr::data(name), + }; - ///////////////////////////////////// - ///////////////////////////////////// - auto Device::reset_fences(std::span fences) const noexcept -> Expected { - return DeviceAPI::reset_fences(*this, std::move(fences)); - } + Try(vk::call_checked(vkSetDebugUtilsObjectNameEXT, *this, &info)); + Return {}; + } - ///////////////////////////////////// - ///////////////////////////////////// - auto Device::set_object_name(u64 object, DebugObjectType type, std::string_view name) const -> Expected { - return DeviceAPI::set_object_name(*this, object, type, std::move(name)); - } - } // namespace view + template class DeviceInterface; + template class DeviceInterface; ///////////////////////////////////// ///////////////////////////////////// - auto Device::do_init(PrivateTag, const CreateInfo& info) noexcept -> Expected { - const auto& queue_families = m_physical_device.queue_families(); + auto DeviceImplementation::do_init(PrivateTag, const CreateInfo& info) noexcept -> Expected { + const auto physical_device = owner(); + const auto& queue_families = physical_device.queue_families(); auto i = 0_u32; auto priorities = std::vector> {}; @@ -339,7 +289,7 @@ namespace stormkit::gpu { }; }); - // const auto& capabilities = m_physical_device.capabilities(); + // const auto& capabilities = physical_device.capabilities(); const auto enabled_1_0_features = init_by([](auto& out) static noexcept { out.multiDrawIndirect = true; out.samplerAnisotropy = true; @@ -359,7 +309,7 @@ namespace stormkit::gpu { out.dynamicRendering = true; }); - const auto device_extensions = m_physical_device.extensions(); + const auto device_extensions = physical_device.extensions(); const auto swapchain_available = [&] { for (const auto& ext : SWAPCHAIN_EXTENSIONS) @@ -416,11 +366,10 @@ namespace stormkit::gpu { .pEnabledFeatures = &enabled_1_0_features, }; - m_vk_handle = Try(vk::call_checked(vkCreateDevice, m_physical_device.native_handle(), &create_info, nullptr)); + m_vk_handle = Try(vk::call_checked(vkCreateDevice, physical_device.native_handle(), &create_info, nullptr)); volkLoadDeviceTable(&m_vk_device_table, m_vk_handle); - const auto physical_device = this->physical_device(); - auto allocator_create_info = VmaAllocatorCreateInfo { + auto allocator_create_info = VmaAllocatorCreateInfo { .flags = 0, .physicalDevice = physical_device, .device = m_vk_handle, @@ -429,7 +378,7 @@ namespace stormkit::gpu { .pDeviceMemoryCallbacks = nullptr, .pHeapSizeLimit = nullptr, .pVulkanFunctions = nullptr, - .instance = instance(), + .instance = physical_device.instance(), .vulkanApiVersion = vk::make_version(1, 4, 0), .pTypeExternalMemoryHandleTypes = nullptr, }; @@ -441,7 +390,19 @@ namespace stormkit::gpu { m_vma_allocator = Try(vk::call_checked(vmaCreateAllocator, &allocator_create_info)); - Try(set_object_name(*this, std::format("StormKit:device ({})", physical_device.info().device_name))); + const auto name = std::format("StormKit:device ({})", physical_device.info().device_name); + if (not vkSetDebugUtilsObjectNameEXT) Return {}; + + const auto vk_object = native_handle(); + const auto debug_info = VkDebugUtilsObjectNameInfoEXT { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, + .pNext = nullptr, + .objectType = vk::to_vk(trait::GpuObject::DEBUG_TYPE), + .objectHandle = as(std::bit_cast(vk_object)), + .pObjectName = stdr::data(name), + }; + + Try(vk::call_checked(vkSetDebugUtilsObjectNameEXT, *this, &debug_info)); Return {}; } @@ -452,7 +413,7 @@ namespace stormkit::gpu { auto imgui_vk_loader(const char* _func_name, void* user_data) noexcept -> PFN_vkVoidFunction { const auto func_name = std::string_view { _func_name }; const auto& device = *std::bit_cast(user_data); - const auto& device_table = device.device_table(); + const auto device_table = device.device_table(); if (func_name == "vkAllocateCommandBuffers") return std::bit_cast(device_table.vkAllocateCommandBuffers); diff --git a/src/gpu/core/fence.cpp b/src/gpu/core/fence.cpp index 2e5ecec38..ddbcd0c10 100644 --- a/src/gpu/core/fence.cpp +++ b/src/gpu/core/fence.cpp @@ -20,103 +20,68 @@ import stormkit.core; import :vulkan; namespace stormkit::gpu { - namespace { - struct FenceAPI { - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto status(const FenceType& fence) noexcept -> Expected { - const auto& device = fence.device(); - - const auto - result = Try((vk::call_checked(device.device_table().vkGetFenceStatus, device, fence))); - if (result == VK_NOT_READY) Return Fence::Status::UNSIGNALED; - Return Fence::Status::SIGNALED; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto wait(const FenceType& fence, const std::chrono::milliseconds& wait_for) noexcept -> Expected { - const auto& device = fence.device(); - const auto handle = fence.native_handle(); - - const auto - result = Try((vk::call_checked(device.device_table().vkWaitForFences, - device, - 1u, - &handle, - true, - std::chrono::duration_cast(wait_for) - .count()))); - - Return vk::from_vk(result); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto reset(const FenceType& fence) noexcept -> Expected { - const auto& device = fence.device(); - const auto handle = fence.native_handle(); - - Try(vk::call_checked(device.device_table().vkResetFences, device, 1u, &handle)); - - Return {}; - } - }; - } // namespace - ///////////////////////////////////// ///////////////////////////////////// - auto Fence::status() const noexcept -> Expected { - return FenceAPI::status(*this); + template + auto FenceInterface::status() const noexcept -> Expected { + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + const auto result = Try((vk::call_checked(device_table.vkGetFenceStatus, device, *this))); + if (result == VK_NOT_READY) Return Fence::Status::UNSIGNALED; + Return Fence::Status::SIGNALED; } ///////////////////////////////////// ///////////////////////////////////// - auto Fence::wait(const std::chrono::milliseconds& wait_for) const noexcept -> Expected { - return FenceAPI::wait(*this, wait_for); + template + auto FenceInterface::wait(const std::chrono::milliseconds& wait_for) const noexcept -> Expected { + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + const auto handle = Base::native_handle(); + + const auto + result = Try((vk::call_checked(device_table.vkWaitForFences, + device, + 1u, + &handle, + true, + std::chrono::duration_cast(wait_for) + .count()))); + + Return vk::from_vk(result); } ///////////////////////////////////// ///////////////////////////////////// - auto Fence::reset() const noexcept -> Expected { - return FenceAPI::reset(*this); + template + auto FenceInterface::reset() const noexcept -> Expected { + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + const auto handle = Base::native_handle(); + + Try(vk::call_checked(device_table.vkResetFences, device, 1u, &handle)); + + Return {}; } + template class FenceInterface; + template class FenceInterface; + ///////////////////////////////////// ///////////////////////////////////// - auto Fence::do_init(PrivateTag, bool signaled) noexcept -> Expected { + auto FenceImplementation::do_init(PrivateTag, bool signaled) noexcept -> Expected { const auto flags = (signaled) ? VkFenceCreateFlags { VK_FENCE_CREATE_SIGNALED_BIT } : VkFenceCreateFlags {}; const auto create_info = VkFenceCreateInfo { .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, .pNext = nullptr, .flags = flags }; - m_vk_handle = Try(vk::call_checked(m_device.device_table().vkCreateFence, m_device, &create_info, nullptr)); + const auto& device = owner(); + const auto& device_table = device.device_table(); + + m_vk_handle = Try(vk::call_checked(device_table.vkCreateFence, device, &create_info, nullptr)); Return {}; } - - namespace view { - ///////////////////////////////////// - ///////////////////////////////////// - auto Fence::status() const noexcept -> Expected { - return FenceAPI::status(*this); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto Fence::wait(const std::chrono::milliseconds& wait_for) const noexcept -> Expected { - return FenceAPI::wait(*this, wait_for); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto Fence::reset() const noexcept -> Expected { - return FenceAPI::reset(*this); - } - } // namespace view } // namespace stormkit::gpu diff --git a/src/gpu/core/instance.cpp b/src/gpu/core/instance.cpp index 8e2d11d5a..433017b45 100644 --- a/src/gpu/core/instance.cpp +++ b/src/gpu/core/instance.cpp @@ -8,6 +8,7 @@ module; #include #include +#include #define STORMKIT_DEFINE_VK_PLATFORM #include @@ -83,26 +84,13 @@ namespace stormkit::gpu { } } // namespace - ///////////////////////////////////// - ///////////////////////////////////// - Instance::Instance(PrivateTag) noexcept : Owned { auto(vkDestroyInstance) } { - } - - ///////////////////////////////////// - ///////////////////////////////////// - Instance::~Instance() = default; - - ///////////////////////////////////// - ///////////////////////////////////// - Instance::Instance(Instance&&) noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - auto Instance::operator=(Instance&&) noexcept -> Instance& = default; + template class InstanceInterface; + template class InstanceInterface; ///////////////////////////////////// ///////////////////////////////////// - auto Instance::do_init(PrivateTag, std::string app_name, bool validation_layers_enabled) noexcept -> Expected { + auto InstanceImplementation::do_init(PrivateTag, std::string app_name, bool validation_layers_enabled) noexcept + -> Expected { const auto exts = Try(vk::enumerate_checked(vkEnumerateInstanceExtensionProperties, nullptr)); m_extensions = transform(exts, [](const auto& ext) static noexcept { return std::string { ext.extensionName }; }); const auto validation_layers = validation_layers_enabled @@ -158,17 +146,17 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto Instance::do_load_instance() noexcept -> Expected { + auto InstanceImplementation::do_load_instance() noexcept -> Expected { volkLoadInstanceOnly(m_vk_handle); Return {}; } ///////////////////////////////////// ///////////////////////////////////// - auto Instance::do_retrieve_physical_devices() noexcept -> Expected { + auto InstanceImplementation::do_retrieve_physical_devices() noexcept -> Expected { m_physical_devices = transform(Try(vk::enumerate_checked(vkEnumeratePhysicalDevices, m_vk_handle)), [this](auto physical_device) noexcept { - return PhysicalDevice::create(*this, std::move(physical_device)); + return PhysicalDevice::create(view::Instance { *this }, std::move(physical_device)); }); Return {}; } diff --git a/src/gpu/core/physical_device.cpp b/src/gpu/core/physical_device.cpp index 28ba528f4..615934144 100644 --- a/src/gpu/core/physical_device.cpp +++ b/src/gpu/core/physical_device.cpp @@ -6,6 +6,7 @@ module; #include +#include #include module stormkit.gpu.core; @@ -46,326 +47,274 @@ namespace stormkit::gpu { return "UNKNOWN"; } - struct PhysicalDeviceAPI { - template - static auto check_extension_support(const PhysicalDeviceType& physical_device, std::string_view extension) noexcept - -> bool { - return stdr::any_of(physical_device.extensions(), [extension](const auto& e) { return e == extension; }); - } - - template - static auto check_extension_support(const PhysicalDeviceType& physical_device, - std::span extensions) noexcept -> bool { - auto required_extensions = HashSet { stdr::begin(extensions), stdr::end(extensions) }; - - for (const auto& extension : physical_device.extensions()) required_extensions.erase(extension); + auto info(const PhysicalDeviceImplementation& physical_device) noexcept -> PhysicalDeviceInfo { + const auto& handle = physical_device.native_handle(); - return stdr::empty(required_extensions); - } - - template - static auto check_extension_support(const PhysicalDeviceType& physical_device, - std::span extensions) noexcept -> bool { - auto required_extensions = HashSet { stdr::begin(extensions), stdr::end(extensions) }; + auto device_info = PhysicalDeviceInfo {}; - for (const auto& extension : physical_device.extensions()) required_extensions.erase(extension); + const auto properties = vk::call(vkGetPhysicalDeviceProperties, handle); + const auto vendor_id = properties.vendorID; - return stdr::empty(required_extensions); - } + device_info.device_id = properties.deviceID; - template - static auto info(const _PhysicalDeviceType& physical_device) noexcept -> PhysicalDeviceInfo { - const auto& handle = physical_device.native_handle(); + const auto device_name_size = std::char_traits::length(properties.deviceName); - auto device_info = PhysicalDeviceInfo {}; + device_info.device_name.resize(device_name_size); + stdr::copy(std::string_view { properties.deviceName, device_name_size }, std::begin(device_info.device_name)); - const auto properties = vk::call(vkGetPhysicalDeviceProperties, handle); - const auto vendor_id = properties.vendorID; + device_info.vendor_id = vendor_id; + device_info.vendor_name = vendor_name_by_id(vendor_id); + device_info.api_major_version = vk::version_major(properties.apiVersion); + device_info.api_minor_version = vk::version_minor(properties.apiVersion); + device_info.api_patch_version = vk::version_patch(properties.apiVersion); - device_info.device_id = properties.deviceID; + device_info.driver_major_version = vk::version_major(properties.driverVersion); + device_info.driver_minor_version = vk::version_minor(properties.driverVersion); + device_info.driver_patch_version = vk::version_patch(properties.driverVersion); + stdr::copy(properties.pipelineCacheUUID, stdr::begin(device_info.pipeline_cache_uuid)); - const auto device_name_size = std::char_traits::length(properties.deviceName); + device_info.type = vk::from_vk(properties.deviceType); - device_info.device_name.resize(device_name_size); - stdr::copy(std::string_view { properties.deviceName, device_name_size }, std::begin(device_info.device_name)); - - device_info.vendor_id = vendor_id; - device_info.vendor_name = vendor_name_by_id(vendor_id); - device_info.api_major_version = vk::version_major(properties.apiVersion); - device_info.api_minor_version = vk::version_minor(properties.apiVersion); - device_info.api_patch_version = vk::version_patch(properties.apiVersion); - - device_info.driver_major_version = vk::version_major(properties.driverVersion); - device_info.driver_minor_version = vk::version_minor(properties.driverVersion); - device_info.driver_patch_version = vk::version_patch(properties.driverVersion); - stdr::copy(properties.pipelineCacheUUID, stdr::begin(device_info.pipeline_cache_uuid)); + return device_info; + } - device_info.type = vk::from_vk(properties.deviceType); + auto capabilities(const PhysicalDeviceImplementation& physical_device) noexcept -> RenderCapabilities { + const auto& handle = physical_device.native_handle(); + + const auto properties = vk::call(vkGetPhysicalDeviceProperties, handle); + // TODO port to vkGetPhysicalDeviceFeatures2 + const auto features = vk::call(vkGetPhysicalDeviceFeatures, handle); + + auto capabilities = RenderCapabilities {}; + capabilities.limits.max_image_dimension_1D = properties.limits.maxImageDimension1D; + capabilities.limits.max_image_dimension_2D = properties.limits.maxImageDimension2D; + capabilities.limits.max_image_dimension_3D = properties.limits.maxImageDimension3D; + capabilities.limits.max_image_dimension_cube = properties.limits.maxImageDimensionCube; + capabilities.limits.max_image_array_layers = properties.limits.maxImageArrayLayers; + capabilities.limits.max_texel_buffer_elements = properties.limits.maxTexelBufferElements; + capabilities.limits.max_uniform_buffer_range = properties.limits.maxUniformBufferRange; + capabilities.limits.max_storage_buffer_range = properties.limits.maxStorageBufferRange; + capabilities.limits.max_push_constants_size = properties.limits.maxPushConstantsSize; + capabilities.limits.max_memory_allocation_count = properties.limits.maxMemoryAllocationCount; + capabilities.limits.max_sampler_allocation_count = properties.limits.maxSamplerAllocationCount; + capabilities.limits.buffer_image_granularity = properties.limits.bufferImageGranularity; + capabilities.limits.sparse_address_space_size = properties.limits.sparseAddressSpaceSize; + capabilities.limits.max_bound_descriptor_sets = properties.limits.maxBoundDescriptorSets; + capabilities.limits.max_per_stage_descriptor_samplers = properties.limits.maxPerStageDescriptorSamplers; + capabilities.limits.max_per_stage_descriptor_uniform_buffers = properties.limits.maxPerStageDescriptorUniformBuffers; + capabilities.limits.max_per_stage_descriptor_storage_buffers = properties.limits.maxPerStageDescriptorStorageBuffers; + capabilities.limits.max_per_stage_descriptor_sampled_images = properties.limits.maxPerStageDescriptorSampledImages; + capabilities.limits.max_per_stage_descriptor_storage_images = properties.limits.maxPerStageDescriptorStorageImages; + capabilities.limits + .max_per_stage_descriptor_input_attachments = properties.limits.maxPerStageDescriptorInputAttachments; + capabilities.limits.max_per_stage_resources = properties.limits.maxPerStageResources; + capabilities.limits.max_descriptor_set_samplers = properties.limits.maxDescriptorSetSamplers; + capabilities.limits.max_descriptor_set_uniform_buffers = properties.limits.maxDescriptorSetUniformBuffers; + capabilities.limits + .max_descriptor_set_uniform_buffers_dynamic = properties.limits.maxDescriptorSetUniformBuffersDynamic; + capabilities.limits.max_descriptor_set_storage_buffers = properties.limits.maxDescriptorSetStorageBuffers; + capabilities.limits + .max_descriptor_set_storage_buffers_dynamic = properties.limits.maxDescriptorSetStorageBuffersDynamic; + capabilities.limits.max_descriptor_set_sampled_images = properties.limits.maxDescriptorSetSampledImages; + capabilities.limits.max_descriptor_set_storage_images = properties.limits.maxDescriptorSetStorageImages; + capabilities.limits.max_descriptor_set_input_attachments = properties.limits.maxDescriptorSetInputAttachments; + capabilities.limits.max_vertex_input_attributes = properties.limits.maxVertexInputAttributes; + capabilities.limits.max_vertex_input_bindings = properties.limits.maxVertexInputBindings; + capabilities.limits.max_vertex_input_attribute_offset = properties.limits.maxVertexInputAttributeOffset; + capabilities.limits.max_vertex_input_binding_stride = properties.limits.maxVertexInputBindingStride; + capabilities.limits.max_vertex_output_components = properties.limits.maxVertexOutputComponents; + capabilities.limits.max_tessellation_generation_level = properties.limits.maxTessellationGenerationLevel; + capabilities.limits.max_tessellation_patch_size = properties.limits.maxTessellationPatchSize; + capabilities.limits + .max_tessellation_control_per_vertex_input_components = properties.limits + .maxTessellationControlPerVertexInputComponents; + capabilities.limits + .max_tessellation_control_per_vertex_output_components = properties.limits + .maxTessellationControlPerVertexOutputComponents; + capabilities.limits + .max_tessellation_control_per_patch_output_components = properties.limits + .maxTessellationControlPerPatchOutputComponents; + capabilities.limits + .max_tessellation_control_total_output_components = properties.limits.maxTessellationControlTotalOutputComponents; + capabilities.limits + .max_tessellation_evaluation_input_components = properties.limits.maxTessellationEvaluationInputComponents; + capabilities.limits + .max_tessellation_evaluation_output_components = properties.limits.maxTessellationEvaluationOutputComponents; + capabilities.limits.max_geometry_shader_invocations = properties.limits.maxGeometryShaderInvocations; + capabilities.limits.max_geometry_input_components = properties.limits.maxGeometryInputComponents; + capabilities.limits.max_geometry_output_components = properties.limits.maxGeometryOutputComponents; + capabilities.limits.max_geometry_output_vertices = properties.limits.maxGeometryOutputVertices; + capabilities.limits.max_geometry_total_output_components = properties.limits.maxGeometryTotalOutputComponents; + capabilities.limits.max_fragment_input_components = properties.limits.maxFragmentInputComponents; + capabilities.limits.max_fragment_output_attachments = properties.limits.maxFragmentOutputAttachments; + capabilities.limits.max_fragment_dual_src_attachments = properties.limits.maxFragmentDualSrcAttachments; + capabilities.limits.max_fragment_combined_output_resources = properties.limits.maxFragmentCombinedOutputResources; + capabilities.limits.max_compute_shared_memory_size = properties.limits.maxComputeSharedMemorySize; + stdr::copy(properties.limits.maxComputeWorkGroupCount, stdr::begin(capabilities.limits.max_compute_work_group_count)); + capabilities.limits.max_compute_work_group_invocations = properties.limits.maxComputeWorkGroupInvocations; + stdr::copy(properties.limits.maxComputeWorkGroupSize, stdr::begin(capabilities.limits.max_compute_work_group_size)); + capabilities.limits.sub_pixel_precision_bits = properties.limits.subPixelPrecisionBits; + capabilities.limits.sub_texel_precision_bits = properties.limits.subTexelPrecisionBits; + capabilities.limits.mipmap_precision_bits = properties.limits.mipmapPrecisionBits; + capabilities.limits.max_draw_indexed_index_value = properties.limits.maxDrawIndexedIndexValue; + capabilities.limits.max_draw_indirect_count = properties.limits.maxDrawIndirectCount; + capabilities.limits.max_sampler_lod_bias = properties.limits.maxSamplerLodBias; + capabilities.limits.max_sampler_anisotropy = properties.limits.maxSamplerAnisotropy; + capabilities.limits.max_viewports = properties.limits.maxViewports; + stdr::copy(properties.limits.maxViewportDimensions, stdr::begin(capabilities.limits.max_viewport_dimensions)); + stdr::copy(properties.limits.viewportBoundsRange, stdr::begin(capabilities.limits.viewport_bounds_range)); + capabilities.limits.viewport_sub_pixel_bits = properties.limits.viewportSubPixelBits; + capabilities.limits.min_memory_map_alignment = properties.limits.minMemoryMapAlignment; + capabilities.limits.min_texel_buffer_offset_alignment = properties.limits.minTexelBufferOffsetAlignment; + capabilities.limits.min_uniform_buffer_offset_alignment = properties.limits.minUniformBufferOffsetAlignment; + capabilities.limits.min_storage_buffer_offset_alignment = properties.limits.minStorageBufferOffsetAlignment; + capabilities.limits.min_texel_offset = properties.limits.minTexelOffset; + capabilities.limits.max_texel_offset = properties.limits.maxTexelOffset; + capabilities.limits.min_texel_gather_offset = properties.limits.minTexelGatherOffset; + capabilities.limits.max_texel_gather_offset = properties.limits.maxTexelGatherOffset; + capabilities.limits.min_interpolation_offset = properties.limits.minInterpolationOffset; + capabilities.limits.max_interpolation_offset = properties.limits.maxInterpolationOffset; + capabilities.limits.sub_pixel_interpolation_offset_bits = properties.limits.subPixelInterpolationOffsetBits; + capabilities.limits.max_framebuffer_width = properties.limits.maxFramebufferWidth; + capabilities.limits.max_framebuffer_height = properties.limits.maxFramebufferHeight; + capabilities.limits.max_framebuffer_layers = properties.limits.maxFramebufferLayers; + capabilities.limits + .framebuffer_color_sample_counts = narrow(properties.limits.framebufferColorSampleCounts); + capabilities.limits + .framebuffer_depth_sample_counts = narrow(properties.limits.framebufferDepthSampleCounts); + capabilities.limits + .framebuffer_stencil_sample_counts = narrow(properties.limits.framebufferStencilSampleCounts); + capabilities.limits + .framebuffer_no_attachments_sample_counts = narrow(properties.limits + .framebufferNoAttachmentsSampleCounts); + capabilities.limits.max_color_attachments = properties.limits.maxColorAttachments; + capabilities.limits + .sampled_image_color_sample_counts = narrow(properties.limits.sampledImageColorSampleCounts); + capabilities.limits + .sampled_image_integer_sample_counts = narrow(properties.limits.sampledImageIntegerSampleCounts); + capabilities.limits + .sampled_image_depth_sample_counts = narrow(properties.limits.sampledImageDepthSampleCounts); + capabilities.limits + .sampled_image_stencil_sample_counts = narrow(properties.limits.sampledImageStencilSampleCounts); + capabilities.limits.storage_image_sample_counts = narrow(properties.limits.storageImageSampleCounts); + capabilities.limits.max_sample_mask_words = properties.limits.maxSampleMaskWords; + capabilities.limits.timestamp_compute_and_engine = properties.limits.timestampComputeAndGraphics; + capabilities.limits.timestamp_period = properties.limits.timestampPeriod; + capabilities.limits.max_clip_distances = properties.limits.maxClipDistances; + capabilities.limits.max_cull_distances = properties.limits.maxCullDistances; + capabilities.limits.max_combined_clip_and_cull_distances = properties.limits.maxCombinedClipAndCullDistances; + capabilities.limits.discrete_queue_priorities = properties.limits.discreteQueuePriorities; + stdr::copy(properties.limits.pointSizeRange, stdr::begin(capabilities.limits.point_size_range)); + stdr::copy(properties.limits.lineWidthRange, stdr::begin(capabilities.limits.line_width_range)); + capabilities.limits.point_size_granularity = properties.limits.pointSizeGranularity; + capabilities.limits.line_width_granularity = properties.limits.lineWidthGranularity; + capabilities.limits.strict_lines = properties.limits.strictLines; + capabilities.limits.standard_sample_locations = properties.limits.standardSampleLocations; + capabilities.limits.optimal_buffer_copy_offset_alignment = properties.limits.optimalBufferCopyOffsetAlignment; + capabilities.limits.optimal_buffer_copy_row_pitch_alignment = properties.limits.optimalBufferCopyRowPitchAlignment; + capabilities.limits.non_coherent_atom_size = properties.limits.nonCoherentAtomSize; + + capabilities.features.robust_buffer_access = features.robustBufferAccess; + capabilities.features.full_draw_index_uint32 = features.fullDrawIndexUint32; + capabilities.features.image_cube_array = features.imageCubeArray; + capabilities.features.independent_blend = features.independentBlend; + capabilities.features.geometry_shader = features.geometryShader; + capabilities.features.tessellation_shader = features.tessellationShader; + capabilities.features.sampler_rate_shading = features.sampleRateShading; + capabilities.features.dual_src_blend = features.dualSrcBlend; + capabilities.features.logic_op = features.logicOp; + capabilities.features.multi_draw_indirect = features.multiDrawIndirect; + capabilities.features.draw_indirect_first_instance = features.drawIndirectFirstInstance; + capabilities.features.depth_clamp = features.depthClamp; + capabilities.features.depth_bias_clamp = features.depthBiasClamp; + capabilities.features.fill_Mode_non_solid = features.fillModeNonSolid; + capabilities.features.depth_bounds = features.depthBounds; + capabilities.features.wide_lines = features.wideLines; + capabilities.features.large_points = features.largePoints; + capabilities.features.alpha_to_one = features.alphaToOne; + capabilities.features.multi_viewport = features.multiViewport; + capabilities.features.sampler_anisotropy = features.samplerAnisotropy; + capabilities.features.texture_compression_etc2 = features.textureCompressionETC2; + capabilities.features.texture_compression_astc_ldr = features.textureCompressionASTC_LDR; + capabilities.features.texture_compression_bc = features.textureCompressionBC; + capabilities.features.occlusion_query_precise = features.occlusionQueryPrecise; + capabilities.features.pipeline_statistics_query = features.pipelineStatisticsQuery; + capabilities.features.vertex_pipeline_stores_and_atomics = features.vertexPipelineStoresAndAtomics; + capabilities.features.fragment_stores_and_atomics = features.fragmentStoresAndAtomics; + capabilities.features.shader_tessellation_and_geometry_point_size = features.shaderTessellationAndGeometryPointSize; + capabilities.features.shader_image_gather_extended = features.shaderImageGatherExtended; + capabilities.features.shader_storage_image_extended_formats = features.shaderStorageImageExtendedFormats; + capabilities.features.shader_storage_image_multisample = features.shaderStorageImageMultisample; + capabilities.features.shader_storage_image_read_without_format = features.shaderStorageImageReadWithoutFormat; + capabilities.features.shader_storage_image_write_without_format = features.shaderStorageImageWriteWithoutFormat; + capabilities.features.shader_uniform_buffer_array_dynamic_indexing = features.shaderUniformBufferArrayDynamicIndexing; + capabilities.features.shader_sampled_image_array_dynamic_indexing = features.shaderSampledImageArrayDynamicIndexing; + capabilities.features.shader_storage_buffer_array_dynamic_indexing = features.shaderStorageBufferArrayDynamicIndexing; + capabilities.features.shader_storage_image_array_dynamic_indexing = features.shaderStorageImageArrayDynamicIndexing; + capabilities.features.shader_clip_distance = features.shaderClipDistance; + capabilities.features.shader_cull_distance = features.shaderCullDistance; + capabilities.features.shader_float_64 = features.shaderFloat64; + capabilities.features.shader_int_64 = features.shaderInt64; + capabilities.features.shader_int_16 = features.shaderInt16; + capabilities.features.shader_resource_residency = features.shaderResourceResidency; + capabilities.features.shader_resource_min_lod = features.shaderResourceMinLod; + capabilities.features.sparse_binding = features.sparseBinding; + capabilities.features.sparse_residency_buffer = features.sparseResidencyBuffer; + capabilities.features.sparse_residency_image_2D = features.sparseResidencyImage2D; + capabilities.features.sparse_residency_image_3D = features.sparseResidencyImage3D; + capabilities.features.sparse_residency_2_samples = features.sparseResidency2Samples; + capabilities.features.sparse_residency_4_samples = features.sparseResidency4Samples; + capabilities.features.sparse_residency_8_samples = features.sparseResidency8Samples; + capabilities.features.sparse_residency_16_samples = features.sparseResidency16Samples; + capabilities.features.sparse_residency_aliased = features.sparseResidencyAliased; + capabilities.features.variable_multisample_rate = features.variableMultisampleRate; + capabilities.features.inherited_queries = features.inheritedQueries; + + return capabilities; + } - return device_info; - } + auto memory_types(const PhysicalDeviceImplementation& physical_device) noexcept -> std::vector { + const auto& handle = physical_device.native_handle(); + const auto vk_memory_properties = vk::call(vkGetPhysicalDeviceMemoryProperties, + handle); - template - static auto capabilities(const PhysicalDeviceType& physical_device) noexcept -> RenderCapabilities { - const auto& handle = physical_device.native_handle(); - - const auto properties = vk::call(vkGetPhysicalDeviceProperties, handle); - // TODO port to vkGetPhysicalDeviceFeatures2 - const auto features = vk::call(vkGetPhysicalDeviceFeatures, handle); - - auto capabilities = RenderCapabilities {}; - capabilities.limits.max_image_dimension_1D = properties.limits.maxImageDimension1D; - capabilities.limits.max_image_dimension_2D = properties.limits.maxImageDimension2D; - capabilities.limits.max_image_dimension_3D = properties.limits.maxImageDimension3D; - capabilities.limits.max_image_dimension_cube = properties.limits.maxImageDimensionCube; - capabilities.limits.max_image_array_layers = properties.limits.maxImageArrayLayers; - capabilities.limits.max_texel_buffer_elements = properties.limits.maxTexelBufferElements; - capabilities.limits.max_uniform_buffer_range = properties.limits.maxUniformBufferRange; - capabilities.limits.max_storage_buffer_range = properties.limits.maxStorageBufferRange; - capabilities.limits.max_push_constants_size = properties.limits.maxPushConstantsSize; - capabilities.limits.max_memory_allocation_count = properties.limits.maxMemoryAllocationCount; - capabilities.limits.max_sampler_allocation_count = properties.limits.maxSamplerAllocationCount; - capabilities.limits.buffer_image_granularity = properties.limits.bufferImageGranularity; - capabilities.limits.sparse_address_space_size = properties.limits.sparseAddressSpaceSize; - capabilities.limits.max_bound_descriptor_sets = properties.limits.maxBoundDescriptorSets; - capabilities.limits.max_per_stage_descriptor_samplers = properties.limits.maxPerStageDescriptorSamplers; - capabilities.limits - .max_per_stage_descriptor_uniform_buffers = properties.limits.maxPerStageDescriptorUniformBuffers; - capabilities.limits - .max_per_stage_descriptor_storage_buffers = properties.limits.maxPerStageDescriptorStorageBuffers; - capabilities.limits - .max_per_stage_descriptor_sampled_images = properties.limits.maxPerStageDescriptorSampledImages; - capabilities.limits - .max_per_stage_descriptor_storage_images = properties.limits.maxPerStageDescriptorStorageImages; - capabilities.limits - .max_per_stage_descriptor_input_attachments = properties.limits.maxPerStageDescriptorInputAttachments; - capabilities.limits.max_per_stage_resources = properties.limits.maxPerStageResources; - capabilities.limits.max_descriptor_set_samplers = properties.limits.maxDescriptorSetSamplers; - capabilities.limits.max_descriptor_set_uniform_buffers = properties.limits.maxDescriptorSetUniformBuffers; - capabilities.limits - .max_descriptor_set_uniform_buffers_dynamic = properties.limits.maxDescriptorSetUniformBuffersDynamic; - capabilities.limits.max_descriptor_set_storage_buffers = properties.limits.maxDescriptorSetStorageBuffers; - capabilities.limits - .max_descriptor_set_storage_buffers_dynamic = properties.limits.maxDescriptorSetStorageBuffersDynamic; - capabilities.limits.max_descriptor_set_sampled_images = properties.limits.maxDescriptorSetSampledImages; - capabilities.limits.max_descriptor_set_storage_images = properties.limits.maxDescriptorSetStorageImages; - capabilities.limits.max_descriptor_set_input_attachments = properties.limits.maxDescriptorSetInputAttachments; - capabilities.limits.max_vertex_input_attributes = properties.limits.maxVertexInputAttributes; - capabilities.limits.max_vertex_input_bindings = properties.limits.maxVertexInputBindings; - capabilities.limits.max_vertex_input_attribute_offset = properties.limits.maxVertexInputAttributeOffset; - capabilities.limits.max_vertex_input_binding_stride = properties.limits.maxVertexInputBindingStride; - capabilities.limits.max_vertex_output_components = properties.limits.maxVertexOutputComponents; - capabilities.limits.max_tessellation_generation_level = properties.limits.maxTessellationGenerationLevel; - capabilities.limits.max_tessellation_patch_size = properties.limits.maxTessellationPatchSize; - capabilities.limits - .max_tessellation_control_per_vertex_input_components = properties.limits - .maxTessellationControlPerVertexInputComponents; - capabilities.limits - .max_tessellation_control_per_vertex_output_components = properties.limits - .maxTessellationControlPerVertexOutputComponents; - capabilities.limits - .max_tessellation_control_per_patch_output_components = properties.limits - .maxTessellationControlPerPatchOutputComponents; - capabilities.limits - .max_tessellation_control_total_output_components = properties.limits - .maxTessellationControlTotalOutputComponents; - capabilities.limits - .max_tessellation_evaluation_input_components = properties.limits.maxTessellationEvaluationInputComponents; - capabilities.limits - .max_tessellation_evaluation_output_components = properties.limits.maxTessellationEvaluationOutputComponents; - capabilities.limits.max_geometry_shader_invocations = properties.limits.maxGeometryShaderInvocations; - capabilities.limits.max_geometry_input_components = properties.limits.maxGeometryInputComponents; - capabilities.limits.max_geometry_output_components = properties.limits.maxGeometryOutputComponents; - capabilities.limits.max_geometry_output_vertices = properties.limits.maxGeometryOutputVertices; - capabilities.limits.max_geometry_total_output_components = properties.limits.maxGeometryTotalOutputComponents; - capabilities.limits.max_fragment_input_components = properties.limits.maxFragmentInputComponents; - capabilities.limits.max_fragment_output_attachments = properties.limits.maxFragmentOutputAttachments; - capabilities.limits.max_fragment_dual_src_attachments = properties.limits.maxFragmentDualSrcAttachments; - capabilities.limits.max_fragment_combined_output_resources = properties.limits.maxFragmentCombinedOutputResources; - capabilities.limits.max_compute_shared_memory_size = properties.limits.maxComputeSharedMemorySize; - stdr::copy(properties.limits.maxComputeWorkGroupCount, - stdr::begin(capabilities.limits.max_compute_work_group_count)); - capabilities.limits.max_compute_work_group_invocations = properties.limits.maxComputeWorkGroupInvocations; - stdr::copy(properties.limits.maxComputeWorkGroupSize, - stdr::begin(capabilities.limits.max_compute_work_group_size)); - capabilities.limits.sub_pixel_precision_bits = properties.limits.subPixelPrecisionBits; - capabilities.limits.sub_texel_precision_bits = properties.limits.subTexelPrecisionBits; - capabilities.limits.mipmap_precision_bits = properties.limits.mipmapPrecisionBits; - capabilities.limits.max_draw_indexed_index_value = properties.limits.maxDrawIndexedIndexValue; - capabilities.limits.max_draw_indirect_count = properties.limits.maxDrawIndirectCount; - capabilities.limits.max_sampler_lod_bias = properties.limits.maxSamplerLodBias; - capabilities.limits.max_sampler_anisotropy = properties.limits.maxSamplerAnisotropy; - capabilities.limits.max_viewports = properties.limits.maxViewports; - stdr::copy(properties.limits.maxViewportDimensions, stdr::begin(capabilities.limits.max_viewport_dimensions)); - stdr::copy(properties.limits.viewportBoundsRange, stdr::begin(capabilities.limits.viewport_bounds_range)); - capabilities.limits.viewport_sub_pixel_bits = properties.limits.viewportSubPixelBits; - capabilities.limits.min_memory_map_alignment = properties.limits.minMemoryMapAlignment; - capabilities.limits.min_texel_buffer_offset_alignment = properties.limits.minTexelBufferOffsetAlignment; - capabilities.limits.min_uniform_buffer_offset_alignment = properties.limits.minUniformBufferOffsetAlignment; - capabilities.limits.min_storage_buffer_offset_alignment = properties.limits.minStorageBufferOffsetAlignment; - capabilities.limits.min_texel_offset = properties.limits.minTexelOffset; - capabilities.limits.max_texel_offset = properties.limits.maxTexelOffset; - capabilities.limits.min_texel_gather_offset = properties.limits.minTexelGatherOffset; - capabilities.limits.max_texel_gather_offset = properties.limits.maxTexelGatherOffset; - capabilities.limits.min_interpolation_offset = properties.limits.minInterpolationOffset; - capabilities.limits.max_interpolation_offset = properties.limits.maxInterpolationOffset; - capabilities.limits.sub_pixel_interpolation_offset_bits = properties.limits.subPixelInterpolationOffsetBits; - capabilities.limits.max_framebuffer_width = properties.limits.maxFramebufferWidth; - capabilities.limits.max_framebuffer_height = properties.limits.maxFramebufferHeight; - capabilities.limits.max_framebuffer_layers = properties.limits.maxFramebufferLayers; - capabilities.limits - .framebuffer_color_sample_counts = narrow(properties.limits.framebufferColorSampleCounts); - capabilities.limits - .framebuffer_depth_sample_counts = narrow(properties.limits.framebufferDepthSampleCounts); - capabilities.limits - .framebuffer_stencil_sample_counts = narrow(properties.limits.framebufferStencilSampleCounts); - capabilities.limits - .framebuffer_no_attachments_sample_counts = narrow(properties.limits - .framebufferNoAttachmentsSampleCounts); - capabilities.limits.max_color_attachments = properties.limits.maxColorAttachments; - capabilities.limits - .sampled_image_color_sample_counts = narrow(properties.limits.sampledImageColorSampleCounts); - capabilities.limits - .sampled_image_integer_sample_counts = narrow(properties.limits - .sampledImageIntegerSampleCounts); - capabilities.limits - .sampled_image_depth_sample_counts = narrow(properties.limits.sampledImageDepthSampleCounts); - capabilities.limits - .sampled_image_stencil_sample_counts = narrow(properties.limits - .sampledImageStencilSampleCounts); - capabilities.limits - .storage_image_sample_counts = narrow(properties.limits.storageImageSampleCounts); - capabilities.limits.max_sample_mask_words = properties.limits.maxSampleMaskWords; - capabilities.limits.timestamp_compute_and_engine = properties.limits.timestampComputeAndGraphics; - capabilities.limits.timestamp_period = properties.limits.timestampPeriod; - capabilities.limits.max_clip_distances = properties.limits.maxClipDistances; - capabilities.limits.max_cull_distances = properties.limits.maxCullDistances; - capabilities.limits.max_combined_clip_and_cull_distances = properties.limits.maxCombinedClipAndCullDistances; - capabilities.limits.discrete_queue_priorities = properties.limits.discreteQueuePriorities; - stdr::copy(properties.limits.pointSizeRange, stdr::begin(capabilities.limits.point_size_range)); - stdr::copy(properties.limits.lineWidthRange, stdr::begin(capabilities.limits.line_width_range)); - capabilities.limits.point_size_granularity = properties.limits.pointSizeGranularity; - capabilities.limits.line_width_granularity = properties.limits.lineWidthGranularity; - capabilities.limits.strict_lines = properties.limits.strictLines; - capabilities.limits.standard_sample_locations = properties.limits.standardSampleLocations; - capabilities.limits.optimal_buffer_copy_offset_alignment = properties.limits.optimalBufferCopyOffsetAlignment; - capabilities.limits - .optimal_buffer_copy_row_pitch_alignment = properties.limits.optimalBufferCopyRowPitchAlignment; - capabilities.limits.non_coherent_atom_size = properties.limits.nonCoherentAtomSize; - - capabilities.features.robust_buffer_access = features.robustBufferAccess; - capabilities.features.full_draw_index_uint32 = features.fullDrawIndexUint32; - capabilities.features.image_cube_array = features.imageCubeArray; - capabilities.features.independent_blend = features.independentBlend; - capabilities.features.geometry_shader = features.geometryShader; - capabilities.features.tessellation_shader = features.tessellationShader; - capabilities.features.sampler_rate_shading = features.sampleRateShading; - capabilities.features.dual_src_blend = features.dualSrcBlend; - capabilities.features.logic_op = features.logicOp; - capabilities.features.multi_draw_indirect = features.multiDrawIndirect; - capabilities.features.draw_indirect_first_instance = features.drawIndirectFirstInstance; - capabilities.features.depth_clamp = features.depthClamp; - capabilities.features.depth_bias_clamp = features.depthBiasClamp; - capabilities.features.fill_Mode_non_solid = features.fillModeNonSolid; - capabilities.features.depth_bounds = features.depthBounds; - capabilities.features.wide_lines = features.wideLines; - capabilities.features.large_points = features.largePoints; - capabilities.features.alpha_to_one = features.alphaToOne; - capabilities.features.multi_viewport = features.multiViewport; - capabilities.features.sampler_anisotropy = features.samplerAnisotropy; - capabilities.features.texture_compression_etc2 = features.textureCompressionETC2; - capabilities.features.texture_compression_astc_ldr = features.textureCompressionASTC_LDR; - capabilities.features.texture_compression_bc = features.textureCompressionBC; - capabilities.features.occlusion_query_precise = features.occlusionQueryPrecise; - capabilities.features.pipeline_statistics_query = features.pipelineStatisticsQuery; - capabilities.features.vertex_pipeline_stores_and_atomics = features.vertexPipelineStoresAndAtomics; - capabilities.features.fragment_stores_and_atomics = features.fragmentStoresAndAtomics; - capabilities.features - .shader_tessellation_and_geometry_point_size = features.shaderTessellationAndGeometryPointSize; - capabilities.features.shader_image_gather_extended = features.shaderImageGatherExtended; - capabilities.features.shader_storage_image_extended_formats = features.shaderStorageImageExtendedFormats; - capabilities.features.shader_storage_image_multisample = features.shaderStorageImageMultisample; - capabilities.features.shader_storage_image_read_without_format = features.shaderStorageImageReadWithoutFormat; - capabilities.features.shader_storage_image_write_without_format = features.shaderStorageImageWriteWithoutFormat; - capabilities.features - .shader_uniform_buffer_array_dynamic_indexing = features.shaderUniformBufferArrayDynamicIndexing; - capabilities.features - .shader_sampled_image_array_dynamic_indexing = features.shaderSampledImageArrayDynamicIndexing; - capabilities.features - .shader_storage_buffer_array_dynamic_indexing = features.shaderStorageBufferArrayDynamicIndexing; - capabilities.features - .shader_storage_image_array_dynamic_indexing = features.shaderStorageImageArrayDynamicIndexing; - capabilities.features.shader_clip_distance = features.shaderClipDistance; - capabilities.features.shader_cull_distance = features.shaderCullDistance; - capabilities.features.shader_float_64 = features.shaderFloat64; - capabilities.features.shader_int_64 = features.shaderInt64; - capabilities.features.shader_int_16 = features.shaderInt16; - capabilities.features.shader_resource_residency = features.shaderResourceResidency; - capabilities.features.shader_resource_min_lod = features.shaderResourceMinLod; - capabilities.features.sparse_binding = features.sparseBinding; - capabilities.features.sparse_residency_buffer = features.sparseResidencyBuffer; - capabilities.features.sparse_residency_image_2D = features.sparseResidencyImage2D; - capabilities.features.sparse_residency_image_3D = features.sparseResidencyImage3D; - capabilities.features.sparse_residency_2_samples = features.sparseResidency2Samples; - capabilities.features.sparse_residency_4_samples = features.sparseResidency4Samples; - capabilities.features.sparse_residency_8_samples = features.sparseResidency8Samples; - capabilities.features.sparse_residency_16_samples = features.sparseResidency16Samples; - capabilities.features.sparse_residency_aliased = features.sparseResidencyAliased; - capabilities.features.variable_multisample_rate = features.variableMultisampleRate; - capabilities.features.inherited_queries = features.inheritedQueries; - - return capabilities; - } + return transform(std::span { vk_memory_properties.memoryTypes, 32 }, + [](const auto& type) static noexcept { return narrow(type.propertyFlags); }); + } - template - static auto memory_types(const PhysicalDeviceType& physical_device) noexcept -> std::vector { - const auto& handle = physical_device.native_handle(); - const auto vk_memory_properties = vk::call(vkGetPhysicalDeviceMemoryProperties, - handle); + auto queue_families(const PhysicalDeviceImplementation& physical_device) noexcept -> std::vector { + const auto& handle = physical_device.native_handle(); + return transform(vk::enumerate(vkGetPhysicalDeviceQueueFamilyProperties, handle), + [](const auto& family) static noexcept { + return QueueFamily { .flags = narrow(family.queueFlags), .count = family.queueCount }; + }); + } - return transform(std::span { vk_memory_properties.memoryTypes, 32 }, - [](const auto& type) static noexcept { return narrow(type.propertyFlags); }); - } + auto extensions(const PhysicalDeviceImplementation& physical_device, const PhysicalDeviceInfo& info) noexcept + -> std::vector { + const auto& handle = physical_device.native_handle(); + const auto extensions = TryAssert(vk::enumerate_checked(vkEnumerateDeviceExtensionProperties, + handle, + nullptr), + format("Failed to enumerate device {} extensions properties", info.device_name)); - template - static auto queue_families(const PhysicalDeviceType& physical_device) noexcept -> std::vector { - const auto& handle = physical_device.native_handle(); - return transform(vk::enumerate(vkGetPhysicalDeviceQueueFamilyProperties, handle), - [](const auto& family) static noexcept { - return QueueFamily { .flags = narrow(family.queueFlags), - .count = family.queueCount }; - }); - } + Return transform(extensions, [](const auto& extension) static noexcept { + const auto string_size = std::char_traits::length(extension.extensionName); - template - static auto extensions(const PhysicalDeviceType& physical_device) noexcept -> std::vector { - const auto& handle = physical_device.native_handle(); - const auto& info = physical_device.info(); - const auto - extensions = TryAssert(vk::enumerate_checked(vkEnumerateDeviceExtensionProperties, - handle, - nullptr), - format("Failed to enumerate device {} extensions properties", info.device_name)); - - Return transform(extensions, [](const auto& extension) static noexcept { - const auto string_size = std::char_traits::length(extension.extensionName); - - return std::string { extension.extensionName, string_size }; - }); - } + return std::string { extension.extensionName, string_size }; + }); + } - template - static auto formats_properties(const PhysicalDeviceType& physical_device) noexcept - -> std::vector> { - const auto& handle = physical_device.native_handle(); - return transform(cm::enumerate(), [&handle](const auto val) noexcept { - return std::make_pair(val, - vk::from_vk(vk::call(vkGetPhysicalDeviceFormatProperties, - handle, - vk::to_vk(val)))); - }); - } - }; + auto formats_properties(const PhysicalDeviceImplementation& physical_device) noexcept + -> std::vector> { + const auto& handle = physical_device.native_handle(); + return transform(cm::enumerate(), [&handle](const auto val) noexcept { + return std::make_pair(val, + vk::from_vk(vk::call(vkGetPhysicalDeviceFormatProperties, + handle, + vk::to_vk(val)))); + }); + } } // namespace ///////////////////////////////////// @@ -401,57 +350,22 @@ namespace stormkit::gpu { // TODO implement // https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VK_KHR_driver_properties.html - ///////////////////////////////////// - ///////////////////////////////////// - auto PhysicalDevice::check_extension_support(std::string_view extension) const noexcept -> bool { - return PhysicalDeviceAPI::check_extension_support(*this, std::move(extension)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto PhysicalDevice::check_extension_support(std::span extensions) const noexcept -> bool { - return PhysicalDeviceAPI::check_extension_support(*this, std::move(extensions)); - } + template class PhysicalDeviceInterface; + template class PhysicalDeviceInterface; ///////////////////////////////////// ///////////////////////////////////// - auto PhysicalDevice::check_extension_support(std::span extensions) const noexcept -> bool { - return PhysicalDeviceAPI::check_extension_support(*this, std::move(extensions)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto PhysicalDevice::do_init(PrivateTag, VkPhysicalDevice&& physical_device) noexcept -> void { + auto PhysicalDeviceImplementation::do_init(PrivateTag, VkPhysicalDevice&& physical_device) noexcept -> void { m_vk_handle = std::move(physical_device); m_data = core::allocate_unsafe(Data { - .device_info = PhysicalDeviceAPI::info(*this), - .capabilities = PhysicalDeviceAPI::capabilities(*this), + .device_info = gpu::info(*this), + .capabilities = gpu::capabilities(*this), }); - m_memory_types = PhysicalDeviceAPI::memory_types(*this); - m_extensions = PhysicalDeviceAPI::extensions(*this); - m_queue_families = PhysicalDeviceAPI::queue_families(*this); - m_format_properties = PhysicalDeviceAPI::formats_properties(*this); + m_memory_types = gpu::memory_types(*this); + m_extensions = gpu::extensions(*this, m_data->device_info); + m_queue_families = gpu::queue_families(*this); + m_format_properties = gpu::formats_properties(*this); } - - namespace view { - ///////////////////////////////////// - ///////////////////////////////////// - auto PhysicalDevice::check_extension_support(std::string_view extension) const noexcept -> bool { - return PhysicalDeviceAPI::check_extension_support(*this, std::move(extension)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto PhysicalDevice::check_extension_support(std::span extensions) const noexcept -> bool { - return PhysicalDeviceAPI::check_extension_support(*this, std::move(extensions)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto PhysicalDevice::check_extension_support(std::span extensions) const noexcept -> bool { - return PhysicalDeviceAPI::check_extension_support(*this, std::move(extensions)); - } - } // namespace view } // namespace stormkit::gpu diff --git a/src/gpu/core/semaphore.cpp b/src/gpu/core/semaphore.cpp index 64e412520..c1f6905ad 100644 --- a/src/gpu/core/semaphore.cpp +++ b/src/gpu/core/semaphore.cpp @@ -17,20 +17,24 @@ import std; import stormkit.core; +import :vulkan; + namespace stormkit::gpu { + template class SemaphoreInterface; + template class SemaphoreInterface; + ///////////////////////////////////// ///////////////////////////////////// - auto Semaphore::do_init(PrivateTag) noexcept -> Expected { + auto SemaphoreImplementation::do_init(PrivateTag) noexcept -> Expected { const auto create_info = VkSemaphoreCreateInfo { .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, .pNext = nullptr, .flags = 0, }; - m_vk_handle = Try(vk::call_checked(m_device.device_table().vkCreateSemaphore, - m_device, - &create_info, - nullptr)); + const auto& device = owner(); + const auto& device_table = device.device_table(); + m_vk_handle = Try(vk::call_checked(device_table.vkCreateSemaphore, device, &create_info, nullptr)); Return {}; } diff --git a/src/gpu/core/surface.cpp b/src/gpu/core/surface.cpp index 2fc4225c0..f6ff0ca12 100644 --- a/src/gpu/core/surface.cpp +++ b/src/gpu/core/surface.cpp @@ -15,6 +15,7 @@ module; #include #endif +#include #define STORMKIT_DEFINE_VK_PLATFORM #include @@ -26,18 +27,22 @@ import stormkit.core; import stormkit.wsi; namespace stormkit::gpu { + template class SurfaceInterface; + template class SurfaceInterface; + ///////////////////////////////////// ///////////////////////////////////// - auto Surface::do_init(PrivateTag) noexcept -> Expected { + auto SurfaceImplementation::do_init(PrivateTag) noexcept -> Expected { assert(false, "not implemented yet"); return {}; } ///////////////////////////////////// ///////////////////////////////////// - auto Surface::do_init(PrivateTag, const wsi::Window& window) noexcept -> Expected { + auto SurfaceImplementation::do_init(PrivateTag, const wsi::Window& window) noexcept -> Expected { EXPECTS(window.is_open()); - const auto instance = m_instance; + const auto instance = owner(); + #if defined(STORMKIT_OS_WINDOWS) const auto create_surface = [&window, &instance] { const auto create_info = VkWin32SurfaceCreateInfoKHR { diff --git a/src/gpu/execution/command_buffer.cpp b/src/gpu/execution/command_buffer.cpp index 5b4efb93e..dcf9326a8 100644 --- a/src/gpu/execution/command_buffer.cpp +++ b/src/gpu/execution/command_buffer.cpp @@ -72,1795 +72,1121 @@ namespace stormkit::gpu { }); } // namespace - struct CommandBufferAPI { - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto reset(CommandBufferType& cmb) noexcept -> Expected { - auto& state = cmb.m_state; - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - Try(vk::call_checked(device_table.vkResetCommandBuffer, cmb, 0)); - state = CommandBuffer::State::INITIAL; - - Return {}; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto begin(CommandBufferType& cmb, bool one_time_submit, InheritanceInfo inheritance_info_variant) noexcept - -> Expected { - auto& state = cmb.m_state; - EXPECTS(state == CommandBuffer::State::INITIAL); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - auto rendering_color_attachments = std::vector {}; - auto vk_rendering_inheritance_info = init_by([](auto& info) noexcept { - info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO; - info.pNext = nullptr; - }); - - const auto vk_inheritance_info = - [&inheritance_info_variant, &rendering_color_attachments, &vk_rendering_inheritance_info] noexcept { - auto info = init_by([](auto& info) noexcept { - info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; - info.pNext = nullptr; - }); - - if (is(inheritance_info_variant)) { - const auto& inheritance_info = as(inheritance_info_variant); - info.renderPass = vk::to_vk(*inheritance_info.render_pass); - info.subpass = inheritance_info.subpass; - info.framebuffer = vk::to_vk(*inheritance_info.framebuffer); - } else if (is(inheritance_info_variant)) { - info.pNext = &vk_rendering_inheritance_info; - - const auto& inheritance_info = as(inheritance_info_variant); - - rendering_color_attachments = inheritance_info.color_attachments - | stdv::transform(gpu::vk::monadic::to_vk()) - | stdr::to(); - vk_rendering_inheritance_info.viewMask = inheritance_info.view_mask; - vk_rendering_inheritance_info - .colorAttachmentCount = as(stdr::size(inheritance_info.color_attachments)); - vk_rendering_inheritance_info.pColorAttachmentFormats = stdr::data(rendering_color_attachments); - - if (inheritance_info.depth_attachment) - vk_rendering_inheritance_info - .depthAttachmentFormat = gpu::vk::to_vk(*inheritance_info.depth_attachment); - if (inheritance_info.stencil_attachment) - vk_rendering_inheritance_info - .stencilAttachmentFormat = gpu::vk::to_vk(*inheritance_info.stencil_attachment); - - vk_rendering_inheritance_info - .rasterizationSamples = gpu::vk::to_vk(inheritance_info.rasterization_samples); - } - return info; - }(); - - const auto flags = [&cmb, one_time_submit, &inheritance_info_variant] noexcept -> VkCommandBufferUsageFlags { - auto flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - - if (!one_time_submit) flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; - if (cmb.level() == CommandBufferLevel::SECONDARY) { - if (is(inheritance_info_variant) - or is(inheritance_info_variant)) - flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; - } - - return flags; - }(); - - const auto begin_info = VkCommandBufferBeginInfo { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, - .pNext = nullptr, - .flags = flags, - .pInheritanceInfo = &vk_inheritance_info, - }; - - Try(vk::call_checked(device_table.vkBeginCommandBuffer, cmb, &begin_info)); - state = CommandBuffer::State::RECORDING; - - Return {}; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto end(CommandBufferType& cmb) noexcept -> Expected { - auto& state = cmb.m_state; - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - Try(vk::call_checked(device_table.vkEndCommandBuffer, cmb)); - state = CommandBuffer::State::EXECUTABLE; - - Return {}; - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto begin_debug_region(const CommandBufferType& cmb, std::string_view&& name, const fcolor_rgb& color) noexcept - -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - if (not vkCmdBeginDebugUtilsLabelEXT) [[unlikely]] - return; - - const auto info = VkDebugUtilsLabelEXT { - .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, - .pNext = nullptr, - .pLabelName = stdr::data(name), - .color = { color.r, color.g, color.b, 1.f } - }; - - vk::call(vkCmdBeginDebugUtilsLabelEXT, cmb, &info); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto insert_debug_label(const CommandBufferType& cmb, std::string_view&& name, const fcolor_rgb& color) noexcept - -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - if (not vkCmdInsertDebugUtilsLabelEXT) [[unlikely]] - return; - - const auto info = VkDebugUtilsLabelEXT { - .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, - .pNext = nullptr, - .pLabelName = stdr::data(name), - .color = { color.r, color.g, color.b, 1.f } - }; - - vk::call(vkCmdInsertDebugUtilsLabelEXT, cmb, &info); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto end_debug_region(const CommandBufferType& cmb) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - if (not vkCmdEndDebugUtilsLabelEXT) [[unlikely]] - return; - - vk::call(vkCmdEndDebugUtilsLabelEXT, cmb); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto begin_rendering(const CommandBufferType& cmb, const RenderingInfo& info, bool secondary) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - auto to_vk_attachment = [](const auto& attachment) static noexcept { - auto attachment_info = VkRenderingAttachmentInfo { - .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, - .pNext = nullptr, - .imageView = vk::to_vk(attachment.image_view), - .imageLayout = vk::to_vk(attachment.layout), - .resolveMode = {}, - .resolveImageView = nullptr, - .resolveImageLayout = {}, - .loadOp = vk::to_vk(attachment.load_op), - .storeOp = vk::to_vk(attachment.store_op), - .clearValue = {}, - }; - - if (attachment.resolve) { - auto& resolve = *attachment.resolve; - - attachment_info.resolveMode = vk::to_vk(resolve.mode); - attachment_info.resolveImageView = vk::to_vk(resolve.image_view); - attachment_info.resolveImageLayout = vk::to_vk(resolve.layout); - } - if (attachment.clear_value) { - attachment_info.clearValue = std:: - visit(Overloaded { - [](const ClearColor& clear_color) static noexcept -> decltype(auto) { - return VkClearValue { - .color = VkClearColorValue { .float32 = { clear_color.color.r, - clear_color.color.b, - clear_color.color.g, - clear_color.color.a } }, - }; - }, - [](const ClearDepthStencil& clear_depth_stencil) static noexcept -> decltype(auto) { - return VkClearValue { - .depthStencil = VkClearDepthStencilValue { .depth = clear_depth_stencil.depth, - .stencil = clear_depth_stencil.stencil }, - }; - } }, - *attachment.clear_value); - } - - return attachment_info; - }; - - const auto color_attachments = transform(info.color_attachments, to_vk_attachment); - const auto depth_attachment = info.depth_attachment ? to_vk_attachment(*info.depth_attachment) - : VkRenderingAttachmentInfo {}; - const auto stencil_attachment = info.stencil_attachment ? to_vk_attachment(*info.stencil_attachment) - : VkRenderingAttachmentInfo {}; - - const auto rendering_info = VkRenderingInfo { - .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, - .pNext = nullptr, - .flags = as((secondary) ? VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT : 0), - .renderArea = vk::to_vk(info.render_area), - .layerCount = info.layer_count, - .viewMask = info.view_mask, - .colorAttachmentCount = as(stdr::size(color_attachments)), - .pColorAttachments = stdr::data(color_attachments), - .pDepthAttachment = info.depth_attachment ? &depth_attachment : nullptr, - .pStencilAttachment = info.stencil_attachment ? &stencil_attachment : nullptr, - }; - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdBeginRenderingKHR, cmb, &rendering_info); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto begin_render_pass(const CommandBufferType& cmb, - view::RenderPass&& render_pass, - view::FrameBuffer&& framebuffer, - std::span&& clear_values, - bool secondary_commandbuffers) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto - vk_clear_values = transform(clear_values, - cmonadic::either( - [](const ClearColor& clear_color) static noexcept -> decltype(auto) { - return VkClearValue { - .color = VkClearColorValue { .float32 = { clear_color.color.r, - clear_color.color.b, - clear_color.color.g, - clear_color.color.a } }, - }; - }, - [](const ClearDepthStencil& clear_depth_stencil) static noexcept -> decltype(auto) { - return VkClearValue { - .depthStencil = VkClearDepthStencilValue { .depth = clear_depth_stencil.depth, - .stencil = clear_depth_stencil - .stencil }, - }; - })); - - const auto begin_info = VkRenderPassBeginInfo { - .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, - .pNext = nullptr, - .renderPass = vk::to_vk(render_pass), - .framebuffer = vk::to_vk(framebuffer), - .renderArea = VkRect2D { .offset = { 0, 0 }, - .extent = { framebuffer.extent().width, framebuffer.extent().height } }, - .clearValueCount = as(stdr::size(vk_clear_values)), - .pClearValues = stdr::data(vk_clear_values), - }; - - const auto subpass_content = secondary_commandbuffers ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS - : VK_SUBPASS_CONTENTS_INLINE; - - vk::call(device_table.vkCmdBeginRenderPass, cmb, &begin_info, subpass_content); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto next_subpass(const CommandBufferType& cmb) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdNextSubpass, cmb, VK_SUBPASS_CONTENTS_INLINE); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto end_render_pass(const CommandBufferType& cmb) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdEndRenderPass, cmb); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto end_rendering(const CommandBufferType& cmb) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdEndRendering, cmb); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto bind_pipeline(const CommandBufferType& cmb, view::Pipeline&& pipeline) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto bind_point = (pipeline.type() == Pipeline::Type::RASTER) ? VK_PIPELINE_BIND_POINT_GRAPHICS - : VK_PIPELINE_BIND_POINT_COMPUTE; - - vk::call(device_table.vkCmdBindPipeline, cmb, bind_point, pipeline); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto set_viewport(const CommandBufferType& cmb, u32 first_viewport, std::span&& viewports) noexcept - -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto vk_viewports = transform(viewports, vk::monadic::to_vk()); + ///////////////////////////////////// + ///////////////////////////////////// + template + auto CommandBufferInterface::reset() noexcept -> Expected { + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); - vk::call(device_table.vkCmdSetViewport, cmb, first_viewport, stdr::size(vk_viewports), stdr::data(vk_viewports)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto set_scissor(const CommandBufferType& cmb, u32 first_scissor, std::span&& scissors) noexcept - -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto vk_scissors = transform(scissors, vk::monadic::to_vk()); - - vk::call(device_table.vkCmdSetScissor, cmb, first_scissor, stdr::size(vk_scissors), stdr::data(vk_scissors)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto set_line_width(const CommandBufferType& cmb, f32 width) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdSetLineWidth, cmb, width); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto set_depth_bias(const CommandBufferType& cmb, f32 constant_factor, f32 clamp, f32 slope_factor) noexcept - -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdSetDepthBias, cmb, constant_factor, clamp, slope_factor); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto set_blend_constants(const CommandBufferType& cmb, std::span&& constants) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - f32 data[] = { constants[0], constants[1], constants[2], constants[3] }; - - vk::call(device_table.vkCmdSetBlendConstants, cmb, data); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto set_depth_bounds(const CommandBufferType& cmb, f32 min, f32 max) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdSetDepthBounds, cmb, min, max); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto set_stencil_compare_mask(const CommandBufferType& cmb, StencilFaceFlag face, u32 mask) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdSetStencilCompareMask, cmb, vk::to_vk(face), mask); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto set_stencil_write_mask(const CommandBufferType& cmb, StencilFaceFlag face, u32 mask) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdSetStencilWriteMask, cmb, vk::to_vk(face), mask); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto set_stencil_reference(const CommandBufferType& cmb, StencilFaceFlag face, u32 reference) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdSetStencilReference, cmb, vk::to_vk(face), reference); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto dispatch(const CommandBufferType& cmb, u32 group_count_x, u32 group_count_y, u32 group_count_z) noexcept - -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdDispatch, cmb, group_count_x, group_count_y, group_count_z); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto draw(const CommandBufferType& cmb, - u32 vertex_count, - u32 instance_count, - u32 first_vertex, - u32 first_instance) noexcept -> void { - EXPECTS(vertex_count > 0); - - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdDraw, cmb, vertex_count, instance_count, first_vertex, first_instance); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto draw_indexed(const CommandBufferType& cmb, - u32 index_count, - u32 instance_count, - u32 first_index, - i32 vertex_offset, - u32 first_instance) noexcept -> void { - EXPECTS(index_count > 0); - - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdDrawIndexed, cmb, index_count, instance_count, first_index, vertex_offset, first_instance); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto draw_indirect(const CommandBufferType& cmb, - view::Buffer&& buffer, - usize offset, - u32 draw_count, - u32 stride) noexcept -> void { - EXPECTS(draw_count > 0); - - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdDrawIndirect, cmb, buffer, offset, draw_count, stride); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto draw_indexed_indirect(const CommandBufferType& cmb, - view::Buffer&& buffer, - usize offset, - u32 draw_count, - u32 stride) noexcept -> void { - EXPECTS(draw_count > 0); - - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdDrawIndexedIndirect, cmb, buffer, offset, draw_count, stride); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto bind_vertex_buffers(const CommandBufferType& cmb, - std::span&& buffers, - std::span&& offsets) noexcept -> void { - EXPECTS(not std::empty(buffers)); - EXPECTS(std::size(buffers) == std::size(offsets)); - - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto vk_buffers = transform(buffers, vk::monadic::to_vk()); - - vk::call(device_table.vkCmdBindVertexBuffers, - cmb, - 0, - stdr::size(vk_buffers), - stdr::data(vk_buffers), - stdr::data(offsets)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto bind_index_buffer(const CommandBufferType& cmb, - view::Buffer&& buffer, - u64 offset, - bool large_indices) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdBindIndexBuffer, - cmb, - buffer, - offset, - (large_indices) ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto bind_descriptor_sets(const CommandBufferType& cmb, - view::Pipeline&& pipeline, - view::PipelineLayout&& layout, - std::span&& descriptor_sets, - std::span&& dynamic_offsets) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto bind_point = (pipeline.type() == Pipeline::Type::RASTER) ? VK_PIPELINE_BIND_POINT_GRAPHICS - : VK_PIPELINE_BIND_POINT_COMPUTE; - - const auto vk_descriptor_sets = transform(descriptor_sets, vk::monadic::to_vk()); - - vk::call(device_table.vkCmdBindDescriptorSets, - cmb, - bind_point, - layout, - 0, - stdr::size(vk_descriptor_sets), - stdr::data(vk_descriptor_sets), - stdr::size(dynamic_offsets), - stdr::data(dynamic_offsets)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto copy_buffer(const CommandBufferType& cmb, - view::Buffer&& src, - view::Buffer&& dst, - usize size, - u64 src_offset, - u64 dst_offset) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto vk_copy_buffers = std::array { - VkBufferCopy { .srcOffset = src_offset, .dstOffset = dst_offset, .size = size } - }; + Try(vk::call_checked(device_table.vkResetCommandBuffer, *this, 0)); + *Base::m_state = CommandBuffer::State::INITIAL; - vk::call(device_table.vkCmdCopyBuffer, cmb, src, dst, stdr::size(vk_copy_buffers), stdr::data(vk_copy_buffers)); - } + Return {}; + } - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto copy_buffer_to_image(const CommandBufferType& cmb, - view::Buffer&& src, - view::Image&& dst, - std::span&& buffer_image_copies) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); + ///////////////////////////////////// + ///////////////////////////////////// + template + auto CommandBufferInterface::begin(bool one_time_submit, InheritanceInfo inheritance_info_variant) noexcept + -> Expected { + auto& state = *Base::m_state; + EXPECTS(state == CommandBuffer::State::INITIAL); - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); - const auto DEFAULT_COPY = std::array { - BufferImageCopy { 0, 0, 0, {}, { 0, 0, 0 }, dst.extent() } - }; - - if (stdr::empty(buffer_image_copies)) buffer_image_copies = DEFAULT_COPY; - - const auto vk_copy_regions = transform(buffer_image_copies, [](const auto& buffer_image_copy) static noexcept { - const auto image_subresource = VkImageSubresourceLayers { - .aspectMask = vk::to_vk(buffer_image_copy.subresource_layers.aspect_mask), - .mipLevel = buffer_image_copy.subresource_layers.mip_level, - .baseArrayLayer = buffer_image_copy.subresource_layers.base_array_layer, - .layerCount = buffer_image_copy.subresource_layers.layer_count, - }; - - return VkBufferImageCopy { .bufferOffset = buffer_image_copy.buffer_offset, - .bufferRowLength = buffer_image_copy.buffer_row_length, - .bufferImageHeight = buffer_image_copy.buffer_image_height, - .imageSubresource = image_subresource, - .imageOffset = vk::to_vk(buffer_image_copy.offset), - .imageExtent = vk::to_vk(buffer_image_copy.extent) }; - }); - - vk::call(device_table.vkCmdCopyBufferToImage, - cmb, - src, - dst, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - stdr::size(vk_copy_regions), - stdr::data(vk_copy_regions)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto copy_image_to_buffer(const CommandBufferType& cmb, - view::Image&& src, - view::Buffer&& dst, - std::span&& buffer_image_copies) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto DEFAULT_COPY = into_array({ - BufferImageCopy { 0, 0, 0, {}, { 0, 0, 0 }, src.extent() } - }); - - if (stdr::empty(buffer_image_copies)) buffer_image_copies = DEFAULT_COPY; - - const auto vk_copy_regions = transform(buffer_image_copies, [](const auto& buffer_image_copy) static noexcept { - const auto image_subresource = VkImageSubresourceLayers { - .aspectMask = vk::to_vk(buffer_image_copy.subresource_layers.aspect_mask), - .mipLevel = buffer_image_copy.subresource_layers.mip_level, - .baseArrayLayer = buffer_image_copy.subresource_layers.base_array_layer, - .layerCount = buffer_image_copy.subresource_layers.layer_count, - }; - - return VkBufferImageCopy { .bufferOffset = buffer_image_copy.buffer_offset, - .bufferRowLength = buffer_image_copy.buffer_row_length, - .bufferImageHeight = buffer_image_copy.buffer_image_height, - .imageSubresource = image_subresource, - .imageOffset = vk::to_vk(buffer_image_copy.offset), - .imageExtent = vk::to_vk(buffer_image_copy.extent) }; - }); - - vk::call(device_table.vkCmdCopyImageToBuffer, - cmb, - src, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - dst, - stdr::size(vk_copy_regions), - stdr::data(vk_copy_regions)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto copy_image(const CommandBufferType& cmb, - view::Image&& src, - view::Image&& dst, - ImageLayout src_layout, - ImageLayout dst_layout, - const ImageSubresourceLayers& src_subresource_layers, - const ImageSubresourceLayers& dst_subresource_layers, - const math::uextent3& extent) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); + auto rendering_color_attachments = std::vector {}; + auto vk_rendering_inheritance_info = init_by([](auto& info) noexcept { + info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO; + info.pNext = nullptr; + }); - const auto vk_src_subresource_layers = VkImageSubresourceLayers { - .aspectMask = vk::to_vk(src_subresource_layers.aspect_mask), - .mipLevel = src_subresource_layers.mip_level, - .baseArrayLayer = src_subresource_layers.base_array_layer, - .layerCount = src_subresource_layers.layer_count - }; + const auto vk_inheritance_info = + [&inheritance_info_variant, &rendering_color_attachments, &vk_rendering_inheritance_info] noexcept { + auto info = init_by([](auto& info) noexcept { + info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO; + info.pNext = nullptr; + }); + + if (is(inheritance_info_variant)) { + const auto& inheritance_info = as(inheritance_info_variant); + info.renderPass = vk::to_vk(*inheritance_info.render_pass); + info.subpass = inheritance_info.subpass; + info.framebuffer = vk::to_vk(*inheritance_info.framebuffer); + } else if (is(inheritance_info_variant)) { + info.pNext = &vk_rendering_inheritance_info; + + const auto& inheritance_info = as(inheritance_info_variant); + + rendering_color_attachments = inheritance_info.color_attachments + | stdv::transform(gpu::vk::monadic::to_vk()) + | stdr::to(); + vk_rendering_inheritance_info.viewMask = inheritance_info.view_mask; + vk_rendering_inheritance_info.colorAttachmentCount = as(stdr::size(inheritance_info.color_attachments)); + vk_rendering_inheritance_info.pColorAttachmentFormats = stdr::data(rendering_color_attachments); + + if (inheritance_info.depth_attachment) + vk_rendering_inheritance_info + .depthAttachmentFormat = gpu::vk::to_vk(*inheritance_info.depth_attachment); + if (inheritance_info.stencil_attachment) + vk_rendering_inheritance_info + .stencilAttachmentFormat = gpu::vk::to_vk(*inheritance_info.stencil_attachment); + + vk_rendering_inheritance_info + .rasterizationSamples = gpu::vk::to_vk(inheritance_info.rasterization_samples); + } + return info; + }(); + + const auto flags = [this, one_time_submit, &inheritance_info_variant] noexcept -> VkCommandBufferUsageFlags { + auto flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + + if (!one_time_submit) flags = VK_COMMAND_BUFFER_USAGE_SIMULTANEOUS_USE_BIT; + if (level() == CommandBufferLevel::SECONDARY) { + if (is(inheritance_info_variant) + or is(inheritance_info_variant)) + flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT; + } + + return flags; + }(); + + const auto begin_info = VkCommandBufferBeginInfo { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + .pNext = nullptr, + .flags = flags, + .pInheritanceInfo = &vk_inheritance_info, + }; + + Try(vk::call_checked(device_table.vkBeginCommandBuffer, *this, &begin_info)); + state = CommandBuffer::State::RECORDING; + + Return {}; + } - const auto vk_dst_subresource_layers = VkImageSubresourceLayers { - .aspectMask = vk::to_vk(dst_subresource_layers.aspect_mask), - .mipLevel = dst_subresource_layers.mip_level, - .baseArrayLayer = dst_subresource_layers.base_array_layer, - .layerCount = dst_subresource_layers.layer_count - }; + ///////////////////////////////////// + ///////////////////////////////////// + template + auto CommandBufferInterface::end() noexcept -> Expected { + auto& state = *Base::m_state; + EXPECTS(state == CommandBuffer::State::RECORDING); - const auto vk_regions = into_array({ - VkImageCopy { .srcSubresource = vk_src_subresource_layers, - .srcOffset = { 0, 0, 0 }, - .dstSubresource = vk_dst_subresource_layers, - .dstOffset = { 0, 0, 0 }, - .extent = vk::to_vk(extent) } - }); - - vk::call(device_table.vkCmdCopyImage, - cmb, - src, - vk::to_vk(src_layout), - dst, - vk::to_vk(dst_layout), - stdr::size(vk_regions), - stdr::data(vk_regions)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto resolve_image(const CommandBufferType& cmb, - view::Image&& src, - view::Image&& dst, - ImageLayout src_layout, - ImageLayout dst_layout, - const ImageSubresourceLayers& src_subresource_layers, - const ImageSubresourceLayers& dst_subresource_layers) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto vk_extent = vk::to_vk(dst.extent()); + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); - const auto vk_src_subresource_layers = VkImageSubresourceLayers { - .aspectMask = vk::to_vk(src_subresource_layers.aspect_mask), - .mipLevel = src_subresource_layers.mip_level, - .baseArrayLayer = src_subresource_layers.base_array_layer, - .layerCount = src_subresource_layers.layer_count - }; + Try(vk::call_checked(device_table.vkEndCommandBuffer, *this)); + state = CommandBuffer::State::EXECUTABLE; - const auto vk_dst_subresource_layers = VkImageSubresourceLayers { - .aspectMask = vk::to_vk(dst_subresource_layers.aspect_mask), - .mipLevel = dst_subresource_layers.mip_level, - .baseArrayLayer = dst_subresource_layers.base_array_layer, - .layerCount = dst_subresource_layers.layer_count - }; + Return {}; + } - const auto vk_regions = into_array({ - VkImageResolve { .srcSubresource = vk_src_subresource_layers, - .srcOffset = { 0, 0, 0 }, - .dstSubresource = vk_dst_subresource_layers, - .dstOffset = { 0, 0, 0 }, - .extent = vk_extent } - }); - - vk::call(device_table.vkCmdResolveImage, - cmb, - src, - vk::to_vk(src_layout), - dst, - vk::to_vk(dst_layout), - stdr::size(vk_regions), - stdr::data(vk_regions)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto blit_image(const CommandBufferType& cmb, - view::Image&& src, - view::Image&& dst, - ImageLayout src_layout, - ImageLayout dst_layout, - std::span&& regions, - Filter filter) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto vk_regions = transform(regions, [](const auto& region) static noexcept { - const auto vk_src_subresource_layers = VkImageSubresourceLayers { - .aspectMask = vk::to_vk(region.src.aspect_mask), - .mipLevel = region.src.mip_level, - .baseArrayLayer = region.src.base_array_layer, - .layerCount = region.src.layer_count - }; - - const auto vk_dst_subresource_layers = VkImageSubresourceLayers { - .aspectMask = vk::to_vk(region.dst.aspect_mask), - .mipLevel = region.dst.mip_level, - .baseArrayLayer = region.dst.base_array_layer, - .layerCount = region.dst.layer_count - }; - - return VkImageBlit { - .srcSubresource = vk_src_subresource_layers, - .srcOffsets = { vk::to_vk(region.src_offset.position), - vk::to_vk(region.src_offset.extent) }, - .dstSubresource = vk_dst_subresource_layers, - .dstOffsets = { vk::to_vk(region.dst_offset.position), - vk::to_vk(region.dst_offset.extent) }, - }; - }); - - vk::call(device_table.vkCmdBlitImage, - cmb, - vk::to_vk(src), - vk::to_vk(src_layout), - vk::to_vk(dst), - vk::to_vk(dst_layout), - stdr::size(vk_regions), - stdr::data(vk_regions), - vk::to_vk(filter)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto transition_image_layout(const CommandBufferType& cmb, - view::Image&& image, - ImageLayout src_layout, - ImageLayout dst_layout, - const ImageSubresourceRange& subresource_range) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto vk_src_layout = vk::to_vk(src_layout); - const auto vk_dst_layout = vk::to_vk(dst_layout); - - const auto& src_access = OLD_LAYOUT_ACCESS_MAP.find(vk_src_layout); - const auto& dst_access = NEW_LAYOUT_ACCESS_MAP.find(vk_dst_layout); - - const auto src_stage = src_access->second.second; - const auto dst_stage = dst_access->second.second; - - const auto vk_subresource_range = VkImageSubresourceRange { - .aspectMask = vk::to_vk(subresource_range.aspect_mask), - .baseMipLevel = subresource_range.base_mip_level, - .levelCount = subresource_range.level_count, - .baseArrayLayer = subresource_range.base_array_layer, - .layerCount = subresource_range.layer_count, - }; + ///////////////////////////////////// + ///////////////////////////////////// + template + auto CommandBufferInterface::begin_debug_region(std::string_view name, const fcolor_rgb& color) const noexcept + -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); - const auto barriers = into_array({ - VkImageMemoryBarrier { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = src_access->second.first, - .dstAccessMask = dst_access->second.first, - .oldLayout = vk_src_layout, - .newLayout = vk_dst_layout, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .image = vk::to_vk(image), - .subresourceRange = vk_subresource_range - - }, - }); - - vk::call(device_table.vkCmdPipelineBarrier, - cmb, - src_stage, - dst_stage, - 0, - 0, - nullptr, - 0, - nullptr, - stdr::size(barriers), - stdr::data(barriers)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto pipeline_barrier(const CommandBufferType& cmb, - PipelineStageFlag src_mask, - PipelineStageFlag dst_mask, - DependencyFlag dependency, - std::span&& memory_barriers, - std::span&& buffer_memory_barriers, - std::span&& image_memory_barriers) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - const auto vk_memory_barriers = transform(memory_barriers, [](const auto& barrier) static noexcept -> decltype(auto) { - return VkMemoryBarrier { - .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = vk::to_vk(barrier.src), - .dstAccessMask = vk::to_vk(barrier.dst), - }; - }); - const auto vk_buffer_memory_barriers = transform(buffer_memory_barriers, - [](const auto& barrier) static noexcept -> decltype(auto) { - return VkBufferMemoryBarrier { - .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = vk::to_vk(barrier.src), - .dstAccessMask = vk::to_vk(barrier.dst), - .srcQueueFamilyIndex = barrier.src_queue_family_index, - .dstQueueFamilyIndex = barrier.dst_queue_family_index, - .buffer = vk::to_vk(barrier.buffer), - .offset = barrier.offset, - .size = barrier.size - }; - }); - const auto vk_image_memory_barriers = transform(image_memory_barriers, - [](const auto& barrier) static noexcept -> decltype(auto) { - const auto vk_subresource_range = VkImageSubresourceRange { - .aspectMask = vk::to_vk(barrier.range - .aspect_mask), - .baseMipLevel = barrier.range.base_mip_level, - .levelCount = barrier.range.level_count, - .baseArrayLayer = barrier.range.base_array_layer, - .layerCount = barrier.range.layer_count - }; - - return VkImageMemoryBarrier { - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = vk::to_vk(barrier.src), - .dstAccessMask = vk::to_vk(barrier.dst), - .oldLayout = vk::to_vk(barrier.old_layout), - .newLayout = vk::to_vk(barrier.new_layout), - .srcQueueFamilyIndex = barrier.src_queue_family_index, - .dstQueueFamilyIndex = barrier.dst_queue_family_index, - .image = vk::to_vk(barrier.image), - .subresourceRange = vk_subresource_range - }; - }); - - vk::call(device_table.vkCmdPipelineBarrier, - cmb, - vk::to_vk(src_mask), - vk::to_vk(dst_mask), - vk::to_vk(dependency), - stdr::size(vk_memory_barriers), - stdr::data(vk_memory_barriers), - stdr::size(vk_buffer_memory_barriers), - stdr::data(vk_buffer_memory_barriers), - stdr::size(vk_image_memory_barriers), - stdr::data(vk_image_memory_barriers)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto push_constants(const CommandBufferType& cmb, - view::PipelineLayout&& pipeline_layout, - ShaderStageFlag stage, - std::span&& data, - u32 offset) noexcept -> void { - EXPECTS(not std::empty(data)); - - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - vk::call(device_table.vkCmdPushConstants, - cmb, - vk::to_vk(pipeline_layout), - vk::to_vk(stage), - offset, - stdr::size(data), - stdr::data(data)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto execute_sub_command_buffers(const CommandBufferType& cmb, - std::span&& commandbuffers) noexcept -> void { - const auto state = cmb.state(); - EXPECTS(state == CommandBuffer::State::RECORDING); - - const auto& device = cmb.device(); - const auto& device_table = device.device_table(); - - constexpr auto expects_secondary = [](auto&& cmb) noexcept -> decltype(auto) { - EXPECTS(cmb.level() == CommandBufferLevel::SECONDARY); - return cmb; - }; + if (not vkCmdBeginDebugUtilsLabelEXT) [[unlikely]] + return *this; - const auto vk_command_buffers = transform(commandbuffers, cmonadic::map(expects_secondary, vk::monadic::to_vk())); - vk::call(device_table.vkCmdExecuteCommands, cmb, stdr::size(vk_command_buffers), stdr::data(vk_command_buffers)); - } - }; + const auto info = VkDebugUtilsLabelEXT { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, + .pNext = nullptr, + .pLabelName = stdr::data(name), + .color = { color.r, color.g, color.b, 1.f } + }; - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::reset() noexcept -> Expected { - return CommandBufferAPI::reset(*this); + vk::call(vkCmdBeginDebugUtilsLabelEXT, *this, &info); + return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::begin(bool one_time_submit, InheritanceInfo inheritance_info_variant) noexcept -> Expected { - return CommandBufferAPI::begin(*this, one_time_submit, std::move(inheritance_info_variant)); - } + template + auto CommandBufferInterface::insert_debug_label(std::string_view name, const fcolor_rgb& color) const noexcept + -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::end() noexcept -> Expected { - return CommandBufferAPI::end(*this); - } + if (not vkCmdInsertDebugUtilsLabelEXT) [[unlikely]] + return *this; - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::begin_debug_region(std::string_view name, const fcolor_rgb& color) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::begin_debug_region(*this, std::move(name), color); + const auto info = VkDebugUtilsLabelEXT { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, + .pNext = nullptr, + .pLabelName = stdr::data(name), + .color = { color.r, color.g, color.b, 1.f } + }; + + vk::call(vkCmdInsertDebugUtilsLabelEXT, *this, &info); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::insert_debug_label(std::string_view name, const fcolor_rgb& color) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::insert_debug_label(*this, std::move(name), color); + template + auto CommandBufferInterface::end_debug_region() const noexcept -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + if (not vkCmdEndDebugUtilsLabelEXT) [[unlikely]] + return *this; + + vk::call(vkCmdEndDebugUtilsLabelEXT, *this); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::end_debug_region() const noexcept -> const CommandBuffer& { - CommandBufferAPI::end_debug_region(*this); + template + auto CommandBufferInterface::begin_rendering(const RenderingInfo& info, bool secondary) const noexcept + -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + auto to_vk_attachment = [](const auto& attachment) static noexcept { + auto attachment_info = VkRenderingAttachmentInfo { + .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, + .pNext = nullptr, + .imageView = vk::to_vk(attachment.image_view), + .imageLayout = vk::to_vk(attachment.layout), + .resolveMode = {}, + .resolveImageView = nullptr, + .resolveImageLayout = {}, + .loadOp = vk::to_vk(attachment.load_op), + .storeOp = vk::to_vk(attachment.store_op), + .clearValue = {}, + }; + + if (attachment.resolve) { + auto& resolve = *attachment.resolve; + + attachment_info.resolveMode = vk::to_vk(resolve.mode); + attachment_info.resolveImageView = vk::to_vk(resolve.image_view); + attachment_info.resolveImageLayout = vk::to_vk(resolve.layout); + } + if (attachment.clear_value) { + attachment_info + .clearValue = std::visit(Overloaded { + [](const ClearColor& clear_color) static noexcept -> decltype(auto) { + return VkClearValue { + .color = VkClearColorValue { .float32 = { clear_color.color.r, + clear_color.color.b, + clear_color.color.g, + clear_color.color.a } }, + }; + }, + [](const ClearDepthStencil& clear_depth_stencil) static noexcept -> decltype(auto) { + return VkClearValue { + .depthStencil = VkClearDepthStencilValue { .depth = clear_depth_stencil + .depth, + .stencil = clear_depth_stencil + .stencil }, + }; + } }, + *attachment.clear_value); + } + + return attachment_info; + }; + + const auto color_attachments = transform(info.color_attachments, to_vk_attachment); + const auto depth_attachment = info.depth_attachment ? to_vk_attachment(*info.depth_attachment) + : VkRenderingAttachmentInfo {}; + const auto stencil_attachment = info.stencil_attachment ? to_vk_attachment(*info.stencil_attachment) + : VkRenderingAttachmentInfo {}; + + const auto rendering_info = VkRenderingInfo { + .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, + .pNext = nullptr, + .flags = as((secondary) ? VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT : 0), + .renderArea = vk::to_vk(info.render_area), + .layerCount = info.layer_count, + .viewMask = info.view_mask, + .colorAttachmentCount = as(stdr::size(color_attachments)), + .pColorAttachments = stdr::data(color_attachments), + .pDepthAttachment = info.depth_attachment ? &depth_attachment : nullptr, + .pStencilAttachment = info.stencil_attachment ? &stencil_attachment : nullptr, + }; + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdBeginRenderingKHR, *this, &rendering_info); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::begin_rendering(const RenderingInfo& info, bool secondary) const noexcept -> const CommandBuffer& { - CommandBufferAPI::begin_rendering(*this, info, secondary); + template + auto CommandBufferInterface::begin_render_pass(view::RenderPass render_pass, + view::FrameBuffer framebuffer, + std::span clear_values, + bool secondary_commandbuffers) const noexcept + -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + const auto + vk_clear_values = transform(clear_values, + cmonadic::either( + [](const ClearColor& clear_color) static noexcept -> decltype(auto) { + return VkClearValue { + .color = VkClearColorValue { .float32 = { clear_color.color.r, + clear_color.color.b, + clear_color.color.g, + clear_color.color.a } }, + }; + }, + [](const ClearDepthStencil& clear_depth_stencil) static noexcept -> decltype(auto) { + return VkClearValue { + .depthStencil = VkClearDepthStencilValue { .depth = clear_depth_stencil.depth, + .stencil = clear_depth_stencil + .stencil }, + }; + })); + + const auto begin_info = VkRenderPassBeginInfo { + .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, + .pNext = nullptr, + .renderPass = vk::to_vk(render_pass), + .framebuffer = vk::to_vk(framebuffer), + .renderArea = VkRect2D { .offset = { 0, 0 }, .extent = { framebuffer.extent().width, framebuffer.extent().height } }, + .clearValueCount = as(stdr::size(vk_clear_values)), + .pClearValues = stdr::data(vk_clear_values), + }; + + const auto subpass_content = secondary_commandbuffers ? VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS + : VK_SUBPASS_CONTENTS_INLINE; + + vk::call(device_table.vkCmdBeginRenderPass, *this, &begin_info, subpass_content); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::begin_render_pass(view::RenderPass render_pass, - view::FrameBuffer framebuffer, - std::span clear_values, - bool secondary_commandbuffers) const noexcept -> const CommandBuffer& { - CommandBufferAPI::begin_render_pass(*this, - std::move(render_pass), - std::move(framebuffer), - std::move(clear_values), - secondary_commandbuffers); + template + auto CommandBufferInterface::next_subpass() const noexcept -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdNextSubpass, *this, VK_SUBPASS_CONTENTS_INLINE); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::next_subpass() const noexcept -> const CommandBuffer& { - CommandBufferAPI::next_subpass(*this); + template + auto CommandBufferInterface::end_render_pass() const noexcept -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdEndRenderPass, *this); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::end_render_pass() const noexcept -> const CommandBuffer& { - CommandBufferAPI::end_render_pass(*this); + template + auto CommandBufferInterface::end_rendering() const noexcept -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdEndRendering, *this); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::end_rendering() const noexcept -> const CommandBuffer& { - CommandBufferAPI::end_rendering(*this); + template + auto CommandBufferInterface::bind_pipeline(view::Pipeline pipeline) const noexcept -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + const auto bind_point = (pipeline.type() == Pipeline::Type::RASTER) ? VK_PIPELINE_BIND_POINT_GRAPHICS + : VK_PIPELINE_BIND_POINT_COMPUTE; + + vk::call(device_table.vkCmdBindPipeline, *this, bind_point, pipeline); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::bind_pipeline(view::Pipeline pipeline) const noexcept -> const CommandBuffer& { - CommandBufferAPI::bind_pipeline(*this, std::move(pipeline)); + template + auto CommandBufferInterface::set_viewport(u32 first_viewport, std::span viewports) const noexcept + -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + const auto vk_viewports = transform(viewports, vk::monadic::to_vk()); + + vk::call(device_table.vkCmdSetViewport, *this, first_viewport, stdr::size(vk_viewports), stdr::data(vk_viewports)); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::set_viewport(u32 first_viewport, std::span viewports) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::set_viewport(*this, first_viewport, std::move(viewports)); + template + auto CommandBufferInterface::set_scissor(u32 first_scissor, std::span scissors) const noexcept + -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + const auto vk_scissors = transform(scissors, vk::monadic::to_vk()); + + vk::call(device_table.vkCmdSetScissor, *this, first_scissor, stdr::size(vk_scissors), stdr::data(vk_scissors)); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::set_scissor(u32 first_scissor, std::span scissors) const noexcept -> const CommandBuffer& { - CommandBufferAPI::set_scissor(*this, first_scissor, std::move(scissors)); + template + auto CommandBufferInterface::set_line_width(f32 width) const noexcept -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdSetLineWidth, *this, width); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::set_line_width(f32 width) const noexcept -> const CommandBuffer& { - CommandBufferAPI::set_line_width(*this, width); + template + auto CommandBufferInterface::set_depth_bias(f32 constant_factor, f32 clamp, f32 slope_factor) const noexcept + -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdSetDepthBias, *this, constant_factor, clamp, slope_factor); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::set_depth_bias(f32 constant_factor, f32 clamp, f32 slope_factor) const noexcept -> const CommandBuffer& { - CommandBufferAPI::set_depth_bias(*this, constant_factor, clamp, slope_factor); + template + auto CommandBufferInterface::set_blend_constants(std::span constants) const noexcept + -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + f32 data[] = { constants[0], constants[1], constants[2], constants[3] }; + + vk::call(device_table.vkCmdSetBlendConstants, *this, data); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::set_blend_constants(std::span constants) const noexcept -> const CommandBuffer& { - CommandBufferAPI::set_blend_constants(*this, std::move(constants)); + template + auto CommandBufferInterface::set_depth_bounds(f32 min, f32 max) const noexcept -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdSetDepthBounds, *this, min, max); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::set_depth_bounds(f32 min, f32 max) const noexcept -> const CommandBuffer& { - CommandBufferAPI::set_depth_bounds(*this, min, max); + template + auto CommandBufferInterface::set_stencil_compare_mask(StencilFaceFlag face, u32 mask) const noexcept + -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdSetStencilCompareMask, *this, vk::to_vk(face), mask); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::set_stencil_compare_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBuffer& { - CommandBufferAPI::set_stencil_compare_mask(*this, face, mask); + template + auto CommandBufferInterface::set_stencil_write_mask(StencilFaceFlag face, u32 mask) const noexcept + -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdSetStencilWriteMask, *this, vk::to_vk(face), mask); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::set_stencil_write_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBuffer& { - CommandBufferAPI::set_stencil_write_mask(*this, face, mask); + template + auto CommandBufferInterface::set_stencil_reference(StencilFaceFlag face, u32 reference) const noexcept + -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdSetStencilReference, *this, vk::to_vk(face), reference); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::set_stencil_reference(StencilFaceFlag face, u32 reference) const noexcept -> const CommandBuffer& { - CommandBufferAPI::set_stencil_reference(*this, face, reference); + template + auto CommandBufferInterface::dispatch(u32 group_count_x, u32 group_count_y, u32 group_count_z) const noexcept + -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdDispatch, *this, group_count_x, group_count_y, group_count_z); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::dispatch(u32 group_count_x, u32 group_count_y, u32 group_count_z) const noexcept -> const CommandBuffer& { - CommandBufferAPI::dispatch(*this, group_count_x, group_count_y, group_count_z); + template + auto CommandBufferInterface::draw(u32 vertex_count, u32 instance_count, u32 first_vertex, u32 first_instance) + const noexcept -> const CommandBufferInterface& { + EXPECTS(vertex_count > 0); + + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdDraw, *this, vertex_count, instance_count, first_vertex, first_instance); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::draw(u32 vertex_count, u32 instance_count, u32 first_vertex, u32 first_instance) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::draw(*this, vertex_count, instance_count, first_vertex, first_instance); + template + auto CommandBufferInterface::draw_indexed(u32 index_count, + u32 instance_count, + u32 first_index, + i32 vertex_offset, + u32 first_instance) const noexcept -> const CommandBufferInterface& { + EXPECTS(index_count > 0); + + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdDrawIndexed, *this, index_count, instance_count, first_index, vertex_offset, first_instance); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::draw_indexed(u32 index_count, u32 instance_count, u32 first_index, i32 vertex_offset, u32 first_instance) - const noexcept -> const CommandBuffer& { - CommandBufferAPI::draw_indexed(*this, index_count, instance_count, first_index, vertex_offset, first_instance); + template + auto CommandBufferInterface::draw_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept + -> const CommandBufferInterface& { + EXPECTS(draw_count > 0); + + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdDrawIndirect, *this, buffer, offset, draw_count, stride); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::draw_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::draw_indirect(*this, std::move(buffer), offset, draw_count, stride); + template + auto CommandBufferInterface::draw_indexed_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) + const noexcept -> const CommandBufferInterface& { + EXPECTS(draw_count > 0); + + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdDrawIndexedIndirect, *this, buffer, offset, draw_count, stride); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::draw_indexed_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::draw_indexed_indirect(*this, std::move(buffer), offset, draw_count, stride); + template + auto CommandBufferInterface::bind_vertex_buffers(std::span buffers, + std::span offsets) const noexcept + -> const CommandBufferInterface& { + EXPECTS(not std::empty(buffers)); + EXPECTS(std::size(buffers) == std::size(offsets)); + + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + const auto vk_buffers = transform(buffers, vk::monadic::to_vk()); + + vk::call(device_table.vkCmdBindVertexBuffers, + *this, + 0, + stdr::size(vk_buffers), + stdr::data(vk_buffers), + stdr::data(offsets)); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::bind_vertex_buffers(std::span buffers, std::span offsets) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::bind_vertex_buffers(*this, std::move(buffers), std::move(offsets)); + template + auto CommandBufferInterface::bind_index_buffer(view::Buffer buffer, u64 offset, bool large_indices) const noexcept + -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdBindIndexBuffer, + *this, + buffer, + offset, + (large_indices) ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::bind_descriptor_sets(view::Pipeline pipeline, - view::PipelineLayout layout, - std::span descriptor_sets, - std::span dynamic_offsets) const noexcept -> const CommandBuffer& { - CommandBufferAPI::bind_descriptor_sets(*this, - std::move(pipeline), - std::move(layout), - std::move(descriptor_sets), - std::move(dynamic_offsets)); + template + auto CommandBufferInterface::bind_descriptor_sets(view::Pipeline pipeline, + view::PipelineLayout layout, + std::span descriptor_sets, + std::span dynamic_offsets) const noexcept + -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + const auto bind_point = (pipeline.type() == Pipeline::Type::RASTER) ? VK_PIPELINE_BIND_POINT_GRAPHICS + : VK_PIPELINE_BIND_POINT_COMPUTE; + + const auto vk_descriptor_sets = transform(descriptor_sets, vk::monadic::to_vk()); + + vk::call(device_table.vkCmdBindDescriptorSets, + *this, + bind_point, + layout, + 0, + stdr::size(vk_descriptor_sets), + stdr::data(vk_descriptor_sets), + stdr::size(dynamic_offsets), + stdr::data(dynamic_offsets)); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::copy_buffer(view::Buffer src, view::Buffer dst, usize size, u64 src_offset, u64 dst_offset) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::copy_buffer(*this, std::move(src), std::move(dst), size, src_offset, dst_offset); + template + auto CommandBufferInterface::copy_buffer(view::Buffer src, view::Buffer dst, usize size, u64 src_offset, u64 dst_offset) + const noexcept -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + const auto vk_copy_buffers = std::array { + VkBufferCopy { .srcOffset = src_offset, .dstOffset = dst_offset, .size = size } + }; + + vk::call(device_table.vkCmdCopyBuffer, *this, src, dst, stdr::size(vk_copy_buffers), stdr::data(vk_copy_buffers)); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::copy_buffer_to_image(view::Buffer src, - view::Image dst, - std::span buffer_image_copies) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::copy_buffer_to_image(*this, std::move(src), std::move(dst), std::move(buffer_image_copies)); + template + auto CommandBufferInterface::copy_buffer_to_image(view::Buffer src, + view::Image dst, + std::span buffer_image_copies) const noexcept + -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + const auto DEFAULT_COPY = std::array { + BufferImageCopy { 0, 0, 0, {}, { 0, 0, 0 }, dst.extent() } + }; + + if (stdr::empty(buffer_image_copies)) buffer_image_copies = DEFAULT_COPY; + + const auto vk_copy_regions = transform(buffer_image_copies, [](const auto& buffer_image_copy) static noexcept { + const auto image_subresource = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(buffer_image_copy.subresource_layers.aspect_mask), + .mipLevel = buffer_image_copy.subresource_layers.mip_level, + .baseArrayLayer = buffer_image_copy.subresource_layers.base_array_layer, + .layerCount = buffer_image_copy.subresource_layers.layer_count, + }; + + return VkBufferImageCopy { .bufferOffset = buffer_image_copy.buffer_offset, + .bufferRowLength = buffer_image_copy.buffer_row_length, + .bufferImageHeight = buffer_image_copy.buffer_image_height, + .imageSubresource = image_subresource, + .imageOffset = vk::to_vk(buffer_image_copy.offset), + .imageExtent = vk::to_vk(buffer_image_copy.extent) }; + }); + + vk::call(device_table.vkCmdCopyBufferToImage, + *this, + src, + dst, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + stdr::size(vk_copy_regions), + stdr::data(vk_copy_regions)); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::copy_image_to_buffer(view::Image src, - view::Buffer dst, - std::span buffer_image_copies) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::copy_image_to_buffer(*this, std::move(src), std::move(dst), std::move(buffer_image_copies)); + template + auto CommandBufferInterface::copy_image_to_buffer(view::Image src, + view::Buffer dst, + std::span buffer_image_copies) const noexcept + -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + const auto DEFAULT_COPY = into_array({ + BufferImageCopy { 0, 0, 0, {}, { 0, 0, 0 }, src.extent() } + }); + + if (stdr::empty(buffer_image_copies)) buffer_image_copies = DEFAULT_COPY; + + const auto vk_copy_regions = transform(buffer_image_copies, [](const auto& buffer_image_copy) static noexcept { + const auto image_subresource = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(buffer_image_copy.subresource_layers.aspect_mask), + .mipLevel = buffer_image_copy.subresource_layers.mip_level, + .baseArrayLayer = buffer_image_copy.subresource_layers.base_array_layer, + .layerCount = buffer_image_copy.subresource_layers.layer_count, + }; + + return VkBufferImageCopy { .bufferOffset = buffer_image_copy.buffer_offset, + .bufferRowLength = buffer_image_copy.buffer_row_length, + .bufferImageHeight = buffer_image_copy.buffer_image_height, + .imageSubresource = image_subresource, + .imageOffset = vk::to_vk(buffer_image_copy.offset), + .imageExtent = vk::to_vk(buffer_image_copy.extent) }; + }); + + vk::call(device_table.vkCmdCopyImageToBuffer, + *this, + src, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + dst, + stdr::size(vk_copy_regions), + stdr::data(vk_copy_regions)); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::copy_image(view::Image src, - view::Image dst, - ImageLayout src_layout, - ImageLayout dst_layout, - const ImageSubresourceLayers& src_subresource_layers, - const ImageSubresourceLayers& dst_subresource_layers, - const math::uextent3& extent) const noexcept -> const CommandBuffer& { - CommandBufferAPI::copy_image(*this, - std::move(src), - std::move(dst), - src_layout, - dst_layout, - src_subresource_layers, - dst_subresource_layers, - extent); + template + auto CommandBufferInterface::copy_image(view::Image src, + view::Image dst, + ImageLayout src_layout, + ImageLayout dst_layout, + const ImageSubresourceLayers& src_subresource_layers, + const ImageSubresourceLayers& dst_subresource_layers, + const math::uextent3& extent) const noexcept -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + const auto vk_src_subresource_layers = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(src_subresource_layers.aspect_mask), + .mipLevel = src_subresource_layers.mip_level, + .baseArrayLayer = src_subresource_layers.base_array_layer, + .layerCount = src_subresource_layers.layer_count + }; + + const auto vk_dst_subresource_layers = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(dst_subresource_layers.aspect_mask), + .mipLevel = dst_subresource_layers.mip_level, + .baseArrayLayer = dst_subresource_layers.base_array_layer, + .layerCount = dst_subresource_layers.layer_count + }; + + const auto vk_regions = into_array({ + VkImageCopy { .srcSubresource = vk_src_subresource_layers, + .srcOffset = { 0, 0, 0 }, + .dstSubresource = vk_dst_subresource_layers, + .dstOffset = { 0, 0, 0 }, + .extent = vk::to_vk(extent) } + }); + + vk::call(device_table.vkCmdCopyImage, + *this, + src, + vk::to_vk(src_layout), + dst, + vk::to_vk(dst_layout), + stdr::size(vk_regions), + stdr::data(vk_regions)); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::resolve_image(view::Image src, - view::Image dst, - ImageLayout src_layout, - ImageLayout dst_layout, - const ImageSubresourceLayers& src_subresource_layers, - const ImageSubresourceLayers& dst_subresource_layers) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::resolve_image(*this, - std::move(src), - std::move(dst), - src_layout, - dst_layout, - src_subresource_layers, - dst_subresource_layers); + template + auto CommandBufferInterface::resolve_image(view::Image src, + view::Image dst, + ImageLayout src_layout, + ImageLayout dst_layout, + const ImageSubresourceLayers& src_subresource_layers, + const ImageSubresourceLayers& dst_subresource_layers) const noexcept + -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + const auto vk_extent = vk::to_vk(dst.extent()); + + const auto vk_src_subresource_layers = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(src_subresource_layers.aspect_mask), + .mipLevel = src_subresource_layers.mip_level, + .baseArrayLayer = src_subresource_layers.base_array_layer, + .layerCount = src_subresource_layers.layer_count + }; + + const auto vk_dst_subresource_layers = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(dst_subresource_layers.aspect_mask), + .mipLevel = dst_subresource_layers.mip_level, + .baseArrayLayer = dst_subresource_layers.base_array_layer, + .layerCount = dst_subresource_layers.layer_count + }; + + const auto vk_regions = into_array({ + VkImageResolve { .srcSubresource = vk_src_subresource_layers, + .srcOffset = { 0, 0, 0 }, + .dstSubresource = vk_dst_subresource_layers, + .dstOffset = { 0, 0, 0 }, + .extent = vk_extent } + }); + + vk::call(device_table.vkCmdResolveImage, + *this, + src, + vk::to_vk(src_layout), + dst, + vk::to_vk(dst_layout), + stdr::size(vk_regions), + stdr::data(vk_regions)); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::blit_image(view::Image src, - view::Image dst, - ImageLayout src_layout, - ImageLayout dst_layout, - std::span regions, - Filter filter) const noexcept -> const CommandBuffer& { - CommandBufferAPI::blit_image(*this, std::move(src), std::move(dst), src_layout, dst_layout, std::move(regions), filter); + template + auto CommandBufferInterface::blit_image(view::Image src, + view::Image dst, + ImageLayout src_layout, + ImageLayout dst_layout, + std::span regions, + Filter filter) const noexcept -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + const auto vk_regions = transform(regions, [](const auto& region) static noexcept { + const auto vk_src_subresource_layers = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(region.src.aspect_mask), + .mipLevel = region.src.mip_level, + .baseArrayLayer = region.src.base_array_layer, + .layerCount = region.src.layer_count + }; + + const auto vk_dst_subresource_layers = VkImageSubresourceLayers { + .aspectMask = vk::to_vk(region.dst.aspect_mask), + .mipLevel = region.dst.mip_level, + .baseArrayLayer = region.dst.base_array_layer, + .layerCount = region.dst.layer_count + }; + + return VkImageBlit { + .srcSubresource = vk_src_subresource_layers, + .srcOffsets = { vk::to_vk(region.src_offset.position), + vk::to_vk(region.src_offset.extent) }, + .dstSubresource = vk_dst_subresource_layers, + .dstOffsets = { vk::to_vk(region.dst_offset.position), + vk::to_vk(region.dst_offset.extent) }, + }; + }); + + vk::call(device_table.vkCmdBlitImage, + *this, + vk::to_vk(src), + vk::to_vk(src_layout), + vk::to_vk(dst), + vk::to_vk(dst_layout), + stdr::size(vk_regions), + stdr::data(vk_regions), + vk::to_vk(filter)); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::transition_image_layout(view::Image image, - ImageLayout src_layout, - ImageLayout dst_layout, - const ImageSubresourceRange& subresource_range) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::transition_image_layout(*this, std::move(image), src_layout, dst_layout, subresource_range); + template + auto CommandBufferInterface::transition_image_layout(view::Image image, + ImageLayout src_layout, + ImageLayout dst_layout, + const ImageSubresourceRange& subresource_range) const noexcept + -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + const auto vk_src_layout = vk::to_vk(src_layout); + const auto vk_dst_layout = vk::to_vk(dst_layout); + + const auto& src_access = OLD_LAYOUT_ACCESS_MAP.find(vk_src_layout); + const auto& dst_access = NEW_LAYOUT_ACCESS_MAP.find(vk_dst_layout); + + const auto src_stage = src_access->second.second; + const auto dst_stage = dst_access->second.second; + + const auto vk_subresource_range = VkImageSubresourceRange { + .aspectMask = vk::to_vk(subresource_range.aspect_mask), + .baseMipLevel = subresource_range.base_mip_level, + .levelCount = subresource_range.level_count, + .baseArrayLayer = subresource_range.base_array_layer, + .layerCount = subresource_range.layer_count, + }; + + const auto barriers = into_array({ + VkImageMemoryBarrier { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = src_access->second.first, + .dstAccessMask = dst_access->second.first, + .oldLayout = vk_src_layout, + .newLayout = vk_dst_layout, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = vk::to_vk(image), + .subresourceRange = vk_subresource_range + + }, + }); + + vk::call(device_table.vkCmdPipelineBarrier, + *this, + src_stage, + dst_stage, + 0, + 0, + nullptr, + 0, + nullptr, + stdr::size(barriers), + stdr::data(barriers)); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::pipeline_barrier(PipelineStageFlag src_mask, - PipelineStageFlag dst_mask, - DependencyFlag dependency, - std::span memory_barriers, - std::span buffer_memory_barriers, - std::span image_memory_barriers) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::pipeline_barrier(*this, - src_mask, - dst_mask, - dependency, - std::move(memory_barriers), - std::move(buffer_memory_barriers), - std::move(image_memory_barriers)); + template + auto CommandBufferInterface::pipeline_barrier(PipelineStageFlag src_mask, + PipelineStageFlag dst_mask, + DependencyFlag dependency, + std::span memory_barriers, + std::span buffer_memory_barriers, + std::span image_memory_barriers) const noexcept + -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + const auto vk_memory_barriers = transform(memory_barriers, [](const auto& barrier) static noexcept -> decltype(auto) { + return VkMemoryBarrier { + .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = vk::to_vk(barrier.src), + .dstAccessMask = vk::to_vk(barrier.dst), + }; + }); + const auto vk_buffer_memory_barriers = transform(buffer_memory_barriers, + [](const auto& barrier) static noexcept -> decltype(auto) { + return VkBufferMemoryBarrier { + .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = vk::to_vk(barrier.src), + .dstAccessMask = vk::to_vk(barrier.dst), + .srcQueueFamilyIndex = barrier.src_queue_family_index, + .dstQueueFamilyIndex = barrier.dst_queue_family_index, + .buffer = vk::to_vk(barrier.buffer), + .offset = barrier.offset, + .size = barrier.size + }; + }); + const auto + vk_image_memory_barriers = transform(image_memory_barriers, [](const auto& barrier) static noexcept -> decltype(auto) { + const auto vk_subresource_range = VkImageSubresourceRange { + .aspectMask = vk::to_vk(barrier.range.aspect_mask), + .baseMipLevel = barrier.range.base_mip_level, + .levelCount = barrier.range.level_count, + .baseArrayLayer = barrier.range.base_array_layer, + .layerCount = barrier.range.layer_count + }; + + return VkImageMemoryBarrier { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = vk::to_vk(barrier.src), + .dstAccessMask = vk::to_vk(barrier.dst), + .oldLayout = vk::to_vk(barrier.old_layout), + .newLayout = vk::to_vk(barrier.new_layout), + .srcQueueFamilyIndex = barrier.src_queue_family_index, + .dstQueueFamilyIndex = barrier.dst_queue_family_index, + .image = vk::to_vk(barrier.image), + .subresourceRange = vk_subresource_range + }; + }); + + vk::call(device_table.vkCmdPipelineBarrier, + *this, + vk::to_vk(src_mask), + vk::to_vk(dst_mask), + vk::to_vk(dependency), + stdr::size(vk_memory_barriers), + stdr::data(vk_memory_barriers), + stdr::size(vk_buffer_memory_barriers), + stdr::data(vk_buffer_memory_barriers), + stdr::size(vk_image_memory_barriers), + stdr::data(vk_image_memory_barriers)); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::push_constants(view::PipelineLayout pipeline_layout, - ShaderStageFlag stage, - std::span data, - u32 offset) const noexcept -> const CommandBuffer& { - CommandBufferAPI::push_constants(*this, std::move(pipeline_layout), stage, std::move(data), offset); + template + auto CommandBufferInterface::push_constants(view::PipelineLayout pipeline_layout, + ShaderStageFlag stage, + std::span data, + u32 offset) const noexcept -> const CommandBufferInterface& { + EXPECTS(not std::empty(data)); + + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + vk::call(device_table.vkCmdPushConstants, + *this, + vk::to_vk(pipeline_layout), + vk::to_vk(stage), + offset, + stdr::size(data), + stdr::data(data)); return *this; } ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::execute_sub_command_buffers(std::span command_buffers) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::execute_sub_command_buffers(*this, std::move(command_buffers)); + template + auto CommandBufferInterface::execute_sub_command_buffers(std::span commandbuffers) + const noexcept -> const CommandBufferInterface& { + const auto state = this->state(); + EXPECTS(state == CommandBuffer::State::RECORDING); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + const auto expects_secondary = [this](auto&&) noexcept -> decltype(auto) { + EXPECTS(level() == CommandBufferLevel::SECONDARY); + return *this; + }; + + const auto vk_command_buffers = transform(commandbuffers, cmonadic::map(expects_secondary, vk::monadic::to_vk())); + vk::call(device_table.vkCmdExecuteCommands, *this, stdr::size(vk_command_buffers), stdr::data(vk_command_buffers)); return *this; } + template class CommandBufferInterface; + template class CommandBufferInterface; + ///////////////////////////////////// ///////////////////////////////////// - auto CommandBuffer::do_init(PrivateTag, CommandBufferLevel level, VkCommandBuffer&& handle, Deleter&& deleter) noexcept - -> void { + auto CommandBufferImplementation::do_init(PrivateTag, + CommandBufferLevel level, + VkCommandBuffer&& handle, + Deleter&& deleter) noexcept -> void { + m_state = core::allocate_unsafe(State::INITIAL); + m_level = level; m_vk_handle = std::move(handle); m_deleter = std::move(deleter); } - - namespace view { - // ///////////////////////////////////// - // ///////////////////////////////////// - // auto CommandBuffer::reset() const noexcept -> Expected { - // return CommandBufferAPI::reset(*this); - // } - - // ///////////////////////////////////// - // ///////////////////////////////////// - // auto CommandBuffer::begin(bool one_time_submit, InheritanceInfo inheritance_info_variant) const noexcept - // -> Expected { - // return CommandBufferAPI::begin(*this, one_time_submit, std::move(inheritance_info_variant)); - // } - - // ///////////////////////////////////// - // ///////////////////////////////////// - // auto CommandBuffer::end() const noexcept -> Expected { - // return CommandBufferAPI::end(*this); - // } - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::begin_debug_region(std::string_view name, const fcolor_rgb& color) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::begin_debug_region(*this, std::move(name), color); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::insert_debug_label(std::string_view name, const fcolor_rgb& color) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::insert_debug_label(*this, std::move(name), color); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::end_debug_region() const noexcept -> const CommandBuffer& { - CommandBufferAPI::end_debug_region(*this); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::begin_rendering(const RenderingInfo& info, bool secondary) const noexcept -> const CommandBuffer& { - CommandBufferAPI::begin_rendering(*this, info, secondary); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::begin_render_pass(view::RenderPass render_pass, - view::FrameBuffer framebuffer, - std::span clear_values, - bool secondary_commandbuffers) const noexcept -> const CommandBuffer& { - CommandBufferAPI::begin_render_pass(*this, - std::move(render_pass), - std::move(framebuffer), - std::move(clear_values), - secondary_commandbuffers); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::next_subpass() const noexcept -> const CommandBuffer& { - CommandBufferAPI::next_subpass(*this); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::end_render_pass() const noexcept -> const CommandBuffer& { - CommandBufferAPI::end_render_pass(*this); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::end_rendering() const noexcept -> const CommandBuffer& { - CommandBufferAPI::end_rendering(*this); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::bind_pipeline(view::Pipeline pipeline) const noexcept -> const CommandBuffer& { - CommandBufferAPI::bind_pipeline(*this, std::move(pipeline)); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::set_viewport(u32 first_viewport, std::span viewports) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::set_viewport(*this, first_viewport, std::move(viewports)); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::set_scissor(u32 first_scissor, std::span scissors) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::set_scissor(*this, first_scissor, std::move(scissors)); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::set_line_width(f32 width) const noexcept -> const CommandBuffer& { - CommandBufferAPI::set_line_width(*this, width); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::set_depth_bias(f32 constant_factor, f32 clamp, f32 slope_factor) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::set_depth_bias(*this, constant_factor, clamp, slope_factor); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::set_blend_constants(std::span constants) const noexcept -> const CommandBuffer& { - CommandBufferAPI::set_blend_constants(*this, std::move(constants)); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::set_depth_bounds(f32 min, f32 max) const noexcept -> const CommandBuffer& { - CommandBufferAPI::set_depth_bounds(*this, min, max); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::set_stencil_compare_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBuffer& { - CommandBufferAPI::set_stencil_compare_mask(*this, face, mask); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::set_stencil_write_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBuffer& { - CommandBufferAPI::set_stencil_write_mask(*this, face, mask); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::set_stencil_reference(StencilFaceFlag face, u32 reference) const noexcept -> const CommandBuffer& { - CommandBufferAPI::set_stencil_reference(*this, face, reference); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::dispatch(u32 group_count_x, u32 group_count_y, u32 group_count_z) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::dispatch(*this, group_count_x, group_count_y, group_count_z); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::draw(u32 vertex_count, u32 instance_count, u32 first_vertex, u32 first_instance) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::draw(*this, vertex_count, instance_count, first_vertex, first_instance); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::draw_indexed(u32 index_count, - u32 instance_count, - u32 first_index, - i32 vertex_offset, - u32 first_instance) const noexcept -> const CommandBuffer& { - CommandBufferAPI::draw_indexed(*this, index_count, instance_count, first_index, vertex_offset, first_instance); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::draw_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::draw_indirect(*this, std::move(buffer), offset, draw_count, stride); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::draw_indexed_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::draw_indexed_indirect(*this, std::move(buffer), offset, draw_count, stride); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::bind_vertex_buffers(std::span buffers, std::span offsets) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::bind_vertex_buffers(*this, std::move(buffers), std::move(offsets)); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::bind_descriptor_sets(view::Pipeline pipeline, - view::PipelineLayout layout, - std::span descriptor_sets, - std::span dynamic_offsets) const noexcept -> const CommandBuffer& { - CommandBufferAPI::bind_descriptor_sets(*this, - std::move(pipeline), - std::move(layout), - std::move(descriptor_sets), - std::move(dynamic_offsets)); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::copy_buffer(view::Buffer src, view::Buffer dst, usize size, u64 src_offset, u64 dst_offset) - const noexcept -> const CommandBuffer& { - CommandBufferAPI::copy_buffer(*this, std::move(src), std::move(dst), size, src_offset, dst_offset); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::copy_buffer_to_image(view::Buffer src, - view::Image dst, - std::span buffer_image_copies) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::copy_buffer_to_image(*this, std::move(src), std::move(dst), std::move(buffer_image_copies)); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::copy_image_to_buffer(view::Image src, - view::Buffer dst, - std::span buffer_image_copies) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::copy_image_to_buffer(*this, std::move(src), std::move(dst), std::move(buffer_image_copies)); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::copy_image(view::Image src, - view::Image dst, - ImageLayout src_layout, - ImageLayout dst_layout, - const ImageSubresourceLayers& src_subresource_layers, - const ImageSubresourceLayers& dst_subresource_layers, - const math::uextent3& extent) const noexcept -> const CommandBuffer& { - CommandBufferAPI::copy_image(*this, - std::move(src), - std::move(dst), - src_layout, - dst_layout, - src_subresource_layers, - dst_subresource_layers, - extent); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::resolve_image(view::Image src, - view::Image dst, - ImageLayout src_layout, - ImageLayout dst_layout, - const ImageSubresourceLayers& src_subresource_layers, - const ImageSubresourceLayers& dst_subresource_layers) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::resolve_image(*this, - std::move(src), - std::move(dst), - src_layout, - dst_layout, - src_subresource_layers, - dst_subresource_layers); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::blit_image(view::Image src, - view::Image dst, - ImageLayout src_layout, - ImageLayout dst_layout, - std::span regions, - Filter filter) const noexcept -> const CommandBuffer& { - CommandBufferAPI::blit_image(*this, - std::move(src), - std::move(dst), - src_layout, - dst_layout, - std::move(regions), - filter); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::transition_image_layout(view::Image image, - ImageLayout src_layout, - ImageLayout dst_layout, - const ImageSubresourceRange& subresource_range) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::transition_image_layout(*this, std::move(image), src_layout, dst_layout, subresource_range); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::pipeline_barrier(PipelineStageFlag src_mask, - PipelineStageFlag dst_mask, - DependencyFlag dependency, - std::span memory_barriers, - std::span buffer_memory_barriers, - std::span image_memory_barriers) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::pipeline_barrier(*this, - src_mask, - dst_mask, - dependency, - std::move(memory_barriers), - std::move(buffer_memory_barriers), - std::move(image_memory_barriers)); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::push_constants(view::PipelineLayout pipeline_layout, - ShaderStageFlag stage, - std::span data, - u32 offset) const noexcept -> const CommandBuffer& { - CommandBufferAPI::push_constants(*this, std::move(pipeline_layout), stage, std::move(data), offset); - return *this; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandBuffer::execute_sub_command_buffers(std::span command_buffers) const noexcept - -> const CommandBuffer& { - CommandBufferAPI::execute_sub_command_buffers(*this, std::move(command_buffers)); - return *this; - } - } // namespace view } // namespace stormkit::gpu diff --git a/src/gpu/execution/command_pool.cpp b/src/gpu/execution/command_pool.cpp index 70df8484e..6fa7df000 100644 --- a/src/gpu/execution/command_pool.cpp +++ b/src/gpu/execution/command_pool.cpp @@ -22,45 +22,42 @@ namespace stdr = std::ranges; namespace stdv = std::views; namespace stormkit::gpu { - namespace { - struct CommandPoolAPI { - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto create_vk_command_buffers(const CommandPoolType& pool, usize count, CommandBufferLevel level) noexcept - -> Expected> { - const auto& device = pool.device(); - const auto& device_table = device.device_table(); - - const auto allocate_info = VkCommandBufferAllocateInfo { - .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, - .pNext = nullptr, - .commandPool = pool, - .level = vk::to_vk(level), - .commandBufferCount = as(count) - }; - - return vk::allocate_checked(count, - device_table.vkAllocateCommandBuffers, - device, - &allocate_info); - } - - ///////////////////////////////////// - ///////////////////////////////////// - static auto delete_vk_command_buffers(view::Device device, - view::CommandPool command_pool, - VkCommandBuffer command_buffer) noexcept -> void { - const auto& device_table = device.device_table(); - vk::call(device_table.vkFreeCommandBuffers, device, command_pool, 1, &command_buffer); - } + ///////////////////////////////////// + ///////////////////////////////////// + template + auto CommandPoolInterface::create_vk_command_buffers(usize count, CommandBufferLevel level) const noexcept + -> Expected> { + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + const auto allocate_info = VkCommandBufferAllocateInfo { + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .pNext = nullptr, + .commandPool = *this, + .level = vk::to_vk(level), + .commandBufferCount = as(count) }; - } // namespace + + return vk::allocate_checked(count, device_table.vkAllocateCommandBuffers, device, &allocate_info); + } ///////////////////////////////////// ///////////////////////////////////// - auto CommandPool::do_init(PrivateTag) noexcept -> Expected { - const auto& device = this->device(); + template + auto CommandPoolInterface::delete_vk_command_buffers(view::Device device, + view::CommandPool pool, + VkCommandBuffer cmb) noexcept -> void { + const auto& device_table = device.device_table(); + vk::call(device_table.vkFreeCommandBuffers, device, pool, 1, &cmb); + } + + template class CommandPoolInterface; + template class CommandPoolInterface; + + ///////////////////////////////////// + ///////////////////////////////////// + auto CommandPoolImplementation::do_init(PrivateTag) noexcept -> Expected { + const auto& device = owner(); const auto& device_table = device.device_table(); const auto create_info = VkCommandPoolCreateInfo { @@ -73,33 +70,4 @@ namespace stormkit::gpu { m_vk_handle = Try(vk::call_checked(device_table.vkCreateCommandPool, device, &create_info, nullptr)); Return {}; } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandPool::create_vk_command_buffers(usize count, CommandBufferLevel level) const noexcept - -> Expected> { - return CommandPoolAPI::create_vk_command_buffers(*this, count, level); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandPool::delete_vk_command_buffers(view::Device device, view::CommandPool pool, VkCommandBuffer cmb) noexcept - -> void { - CommandPoolAPI::delete_vk_command_buffers(std::move(device), std::move(pool), cmb); - } - - namespace view { - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandPool::create_vk_command_buffers(usize count, CommandBufferLevel level) const noexcept - -> Expected> { - return CommandPoolAPI::create_vk_command_buffers(*this, count, level); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto CommandPool::delete_vk_command_buffers(Device device, CommandPool pool, VkCommandBuffer cmb) noexcept -> void { - CommandPoolAPI::delete_vk_command_buffers(std::move(device), std::move(pool), cmb); - } - } // namespace view } // namespace stormkit::gpu diff --git a/src/gpu/execution/descriptor_pool.cpp b/src/gpu/execution/descriptor_pool.cpp index 576c3d9dc..80cc901b2 100644 --- a/src/gpu/execution/descriptor_pool.cpp +++ b/src/gpu/execution/descriptor_pool.cpp @@ -23,42 +23,43 @@ namespace stdv = std::views; using namespace std::literals; namespace stormkit::gpu { - namespace { - struct DescriptorPoolAPI { - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto create_vk_descriptor_sets(const DescriptorPoolType& descriptor_pool, - usize count, - view::DescriptorSetLayout&& layout) noexcept - -> Expected> { - const auto vk_layout = vk::to_vk(layout); - const auto allocate_info = VkDescriptorSetAllocateInfo { - .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, - .pNext = nullptr, - .descriptorPool = descriptor_pool, - .descriptorSetCount = as(count), - .pSetLayouts = &vk_layout, - }; - - const auto& device = descriptor_pool.device(); - const auto& device_table = device.device_table(); - - return vk::allocate_checked(count, - device_table.vkAllocateDescriptorSets, - device, - &allocate_info); - } - - ///////////////////////////////////// - ///////////////////////////////////// - static auto delete_vk_descriptor_set(view::Device&&, view::DescriptorPool&&, VkDescriptorSet) -> void {} + ///////////////////////////////////// + ///////////////////////////////////// + template + auto DescriptorPoolInterface::create_vk_descriptor_sets(usize count, view::DescriptorSetLayout&& layout) const noexcept + -> Expected> { + const auto vk_layout = vk::to_vk(layout); + const auto allocate_info = VkDescriptorSetAllocateInfo { + .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, + .pNext = nullptr, + .descriptorPool = *this, + .descriptorSetCount = as(count), + .pSetLayouts = &vk_layout, }; - } // namespace + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + return vk::allocate_checked(count, device_table.vkAllocateDescriptorSets, device, &allocate_info); + } + + ///////////////////////////////////// ///////////////////////////////////// + template + auto DescriptorPoolInterface::delete_vk_descriptor_set(view::Device device, + view::DescriptorPool pool, + VkDescriptorSet set) noexcept -> void { + const auto& device_table = device.device_table(); + TryAssert(vk::call_checked(device_table.vkFreeDescriptorSets, device, pool, 1, &set), "Failed to free a descriptor set"); + } + + template class DescriptorPoolInterface; + template class DescriptorPoolInterface; + ///////////////////////////////////// - auto DescriptorPool::do_init(PrivateTag, std::span&& sizes, u32 max_sets) noexcept -> Expected { + ///////////////////////////////////// + auto DescriptorPoolImplementation::do_init(PrivateTag, std::span&& sizes, u32 max_sets) noexcept + -> Expected { const auto pool_sizes = transform(sizes, [](const Size& size) static noexcept { return VkDescriptorPoolSize { .type = vk::to_vk(size.type), @@ -75,42 +76,10 @@ namespace stormkit::gpu { .pPoolSizes = stdr::data(pool_sizes), }; - const auto& device = this->device(); + const auto& device = owner(); const auto& device_table = device.device_table(); m_vk_handle = Try(vk::call_checked(device_table.vkCreateDescriptorPool, device, &create_info, nullptr)); Return {}; } - - ///////////////////////////////////// - ///////////////////////////////////// - auto DescriptorPool::create_vk_descriptor_sets(usize count, view::DescriptorSetLayout&& layout) const noexcept - -> Expected> { - return DescriptorPoolAPI::create_vk_descriptor_sets(*this, count, std::move(layout)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto DescriptorPool::delete_vk_descriptor_set(view::Device device, - view::DescriptorPool command_pool, - VkDescriptorSet descriptor_set) noexcept -> void { - DescriptorPoolAPI::delete_vk_descriptor_set(std::move(device), std::move(command_pool), descriptor_set); - } - - namespace view { - ///////////////////////////////////// - ///////////////////////////////////// - auto DescriptorPool::create_vk_descriptor_sets(usize count, DescriptorSetLayout&& layout) const noexcept - -> Expected> { - return DescriptorPoolAPI::create_vk_descriptor_sets(*this, count, std::move(layout)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto DescriptorPool::delete_vk_descriptor_set(Device device, - DescriptorPool command_pool, - VkDescriptorSet descriptor_set) noexcept -> void { - DescriptorPoolAPI::delete_vk_descriptor_set(std::move(device), std::move(command_pool), descriptor_set); - } - } // namespace view } // namespace stormkit::gpu diff --git a/src/gpu/execution/descriptor_set.cpp b/src/gpu/execution/descriptor_set.cpp index 6b1b65fb5..da32fbc47 100644 --- a/src/gpu/execution/descriptor_set.cpp +++ b/src/gpu/execution/descriptor_set.cpp @@ -22,96 +22,79 @@ namespace stdv = std::views; using namespace std::literals; namespace stormkit::gpu { - namespace { - struct DescriptorSetAPI { - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto update(const DescriptorSetType& descriptor_set, std::span&& descriptors) -> void { - const auto& device = descriptor_set.device(); - const auto& device_table = device.device_table(); - - auto&& [_, _, _writes] = [&descriptor_set, descriptors = std::move(descriptors)] noexcept -> decltype(auto) { - auto buffers = std::vector {}; - auto images = std::vector {}; - auto writes = std::vector {}; - buffers.reserve(std::size(descriptors)); - images.reserve(std::size(descriptors)); - writes.reserve(std::size(descriptors)); - - stdr::for_each(std::move(descriptors), - core::monadic::either( - [&descriptor_set, &buffers, &writes](const BufferDescriptor& descriptor) noexcept - -> decltype(auto) { - buffers.push_back(VkDescriptorBufferInfo { - .buffer = descriptor.buffer, - .offset = descriptor.offset, - .range = descriptor.range.value_or(VK_WHOLE_SIZE), - }); - const auto& buffer_descriptor = buffers.back(); - - writes.push_back(VkWriteDescriptorSet { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = descriptor_set, - .dstBinding = descriptor.binding, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = vk::to_vk(descriptor.type), - .pImageInfo = nullptr, - .pBufferInfo = &buffer_descriptor, - .pTexelBufferView = nullptr, - }); - }, - [&descriptor_set, &images, &writes](const ImageDescriptor& descriptor) noexcept - -> decltype(auto) { - images.push_back(VkDescriptorImageInfo { - .sampler = descriptor.sampler, - .imageView = descriptor.image_view, - .imageLayout = vk::to_vk(descriptor.layout), - }); - const auto& image_descriptor = images.back(); - - writes.push_back(VkWriteDescriptorSet { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = descriptor_set, - .dstBinding = descriptor.binding, - .dstArrayElement = 0, - .descriptorCount = 1, - .descriptorType = vk::to_vk(descriptor.type), - .pImageInfo = &image_descriptor, - .pBufferInfo = nullptr, - .pTexelBufferView = nullptr, - }); - })); - - return std::tuple { std::move(buffers), std::move(images), std::move(writes) }; - }(); - - vk::call(device_table.vkUpdateDescriptorSets, device, stdr::size(_writes), stdr::data(_writes), 0, nullptr); - } - }; - } // namespace - ///////////////////////////////////// ///////////////////////////////////// - auto DescriptorSet::do_init(VkDescriptorSet&& descriptor_set, Deleter&& deleter) noexcept -> void { - m_vk_handle = std::move(descriptor_set); - m_deleter = std::move(deleter); + template + auto DescriptorSetInterface::update(std::span descriptors) const noexcept -> void { + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + auto&& [_, _, _writes] = [this, descriptors = std::move(descriptors)] noexcept -> decltype(auto) { + auto buffers = std::vector {}; + auto images = std::vector {}; + auto writes = std::vector {}; + buffers.reserve(std::size(descriptors)); + images.reserve(std::size(descriptors)); + writes.reserve(std::size(descriptors)); + + stdr::for_each(std::move(descriptors), + core::monadic::either( + [this, &buffers, &writes](const BufferDescriptor& descriptor) noexcept -> decltype(auto) { + buffers.push_back(VkDescriptorBufferInfo { + .buffer = descriptor.buffer, + .offset = descriptor.offset, + .range = descriptor.range.value_or(VK_WHOLE_SIZE), + }); + const auto& buffer_descriptor = buffers.back(); + + writes.push_back(VkWriteDescriptorSet { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = nullptr, + .dstSet = *this, + .dstBinding = descriptor.binding, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = vk::to_vk(descriptor.type), + .pImageInfo = nullptr, + .pBufferInfo = &buffer_descriptor, + .pTexelBufferView = nullptr, + }); + }, + [this, &images, &writes](const ImageDescriptor& descriptor) noexcept -> decltype(auto) { + images.push_back(VkDescriptorImageInfo { + .sampler = descriptor.sampler, + .imageView = descriptor.image_view, + .imageLayout = vk::to_vk(descriptor.layout), + }); + const auto& image_descriptor = images.back(); + + writes.push_back(VkWriteDescriptorSet { + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .pNext = nullptr, + .dstSet = *this, + .dstBinding = descriptor.binding, + .dstArrayElement = 0, + .descriptorCount = 1, + .descriptorType = vk::to_vk(descriptor.type), + .pImageInfo = &image_descriptor, + .pBufferInfo = nullptr, + .pTexelBufferView = nullptr, + }); + })); + + return std::tuple { std::move(buffers), std::move(images), std::move(writes) }; + }(); + + vk::call(device_table.vkUpdateDescriptorSets, device, stdr::size(_writes), stdr::data(_writes), 0, nullptr); } + template class DescriptorSetInterface; + template class DescriptorSetInterface; + ///////////////////////////////////// ///////////////////////////////////// - auto DescriptorSet::update(std::span descriptors) const noexcept -> void { - DescriptorSetAPI::update(*this, std::move(descriptors)); + auto DescriptorSetImplementation::do_init(PrivateTag, VkDescriptorSet&& descriptor_set, Deleter&& deleter) noexcept -> void { + m_vk_handle = std::move(descriptor_set); + m_deleter = std::move(deleter); } - - namespace view { - ///////////////////////////////////// - ///////////////////////////////////// - auto DescriptorSet::update(std::span descriptors) const noexcept -> void { - DescriptorSetAPI::update(*this, std::move(descriptors)); - } - } // namespace view } // namespace stormkit::gpu diff --git a/src/gpu/execution/descriptor_set_layout.cpp b/src/gpu/execution/descriptor_set_layout.cpp index 2ba9c843b..be17da3c4 100644 --- a/src/gpu/execution/descriptor_set_layout.cpp +++ b/src/gpu/execution/descriptor_set_layout.cpp @@ -22,7 +22,13 @@ namespace stdv = std::views; using namespace std::literals; namespace stormkit::gpu { - auto DescriptorSetLayout::do_init(PrivateTag, std::vector&& bindings) noexcept -> Expected { + template class DescriptorSetLayoutInterface; + template class DescriptorSetLayoutInterface; + + ///////////////////////////////////// + ///////////////////////////////////// + auto DescriptorSetLayoutImplementation::do_init(PrivateTag, std::vector&& bindings) noexcept + -> Expected { m_bindings = std::move(bindings); const auto vk_bindings = transform(m_bindings, [](const DescriptorSetLayoutBinding& binding) static noexcept { return VkDescriptorSetLayoutBinding { @@ -42,7 +48,7 @@ namespace stormkit::gpu { .pBindings = stdr::data(vk_bindings) }; - const auto& device = this->device(); + const auto& device = owner(); const auto& device_table = device.device_table(); m_vk_handle = Try(vk::call_checked(device_table.vkCreateDescriptorSetLayout, device, diff --git a/src/gpu/execution/frame_buffer.cpp b/src/gpu/execution/frame_buffer.cpp index dabb4a094..c5c2d07a6 100644 --- a/src/gpu/execution/frame_buffer.cpp +++ b/src/gpu/execution/frame_buffer.cpp @@ -22,11 +22,15 @@ namespace stdv = std::views; using namespace std::literals; namespace stormkit::gpu { + template class FrameBufferInterface; + template class FrameBufferInterface; + ///////////////////////////////////// ///////////////////////////////////// - auto FrameBuffer::do_init(view::RenderPass&& render_pass, - const math::uextent2& extent, - std::vector&& attachments) noexcept -> Expected { + auto FrameBufferImplementation::do_init(PrivateTag, + view::RenderPass&& render_pass, + const math::uextent2& extent, + std::vector&& attachments) noexcept -> Expected { m_extent = extent; m_attachments = std::move(attachments); const auto vk_attachments = transform(m_attachments, vk::monadic::to_vk()); @@ -43,7 +47,7 @@ namespace stormkit::gpu { .layers = 1, }; - const auto& device = this->device(); + const auto& device = owner(); const auto& device_table = device.device_table(); m_vk_handle = Try(vk::call_checked(device_table.vkCreateFramebuffer, device, &create_info, nullptr)); diff --git a/src/gpu/execution/pipeline.cpp b/src/gpu/execution/pipeline.cpp index cb8a61637..c3af0859e 100644 --- a/src/gpu/execution/pipeline.cpp +++ b/src/gpu/execution/pipeline.cpp @@ -201,17 +201,20 @@ namespace stormkit::gpu { } } // namespace + template class PipelineInterface; + template class PipelineInterface; + ///////////////////////////////////// ///////////////////////////////////// - auto Pipeline::do_init(PrivateTag, - const RasterPipelineState& _state, - view::PipelineLayout&& layout, - const RasterPipelineRenderingInfo& rendering_info, - std::optional&& pipeline_cache) noexcept -> Expected { + auto PipelineImplementation::do_init(PrivateTag, + const RasterPipelineState& _state, + view::PipelineLayout layout, + const RasterPipelineRenderingInfo& rendering_info, + std::optional&& pipeline_cache) noexcept -> Expected { m_type = Type::RASTER; - m_state = _state; + m_state = core::allocate_unsafe(_state); - const auto& state = as(m_state); + const auto& state = as(*m_state); const auto [binding_descriptions, attribute_descriptions, @@ -275,7 +278,7 @@ namespace stormkit::gpu { const auto vk_pipeline_cache = either(pipeline_cache, vk::monadic::to_vk(), cmonadic::init(nullptr)); - const auto& device = this->device(); + const auto& device = owner(); const auto& device_table = device.device_table(); m_vk_handle = Try(vk::call_checked(device_table.vkCreateGraphicsPipelines, @@ -289,15 +292,15 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto Pipeline::do_init(PrivateTag, - const RasterPipelineState& _state, - view::PipelineLayout&& layout, - view::RenderPass&& render_pass, - std::optional&& pipeline_cache) noexcept -> Expected { + auto PipelineImplementation::do_init(PrivateTag, + const RasterPipelineState& _state, + view::PipelineLayout layout, + view::RenderPass render_pass, + std::optional&& pipeline_cache) noexcept -> Expected { m_type = Type::RASTER; - m_state = _state; + m_state = core::allocate_unsafe(_state); - const auto& state = as(m_state); + const auto& state = as(*m_state); const auto [binding_descriptions, attribute_descriptions, @@ -339,7 +342,7 @@ namespace stormkit::gpu { const auto vk_pipeline_cache = either(pipeline_cache, vk::monadic::to_vk(), cmonadic::init(nullptr)); - const auto& device = this->device(); + const auto& device = owner(); const auto& device_table = device.device_table(); m_vk_handle = Try(vk::call_checked(device_table.vkCreateGraphicsPipelines, diff --git a/src/gpu/execution/pipeline_cache.cpp b/src/gpu/execution/pipeline_cache.cpp index 2268d8124..66b273d5c 100644 --- a/src/gpu/execution/pipeline_cache.cpp +++ b/src/gpu/execution/pipeline_cache.cpp @@ -26,32 +26,31 @@ namespace stormkit::gpu { namespace { ///////////////////////////////////// ///////////////////////////////////// - auto sys_to_load_error(SystemError error) noexcept -> PipelineCache::LoadSaveError { - return PipelineCache::LoadSaveError { { error } }; + auto sys_to_load_error(SystemError error) noexcept -> LoadSaveError { + return LoadSaveError { { error } }; } ///////////////////////////////////// ///////////////////////////////////// - auto result_to_load_error(Result error) noexcept -> PipelineCache::LoadSaveError { - return PipelineCache::LoadSaveError { { error } }; + auto result_to_load_error(Result error) noexcept -> LoadSaveError { + return LoadSaveError { { error } }; } } // namespace - ///////////////////////////////////// - ///////////////////////////////////// - PipelineCache::~PipelineCache() noexcept = default; + template class PipelineCacheInterface; + template class PipelineCacheInterface; ///////////////////////////////////// ///////////////////////////////////// - auto PipelineCache::do_init(PrivateTag, stdfs::path&& path) noexcept -> LoadSaveExpected { + auto PipelineCacheImplementation::do_init(PrivateTag, stdfs::path&& path) noexcept -> LoadSaveExpected { m_path = std::move(path); Return read_pipeline_cache(); } ///////////////////////////////////// ///////////////////////////////////// - auto PipelineCache::create_new_pipeline_cache() noexcept -> LoadSaveExpected { - const auto& device = this->device(); + auto PipelineCacheImplementation::create_new_pipeline_cache() noexcept -> LoadSaveExpected { + const auto& device = owner(); const auto& device_table = device.device_table(); const auto& physical_device_infos = device.physical_device().info(); @@ -84,10 +83,10 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto PipelineCache::read_pipeline_cache() noexcept -> LoadSaveExpected { + auto PipelineCacheImplementation::read_pipeline_cache() noexcept -> LoadSaveExpected { if (not stdfs::exists(m_path)) Return create_new_pipeline_cache(); - const auto& device = this->device(); + const auto& device = owner(); const auto& device_table = device.device_table(); const auto& physical_device_infos = device.physical_device().info(); @@ -127,8 +126,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto PipelineCache::save_cache() noexcept -> LoadSaveExpected { - const auto& device = this->device(); + auto PipelineCacheImplementation::save_cache() noexcept -> LoadSaveExpected { + const auto& device = owner(); const auto& device_table = device.device_table(); auto size = 0_usize; diff --git a/src/gpu/execution/pipeline_layout.cpp b/src/gpu/execution/pipeline_layout.cpp index e4fb71378..d7fba278d 100644 --- a/src/gpu/execution/pipeline_layout.cpp +++ b/src/gpu/execution/pipeline_layout.cpp @@ -22,14 +22,17 @@ namespace stdv = std::views; using namespace std::literals; namespace stormkit::gpu { + template class PipelineLayoutInterface; + template class PipelineLayoutInterface; + ///////////////////////////////////// ///////////////////////////////////// - auto PipelineLayout::do_init(PrivateTag, const RasterPipelineLayout& layout) noexcept -> Expected { - m_layout = layout; + auto PipelineLayoutImplementation::do_init(PrivateTag, const RasterPipelineLayout& layout) noexcept -> Expected { + m_layout = core::allocate_unsafe(layout); - const auto set_layouts = transform(m_layout.descriptor_set_layouts, vk::monadic::to_vk()); + const auto set_layouts = transform(m_layout->descriptor_set_layouts, vk::monadic::to_vk()); - const auto push_constant_ranges = transform(m_layout.push_constant_ranges, [](const auto& push_constant_range) noexcept { + const auto push_constant_ranges = transform(m_layout->push_constant_ranges, [](const auto& push_constant_range) noexcept { return VkPushConstantRange { .stageFlags = vk::to_vk(push_constant_range.stages), .offset = push_constant_range.offset, @@ -47,7 +50,7 @@ namespace stormkit::gpu { .pPushConstantRanges = stdr::data(push_constant_ranges), }; - const auto& device = this->device(); + const auto& device = owner(); const auto& device_table = device.device_table(); m_vk_handle = Try(vk::call_checked(device_table.vkCreatePipelineLayout, device, &create_info, nullptr)); diff --git a/src/gpu/execution/queue.cpp b/src/gpu/execution/queue.cpp index 2bb64b31c..30b8d5d0d 100644 --- a/src/gpu/execution/queue.cpp +++ b/src/gpu/execution/queue.cpp @@ -24,221 +24,171 @@ namespace stdv = std::views; namespace stdp = std::pmr; namespace stormkit::gpu { - namespace { - struct QueueAPI { - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto wait_idle(const QueueType& queue) noexcept -> Expected { - const auto& device = queue.device(); - const auto& device_table = device.device_table(); - - return vk::call_checked(device_table.vkQueueWaitIdle, queue); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto submit(const QueueType& queue, - std::span&& submit_infos, - std::optional&& fence) noexcept -> Expected { - struct SubmitInfoRange { - std::span wait_semaphores; - std::span wait_dst_stages; - std::span command_buffers; - std::span signal_semaphores; - }; - - const auto bytes_count = [&submit_infos] noexcept { - auto _wait_semaphores_count = 0uz; - auto _wait_dst_stages_count = 0uz; - auto _command_buffers_count = 0uz; - auto _signal_semaphores_count = 0uz; - - for (auto&& submit_info : submit_infos) { - _wait_semaphores_count = stdr::size(submit_info.wait_semaphores); - _wait_dst_stages_count = stdr::size(submit_info.wait_dst_stages); - _command_buffers_count = stdr::size(submit_info.command_buffers); - _signal_semaphores_count = stdr::size(submit_info.signal_semaphores); - } - return _wait_semaphores_count * sizeof(VkSemaphore) - + _wait_dst_stages_count * sizeof(VkPipelineStageFlags) - + _command_buffers_count * sizeof(VkCommandBuffer) - + _signal_semaphores_count * sizeof(VkSemaphore) - + stdr::size(submit_infos) * sizeof(SubmitInfoRange); - }(); - - auto memory_resource = stdp::monotonic_buffer_resource { bytes_count }; - - auto wait_semaphores_buf = stdp::vector> { &memory_resource }; - wait_semaphores_buf.reserve(stdr::size(submit_infos)); - auto wait_dst_stages_buf = stdp::vector> { &memory_resource }; - wait_dst_stages_buf.reserve(stdr::size(submit_infos)); - auto command_buffers_buf = stdp::vector> { &memory_resource }; - command_buffers_buf.reserve(stdr::size(submit_infos)); - auto signal_semaphores_buf = stdp::vector> { &memory_resource }; - signal_semaphores_buf.reserve(stdr::size(submit_infos)); - - const auto submit_ranges = [&] noexcept { - auto vec = stdp::vector { &memory_resource }; - vec.reserve(stdr::size(submit_infos)); - for (auto&& submit_info : submit_infos) { - auto& wait_semaphores = wait_semaphores_buf.emplace_back(std::from_range, - submit_info.wait_semaphores - | stdv::transform(vk::monadic::to_vk())); - - auto& - wait_dst_stages = wait_dst_stages_buf - .emplace_back(std::from_range, - submit_info.wait_dst_stages - | stdv::transform(vk::monadic::to_vk())); - - auto& command_buffers = command_buffers_buf.emplace_back(std::from_range, - submit_info.command_buffers - | stdv::transform(vk::monadic::to_vk())); - - auto& signal_semaphores = signal_semaphores_buf.emplace_back(std::from_range, - submit_info.signal_semaphores - | stdv::transform(vk::monadic::to_vk())); - - vec.emplace_back(SubmitInfoRange { - .wait_semaphores = wait_semaphores, - .wait_dst_stages = wait_dst_stages, - .command_buffers = command_buffers, - .signal_semaphores = signal_semaphores, - }); - } - return vec; - }(); - - const auto vk_submit_infos = submit_ranges - | stdv::transform([](auto&& submit_range) noexcept { - EXPECTS(stdr::size(submit_range.wait_semaphores) - == stdr::size(submit_range.wait_dst_stages)); - - return VkSubmitInfo { - .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, - .pNext = nullptr, - .waitSemaphoreCount = as(stdr::size(submit_range.wait_semaphores)), - .pWaitSemaphores = stdr::data(submit_range.wait_semaphores), - .pWaitDstStageMask = stdr::data(submit_range.wait_dst_stages), - .commandBufferCount = as(stdr::size(submit_range.command_buffers)), - .pCommandBuffers = stdr::data(submit_range.command_buffers), - .signalSemaphoreCount = as(stdr::size(submit_range - .signal_semaphores)), - .pSignalSemaphores = stdr::data(submit_range.signal_semaphores), - }; - }) - | stdr::to(); - - const auto vk_fence = either(fence, vk::monadic::to_vk(), core::monadic::init(VK_NULL_HANDLE)); - - const auto& device = queue.device(); - const auto& device_table = device.device_table(); - return vk::call_checked(device_table.vkQueueSubmit, - queue, - stdr::size(vk_submit_infos), - stdr::data(vk_submit_infos), - vk_fence); - } - - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto present(const QueueType& queue, - std::span swapchains, - std::span wait_semaphores, - std::span image_indices) noexcept -> Expected { - EXPECTS(stdr::size(wait_semaphores) >= 1); - EXPECTS(stdr::size(image_indices) >= 1); - - const auto swapchains_count = stdr::size(swapchains); - const auto wait_semaphores_count = stdr::size(wait_semaphores); - - const auto bytes_count = swapchains_count * sizeof(VkSwapchainKHR) + wait_semaphores_count * sizeof(VkSemaphore); - auto memory_resource = stdp::monotonic_buffer_resource { bytes_count }; - - const auto vk_swapchains = stdp::vector { std::from_range, - swapchains | stdv::transform(vk::monadic::to_vk()), - &memory_resource }; - const auto vk_semaphores = stdp::vector { std::from_range, - wait_semaphores | stdv::transform(vk::monadic::to_vk()), - &memory_resource }; - - const auto present_info = VkPresentInfoKHR { - .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, - .pNext = nullptr, - .waitSemaphoreCount = as(stdr::size(vk_semaphores)), - .pWaitSemaphores = stdr::data(vk_semaphores), - .swapchainCount = as(stdr::size(vk_swapchains)), - .pSwapchains = stdr::data(vk_swapchains), - .pImageIndices = stdr::data(image_indices), - .pResults = nullptr, - }; - - const auto& device = queue.device(); - const auto& device_table = device.device_table(); - const auto - result = Try((vk::call_checked(device_table - .vkQueuePresentKHR, - queue, - &present_info))); - Return vk::from_vk(result); - } - }; - } // namespace - ///////////////////////////////////// ///////////////////////////////////// - auto Queue::wait_idle() const noexcept -> Expected { - return QueueAPI::wait_idle(*this); + template + auto QueueInterface::wait_idle() const noexcept -> Expected { + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + return vk::call_checked(device_table.vkQueueWaitIdle, *this); } ///////////////////////////////////// ///////////////////////////////////// - auto Queue::present(std::span swapchains, - std::span wait_semaphores, - std::span image_indices) const noexcept -> Expected { - return QueueAPI::present(*this, std::move(swapchains), std::move(wait_semaphores), std::move(image_indices)); + template + auto QueueInterface::submit(std::span submit_infos, std::optional fence) const noexcept + -> Expected { + struct SubmitInfoRange { + std::span wait_semaphores; + std::span wait_dst_stages; + std::span command_buffers; + std::span signal_semaphores; + }; + + const auto bytes_count = [&submit_infos] noexcept { + auto _wait_semaphores_count = 0uz; + auto _wait_dst_stages_count = 0uz; + auto _command_buffers_count = 0uz; + auto _signal_semaphores_count = 0uz; + + for (auto&& submit_info : submit_infos) { + _wait_semaphores_count = stdr::size(submit_info.wait_semaphores); + _wait_dst_stages_count = stdr::size(submit_info.wait_dst_stages); + _command_buffers_count = stdr::size(submit_info.command_buffers); + _signal_semaphores_count = stdr::size(submit_info.signal_semaphores); + } + return _wait_semaphores_count * sizeof(VkSemaphore) + + _wait_dst_stages_count * sizeof(VkPipelineStageFlags) + + _command_buffers_count * sizeof(VkCommandBuffer) + + _signal_semaphores_count * sizeof(VkSemaphore) + + stdr::size(submit_infos) * sizeof(SubmitInfoRange); + }(); + + auto memory_resource = stdp::monotonic_buffer_resource { bytes_count }; + + auto wait_semaphores_buf = stdp::vector> { &memory_resource }; + wait_semaphores_buf.reserve(stdr::size(submit_infos)); + auto wait_dst_stages_buf = stdp::vector> { &memory_resource }; + wait_dst_stages_buf.reserve(stdr::size(submit_infos)); + auto command_buffers_buf = stdp::vector> { &memory_resource }; + command_buffers_buf.reserve(stdr::size(submit_infos)); + auto signal_semaphores_buf = stdp::vector> { &memory_resource }; + signal_semaphores_buf.reserve(stdr::size(submit_infos)); + + const auto submit_ranges = [&] noexcept { + auto vec = stdp::vector { &memory_resource }; + vec.reserve(stdr::size(submit_infos)); + for (auto&& submit_info : submit_infos) { + auto& wait_semaphores = wait_semaphores_buf + .emplace_back(std::from_range, + submit_info.wait_semaphores | stdv::transform(vk::monadic::to_vk())); + + auto& wait_dst_stages = wait_dst_stages_buf + .emplace_back(std::from_range, + submit_info.wait_dst_stages + | stdv::transform(vk::monadic::to_vk())); + + auto& command_buffers = command_buffers_buf + .emplace_back(std::from_range, + submit_info.command_buffers | stdv::transform(vk::monadic::to_vk())); + + auto& signal_semaphores = signal_semaphores_buf + .emplace_back(std::from_range, + submit_info.signal_semaphores | stdv::transform(vk::monadic::to_vk())); + + vec.emplace_back(SubmitInfoRange { + .wait_semaphores = wait_semaphores, + .wait_dst_stages = wait_dst_stages, + .command_buffers = command_buffers, + .signal_semaphores = signal_semaphores, + }); + } + return vec; + }(); + + const auto vk_submit_infos = submit_ranges + | stdv::transform([](auto&& submit_range) noexcept { + EXPECTS(stdr::size(submit_range.wait_semaphores) + == stdr::size(submit_range.wait_dst_stages)); + + return VkSubmitInfo { + .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .pNext = nullptr, + .waitSemaphoreCount = as(stdr::size(submit_range.wait_semaphores)), + .pWaitSemaphores = stdr::data(submit_range.wait_semaphores), + .pWaitDstStageMask = stdr::data(submit_range.wait_dst_stages), + .commandBufferCount = as(stdr::size(submit_range.command_buffers)), + .pCommandBuffers = stdr::data(submit_range.command_buffers), + .signalSemaphoreCount = as(stdr::size(submit_range.signal_semaphores)), + .pSignalSemaphores = stdr::data(submit_range.signal_semaphores), + }; + }) + | stdr::to(); + + const auto vk_fence = either(fence, vk::monadic::to_vk(), core::monadic::init(VK_NULL_HANDLE)); + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + return vk::call_checked(device_table.vkQueueSubmit, + *this, + stdr::size(vk_submit_infos), + stdr::data(vk_submit_infos), + vk_fence); } ///////////////////////////////////// ///////////////////////////////////// - auto Queue::submit(std::span submit_infos, std::optional fence) const noexcept - -> Expected { - return QueueAPI::submit(*this, std::move(submit_infos), std::move(fence)); + template + auto QueueInterface::present(std::span swapchains, + std::span wait_semaphores, + std::span image_indices) const noexcept -> Expected { + EXPECTS(stdr::size(wait_semaphores) >= 1); + EXPECTS(stdr::size(image_indices) >= 1); + + const auto swapchains_count = stdr::size(swapchains); + const auto wait_semaphores_count = stdr::size(wait_semaphores); + + const auto bytes_count = swapchains_count * sizeof(VkSwapchainKHR) + wait_semaphores_count * sizeof(VkSemaphore); + auto memory_resource = stdp::monotonic_buffer_resource { bytes_count }; + + const auto vk_swapchains = stdp::vector { std::from_range, + swapchains | stdv::transform(vk::monadic::to_vk()), + &memory_resource }; + const auto vk_semaphores = stdp::vector { std::from_range, + wait_semaphores | stdv::transform(vk::monadic::to_vk()), + &memory_resource }; + + const auto present_info = VkPresentInfoKHR { + .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, + .pNext = nullptr, + .waitSemaphoreCount = as(stdr::size(vk_semaphores)), + .pWaitSemaphores = stdr::data(vk_semaphores), + .swapchainCount = as(stdr::size(vk_swapchains)), + .pSwapchains = stdr::data(vk_swapchains), + .pImageIndices = stdr::data(image_indices), + .pResults = nullptr, + }; + + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + const auto result = Try((vk::call_checked(device_table + .vkQueuePresentKHR, + *this, + &present_info))); + Return vk::from_vk(result); } + template class QueueInterface; + template class QueueInterface; + ///////////////////////////////////// ///////////////////////////////////// - auto Queue::do_init(PrivateTag, const Device::QueueEntry& entry) -> void { + auto QueueImplementation::do_init(PrivateTag, const QueueEntry& entry) -> void { m_entry = entry; - const auto& device = this->device(); + const auto& device = owner(); const auto& device_table = device.device_table(); m_vk_handle = vk::call(device_table.vkGetDeviceQueue, device, m_entry.id, 0); } - - namespace view { - ///////////////////////////////////// - ///////////////////////////////////// - auto Queue::wait_idle() const noexcept -> Expected { - return QueueAPI::wait_idle(*this); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto Queue::present(std::span swapchains, - std::span wait_semaphores, - std::span image_indices) const noexcept -> Expected { - return QueueAPI::present(*this, std::move(swapchains), std::move(wait_semaphores), std::move(image_indices)); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto Queue::submit(std::span submit_infos, std::optional fence) const noexcept - -> Expected { - return QueueAPI::submit(*this, std::move(submit_infos), std::move(fence)); - } - } // namespace view } // namespace stormkit::gpu diff --git a/src/gpu/execution/render_pass.cpp b/src/gpu/execution/render_pass.cpp index 5cb737f85..515dd7fe9 100644 --- a/src/gpu/execution/render_pass.cpp +++ b/src/gpu/execution/render_pass.cpp @@ -31,12 +31,15 @@ namespace stormkit::gpu { } } // namespace monadic + template class RenderPassInterface; + template class RenderPassInterface; + ///////////////////////////////////// ///////////////////////////////////// - auto RenderPass::do_init(PrivateTag, const RenderPassDescription& description) noexcept -> Expected { - m_description = description; + auto RenderPassImplementation::do_init(PrivateTag, const RenderPassDescription& description) noexcept -> Expected { + m_description = core::allocate_unsafe(description); - const auto attachments = transform(m_description.attachments, [](auto&& attachment) static noexcept { + const auto attachments = transform(m_description->attachments, [](auto&& attachment) static noexcept { return VkAttachmentDescription { .flags = 0, .format = vk::to_vk(attachment.format), @@ -56,12 +59,12 @@ namespace stormkit::gpu { auto subpasses = std::vector {}; auto subpasses_deps = std::vector {}; - color_attachment_refs.reserve(stdr::size(m_description.subpasses)); - resolve_attachment_refs.reserve(stdr::size(m_description.subpasses)); - subpasses.reserve(stdr::size(m_description.subpasses)); - subpasses_deps.reserve(stdr::size(m_description.subpasses)); + color_attachment_refs.reserve(stdr::size(m_description->subpasses)); + resolve_attachment_refs.reserve(stdr::size(m_description->subpasses)); + subpasses.reserve(stdr::size(m_description->subpasses)); + subpasses_deps.reserve(stdr::size(m_description->subpasses)); - for (const auto& subpass : m_description.subpasses) { + for (const auto& subpass : m_description->subpasses) { auto& color_attachment_ref = color_attachment_refs .emplace_back(transform(subpass.color_attachment_refs, monadic::vk_ref())); auto& resolve_attachment_ref = resolve_attachment_refs @@ -104,7 +107,7 @@ namespace stormkit::gpu { .pDependencies = stdr::data(subpasses_deps), }; - const auto& device = this->device(); + const auto& device = owner(); const auto& device_table = device.device_table(); m_vk_handle = Try(vk::call_checked(device_table.vkCreateRenderPass, device, &create_info, nullptr)); diff --git a/src/gpu/execution/swapchain.cpp b/src/gpu/execution/swapchain.cpp index 26863cffe..5bfd6f9bb 100644 --- a/src/gpu/execution/swapchain.cpp +++ b/src/gpu/execution/swapchain.cpp @@ -69,39 +69,38 @@ namespace stormkit::gpu { return image_count; } - - struct SwapChainAPI { - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto acquire_next_image(const SwapChainType& swapchain, - std::chrono::nanoseconds wait, - view::Semaphore&& image_available) noexcept -> Expected { - const auto& device = swapchain.device(); - const auto& device_table = device.device_table(); - - auto id = u32 { 0 }; - const auto - result = Try((vk::call_checked(device_table - .vkAcquireNextImageKHR, - device, - swapchain, - wait.count(), - image_available, - nullptr, - &id))); - Return SwapChain::NextImage { .result = vk::from_vk(result), .id = id }; - } - }; } // namespace ///////////////////////////////////// ///////////////////////////////////// - auto SwapChain::do_init(PrivateTag, - view::Surface&& surface, - const math::uextent2& extent, - VkSwapchainKHR old_swapchain) noexcept -> Expected { - const auto& device = this->device(); + template + auto SwapChainInterface::acquire_next_image(std::chrono::nanoseconds wait, + view::Semaphore image_available) const noexcept -> Expected { + const auto& device = Base::owner(); + const auto& device_table = device.device_table(); + + auto id = u32 { 0 }; + const auto result = Try((vk::call_checked(device_table + .vkAcquireNextImageKHR, + device, + *this, + wait.count(), + image_available, + nullptr, + &id))); + Return SwapChain::NextImage { .result = vk::from_vk(result), .id = id }; + } + + template class SwapChainInterface; + template class SwapChainInterface; + + ///////////////////////////////////// + ///////////////////////////////////// + auto SwapChainImplementation::do_init(PrivateTag, + view::Surface surface, + const math::uextent2& extent, + VkSwapchainKHR old_swapchain) noexcept -> Expected { + const auto& device = owner(); const auto& device_table = device.device_table(); const auto& physical_device = device.physical_device(); @@ -163,20 +162,4 @@ namespace stormkit::gpu { Return {}; } - - ///////////////////////////////////// - ///////////////////////////////////// - auto SwapChain::acquire_next_image(std::chrono::nanoseconds wait, view::Semaphore image_available) const noexcept - -> Expected { - return SwapChainAPI::acquire_next_image(*this, std::move(wait), std::move(image_available)); - } - - namespace view { - ///////////////////////////////////// - ///////////////////////////////////// - auto SwapChain::acquire_next_image(std::chrono::nanoseconds wait, Semaphore image_available) const noexcept - -> Expected { - return SwapChainAPI::acquire_next_image(*this, std::move(wait), std::move(image_available)); - } - } // namespace view } // namespace stormkit::gpu diff --git a/src/gpu/resource/buffer.cpp b/src/gpu/resource/buffer.cpp index ca4be7b4e..b16485af2 100644 --- a/src/gpu/resource/buffer.cpp +++ b/src/gpu/resource/buffer.cpp @@ -18,108 +18,89 @@ import stormkit.core; import stormkit.gpu.core; namespace stormkit::gpu { - struct BufferAPI { - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto map(BufferType& buffer, ioffset offset) noexcept -> Expected { - EXPECTS(buffer.allocation() and buffer.native_handle()); - EXPECTS(offset < as(buffer.size())); - - const auto& device = buffer.device(); - const auto& allocator = device.allocator(); - const auto& allocation = buffer.allocation(); - - auto ptr = Try(vk::call_checked(vmaMapMemory, allocator, allocation)); - - buffer.m_mapped_pointer = std::bit_cast(ptr); - buffer.m_mapped_pointer += offset; - return buffer.m_mapped_pointer; - } + ///////////////////////////////////// + ///////////////////////////////////// + template + auto BufferInterface::map(ioffset offset) noexcept -> Expected { + EXPECTS(allocation() and Base::native_handle()); + EXPECTS(offset < as(size())); - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto flush(const BufferType& buffer, ioffset offset, usize size) noexcept -> Expected { - EXPECTS(buffer.allocation() and buffer.native_handle()); - EXPECTS(offset <= as(buffer.size())); - EXPECTS(size <= buffer.size()); + const auto& device = Base::owner(); + const auto& allocator = device.allocator(); + const auto& allocation = this->allocation(); - const auto& device = buffer.device(); - const auto& allocator = device.allocator(); - const auto& allocation = buffer.allocation(); + auto ptr = Try(vk::call_checked(vmaMapMemory, allocator, allocation)); - return vk::call_checked(vmaFlushAllocation, allocator, allocation, offset, size); - } + Base::m_mapped_pointer = std::bit_cast(ptr); + Base::m_mapped_pointer += offset; + return Base::m_mapped_pointer; + } - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto unmap(BufferType& buffer) noexcept -> void { - EXPECTS(buffer.allocation() and buffer.native_handle()); - // expects(buffer.is_persistently_mapped(), "unmapping persistent buffer !"); + ///////////////////////////////////// + ///////////////////////////////////// + template + auto BufferInterface::flush(ioffset offset, usize size) const noexcept -> Expected { + EXPECTS(allocation() and Base::native_handle()); + EXPECTS(offset <= as(this->size())); + EXPECTS(size <= this->size()); - const auto& device = buffer.device(); - const auto& allocator = device.allocator(); - const auto& allocation = buffer.allocation(); + const auto& device = Base::owner(); + const auto& allocator = device.allocator(); + const auto& allocation = this->allocation(); - vk::call(vmaUnmapMemory, allocator, allocation); + return vk::call_checked(vmaFlushAllocation, allocator, allocation, offset, size); + } - buffer.m_mapped_pointer = nullptr; - } + ///////////////////////////////////// + ///////////////////////////////////// + template + auto BufferInterface::unmap() noexcept -> void { + if (not mapped()) return; - ///////////////////////////////////// - ///////////////////////////////////// - template - static auto upload(BufferType& buffer, std::span data, ioffset offset) noexcept -> Expected { - EXPECTS(stdr::size(data) <= buffer.size()); + if constexpr (cmeta::SameAs) + if (is_persistently_mapped()) return; - if (buffer.is_persistently_mapped()) { - stdr::copy(data, buffer.m_mapped_pointer); - Return {}; - } + EXPECTS(allocation() and Base::native_handle()); - auto gpu_data = Try(buffer.map(offset, stdr::size(data))); - stdr::copy(data, stdr::begin(gpu_data)); - buffer.unmap(); + const auto& device = Base::owner(); + const auto& allocator = device.allocator(); + const auto& allocation = this->allocation(); - Return {}; - } - }; + vk::call(vmaUnmapMemory, allocator, allocation); - ///////////////////////////////////// - ///////////////////////////////////// - auto Buffer::map(ioffset offset) noexcept -> Expected { - return BufferAPI::map(*this, offset); + Base::m_mapped_pointer = nullptr; } ///////////////////////////////////// ///////////////////////////////////// - auto Buffer::flush(ioffset offset, usize size) noexcept -> Expected { - return BufferAPI::flush(*this, offset, size); - } + template + auto BufferInterface::upload(std::span data, ioffset offset) noexcept -> Expected { + EXPECTS(stdr::size(data) <= this->size()); - ///////////////////////////////////// - ///////////////////////////////////// - auto Buffer::unmap() noexcept -> void { - return BufferAPI::unmap(*this); - } + if (is_persistently_mapped()) { + stdr::copy(data, Base::m_mapped_pointer); + Return {}; + } - ///////////////////////////////////// - ///////////////////////////////////// - auto Buffer::upload(std::span data, ioffset offset) noexcept -> Expected { - return BufferAPI::upload(*this, std::move(data), offset); + auto gpu_data = Try(map(offset, stdr::size(data))); + stdr::copy(data, stdr::begin(gpu_data)); + unmap(); + + Return {}; } + template class BufferInterface; + template class BufferInterface; + ///////////////////////////////////// ///////////////////////////////////// - auto Buffer::do_init(PrivateTag, const CreateInfo& _create_info) noexcept -> Expected { + auto BufferImplementation::do_init(PrivateTag, const CreateInfo& _create_info) noexcept -> Expected { m_usages = _create_info.usages; m_size = _create_info.size; m_memory_properties = _create_info.properties; m_is_persistently_mapped = _create_info.persistently_mapped; - const auto& device = this->device(); + const auto& device = owner(); const auto& device_table = device.device_table(); const auto create_info = VkBufferCreateInfo { .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, @@ -152,50 +133,27 @@ namespace stormkit::gpu { m_vma_allocation = std::move(out); Try(vk::call_checked(vmaBindBufferMemory, allocator, m_vma_allocation, m_vk_handle)); - if (m_is_persistently_mapped) Try(map(0u)); - - Return {}; - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto Buffer::find_memory_type(u32 type_filter, - VkMemoryPropertyFlagBits properties, - const VkPhysicalDeviceMemoryProperties& mem_properties, - const VkMemoryRequirements&) noexcept -> u32 { - for (const auto i : range(mem_properties.memoryTypeCount)) { - if ((type_filter & (1 << i)) - and (check_flag_bit(static_cast(mem_properties.memoryTypes[i].propertyFlags), - properties))) - return i; + if (m_is_persistently_mapped) { + auto ptr = Try(vk::call_checked(vmaMapMemory, allocator, m_vma_allocation)); + m_mapped_pointer = std::bit_cast(ptr); } - return 0; + Return {}; } - namespace view { - ///////////////////////////////////// - ///////////////////////////////////// - auto Buffer::map(ioffset offset) noexcept -> Expected { - return BufferAPI::map(*this, offset); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto Buffer::flush(ioffset offset, usize size) noexcept -> Expected { - return BufferAPI::flush(*this, offset, size); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto Buffer::unmap() noexcept -> void { - return BufferAPI::unmap(*this); - } - - ///////////////////////////////////// - ///////////////////////////////////// - auto Buffer::upload(std::span data, ioffset offset) noexcept -> Expected { - return BufferAPI::upload(*this, std::move(data), offset); - } - } // namespace view + // ///////////////////////////////////// + // ///////////////////////////////////// + // auto BufferImplementation::find_memory_type(u32 type_filter, + // VkMemoryPropertyFlagBits properties, + // const VkPhysicalDeviceMemoryProperties& mem_properties, + // const VkMemoryRequirements&) noexcept -> u32 { + // for (const auto i : range(mem_properties.memoryTypeCount)) { + // if ((type_filter & (1 << i)) + // and (check_flag_bit(static_cast(mem_properties.memoryTypes[i].propertyFlags), + // properties))) + // return i; + // } + + // return 0; + // } } // namespace stormkit::gpu diff --git a/src/gpu/resource/image.cpp b/src/gpu/resource/image.cpp index ebb25a093..274610fe8 100644 --- a/src/gpu/resource/image.cpp +++ b/src/gpu/resource/image.cpp @@ -82,9 +82,12 @@ namespace stormkit::gpu { // } } // namespace + template class ImageInterface; + template class ImageInterface; + ///////////////////////////////////// ///////////////////////////////////// - auto Image::do_init(PrivateTag, const CreateInfo& _create_info) noexcept -> Expected { + auto ImageImplementation::do_init(PrivateTag, const CreateInfo& _create_info) noexcept -> Expected { m_extent = _create_info.extent; m_format = _create_info.format; m_layers = _create_info.layers; @@ -114,7 +117,7 @@ namespace stormkit::gpu { .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, }; - const auto& device = this->device(); + const auto& device = owner(); m_vk_handle = Try(vk::call_checked(device.device_table().vkCreateImage, device, &create_info, nullptr)); diff --git a/src/gpu/resource/image_view.cpp b/src/gpu/resource/image_view.cpp index fce96904f..187236712 100644 --- a/src/gpu/resource/image_view.cpp +++ b/src/gpu/resource/image_view.cpp @@ -18,12 +18,15 @@ import stormkit.core; import stormkit.gpu.core; namespace stormkit::gpu { + template class ImageViewInterface; + template class ImageViewInterface; + ///////////////////////////////////// ///////////////////////////////////// - auto ImageView::do_init(PrivateTag, - view::Image image, - ImageViewType type, - const ImageSubresourceRange& subresource_range) noexcept -> Expected { + auto ImageViewImplementation::do_init(PrivateTag, + view::Image image, + ImageViewType type, + const ImageSubresourceRange& subresource_range) noexcept -> Expected { m_type = type; m_subresource_range = subresource_range; @@ -49,7 +52,7 @@ namespace stormkit::gpu { .subresourceRange = vk_subresource_range, }; - const auto& device = this->device(); + const auto device = owner(); m_vk_handle = Try(vk::call_checked(device.device_table().vkCreateImageView, device, &create_info, nullptr)); Return {}; diff --git a/src/gpu/resource/sampler.cpp b/src/gpu/resource/sampler.cpp index c4d0bc1ed..1c193a5d4 100644 --- a/src/gpu/resource/sampler.cpp +++ b/src/gpu/resource/sampler.cpp @@ -17,9 +17,12 @@ import stormkit.core; import stormkit.gpu.core; namespace stormkit::gpu { + template class SamplerInterface; + template class SamplerInterface; + ///////////////////////////////////// ///////////////////////////////////// - auto Sampler::do_init(PrivateTag, const Settings& settings) noexcept -> Expected { + auto SamplerImplementation::do_init(PrivateTag, const Settings& settings) noexcept -> Expected { m_settings = settings; const auto create_info = VkSamplerCreateInfo { .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, @@ -41,7 +44,7 @@ namespace stormkit::gpu { .borderColor = vk::to_vk(m_settings.border_color), .unnormalizedCoordinates = m_settings.unnormalized_coordinates }; - const auto& device = this->device(); + const auto& device = owner(); m_vk_handle = Try(vk::call_checked(device.device_table().vkCreateSampler, device, &create_info, nullptr)); Return {}; diff --git a/src/gpu/resource/shader.cpp b/src/gpu/resource/shader.cpp index 8aadfcd1e..c9ebecb96 100644 --- a/src/gpu/resource/shader.cpp +++ b/src/gpu/resource/shader.cpp @@ -18,9 +18,12 @@ import stormkit.gpu.core; ; namespace stormkit::gpu { + template class ShaderInterface; + template class ShaderInterface; + ///////////////////////////////////// ///////////////////////////////////// - auto Shader::do_init(PrivateTag, std::vector data, ShaderStageFlag type) -> Expected { + auto ShaderImplementation::do_init(PrivateTag, std::vector&& data, ShaderStageFlag type) -> Expected { m_source = std::move(data); m_type = type; @@ -32,46 +35,11 @@ namespace stormkit::gpu { .pCode = stdr::data(m_source) }; - const auto& device = this->device(); + const auto& device = owner(); m_vk_handle = Try(vk::call_checked(device.device_table().vkCreateShaderModule, device, &create_info, nullptr)); Return {}; } - - ///////////////////////////////////// - ///////////////////////////////////// - auto Shader::reflect() noexcept -> void { -#ifdef STORMKIT_ENABLE_SPIRV_INTROSPECT - auto ir = std::vector {}; - ir.resize(std::size(m_source) / sizeof(SpirvID)); - std::memcpy(std::data(ir), std::data(m_source), std::size(m_source)); - - auto compiler = spirv_cross::CompilerGLSL { std::move(ir) }; - const auto add_bindings = [this, &compiler](span resources, gpu::DescriptorType type) { - for (const auto& resource : resources) { - /*const auto set = - spvc_compiler_get_decoration(compiler, resources[i].id, - SpvDecorationDescriptorSet);*/ - const auto binding = compiler.get_decoration(resource.id, spv::DecorationBinding); - // const auto name = spvc_compiler_get_name(compiler, resources[i].id); - - m_descriptor_set_layout - .addBinding({ binding, - type, - gpu::ShaderStageFlag::Vertex | gpu::ShaderStageFlag::Fragment | gpu::ShaderStageFlag::Compute, - 1 }); - } - }; - - auto resources = compiler.get_shader_resources(); - add_bindings(resources.uniform_buffers, DescriptorType::Uniform_Buffer); - add_bindings(resources.storage_buffers, DescriptorType::Storage_Buffer); - add_bindings(resources.sampled_images, DescriptorType::Sampled_Image); - add_bindings(resources.storage_images, DescriptorType::Storage_Image); - -#endif - // m_descriptor_set_layout.bake(); - } } // namespace stormkit::gpu From 237339e57b677e6aadfcf4eb6aad80ba131edbb3 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 25 Mar 2026 21:56:36 +0100 Subject: [PATCH 175/194] (entities) remove UB --- modules/stormkit/entities.cppm | 4 ++-- src/entities/entity_manager.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/stormkit/entities.cppm b/modules/stormkit/entities.cppm index d6f9e0d48..5f3fea0c7 100644 --- a/modules/stormkit/entities.cppm +++ b/modules/stormkit/entities.cppm @@ -317,7 +317,7 @@ namespace stormkit::entities { auto _component = add_raw_component(entity, component.type(), as_bytes(std::forward(component)), - [](auto ptr) static noexcept { std::bit_cast(ptr)->~PureT(); }); + [](auto ptr) static noexcept { std::launder(std::bit_cast(ptr))->~PureT(); }); return bytes_mut_as(_component); } @@ -567,7 +567,7 @@ namespace stormkit::entities { auto component_it = stdr::data(components); for (;;) { - auto e = *std::bit_cast(component_it); + auto e = *std::launder(std::bit_cast(component_it)); if (e != entity) { component_it += sizeof(Entity) + size; continue; diff --git a/src/entities/entity_manager.cpp b/src/entities/entity_manager.cpp index 8471befb8..1a4868fa7 100644 --- a/src/entities/entity_manager.cpp +++ b/src/entities/entity_manager.cpp @@ -91,7 +91,7 @@ namespace stormkit::entities { auto component_it = stdr::begin(components); for (;;) { - auto e = *std::bit_cast(&*component_it); + auto e = *std::launder(std::bit_cast(&*component_it)); if (e == entity) break; From 8487949ab136dd4a05bca97de19e630805bf86ac Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 25 Mar 2026 21:56:45 +0100 Subject: [PATCH 176/194] (core) format --- modules/stormkit/core/utils/filesystem.cppm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/stormkit/core/utils/filesystem.cppm b/modules/stormkit/core/utils/filesystem.cppm index bdd13cdf0..2df73be60 100644 --- a/modules/stormkit/core/utils/filesystem.cppm +++ b/modules/stormkit/core/utils/filesystem.cppm @@ -76,8 +76,7 @@ export { namespace io { template - class Descriptor final: TemplatedNamedConstructorHelper, - protected UseNamedConstructors, Expected> { + class Descriptor final: protected UseNamedConstructors, Expected> { public: static auto open(const stdfs::path& path, Access access) noexcept -> Expected; static auto allocate_and_open(const stdfs::path& path, Access access) noexcept -> Expected; From d2f250eec6941ef7f68b8e4e7287bc37a9645c85 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 25 Mar 2026 21:57:17 +0100 Subject: [PATCH 177/194] (core) improve ReturnType query --- modules/stormkit/core/meta/type_query.cppm | 64 ++++++++++++++++++---- 1 file changed, 54 insertions(+), 10 deletions(-) diff --git a/modules/stormkit/core/meta/type_query.cppm b/modules/stormkit/core/meta/type_query.cppm index 04b777c93..57c5f05a0 100644 --- a/modules/stormkit/core/meta/type_query.cppm +++ b/modules/stormkit/core/meta/type_query.cppm @@ -74,18 +74,62 @@ namespace stormkit { inline namespace core { namespace meta { template struct ContainedOrPointedType: PointedType {}; - template - struct ReturnType; + template + struct CallableTrait; - template - struct ReturnType { - using Type = R; + template + struct SignatureTrait { + using ReturnType = Return; + // using ArgumentsTypes = std::tuple; }; - template - struct ReturnType { - using Type = R; - }; + template + struct CallableTrait: SignatureTrait {}; + + template + struct CallableTrait: SignatureTrait {}; + + template + struct CallableTrait: CallableTrait {}; + + template + struct CallableTrait: CallableTrait {}; + + template + struct CallableTrait: CallableTrait {}; + + template + struct CallableTrait: CallableTrait {}; + + template + struct CallableTrait: CallableTrait {}; + + template + struct CallableTrait: CallableTrait {}; + + template + struct CallableTrait: CallableTrait {}; + + template + struct CallableTrait: CallableTrait {}; + + template + struct CallableTrait: CallableTrait {}; + + template + struct CallableTrait: CallableTrait {}; + + template + struct CallableTrait: CallableTrait {}; + + template + struct CallableTrait: CallableTrait {}; + + template + struct CallableTrait: CallableTrait {}; + + template + struct CallableTrait: CallableTrait {}; template concept HasStdValueType = requires() { typename T::value_type; }; @@ -145,7 +189,7 @@ namespace stormkit { inline namespace core { namespace meta { using ContainedOrPointedType = details::ContainedOrPointedType::Type; template - using ReturnType = details::ReturnType::Type; + using ReturnType = details::CallableTrait::ReturnType; template using ExpectedType = typename T::ExpectedType; From 0cd84b53c3b8423e697775d89fa9a3a378e3505c Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 25 Mar 2026 21:57:24 +0100 Subject: [PATCH 178/194] (core) improve named constructors --- modules/stormkit/core/named_constructors.cppm | 171 ++++++++++++------ 1 file changed, 120 insertions(+), 51 deletions(-) diff --git a/modules/stormkit/core/named_constructors.cppm b/modules/stormkit/core/named_constructors.cppm index 5b7d02357..eb0e4f542 100644 --- a/modules/stormkit/core/named_constructors.cppm +++ b/modules/stormkit/core/named_constructors.cppm @@ -16,15 +16,6 @@ import :utils.allocation; namespace stormkit { inline namespace core { export { - struct TemplatedNamedConstructorHelper { - protected: - static constexpr struct PrivateTag { - } PRIVATE; - - template - friend class UseNamedConstructors; - }; - namespace meta { template concept HasCreateAllocateProtected = requires() { @@ -43,6 +34,22 @@ namespace stormkit { inline namespace core { } export { + struct PrivateTagBase { + struct Tag { + private: + Tag() = default; + friend struct PrivateTagBase; + }; + + private: + static constexpr auto PRIVATE = Tag {}; + + template + friend class UseNamedConstructors; + }; + + using PrivateTag = PrivateTagBase::Tag; + template, meta::DoInitExpectedType, void>, typename... ConstructorArgs> @@ -59,31 +66,54 @@ namespace stormkit { inline namespace core { constexpr UseNamedConstructors(UseNamedConstructors&&) noexcept; constexpr auto operator=(UseNamedConstructors&&) noexcept -> UseNamedConstructors&; + // template + // requires(sizeof...(ConstructorArgs_) == sizeof...(ConstructorArgs) + // and (std::constructible_from and ...) + // and meta::IsStdExpected) + // [[nodiscard]] + // static constexpr auto create(ConstructorArgs_&&... c_args, Args&&... args) noexcept + // -> meta::TransformExpectedValueTo; + template - requires(meta::IsStdExpected) [[nodiscard]] - static constexpr auto create(ConstructorArgs... c_args, Args&&... args) noexcept - -> meta::TransformExpectedValueTo; + static constexpr auto create(ConstructorArgs... c_args, Args&&... args) noexcept -> ValueType; template - requires(not meta::IsStdExpected) [[nodiscard]] - static constexpr auto create(ConstructorArgs... c_args, Args&&... args) noexcept -> ValueType; + static constexpr auto allocate(ConstructorArgs... c_args, Args&&... args) noexcept -> Heap; + + protected: + static constexpr auto PRIVATE = PrivateTagBase::PRIVATE; + + constexpr UseNamedConstructors() noexcept; + }; + + template + class UseNamedConstructors { + using ValueType = T; + using RetType = DoInitRetType; + + public: + constexpr ~UseNamedConstructors() noexcept; + + constexpr UseNamedConstructors(const UseNamedConstructors&) noexcept; + constexpr auto operator=(const UseNamedConstructors&) noexcept -> UseNamedConstructors&; + + constexpr UseNamedConstructors(UseNamedConstructors&&) noexcept; + constexpr auto operator=(UseNamedConstructors&&) noexcept -> UseNamedConstructors&; template - requires(meta::IsStdExpected) [[nodiscard]] - static constexpr auto allocate(ConstructorArgs... c_args, Args&&... args) noexcept - -> meta::TransformExpectedValueTo, RetType>; + static constexpr auto create(ConstructorArgs... c_args, Args&&... args) noexcept -> decltype(auto); + // -> meta::TransformExpectedValueTo; template - requires(not meta::IsStdExpected) [[nodiscard]] - static constexpr auto allocate(ConstructorArgs... c_args, Args&&... args) noexcept -> Heap; + static constexpr auto allocate(ConstructorArgs... c_args, Args&&... args) noexcept -> decltype(auto); + // -> meta::TransformExpectedValueTo, RetType>; protected: - using PrivateTag = TemplatedNamedConstructorHelper::PrivateTag; - static constexpr auto PRIVATE = TemplatedNamedConstructorHelper::PRIVATE; + static constexpr auto PRIVATE = PrivateTagBase::PRIVATE; constexpr UseNamedConstructors() noexcept; }; @@ -139,62 +169,101 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template template - requires(meta::IsStdExpected) STORMKIT_FORCE_INLINE constexpr auto UseNamedConstructors::create(ConstructorArgs... c_args, - Args&&... args) noexcept - -> meta::TransformExpectedValueTo { - using ReturnValue = meta::TransformExpectedValueTo; - - auto out_expected = ReturnValue { std::in_place, PRIVATE, c_args... }; - if (auto result = out_expected.value().do_init(PRIVATE, std::forward(args)...); not result) - out_expected = ReturnValue { std::unexpect, std::move(result).error() }; - - return out_expected; + Args&&... args) noexcept -> ValueType { + auto out = ValueType { PrivateTagBase::PRIVATE, std::forward(c_args)... }; + out.do_init(PrivateTagBase::PRIVATE, std::forward(args)...); + return out; } ///////////////////////////////////// ///////////////////////////////////// template template - requires(not meta::IsStdExpected) STORMKIT_FORCE_INLINE - constexpr auto UseNamedConstructors::create(ConstructorArgs... c_args, - Args&&... args) noexcept -> ValueType { - auto out = ValueType { PRIVATE, c_args... }; - out.do_init(PRIVATE, std::forward(args)...); + constexpr auto UseNamedConstructors::allocate(ConstructorArgs... c_args, + Args&&... args) noexcept + -> Heap { + auto out = core::allocate_unsafe(PrivateTagBase::PRIVATE, std::forward(c_args)...); + out->do_init(PrivateTagBase::PRIVATE, std::forward(args)...); return out; } ///////////////////////////////////// ///////////////////////////////////// - template + template + STORMKIT_FORCE_INLINE + constexpr UseNamedConstructors::UseNamedConstructors() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr UseNamedConstructors::~UseNamedConstructors() noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto UseNamedConstructors::operator=(const UseNamedConstructors&) noexcept + -> UseNamedConstructors& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr UseNamedConstructors:: + UseNamedConstructors(const UseNamedConstructors&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr auto UseNamedConstructors::operator=(UseNamedConstructors&&) noexcept + -> UseNamedConstructors& = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + constexpr UseNamedConstructors:: + UseNamedConstructors(UseNamedConstructors&&) noexcept = default; + + ///////////////////////////////////// + ///////////////////////////////////// + template template - requires(meta::IsStdExpected) STORMKIT_FORCE_INLINE - constexpr auto UseNamedConstructors::allocate(ConstructorArgs... c_args, - Args&&... args) noexcept - -> meta::TransformExpectedValueTo, RetType> { - using ReturnValue = meta::TransformExpectedValueTo, RetType>; + constexpr auto UseNamedConstructors::create(ConstructorArgs... c_args, + Args&&... args) noexcept -> decltype(auto) { + using ReturnValue = meta::TransformExpectedValueTo; - auto out_expected = ReturnValue { std::in_place, core::allocate_unsafe(PRIVATE, c_args...) }; - if (auto result = out_expected.value().do_init(PRIVATE, std::forward(args)...); not result) - out_expected = ReturnValue { std::unexpect, std::move(result).error() }; + auto out_expected = ReturnValue { std::in_place, PrivateTagBase::PRIVATE, std::forward(c_args)... }; + if (auto result = out_expected.value().do_init(PrivateTagBase::PRIVATE, std::forward(args)...); not result) + out_expected = std::unexpected { std::move(result).error() }; return out_expected; } ///////////////////////////////////// ///////////////////////////////////// - template + template template - requires(not meta::IsStdExpected) STORMKIT_FORCE_INLINE constexpr auto UseNamedConstructors::allocate(ConstructorArgs... c_args, Args&&... args) noexcept - -> Heap { - auto out = core::allocate_unsafe(PRIVATE, c_args...); - out->do_init(PRIVATE, std::forward(args)...); - return out; + -> decltype(auto) { + using ReturnValue = meta::TransformExpectedValueTo, RetType>; + + auto out_expected = ReturnValue { + std::in_place, + core::allocate_unsafe(PrivateTagBase::PRIVATE, std::forward(c_args)...) + }; + if (auto result = out_expected.value()->do_init(PrivateTagBase::PRIVATE, std::forward(args)...); not result) + out_expected = std::unexpected { std::move(result).error() }; + + return out_expected; } + }} // namespace stormkit::core From 360f17d877d429113a34c6bfefce277d5ba01c16 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Wed, 25 Mar 2026 21:57:30 +0100 Subject: [PATCH 179/194] (core) remove UBs --- modules/stormkit/core/typesafe/byte.cppm | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/stormkit/core/typesafe/byte.cppm b/modules/stormkit/core/typesafe/byte.cppm index be1f5b5fa..8f3903528 100644 --- a/modules/stormkit/core/typesafe/byte.cppm +++ b/modules/stormkit/core/typesafe/byte.cppm @@ -177,7 +177,7 @@ namespace stormkit { inline namespace core { stdr::reverse(repr); - return std::bit_cast(repr); + return std::launder(std::bit_cast(repr)); } } @@ -251,7 +251,7 @@ namespace stormkit { inline namespace core { constexpr auto bytes_as(std::span bytes) noexcept -> const T& { if constexpr (EXTENT != std::dynamic_extent) EXPECTS(EXTENT == sizeof(T)); EXPECTS(stdr::size(bytes) == sizeof(T)); - return *std::bit_cast(stdr::data(bytes)); + return *std::launder(std::bit_cast(stdr::data(bytes))); } ///////////////////////////////////// @@ -260,7 +260,7 @@ namespace stormkit { inline namespace core { requires(meta::SameAs>, byte>) STORMKIT_FORCE_INLINE constexpr auto bytes_as_span(const Range& bytes) noexcept -> std::span { - return std::span { std::bit_cast(stdr::data(bytes)), stdr::size(bytes) / sizeof(T) }; + return std::span { std::launder(std::bit_cast(stdr::data(bytes))), stdr::size(bytes) / sizeof(T) }; } ///////////////////////////////////// @@ -273,7 +273,7 @@ namespace stormkit { inline namespace core { return std::span { std::bit_cast(stdr::data(bytes)), EXTENT / sizeof(T) }; else - return std::span { std::bit_cast(stdr::data(bytes)), stdr::size(bytes) / sizeof(T) }; + return std::span { std::launder(std::bit_cast(stdr::data(bytes))), stdr::size(bytes) / sizeof(T) }; } ///////////////////////////////////// @@ -283,7 +283,7 @@ namespace stormkit { inline namespace core { constexpr auto bytes_mut_as(std::span bytes) noexcept -> T& { if constexpr (EXTENT != std::dynamic_extent) EXPECTS(EXTENT == sizeof(T)); EXPECTS(stdr::size(bytes) == sizeof(T)); - return *std::bit_cast(stdr::data(bytes)); + return *std::launder(std::bit_cast(stdr::data(bytes))); } ///////////////////////////////////// @@ -292,7 +292,7 @@ namespace stormkit { inline namespace core { requires(meta::SameAs, byte> and not meta::IsConst) STORMKIT_FORCE_INLINE constexpr auto bytes_mut_as_span(Range& bytes) noexcept -> std::span { - return std::span { std::bit_cast(stdr::data(bytes)), stdr::size(bytes) / sizeof(T) }; + return std::span { std::launder(std::bit_cast(stdr::data(bytes))), stdr::size(bytes) / sizeof(T) }; } ///////////////////////////////////// @@ -304,7 +304,7 @@ namespace stormkit { inline namespace core { if constexpr (EXTENT != std::dynamic_extent) return std::span { std::bit_cast(stdr::data(bytes)), EXTENT / sizeof(T) }; else - return std::span { std::bit_cast(stdr::data(bytes)), stdr::size(bytes) / sizeof(T) }; + return std::span { std::launder(std::bit_cast(stdr::data(bytes))), stdr::size(bytes) / sizeof(T) }; } ///////////////////////////////////// From 84f06638c3af04ac67adcc56616b5412512183d4 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 26 Mar 2026 16:28:08 +0100 Subject: [PATCH 180/194] (core) fix matrix translation and scale --- modules/stormkit/core/math/linear-matrix.cppm | 6 +- modules/stormkit/core/math/linear.cppm | 56 +++++++++---------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/modules/stormkit/core/math/linear-matrix.cppm b/modules/stormkit/core/math/linear-matrix.cppm index 26c1f731b..06330de91 100644 --- a/modules/stormkit/core/math/linear-matrix.cppm +++ b/modules/stormkit/core/math/linear-matrix.cppm @@ -478,7 +478,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m template STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto translate(const mat4x4& mat, const vec3& translation) noexcept -> mat4x4 { - auto out = mat4x4 {}; + auto out = auto(mat); math::translate(as_mdspan(mat), as_mdspan(translation), as_mdspan_mut(out)); @@ -490,7 +490,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m template STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto scale(const mat4x4& mat, const vec3& scale_factors) noexcept -> mat4x4 { - auto out = mat4x4 {}; + auto out = auto(mat); math::scale(as_mdspan(mat), as_mdspan(scale_factors), as_mdspan_mut(out)); @@ -502,7 +502,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m template STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto rotate(const mat4x4& mat, angle::radian angle, const vec3& axis) noexcept -> mat4x4 { - auto out = mat4x4 {}; + auto out = auto(mat); math::rotate(as_mdspan(mat), angle, as_mdspan(axis), as_mdspan_mut(out)); diff --git a/modules/stormkit/core/math/linear.cppm b/modules/stormkit/core/math/linear.cppm index b2c61bec4..1f263f0ed 100644 --- a/modules/stormkit/core/math/linear.cppm +++ b/modules/stormkit/core/math/linear.cppm @@ -557,13 +557,13 @@ namespace stormkit { inline namespace core { namespace math { EXPECTS(a.data_handle() != out.data_handle()); EXPECTS(translation.data_handle() != out.data_handle()); - for (auto i = 0u; i < 3; ++i) - for (auto j = 0u; j < 3; ++j) out[i, j] = a[i, j]; - - out[3, 0] = a[0, 0] * translation[0] + a[1, 0] * translation[1] + a[2, 0] * translation[2] + a[3, 0]; - out[3, 1] = a[0, 1] * translation[0] + a[1, 1] * translation[1] + a[2, 1] * translation[2] + a[3, 1]; - out[3, 2] = a[0, 2] * translation[0] + a[1, 2] * translation[1] + a[2, 2] * translation[2] + a[3, 2]; - out[3, 3] = a[0, 3] * translation[0] + a[1, 3] * translation[1] + a[2, 3] * translation[2] + a[3, 3]; + out[0, 3] = a[0, 3] + + translation[0]; // a[0, 0] * translation[0] + a[1, 0] * translation[1] + a[2, 0] * translation[2] + a[3, 0]; + out[1, 3] = a[1, 3] + + translation[1]; // a[0, 1] * translation[0] + a[1, 1] * translation[1] + a[2, 1] * translation[2] + a[3, 1]; + out[2, 3] = a[2, 3] + + translation[2]; // a[0, 2] * translation[0] + a[1, 2] * translation[1] + a[2, 2] * translation[2] + a[3, 2]; + // out[3, 3] = a[0, 3] * translation[0] + a[1, 3] * translation[1] + a[2, 3] * translation[2] + a[3, 3]; } //////////////////////////////////////// @@ -576,23 +576,23 @@ namespace stormkit { inline namespace core { namespace math { EXPECTS(scale.data_handle() != out.data_handle()); out[0, 0] = a[0, 0] * scale[0]; - out[0, 1] = a[0, 1] * scale[0]; - out[0, 2] = a[0, 2] * scale[0]; - out[0, 3] = a[0, 3] * scale[0]; + out[1, 0] = a[1, 0] * scale[0]; + out[2, 0] = a[2, 0] * scale[0]; + out[3, 0] = a[3, 0] * scale[0]; - out[1, 0] = a[1, 0] * scale[1]; + out[0, 1] = a[0, 1] * scale[1]; out[1, 1] = a[1, 1] * scale[1]; - out[1, 2] = a[1, 2] * scale[1]; - out[1, 3] = a[1, 3] * scale[1]; + out[2, 1] = a[2, 1] * scale[1]; + out[3, 1] = a[3, 1] * scale[1]; - out[2, 0] = a[2, 0] * scale[2]; - out[2, 1] = a[2, 1] * scale[2]; + out[0, 2] = a[0, 2] * scale[2]; + out[1, 2] = a[1, 2] * scale[2]; out[2, 2] = a[2, 2] * scale[2]; - out[2, 3] = a[2, 3] * scale[2]; + out[3, 2] = a[3, 2] * scale[2]; - out[3, 0] = a[3, 0]; - out[3, 1] = a[3, 1]; - out[3, 2] = a[3, 2]; + out[0, 3] = a[0, 3]; + out[1, 3] = a[1, 3]; + out[2, 3] = a[2, 3]; out[3, 3] = a[3, 3]; } @@ -631,15 +631,15 @@ namespace stormkit { inline namespace core { namespace math { auto rotation_matrix_ = as_mdspan_mut<4, 4>(rotation_matrix); rotation_matrix_[0, 0] = cos + temp[0] * axis_norm[0]; - rotation_matrix_[0, 1] = temp[0] * axis_norm[1] + sin * axis_norm[2]; - rotation_matrix_[0, 2] = temp[0] * axis_norm[2] - sin * axis_norm[1]; + rotation_matrix_[1, 0] = temp[0] * axis_norm[1] + sin * axis_norm[2]; + rotation_matrix_[2, 0] = temp[0] * axis_norm[2] - sin * axis_norm[1]; - rotation_matrix_[1, 0] = temp[1] * axis_norm[0] - sin * axis_norm[2]; + rotation_matrix_[0, 1] = temp[1] * axis_norm[0] - sin * axis_norm[2]; rotation_matrix_[1, 1] = cos + temp[1] * axis_norm[1]; - rotation_matrix_[1, 2] = temp[1] * axis_norm[2] + sin * axis_norm[0]; + rotation_matrix_[2, 1] = temp[1] * axis_norm[2] + sin * axis_norm[0]; - rotation_matrix_[2, 0] = temp[2] * axis_norm[0] + sin * axis_norm[1]; - rotation_matrix_[2, 1] = temp[2] * axis_norm[1] - sin * axis_norm[0]; + rotation_matrix_[0, 2] = temp[2] * axis_norm[0] + sin * axis_norm[1]; + rotation_matrix_[1, 2] = temp[2] * axis_norm[1] - sin * axis_norm[0]; rotation_matrix_[2, 2] = cos + temp[2] * axis_norm[2]; // TODO replace by mul when submdspan is available @@ -647,9 +647,9 @@ namespace stormkit { inline namespace core { namespace math { for (auto j = 0u; j < 3; ++j) for (auto k = 0u; k < 3; ++k) out[i, j] += a[i, k] * rotation_matrix_[k, j]; - out[3, 0] = a[3, 0]; - out[3, 1] = a[3, 1]; - out[3, 2] = a[3, 2]; + out[0, 3] = a[0, 3]; + out[1, 3] = a[1, 3]; + out[2, 3] = a[2, 3]; out[3, 3] = a[3, 3]; } From 0934cf99b2c1d6569eab23a1d2837a39597162ca Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 26 Mar 2026 16:28:25 +0100 Subject: [PATCH 181/194] (core) fix Locked when using a Container or a smart Pointer type --- modules/stormkit/core/parallelism/locked.cppm | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/modules/stormkit/core/parallelism/locked.cppm b/modules/stormkit/core/parallelism/locked.cppm index b964a3a71..3ed3daec5 100644 --- a/modules/stormkit/core/parallelism/locked.cppm +++ b/modules/stormkit/core/parallelism/locked.cppm @@ -15,13 +15,27 @@ import :meta; import :typesafe.integer; import :typesafe.ref; -namespace stormkit { inline namespace core { namespace details { - using DefaultMutex = std::mutex; - template - using DefaultReadOnlyLock = std::unique_lock; - template - using DefaultReadWriteLock = std::unique_lock; -}}} // namespace stormkit::core::details +namespace stormkit { inline namespace core { + namespace meta { namespace details { + template + struct LockedValueType { + using Type = T; + }; + + template + struct LockedValueType { + using Type = meta::ContainedOrPointedType; + }; + }} // namespace meta::details + + namespace details { + using DefaultMutex = std::mutex; + template + using DefaultReadOnlyLock = std::unique_lock; + template + using DefaultReadWriteLock = std::unique_lock; + } // namespace details +}} // namespace stormkit::core export namespace stormkit { inline namespace core { enum class LockAccessMode : core::u8 { @@ -32,7 +46,7 @@ export namespace stormkit { inline namespace core { template class STORMKIT_CORE_API Locked { public: - using ValueType = meta::PointedType; + using ValueType = meta::details::LockedValueType::Type; using ReferenceType = ValueType&; using ConstReferenceType = const ValueType&; using PointerType = ValueType*; @@ -129,6 +143,10 @@ export namespace stormkit { inline namespace core { template Locked(T) -> Locked; + + template class Locked; + template class Locked>; + template class Locked>; }} // namespace stormkit::core //////////////////////////////////////////////////////////////////// From eed73a5677a865f386e08c231fddc18be108239d Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 26 Mar 2026 16:28:42 +0100 Subject: [PATCH 182/194] (gpu) format --- modules/stormkit/gpu/core/base.cppm | 18 +++++----- modules/stormkit/gpu/core/device.cppm | 4 ++- modules/stormkit/gpu/core/instance.cppm | 23 ++++++------ .../stormkit/gpu/execution/descriptors.cppm | 18 +++++----- modules/stormkit/gpu/resource/buffer.cppm | 35 +++++++++++-------- modules/stormkit/gpu/resource/image.cppm | 26 +++++++------- src/gpu/core/instance.cpp | 16 ++++++--- src/gpu/execution/command_buffer.cpp | 6 ++-- tests/core/math/linear-matrix.cpp | 6 ++-- 9 files changed, 86 insertions(+), 66 deletions(-) diff --git a/modules/stormkit/gpu/core/base.cppm b/modules/stormkit/gpu/core/base.cppm index b86a1face..8cb2ec392 100644 --- a/modules/stormkit/gpu/core/base.cppm +++ b/modules/stormkit/gpu/core/base.cppm @@ -116,7 +116,7 @@ export namespace stormkit::gpu { using ViewType = Base::ViewType; GpuObjectViewImplementation(const GpuObjectImplementation&) noexcept; - template> TContainerOrPointer> + template GpuObjectViewImplementation(const TContainerOrPointer&) noexcept; ~GpuObjectViewImplementation() noexcept; @@ -142,7 +142,7 @@ export namespace stormkit::gpu { using OwnerViewType = Base::OwnerViewType; GpuObjectViewImplementation(const GpuObjectImplementation&) noexcept; - template> TContainerOrPointer> + template GpuObjectViewImplementation(const TContainerOrPointer&) noexcept; ~GpuObjectViewImplementation() noexcept; @@ -212,8 +212,9 @@ export namespace stormkit::gpu { DeleterType m_deleter_ptr; }; - template - auto as_view(T&& value) noexcept -> T; + template + requires(meta::IsGpuView>) + auto as_view(T&& value) noexcept -> decltype(auto); template auto as_view(const T& value) noexcept -> trait::GpuObject::ViewType; @@ -404,7 +405,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - template> TContainerOrPointer> + template STORMKIT_FORCE_INLINE inline GpuObjectViewImplementation::GpuObjectViewImplementation(const TContainerOrPointer& object) noexcept : GpuObjectBase {} { @@ -467,7 +468,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template requires(meta::HasOwnerType) - template> TContainerOrPointer> + template STORMKIT_FORCE_INLINE inline GpuObjectViewImplementation::GpuObjectViewImplementation(const TContainerOrPointer& object) noexcept : GpuObjectBase { (*object).owner() } { @@ -622,9 +623,10 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - template + template + requires(meta::IsGpuView>) STORMKIT_FORCE_INLINE - inline auto as_view(T&& value) noexcept -> T { + inline auto as_view(T&& value) noexcept -> decltype(auto) { return std::forward(value); } diff --git a/modules/stormkit/gpu/core/device.cppm b/modules/stormkit/gpu/core/device.cppm index 4ba0745f9..019d70e20 100644 --- a/modules/stormkit/gpu/core/device.cppm +++ b/modules/stormkit/gpu/core/device.cppm @@ -144,7 +144,9 @@ namespace stormkit::gpu { if (not vkSetDebugUtilsObjectNameEXT) return {}; const auto vk_object = vk::to_vk(object); - return set_object_name(as(std::bit_cast(vk_object)), trait::GpuObject::DEBUG_TYPE, std::move(name)); + return set_object_name(as(std::bit_cast(vk_object)), + trait::GpuObject::DEBUG_TYPE, + std::move(name)); } ///////////////////////////////////// diff --git a/modules/stormkit/gpu/core/instance.cppm b/modules/stormkit/gpu/core/instance.cppm index def2623b0..dc0ab62a2 100644 --- a/modules/stormkit/gpu/core/instance.cppm +++ b/modules/stormkit/gpu/core/instance.cppm @@ -24,6 +24,8 @@ import :base; import :structs; import :objects; +namespace cmonadic = stormkit::core::monadic; + namespace stormkit::gpu { export { template @@ -36,9 +38,11 @@ namespace stormkit::gpu { [[nodiscard]] auto check_extension_support(std::string_view extension) const noexcept -> bool; [[nodiscard]] - auto check_extension_support(std::span extensions) const noexcept -> bool; + auto check_extension_support(std::span extensions) const noexcept + -> std::optional>; [[nodiscard]] - auto check_extension_support(std::span extensions) const noexcept -> bool; + auto check_extension_support(std::span extensions) const noexcept + -> std::optional>; [[nodiscard]] auto info() const noexcept -> const PhysicalDeviceInfo&; @@ -198,24 +202,23 @@ namespace stormkit::gpu { ///////////////////////////////////// template inline auto PhysicalDeviceInterface::check_extension_support(std::span extensions) - const noexcept -> bool { + const noexcept -> std::optional> { auto required_extensions = HashSet { stdr::begin(extensions), stdr::end(extensions) }; for (const auto& extension : this->extensions()) required_extensions.erase(extension); - return stdr::empty(required_extensions); + if (not required_extensions.empty()) return required_extensions; + + return std::nullopt; } ///////////////////////////////////// ///////////////////////////////////// template inline auto PhysicalDeviceInterface::check_extension_support(std::span extensions) const noexcept - -> bool { - auto required_extensions = HashSet { stdr::begin(extensions), stdr::end(extensions) }; - - for (const auto& extension : this->extensions()) required_extensions.erase(extension); - - return stdr::empty(required_extensions); + -> std::optional> { + const auto ext = transform(extensions, cmonadic::init()); + return check_extension_support(ext); } ///////////////////////////////////// diff --git a/modules/stormkit/gpu/execution/descriptors.cppm b/modules/stormkit/gpu/execution/descriptors.cppm index 88cc542df..aa3095503 100644 --- a/modules/stormkit/gpu/execution/descriptors.cppm +++ b/modules/stormkit/gpu/execution/descriptors.cppm @@ -55,10 +55,10 @@ namespace stormkit::gpu { }; template - class DescriptorSetInterface: public Base { + class DescriptorSetInterface final: public DeviceObject { public: - using Base::Base; - using Base::operator=; + using DeviceObject::DeviceObject; + using DeviceObject::operator=; using TagType = DescriptorSetTag; auto update(std::span descriptors) const noexcept -> void; @@ -74,10 +74,10 @@ namespace stormkit::gpu { export { template - class DescriptorSetLayoutInterface: public Base, public DescriptorSetLayoutInterfaceBase { + class DescriptorSetLayoutInterface final: public DeviceObject, public DescriptorSetLayoutInterfaceBase { public: - using Base::Base; - using Base::operator=; + using DeviceObject::DeviceObject; + using DeviceObject::operator=; using TagType = DescriptorSetLayoutTag; using DescriptorSetLayoutInterfaceBase::Size; @@ -87,10 +87,10 @@ namespace stormkit::gpu { }; template - class DescriptorPoolInterface: public Base { + class DescriptorPoolInterface final: public DeviceObject { public: - using Base::Base; - using Base::operator=; + using DeviceObject::DeviceObject; + using DeviceObject::operator=; using TagType = DescriptorPoolTag; auto create_descriptor_set(this const auto&, view::DescriptorSetLayout layout) noexcept -> Expected; diff --git a/modules/stormkit/gpu/resource/buffer.cppm b/modules/stormkit/gpu/resource/buffer.cppm index b9a207940..6bc6f3239 100644 --- a/modules/stormkit/gpu/resource/buffer.cppm +++ b/modules/stormkit/gpu/resource/buffer.cppm @@ -141,17 +141,22 @@ namespace stormkit::gpu { }; } // namespace view - export struct BufferMemoryBarrier { - AccessFlag src; - AccessFlag dst; + export { + struct BufferMemoryBarrier { + AccessFlag src; + AccessFlag dst; - u32 src_queue_family_index = QUEUE_FAMILY_IGNORED; - u32 dst_queue_family_index = QUEUE_FAMILY_IGNORED; + u32 src_queue_family_index = QUEUE_FAMILY_IGNORED; + u32 dst_queue_family_index = QUEUE_FAMILY_IGNORED; - view::Buffer buffer; - usize size; - u64 offset = 0; - }; + view::Buffer buffer; + usize size; + u64 offset = 0; + }; + + template + constexpr auto hasher(const Buffer::CreateInfo& value) noexcept -> Ret; + } } // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// @@ -380,10 +385,10 @@ namespace stormkit::gpu { inline auto BufferImplementation::operator=(BufferImplementation&&) noexcept -> BufferImplementation& = default; } // namespace view - ///////////////////////////////////// - ///////////////////////////////////// - // template - // constexpr auto hasher(const Buffer::CreateInfo& create_info) noexcept -> Ret { - // return hash(create_info.usages, create_info.size, create_info.properties); - // } + /////////////////////////////////// + /////////////////////////////////// + template + constexpr auto hasher(const Buffer::CreateInfo& create_info) noexcept -> Ret { + return hash(create_info.usages, create_info.size, create_info.properties); + } } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/resource/image.cppm b/modules/stormkit/gpu/resource/image.cppm index f4dc99da3..db40b2f6a 100644 --- a/modules/stormkit/gpu/resource/image.cppm +++ b/modules/stormkit/gpu/resource/image.cppm @@ -258,22 +258,24 @@ namespace stormkit::gpu { }; } // namespace view - export struct ImageMemoryBarrier { - AccessFlag src; - AccessFlag dst; + export { + struct ImageMemoryBarrier { + AccessFlag src; + AccessFlag dst; - ImageLayout old_layout; - ImageLayout new_layout; + ImageLayout old_layout; + ImageLayout new_layout; - u32 src_queue_family_index = QUEUE_FAMILY_IGNORED; - u32 dst_queue_family_index = QUEUE_FAMILY_IGNORED; + u32 src_queue_family_index = QUEUE_FAMILY_IGNORED; + u32 dst_queue_family_index = QUEUE_FAMILY_IGNORED; - view::Image image; - ImageSubresourceRange range; - }; + view::Image image; + ImageSubresourceRange range; + }; - template - constexpr auto hasher(const Image::CreateInfo& value) noexcept -> Ret; + template + constexpr auto hasher(const Image::CreateInfo& value) noexcept -> Ret; + } } // namespace stormkit::gpu //////////////////////////////////////////////////////////////////// diff --git a/src/gpu/core/instance.cpp b/src/gpu/core/instance.cpp index 433017b45..c7b36b985 100644 --- a/src/gpu/core/instance.cpp +++ b/src/gpu/core/instance.cpp @@ -23,6 +23,8 @@ namespace stdv = std::views; using namespace std::literals; +namespace cmonadic = stormkit::core::monadic; + namespace stormkit::gpu { namespace { constexpr auto VALIDATION_LAYERS = into_array_of("VK_LAYER_KHRONOS_validation", @@ -67,19 +69,22 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// auto check_extension_support(std::span supported_extensions, - std::span extensions) noexcept -> bool { + std::span extensions) noexcept + -> std::optional> { auto required_extensions = HashSet { stdr::begin(extensions), stdr::end(extensions) }; for (const auto& extension : supported_extensions) required_extensions.erase(extension); - return required_extensions.empty(); + if (not required_extensions.empty()) return required_extensions; + + return std::nullopt; } ///////////////////////////////////// ///////////////////////////////////// auto check_extension_support(std::span supported_extensions, - std::span extensions) noexcept -> bool { - const auto ext = transform(extensions, core::monadic::init()); + std::span extensions) noexcept -> std::optional> { + const auto ext = transform(extensions, cmonadic::init()); return check_extension_support(supported_extensions, ext); } } // namespace @@ -107,7 +112,8 @@ namespace stormkit::gpu { if (validation_layers_enabled) e.emplace_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); return e; }(); - ensures(check_extension_support(m_extensions, instance_extensions), "Missing extensions!"); + const auto result = check_extension_support(m_extensions, instance_extensions); + if (result.has_value()) ensures(true, std::format("Missing extensions! {}", result.value())); constexpr auto ENGINE_NAME = "StormKit"; diff --git a/src/gpu/execution/command_buffer.cpp b/src/gpu/execution/command_buffer.cpp index dcf9326a8..95076b31f 100644 --- a/src/gpu/execution/command_buffer.cpp +++ b/src/gpu/execution/command_buffer.cpp @@ -1163,9 +1163,9 @@ namespace stormkit::gpu { const auto& device = Base::owner(); const auto& device_table = device.device_table(); - const auto expects_secondary = [this](auto&&) noexcept -> decltype(auto) { - EXPECTS(level() == CommandBufferLevel::SECONDARY); - return *this; + const auto expects_secondary = [](auto&& cmb) static noexcept -> decltype(auto) { + EXPECTS(cmb.level() == CommandBufferLevel::SECONDARY); + return cmb; }; const auto vk_command_buffers = transform(commandbuffers, cmonadic::map(expects_secondary, vk::monadic::to_vk())); diff --git a/tests/core/math/linear-matrix.cpp b/tests/core/math/linear-matrix.cpp index b325e2679..685d4ecc1 100644 --- a/tests/core/math/linear-matrix.cpp +++ b/tests/core/math/linear-matrix.cpp @@ -154,9 +154,9 @@ namespace { EXPECTS((result[0, 0] == 1)); EXPECTS((result[1, 1] == 1)); EXPECTS((result[2, 2] == 1)); - EXPECTS((result[3, 0] == 3)); - EXPECTS((result[3, 1] == 2)); - EXPECTS((result[3, 2] == 3)); + EXPECTS((result[0, 3] == 3)); + EXPECTS((result[1, 3] == 2)); + EXPECTS((result[2, 3] == 3)); EXPECTS((result[3, 3] == 1)); }, }, { From be729ed0de7cc0835ce14d0c43df7bddc10da177 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 26 Mar 2026 16:43:15 +0100 Subject: [PATCH 183/194] (all) replace tl_function_ref by nontype_functional and use move_only_function when required --- modules/stormkit/core/containers/dag.cppm | 6 ++--- modules/stormkit/core/containers/tree.cppm | 22 ++++++++++--------- .../stormkit/core/parallelism/threadpool.cppm | 12 +++++----- modules/stormkit/core/utils.cppm | 2 +- modules/stormkit/core/utils/function_ref.cppm | 15 ++++++------- .../gpu/execution/command_buffer.cppm | 2 +- src/gpu/core/surface.cpp | 2 +- src/wsi/linux/wayland/context.cpp | 4 ++-- xmake/rules/stormkit_application.xmake.lua | 2 +- xmake/rules/stormkit_library.xmake.lua | 2 +- xmake/targets/core.xmake.lua | 4 ++-- 11 files changed, 37 insertions(+), 36 deletions(-) diff --git a/modules/stormkit/core/containers/dag.cppm b/modules/stormkit/core/containers/dag.cppm index e748b1e3a..e71108753 100644 --- a/modules/stormkit/core/containers/dag.cppm +++ b/modules/stormkit/core/containers/dag.cppm @@ -19,7 +19,7 @@ import :typesafe.byte; import :typesafe.safecasts; import :utils.handle; import :utils.contract; -import :utils.function_ref; +import :utils.std23_functional; import :utils.filesystem; import :string.format; @@ -46,8 +46,8 @@ export namespace stormkit { inline namespace core { class DAG { public: using Vertex = dag::Vertex; - using ColorizeClosure = FunctionRef; - using FormatValueClosure = FunctionRef; + using ColorizeClosure = std23::function_ref; + using FormatValueClosure = std23::function_ref; using ValueType = Vertex; diff --git a/modules/stormkit/core/containers/tree.cppm b/modules/stormkit/core/containers/tree.cppm index 96ab888e8..b03f6c1be 100644 --- a/modules/stormkit/core/containers/tree.cppm +++ b/modules/stormkit/core/containers/tree.cppm @@ -18,7 +18,7 @@ import :typesafe.byte; import :typesafe.safecasts; import :utils.handle; import :utils.contract; -import :utils.function_ref; +import :utils.std23_functional; import :utils.filesystem; namespace stdr = std::ranges; @@ -109,12 +109,14 @@ export namespace stormkit { inline namespace core { [[nodiscard]] auto dirties() const noexcept -> std::span; - auto gen_dot_file(stdfs::path filepath, FunctionRef colorize_node) const noexcept + auto gen_dot_file(stdfs::path filepath, + std23::function_ref colorize_node) const noexcept -> io::Expected; - auto gen_dot_file(stdfs::path filepath, - core::u32 highlight, - FunctionRef colorize_node) const noexcept -> io::Expected; + auto gen_dot_file(stdfs::path filepath, + core::u32 highlight, + std23::function_ref colorize_node) const noexcept + -> io::Expected; private: TreeNodeIndexType m_first_free_index = 0; @@ -440,8 +442,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - auto Tree::gen_dot_file(stdfs::path filepath, - FunctionRef colorize_node) const noexcept + auto Tree::gen_dot_file(stdfs::path filepath, + std23::function_ref colorize_node) const noexcept -> io::Expected { using namespace stormkit::literals; auto out = std::string {}; @@ -481,9 +483,9 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - auto Tree::gen_dot_file(stdfs::path filepath, - core::u32 highlight, - FunctionRef colorize_node) const noexcept + auto Tree::gen_dot_file(stdfs::path filepath, + core::u32 highlight, + std23::function_ref colorize_node) const noexcept -> io::Expected { using namespace stormkit::literals; auto out = std::string {}; diff --git a/modules/stormkit/core/parallelism/threadpool.cppm b/modules/stormkit/core/parallelism/threadpool.cppm index 0b5f8bdea..d1d1c21a7 100644 --- a/modules/stormkit/core/parallelism/threadpool.cppm +++ b/modules/stormkit/core/parallelism/threadpool.cppm @@ -15,6 +15,7 @@ import :parallelism.threadutils; import :meta; +import :utils.std23_functional; import :utils.numeric_range; import :typesafe.integer; @@ -25,8 +26,7 @@ export namespace stormkit { inline namespace core { } NO_FUTURE = {}; template - using Closure = std::function; - // using Closure = std::move_only_function; + using Closure = std23::move_only_function; explicit ThreadPool(u32 worker_count = std::thread::hardware_concurrency() / 2); ~ThreadPool(); @@ -62,13 +62,13 @@ export namespace stormkit { inline namespace core { Task() = default; - inline Task(Type _type, std::function _work) : type { _type }, work { std::move(_work) } {} + inline Task(Type _type, std23::move_only_function&& _work) : type { _type }, work { std::move(_work) } {} Task(Task&&) noexcept = default; auto operator=(Task&&) noexcept -> Task& = default; - Type type; - std::function work; + Type type; + std23::move_only_function work; }; template @@ -181,7 +181,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template inline auto ThreadPool::post_task(Task::Type type, Closure closure, NoFutureType) noexcept -> void { - auto task = Task { type, [task = std::move(closure)]() { task(); } }; + auto task = Task { type, [task = std::move(closure)]() mutable noexcept { task(); } }; { auto lock = std::unique_lock { m_mutex }; diff --git a/modules/stormkit/core/utils.cppm b/modules/stormkit/core/utils.cppm index 0ebe7859d..511f19881 100644 --- a/modules/stormkit/core/utils.cppm +++ b/modules/stormkit/core/utils.cppm @@ -12,7 +12,7 @@ export import :utils.color; export import :utils.deferinit; export import :utils.dynamic_loader; export import :utils.filesystem; -export import :utils.function_ref; +export import :utils.std23_functional; export import :utils.handle; export import :utils.numeric_range; export import :utils.pimpl; diff --git a/modules/stormkit/core/utils/function_ref.cppm b/modules/stormkit/core/utils/function_ref.cppm index cb48aa41b..4b92ccb1a 100644 --- a/modules/stormkit/core/utils/function_ref.cppm +++ b/modules/stormkit/core/utils/function_ref.cppm @@ -1,12 +1,11 @@ module; -#include +#include +#include -export module stormkit.core:utils.function_ref; +export module stormkit.core:utils.std23_functional; -export namespace stormkit { inline namespace core { - using tl::swap; - - template - using FunctionRef = tl::function_ref; -}} // namespace stormkit::core +export namespace std23 { + using std23::function_ref; + using std23::move_only_function; +} // namespace std23 diff --git a/modules/stormkit/gpu/execution/command_buffer.cppm b/modules/stormkit/gpu/execution/command_buffer.cppm index a3795feac..8641ce297 100644 --- a/modules/stormkit/gpu/execution/command_buffer.cppm +++ b/modules/stormkit/gpu/execution/command_buffer.cppm @@ -117,7 +117,7 @@ namespace stormkit::gpu { RECORDING, EXECUTABLE, }; - using RecordClosure = FunctionRef; + using RecordClosure = std23::function_ref; }; export { diff --git a/src/gpu/core/surface.cpp b/src/gpu/core/surface.cpp index f6ff0ca12..e7b6df2f5 100644 --- a/src/gpu/core/surface.cpp +++ b/src/gpu/core/surface.cpp @@ -99,7 +99,7 @@ namespace stormkit::gpu { }; const auto create_surface = - [&window, &make_wayland_surface, &make_xcb_surface] noexcept -> FunctionRef()> { + [&window, &make_wayland_surface, &make_xcb_surface] noexcept -> std23::function_ref()> { const auto is_wayland = window.wm() == wsi::WM::WAYLAND; if (is_wayland) return make_wayland_surface; diff --git a/src/wsi/linux/wayland/context.cpp b/src/wsi/linux/wayland/context.cpp index f12ef8f03..f92a577b8 100644 --- a/src/wsi/linux/wayland/context.cpp +++ b/src/wsi/linux/wayland/context.cpp @@ -84,9 +84,9 @@ namespace stormkit::wsi::linux::wayland::wl { struct RegistryBinder { const wl_interface* interface; - FunctionRef bind; + std23::function_ref bind; u32 version = 1; - FunctionRef after_bind = monadic::noop(); + std23::function_ref after_bind = monadic::noop(); }; ///////////////////////////////////// diff --git a/xmake/rules/stormkit_application.xmake.lua b/xmake/rules/stormkit_application.xmake.lua index 0e9d4605b..ca5fb4fe8 100644 --- a/xmake/rules/stormkit_application.xmake.lua +++ b/xmake/rules/stormkit_application.xmake.lua @@ -9,7 +9,7 @@ namespace("stormkit", function() local stormkit_components_set = hashset.from(stormkit_components) -- core -- - target:add("packages", "frozen", "unordered_dense", "tl_function_ref") + target:add("packages", "frozen", "unordered_dense", "nontype_functional") if stormkit_components_set:has("image") then target:add("packages", "libktx", "libpng", "libjpeg-turbo") end if stormkit_components_set:has("wsi") then diff --git a/xmake/rules/stormkit_library.xmake.lua b/xmake/rules/stormkit_library.xmake.lua index fa37232fb..979ea4af3 100644 --- a/xmake/rules/stormkit_library.xmake.lua +++ b/xmake/rules/stormkit_library.xmake.lua @@ -9,7 +9,7 @@ namespace("stormkit", function() local stormkit_components_set = hashset.from(stormkit_components) -- core -- - target:add("packages", "frozen", "unordered_dense", "tl_function_ref") + target:add("packages", "frozen", "unordered_dense", "nontype_functional") if stormkit_components_set:has("image") then target:add("packages", "libktx", "libpng", "libjpeg-turbo") end if stormkit_components_set:has("wsi") then diff --git a/xmake/targets/core.xmake.lua b/xmake/targets/core.xmake.lua index 062101467..da4b5cb13 100644 --- a/xmake/targets/core.xmake.lua +++ b/xmake/targets/core.xmake.lua @@ -1,6 +1,6 @@ add_requires("frozen", { system = false, configs = { modules = true, std_import = true, cpp = "latest" } }) add_requires("unordered_dense", { system = false, configs = { modules = true, std_import = true } }) -add_requires("tl_function_ref", { system = false, configs = { modules = true, std_import = true } }) +add_requires("nontype_functional") local src_core_dir = path.join(src_dir, "core") local module_core_dir = path.join(module_dir, "core") @@ -38,7 +38,7 @@ target("core", function() add_headerfiles(path.join(include_dir, "(stormkit/core/**.hpp)"), "$(builddir)/.gens/include/(stormkit/core/*.hpp)") add_includedirs(include_dir, { public = true }) - add_packages("frozen", "unordered_dense", "tl_function_ref", { public = true }) + add_packages("frozen", "unordered_dense", "nontype_functional", { public = true }) on_config(function(target) local output, errors = os.iorunv("git", { "rev-parse", "--abbrev-ref", "HEAD" }) From 11e6154f99c23209cb367adba0ec338f6bb70da0 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 26 Mar 2026 17:35:14 +0100 Subject: [PATCH 184/194] (core) fix thread pool no future post_task --- modules/stormkit/core/parallelism/threadpool.cppm | 2 +- src/core/threadpool.cpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/stormkit/core/parallelism/threadpool.cppm b/modules/stormkit/core/parallelism/threadpool.cppm index d1d1c21a7..1350cb09b 100644 --- a/modules/stormkit/core/parallelism/threadpool.cppm +++ b/modules/stormkit/core/parallelism/threadpool.cppm @@ -153,7 +153,7 @@ namespace stormkit { inline namespace core { template STORMKIT_FORCE_INLINE inline auto ThreadPool::post_task(Closure task, NoFutureType t) noexcept -> void { - auto _ = post_task(Task::Type::Standard, std::move(task), t); + post_task(Task::Type::Standard, std::move(task), t); } //////////////////////////////////////// diff --git a/src/core/threadpool.cpp b/src/core/threadpool.cpp index 4e5fb7ea8..c9b94f64a 100644 --- a/src/core/threadpool.cpp +++ b/src/core/threadpool.cpp @@ -99,8 +99,7 @@ namespace stormkit { { auto lock = std::unique_lock { m_mutex }; - if (stdr::empty(m_tasks)) m_work_signal.wait(lock, [this] { return not std::empty(m_tasks); }); - + m_work_signal.wait(lock, [this] { return not std::empty(m_tasks); }); task = std::move(m_tasks.front()); m_tasks.pop(); } From 8f3b5918187856bdcb0520973002322a176c24c7 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 26 Mar 2026 18:12:28 +0100 Subject: [PATCH 185/194] (core) add tests for threadpool --- tests/core/parallelism/threadpool.cpp | 116 ++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 tests/core/parallelism/threadpool.cpp diff --git a/tests/core/parallelism/threadpool.cpp b/tests/core/parallelism/threadpool.cpp new file mode 100644 index 000000000..fe4da6920 --- /dev/null +++ b/tests/core/parallelism/threadpool.cpp @@ -0,0 +1,116 @@ +// Copyright (C) 2024 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +import std; + +import stormkit.core; +import stormkit.test; + +#include + +using namespace stormkit::core; + +using namespace std::literals; + +namespace stdr = std::ranges; +namespace stdv = std::views; + +namespace { + auto _ = test::TestSuite { + "Core.parallelism", + { + { "ThreadPool.post_task_future_void", + [] static noexcept { + auto thread_pool = ThreadPool {}; + + auto future = thread_pool.post_task([] static noexcept { std::println("Hello from a thread!"); }); + + EXPECTS(future.valid()); + future.wait(); + } }, + { "ThreadPool.post_task_future_int", + [] static noexcept { + auto thread_pool = ThreadPool {}; + + auto future = thread_pool.post_task([] static noexcept { + std::println("Hello from a thread!"); + return 8; + }); + + EXPECTS(future.valid()); + future.wait(); + EXPECTS(future.get() == 8); + } }, + { "ThreadPool.post_task_no_future", + [] static noexcept { + auto thread_pool = ThreadPool {}; + + auto val = std::atomic_int { 5 }; + + thread_pool.post_task( + [&val] noexcept { + std::println("Hello from a thread!"); + val = 8; + }, + ThreadPool::NO_FUTURE); + + std::this_thread::sleep_for(1s); + + EXPECTS(val == 8); + } }, + { "ThreadPool.post_task_from_other_task", + [] static noexcept { + auto thread_pool = ThreadPool {}; + + auto val = std::atomic_int { 5 }; + + thread_pool.post_task( + [&val, &thread_pool] noexcept { + thread_pool.post_task( + [&val, &thread_pool] noexcept { + std::println("Hello from a thread!"); + val = 8; + }, + ThreadPool::NO_FUTURE); + }, + ThreadPool::NO_FUTURE); + + std::this_thread::sleep_for(1s); + + EXPECTS(val == 8); + } }, + { "ThreadPool.post_task_from_other_thread", + [] static noexcept { + auto thread_pool = ThreadPool {}; + + auto val = std::atomic_int { 5 }; + + auto thread = std::jthread { [&val, &thread_pool] noexcept { + thread_pool.post_task( + [&val, &thread_pool] noexcept { + std::println("Hello from a thread!"); + val = 8; + }, + ThreadPool::NO_FUTURE); + } }; + + std::this_thread::sleep_for(1s); + + if (thread.joinable()) thread.join(); + + EXPECTS(val == 8); + } }, + { "ThreadPool.parallel_for", + [] static noexcept { + auto thread_pool = ThreadPool {}; + + auto values = std::vector { std::from_range, range(0, 1000000) }; + parallel_for(thread_pool, values, [](auto& value) { value += value; }); + + auto k = 0; + for (auto v : values) EXPECTS(v == (k++ * 2)); + } }, + } + }; +} // namespace From 12460aa07f6e653d2b15495443f5cbb09c3858c8 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 26 Mar 2026 18:27:06 +0100 Subject: [PATCH 186/194] (core, main) change thread naming --- src/core/threadpool.cpp | 4 ++-- src/main/linux/main_linux.cpp | 2 +- src/main/macos/Main-macOS.mm | 2 +- src/main/win32/main_win.cpp | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/threadpool.cpp b/src/core/threadpool.cpp index c9b94f64a..0e493d6df 100644 --- a/src/core/threadpool.cpp +++ b/src/core/threadpool.cpp @@ -23,7 +23,7 @@ namespace stormkit { m_workers.reserve(m_worker_count); for (const auto i : range(m_worker_count)) { auto& thread = m_workers.emplace_back([this] { worker_main(); }); - set_thread_name(thread, std::format("StormKit:WorkerThread:{}", i)); + set_thread_name(thread, std::format("stormkit:worker_thread:{}", i)); } } @@ -48,7 +48,7 @@ namespace stormkit { m_workers.reserve(m_worker_count); for (const auto i : range(m_worker_count)) { auto& thread = m_workers.emplace_back([this] { worker_main(); }); - set_thread_name(thread, std::format("StormKit:WorkerThread:{}", i)); + set_thread_name(thread, std::format("stormkit:worker_thread:{}", i)); } return *this; diff --git a/src/main/linux/main_linux.cpp b/src/main/linux/main_linux.cpp index 60c052300..03f381736 100644 --- a/src/main/linux/main_linux.cpp +++ b/src/main/linux/main_linux.cpp @@ -11,7 +11,7 @@ extern auto user_main(std::span) -> int; auto main(int argc, char** argv) -> int { stormkit::setup_signal_handler(); - stormkit::set_current_thread_name("MainThread"); + stormkit::set_current_thread_name("stormkit:main_thread"); auto args = std::vector {}; diff --git a/src/main/macos/Main-macOS.mm b/src/main/macos/Main-macOS.mm index 3c7a4a504..f05c979fc 100644 --- a/src/main/macos/Main-macOS.mm +++ b/src/main/macos/Main-macOS.mm @@ -8,7 +8,7 @@ auto main(const int argc, const char** argv) -> int { setup_signal_handler(); - set_current_thread_name("MainThread"); + set_current_thread_name("stormkit:main_thread"); auto args = std::vector {}; diff --git a/src/main/win32/main_win.cpp b/src/main/win32/main_win.cpp index a8c37d70b..a851f492c 100644 --- a/src/main/win32/main_win.cpp +++ b/src/main/win32/main_win.cpp @@ -86,7 +86,7 @@ auto __stdcall main(int argc, char** argv) -> int { redirect_io_to_console(false); setup_signal_handler(); - set_current_thread_name("MainThread"); + set_current_thread_name("stormkit:main_thread"); return user_main(args); } @@ -103,7 +103,7 @@ auto __stdcall WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) -> int { const auto has_allocated = redirect_io_to_console(false); setup_signal_handler(); - set_current_thread_name("MainThread"); + set_current_thread_name("stormkit:main_thread"); const auto ret_value = user_main(args); if (has_allocated) ::FreeConsole(); From 54a929d48e006fa9ba174626c705a32baf2c39f8 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 26 Mar 2026 18:35:02 +0100 Subject: [PATCH 187/194] (core) use prctl instead of pthread for naming current thread --- modules/stormkit/core/parallelism/threadpool.cppm | 2 +- src/core/linux/threadutils.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/stormkit/core/parallelism/threadpool.cppm b/modules/stormkit/core/parallelism/threadpool.cppm index 1350cb09b..9117798fd 100644 --- a/modules/stormkit/core/parallelism/threadpool.cppm +++ b/modules/stormkit/core/parallelism/threadpool.cppm @@ -113,7 +113,7 @@ namespace stormkit { inline namespace core { for (auto i : range(m_worker_count)) { auto& worker = m_workers.emplace_back([this] { worker_main(); }); - set_thread_name(worker, std::format("StormKit:WorkerThread:{}", i)); + set_thread_name(worker, std::format("stormkit:worker_thread:{}", i)); } } diff --git a/src/core/linux/threadutils.cpp b/src/core/linux/threadutils.cpp index 9784da45a..ff63e79b6 100644 --- a/src/core/linux/threadutils.cpp +++ b/src/core/linux/threadutils.cpp @@ -1,6 +1,7 @@ module; #include +#include module stormkit.core; @@ -26,8 +27,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// auto set_current_thread_name(std::string_view name) noexcept -> void { - const auto id = pthread_self(); - details::set_thread_name(id, name); + prctl(PR_SET_NAME, stdr::data(name), 0, 0, 0); } //////////////////////////////////////// From 03ad3af0fb2e738b141421e92f28a06782bc7e1c Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 26 Mar 2026 20:51:58 +0100 Subject: [PATCH 188/194] (core) try to fix thread name --- .../stormkit/core/parallelism/threadpool.cppm | 14 +++++------ src/core/threadpool.cpp | 25 +++++++++++-------- tests/core/parallelism/threadpool.cpp | 4 +-- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/modules/stormkit/core/parallelism/threadpool.cppm b/modules/stormkit/core/parallelism/threadpool.cppm index 9117798fd..9bddb56ec 100644 --- a/modules/stormkit/core/parallelism/threadpool.cppm +++ b/modules/stormkit/core/parallelism/threadpool.cppm @@ -14,6 +14,7 @@ import std; import :parallelism.threadutils; import :meta; +import :functional; import :utils.std23_functional; import :utils.numeric_range; @@ -77,7 +78,9 @@ export namespace stormkit { inline namespace core { template auto post_task(Task::Type type, Closure task, NoFutureType) noexcept -> void; - auto worker_main() noexcept -> void; + auto worker_main(i32 id) noexcept -> void; + + auto spawn_workers() noexcept -> void; u32 m_worker_count = 0; @@ -109,12 +112,7 @@ namespace stormkit { inline namespace core { STORMKIT_FORCE_INLINE inline ThreadPool::ThreadPool(u32 worker_count) : m_worker_count { worker_count }, m_running_task_counter { worker_count } { - m_workers.reserve(m_worker_count); - - for (auto i : range(m_worker_count)) { - auto& worker = m_workers.emplace_back([this] { worker_main(); }); - set_thread_name(worker, std::format("stormkit:worker_thread:{}", i)); - } + spawn_workers(); } ///////////////////////////////////// @@ -217,7 +215,7 @@ namespace stormkit { inline namespace core { if (end >= (chunk_count * size)) end = size; out.emplace_back(pool.post_task([&f, &range, start, end] mutable noexcept { - auto it = std::begin(range) + start; + auto it = std::begin(range) + as(start); for (auto _ : stormkit::range(start, end)) { f(*it); ++it; diff --git a/src/core/threadpool.cpp b/src/core/threadpool.cpp index 0e493d6df..1dd5e2be8 100644 --- a/src/core/threadpool.cpp +++ b/src/core/threadpool.cpp @@ -20,11 +20,8 @@ namespace stormkit { m_tasks = std::move(other.m_tasks); - m_workers.reserve(m_worker_count); - for (const auto i : range(m_worker_count)) { - auto& thread = m_workers.emplace_back([this] { worker_main(); }); - set_thread_name(thread, std::format("stormkit:worker_thread:{}", i)); - } + m_workers.clear(); + spawn_workers(); } ///////////////////////////////////// @@ -45,11 +42,8 @@ namespace stormkit { m_worker_count = other.m_worker_count; m_tasks = std::move(other.m_tasks); - m_workers.reserve(m_worker_count); - for (const auto i : range(m_worker_count)) { - auto& thread = m_workers.emplace_back([this] { worker_main(); }); - set_thread_name(thread, std::format("stormkit:worker_thread:{}", i)); - } + m_workers.clear(); + spawn_workers(); return *this; } @@ -93,7 +87,8 @@ namespace stormkit { ///////////////////////////////////// ///////////////////////////////////// - auto ThreadPool::worker_main() noexcept -> void { + auto ThreadPool::worker_main(i32 id) noexcept -> void { + set_current_thread_name(std::format("stormkit:worker_thread:{}", id)); for (;;) { auto task = Task {}; @@ -111,4 +106,12 @@ namespace stormkit { if (task.type == Task::Type::Terminate) return; } } + + ///////////////////////////////////// + ///////////////////////////////////// + auto ThreadPool::spawn_workers() noexcept -> void { + m_workers.reserve(m_worker_count); + + for (auto i : range(m_worker_count)) m_workers.emplace_back(bind_front(&ThreadPool::worker_main, this, i)); + } } // namespace stormkit diff --git a/tests/core/parallelism/threadpool.cpp b/tests/core/parallelism/threadpool.cpp index fe4da6920..48669b4e1 100644 --- a/tests/core/parallelism/threadpool.cpp +++ b/tests/core/parallelism/threadpool.cpp @@ -68,7 +68,7 @@ namespace { thread_pool.post_task( [&val, &thread_pool] noexcept { thread_pool.post_task( - [&val, &thread_pool] noexcept { + [&val] noexcept { std::println("Hello from a thread!"); val = 8; }, @@ -88,7 +88,7 @@ namespace { auto thread = std::jthread { [&val, &thread_pool] noexcept { thread_pool.post_task( - [&val, &thread_pool] noexcept { + [&val] noexcept { std::println("Hello from a thread!"); val = 8; }, From dca54e1e08b8744c9a7776460850bdee88508335 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 26 Mar 2026 20:52:26 +0100 Subject: [PATCH 189/194] (core) add read / write / access overload which take a closure for locked --- modules/stormkit/core/parallelism/locked.cppm | 63 +++++++++++++++++++ tests/core/parallelism/locked.cpp | 18 ++++++ 2 files changed, 81 insertions(+) diff --git a/modules/stormkit/core/parallelism/locked.cppm b/modules/stormkit/core/parallelism/locked.cppm index 3ed3daec5..1fa29fa4e 100644 --- a/modules/stormkit/core/parallelism/locked.cppm +++ b/modules/stormkit/core/parallelism/locked.cppm @@ -59,6 +59,9 @@ export namespace stormkit { inline namespace core { using MutexType = Mutex; private: + template + using AccessClosureInvokeParameter = meta::If; + template class Lock, LockAccessMode Mode> class Access; @@ -85,12 +88,30 @@ export namespace stormkit { inline namespace core { template class Lock, typename... LockArgs, class Self> auto access(this Self& self, LockArgs&&... lock_args) noexcept -> Access; + template> Closure, + template class Lock, + typename... LockArgs, + class Self> + auto access(this Self& self, Closure&& closure, LockArgs&&... lock_args) noexcept + -> std::invoke_result_t>; + template class Lock = details::DefaultReadOnlyLock, typename... LockArgs> auto read(LockArgs&&... lock_args) const noexcept -> ReadAccess; + template Closure, + template class Lock = details::DefaultReadOnlyLock, + typename... LockArgs> + auto read(Closure&& closure, LockArgs&&... lock_args) const noexcept -> std::invoke_result_t; + template class Lock = details::DefaultReadWriteLock, typename... LockArgs> auto write(LockArgs&&... lock_args) noexcept -> WriteAccess; + template Closure, + template class Lock = details::DefaultReadWriteLock, + typename... LockArgs> + auto write(Closure&& closure, LockArgs&&... lock_args) noexcept -> std::invoke_result_t; + template class Lock = details::DefaultReadOnlyLock, typename... LockArgs> auto copy(LockArgs&&... lock_args) const noexcept -> ValueType; @@ -210,6 +231,24 @@ namespace stormkit { inline namespace core { return AccessType { std::forward(self), std::forward(lock_args)... }; } + //////////////////////////////////////// + //////////////////////////////////////// + template + template::template AccessClosureInvokeParameter> Closure, + template class Lock, + typename... LockArgs, + class Self> + STORMKIT_FORCE_INLINE + auto Locked::access(this Self& self, Closure&& closure, LockArgs&&... lock_args) noexcept + -> std::invoke_result_t> { + static_assert(not(Mode == LockAccessMode::READ_ONLY and not std::is_const_v>), + "can't get read access on const Locked"); + using AccessType = Access; + auto access_ = AccessType { std::forward(self), std::forward(lock_args)... }; + return std::invoke(std::forward(closure), *access_); + } + //////////////////////////////////////// //////////////////////////////////////// template @@ -219,6 +258,19 @@ namespace stormkit { inline namespace core { return access(std::forward(lock_args)...); } + //////////////////////////////////////// + //////////////////////////////////////// + template + template::ConstReferenceType> Closure, + template class Lock, + typename... LockArgs> + STORMKIT_FORCE_INLINE + auto Locked::read(Closure&& closure, LockArgs&&... lock_args) const noexcept + -> std::invoke_result_t { + return access(std::forward(closure), + std::forward(lock_args)...); + } + //////////////////////////////////////// //////////////////////////////////////// template @@ -228,6 +280,17 @@ namespace stormkit { inline namespace core { return access(std::forward(lock_args)...); } + //////////////////////////////////////// + //////////////////////////////////////// + template + template::ReferenceType> Closure, template class Lock, typename... LockArgs> + STORMKIT_FORCE_INLINE + auto Locked::write(Closure&& closure, LockArgs&&... lock_args) noexcept + -> std::invoke_result_t { + return access(std::forward(closure), + std::forward(lock_args)...); + } + //////////////////////////////////////// //////////////////////////////////////// template diff --git a/tests/core/parallelism/locked.cpp b/tests/core/parallelism/locked.cpp index 8240724be..008892c88 100644 --- a/tests/core/parallelism/locked.cpp +++ b/tests/core/parallelism/locked.cpp @@ -32,6 +32,24 @@ namespace { future_1.wait(); future_2.wait(); + EXPECTS(locked_int.unsafe() == (ITERATIONS * 2)); + } }, + { "Locked.write_closure", + [] static noexcept { + static constexpr auto ITERATIONS = 1'000'000; + auto locked_int = Locked { 0 }; + const auto func = [&locked_int] noexcept { + for (auto foo = 0; foo != ITERATIONS; ++foo) { + locked_int.write([](auto& value) static noexcept { value += 1; }); + } + }; + + auto future_1 = std::async(std::launch::async, func); + auto future_2 = std::async(std::launch::async, func); + + future_1.wait(); + future_2.wait(); + EXPECTS(locked_int.unsafe() == (ITERATIONS * 2)); } }, { "Locked.move", From f1c5736a95fc8f3dd96ebe07418424fe10e0dae9 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Thu, 26 Mar 2026 21:22:11 +0100 Subject: [PATCH 190/194] (all) format --- .clang-format | 199 +++++++++--------- modules/stormkit/core/containers/dag.cppm | 20 +- modules/stormkit/core/errors.cppm | 4 +- modules/stormkit/core/functional/monadic.cppm | 3 +- modules/stormkit/core/math/combinatoric.cppm | 5 +- modules/stormkit/core/math/linear-matrix.cppm | 12 +- modules/stormkit/core/meta/concepts.cppm | 17 +- modules/stormkit/core/parallelism/locked.cppm | 7 +- .../stormkit/core/typesafe/strong_type.cppm | 16 +- .../stormkit/core/utils/dynamic_loader.cppm | 15 +- modules/stormkit/entities.cppm | 4 +- modules/stormkit/gpu/core/base.cppm | 4 +- modules/stormkit/gpu/core/vulkan/enums.cppm | 22 +- .../gpu/execution/command_buffer.cppm | 3 +- modules/stormkit/image.cppm | 4 +- src/gpu/core/debug_callback.cpp | 6 +- src/gpu/core/device.cpp | 15 +- src/gpu/core/fence.cpp | 22 +- src/gpu/core/instance.cpp | 5 +- src/gpu/core/physical_device.cpp | 87 ++++---- src/gpu/execution/command_buffer.cpp | 133 ++++++------ src/gpu/execution/descriptor_set_layout.cpp | 6 +- src/gpu/execution/pipeline.cpp | 22 +- src/gpu/execution/pipeline_cache.cpp | 12 +- src/gpu/execution/queue.cpp | 52 ++--- src/gpu/execution/render_pass.cpp | 8 +- src/gpu/execution/swapchain.cpp | 16 +- src/gpu/resource/shader.cpp | 6 +- src/image/image.cpp | 17 +- src/image/png.cppm | 3 +- src/wsi/linux/wayland/context.cpp | 4 +- src/wsi/linux/wayland/wayland.cppm | 80 +++---- src/wsi/linux/wayland/window.cpp | 7 +- src/wsi/linux/x11/monitor.cppm | 7 +- src/wsi/linux/x11/window.cpp | 48 +++-- 35 files changed, 452 insertions(+), 439 deletions(-) diff --git a/.clang-format b/.clang-format index 849cdca54..24420da65 100644 --- a/.clang-format +++ b/.clang-format @@ -4,31 +4,31 @@ BasedOnStyle: LLVM Language: Cpp AlignAfterOpenBracket: Align AlignArrayOfStructures: Left -AlignConsecutiveAssignments: 'true' -AlignConsecutiveDeclarations: 'true' +AlignConsecutiveAssignments: "true" +AlignConsecutiveDeclarations: "true" AlignEscapedNewlines: Left AlignOperands: Align -AlignTrailingComments: 'true' -AllowAllParametersOfDeclarationOnNextLine: 'false' -AllowAllArgumentsOnNextLine: 'false' -AllowShortBlocksOnASingleLine: 'true' -AllowShortCaseLabelsOnASingleLine: 'true' +AlignTrailingComments: "true" +AllowAllParametersOfDeclarationOnNextLine: "false" +AllowAllArgumentsOnNextLine: "false" +AllowShortBlocksOnASingleLine: "true" +AllowShortCaseLabelsOnASingleLine: "true" AllowShortFunctionsOnASingleLine: InlineOnly AllowShortIfStatementsOnASingleLine: Always -AllowShortLoopsOnASingleLine: 'true' -AllowShortLambdasOnASingleLine: 'true' -AllowShortEnumsOnASingleLine: 'false' +AllowShortLoopsOnASingleLine: "true" +AllowShortLambdasOnASingleLine: "true" +AllowShortEnumsOnASingleLine: "false" AlignConsecutiveMacros: Consecutive BitFieldColonSpacing: After -BreakBeforeConceptDeclarations: 'true' +BreakBeforeConceptDeclarations: "true" BreakBinaryOperations: RespectPrecedence EmptyLineBeforeAccessModifier: LogicalBlock EnumTrailingComma: Insert -FixNamespaceComments: 'true' +FixNamespaceComments: "true" IndentExternBlock: Indent -IndentGotoLabels: 'false' -IndentRequiresClause: 'true' -InsertBraces: 'false' +IndentGotoLabels: "false" +IndentRequiresClause: "true" +InsertBraces: "false" InsertTrailingCommas: Wrapped LambdaBodyIndentation: Signature PPIndentWidth: 4 @@ -36,20 +36,29 @@ PenaltyBreakAssignment: 1000 PenaltyReturnTypeOnItsOwnLine: 1000 PenaltyBreakBeforeFirstCallParameter: 1000 PenaltyBreakOpenParenthesis: 1000 -PenaltyBreakBeforeMemberAccess: 10 -PenaltyIndentedWhitespace: 1 +PenaltyBreakBeforeMemberAccess: 1000 +PenaltyIndentedWhitespace: 2 ContinuationIndentWidth: 2 ReferenceAlignment: Left # RemoveBracesLLVM: 'true' RequiresClausePosition: OwnLine SeparateDefinitionBlocks: Always -SpaceAfterLogicalNot: 'false' +SpaceAfterLogicalNot: "false" SpaceAroundPointerQualifiers: After -SpaceBeforeCaseColon: 'false' +SpaceBeforeCaseColon: "false" AlwaysBreakAfterDefinitionReturnType: None -SpaceBeforeSquareBrackets: 'false' -SpaceInEmptyBlock: 'false' -AttributeMacros: [STORMKIT_FORCE_INLINE, STORMKIT_API, STORMKIT_PRIVATE, STORMKIT_PUBLIC, STORMKIT_CONST, STORMKIT_PURE, STORMKIT_INTRINSIC] +SpaceBeforeSquareBrackets: "false" +SpaceInEmptyBlock: "false" +AttributeMacros: + [ + STORMKIT_FORCE_INLINE, + STORMKIT_API, + STORMKIT_PRIVATE, + STORMKIT_PUBLIC, + STORMKIT_CONST, + STORMKIT_PURE, + STORMKIT_INTRINSIC, + ] IfMacros: [CASE_DO, CASE_DO_RETURN, CASE, CASE_ARGS_DO] BreakAfterAttributes: Always Macros: @@ -60,120 +69,122 @@ Macros: - STORMKIT_CONST=[[maybe_unused]] - STORMKIT_PURE=[[maybe_unused]] - STORMKIT_INTRINSIC=[[maybe_unused]] - + QualifierAlignment: Custom QualifierOrder: [static, inline, volatile, restrict, constexpr, const, type] SpacesInLineCommentPrefix: - Minimum: '1' - Maximum: '4' + Minimum: "1" + Maximum: "4" AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: 'false' -AlwaysBreakTemplateDeclarations: 'Yes' -BinPackArguments: 'false' -BinPackParameters: 'false' +AlwaysBreakBeforeMultilineStrings: "false" +AlwaysBreakTemplateDeclarations: "Yes" +BinPackArguments: "false" +BinPackParameters: "false" BreakBeforeBinaryOperators: All BreakBeforeBraces: Attach BreakConstructorInitializers: BeforeColon +BreakBeforeCloseBracketBracedList: "true" BreakInheritanceList: BeforeColon -BreakStringLiterals: 'true' -ColumnLimit: '130' -CompactNamespaces: 'true' -ConstructorInitializerAllOnOneLineOrOnePerLine: 'true' -ConstructorInitializerIndentWidth: '4' +BreakStringLiterals: "true" +ColumnLimit: "130" +CompactNamespaces: "true" +ConstructorInitializerAllOnOneLineOrOnePerLine: "true" +ConstructorInitializerIndentWidth: "4" IncludeBlocks: Preserve -IndentCaseLabels: 'true' -IndentWidth: '4' -IndentWrappedFunctionNames: 'true' +IndentCaseLabels: "true" +IndentWidth: "4" +IndentWrappedFunctionNames: "true" IndentPPDirectives: BeforeHash -KeepEmptyLinesAtTheStartOfBlocks: 'false' -Cpp11BracedListStyle: 'false' -MaxEmptyLinesToKeep: '1' +KeepEmptyLinesAtTheStartOfBlocks: "false" +Cpp11BracedListStyle: "Block" +MaxEmptyLinesToKeep: "1" NamespaceIndentation: All ObjCSpaceAfterProperty: true ObjCSpaceBeforeProtocolList: false PointerAlignment: Left -SortIncludes: 'true' -SortUsingDeclarations: 'true' -SpaceAfterTemplateKeyword: 'false' -SpaceBeforeAssignmentOperators: 'true' -SpaceBeforeCpp11BracedList: 'true' -SpaceBeforeCtorInitializerColon: 'true' -SpaceBeforeInheritanceColon: 'false' -SpaceBeforeRangeBasedForLoopColon: 'true' -SpaceInEmptyParentheses: 'false' -SpacesInAngles: 'false' +SortIncludes: "true" +SortUsingDeclarations: "true" +SpaceAfterTemplateKeyword: "false" +SpaceBeforeAssignmentOperators: "true" +SpaceBeforeCpp11BracedList: "true" +SpaceBeforeCtorInitializerColon: "true" +SpaceBeforeInheritanceColon: "false" +SpaceBeforeRangeBasedForLoopColon: "true" +SpaceInEmptyParentheses: "false" +SpacesInAngles: "false" Standard: c++20 -TabWidth: '4' +TabWidth: "4" UseTab: Never --- Language: ObjC AlignAfterOpenBracket: Align AlignArrayOfStructures: Left -AlignConsecutiveAssignments: 'true' -AlignConsecutiveDeclarations: 'false' +AlignConsecutiveAssignments: "true" +AlignConsecutiveDeclarations: "false" AlignEscapedNewlines: Left AlignOperands: Align -AlignTrailingComments: 'true' -AllowAllParametersOfDeclarationOnNextLine: 'false' -AllowAllArgumentsOnNextLine: 'false' -AllowShortBlocksOnASingleLine: 'true' -AllowShortCaseLabelsOnASingleLine: 'true' +AlignTrailingComments: "true" +AllowAllParametersOfDeclarationOnNextLine: "false" +AllowAllArgumentsOnNextLine: "false" +AllowShortBlocksOnASingleLine: "true" +AllowShortCaseLabelsOnASingleLine: "true" AllowShortFunctionsOnASingleLine: InlineOnly AllowShortIfStatementsOnASingleLine: Always -AllowShortLoopsOnASingleLine: 'true' -AllowShortLambdasOnASingleLine: 'true' +AllowShortLoopsOnASingleLine: "true" +AllowShortLambdasOnASingleLine: "true" AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None -AlwaysBreakBeforeMultilineStrings: 'false' -AlwaysBreakTemplateDeclarations: 'Yes' -BinPackArguments: 'false' -BinPackParameters: 'false' +AlwaysBreakBeforeMultilineStrings: "false" +AlwaysBreakTemplateDeclarations: "Yes" +BinPackArguments: "false" +BinPackParameters: "false" BreakBeforeBinaryOperators: All BreakBeforeBraces: Attach BreakBinaryOperations: OnePerLine BreakConstructorInitializers: BeforeColon BreakInheritanceList: BeforeColon -BreakStringLiterals: 'true' -ColumnLimit: '130' -CompactNamespaces: 'true' -ConstructorInitializerAllOnOneLineOrOnePerLine: 'false' -ConstructorInitializerIndentWidth: '4' -ContinuationIndentWidth: '4' +BreakStringLiterals: "true" +ColumnLimit: "130" +CompactNamespaces: "true" +ConstructorInitializerAllOnOneLineOrOnePerLine: "false" +ConstructorInitializerIndentWidth: "4" +ContinuationIndentWidth: "4" IncludeBlocks: Preserve -IndentCaseLabels: 'true' -IndentWidth: '4' -IndentWrappedFunctionNames: 'true' +IndentCaseLabels: "true" +IndentWidth: "4" +IndentWrappedFunctionNames: "true" IndentPPDirectives: BeforeHash -KeepEmptyLinesAtTheStartOfBlocks: 'false' -Cpp11BracedListStyle: 'false' -MaxEmptyLinesToKeep: '1' +KeepEmptyLinesAtTheStartOfBlocks: "false" +Cpp11BracedListStyle: "false" +MaxEmptyLinesToKeep: "1" NamespaceIndentation: All ObjCSpaceAfterProperty: true ObjCSpaceBeforeProtocolList: false PointerAlignment: Right -PenaltyBreakAssignment: 1000 -PenaltyReturnTypeOnItsOwnLine: 1000 -PenaltyBreakBeforeFirstCallParameter: 1000 -PenaltyBreakOpenParenthesis: 1000 -PenaltyBreakBeforeMemberAccess: 10 -SortIncludes: 'true' -SortUsingDeclarations: 'true' -SpaceAfterTemplateKeyword: 'false' -SpaceBeforeAssignmentOperators: 'true' -SpaceBeforeCpp11BracedList: 'true' -SpaceBeforeCtorInitializerColon: 'true' -SpaceBeforeInheritanceColon: 'false' -SpaceBeforeRangeBasedForLoopColon: 'true' -SpaceInEmptyParentheses: 'false' -SpacesInAngles: 'false' +PenaltyBreakAssignment: 300 +PenaltyReturnTypeOnItsOwnLine: 100 +PenaltyBreakBeforeFirstCallParameter: 500 +PenaltyBreakOpenParenthesis: 700 +PenaltyBreakBeforeMemberAccess: 700 +SortIncludes: "true" +SortUsingDeclarations: "true" +SpaceAfterTemplateKeyword: "false" +SpaceBeforeAssignmentOperators: "true" +SpaceBeforeCpp11BracedList: "true" +SpaceBeforeCtorInitializerColon: "true" +SpaceBeforeInheritanceColon: "false" +SpaceBeforeRangeBasedForLoopColon: "true" +SpaceInEmptyParentheses: "false" +SpacesInAngles: "false" Standard: c++20 -TabWidth: '4' +TabWidth: "4" UseTab: Never -PenaltyIndentedWhitespace: '1' +PenaltyIndentedWhitespace: "1" QualifierAlignment: Custom QualifierOrder: [static, inline, volatile, restrict, constexpr, const, type] -AttributeMacros: [STORMKIT_FORCE_INLINE, STORMKIT_API, STORMKIT_PRIVATE, STORMKIT_PUBLIC] +AttributeMacros: + [STORMKIT_FORCE_INLINE, STORMKIT_API, STORMKIT_PRIVATE, STORMKIT_PUBLIC] IfMacros: [CASE_DO, CASE_DO_RETURN, CASE, CASE_ARGS_DO] BreakAfterAttributes: Always diff --git a/modules/stormkit/core/containers/dag.cppm b/modules/stormkit/core/containers/dag.cppm index e71108753..95f13cfa6 100644 --- a/modules/stormkit/core/containers/dag.cppm +++ b/modules/stormkit/core/containers/dag.cppm @@ -226,8 +226,9 @@ namespace stormkit { inline namespace core { -> meta::ForwardLike { expects(self.has_vertex(id), std::format("Unknown DAG vertex id: {}!", id)); - return std::forward_like(stdr::find_if(self.m_vertices, [id](const auto& other) noexcept { return other.id == id; }) - ->value); + return std::forward_like(stdr::find_if(self.m_vertices, [id](const auto& other) noexcept { + return other.id == id; + })->value); } //////////////////////////////////////// @@ -338,8 +339,9 @@ namespace stormkit { inline namespace core { constexpr auto DAG::adjacent_edges(dag::VertexID id) const noexcept -> const std::vector& { expects(has_vertex(id), std::format("Unknown DAG vertex id: {}!", id)); - const auto& adjacent_edges = stdr::find_if(m_adjacent_edges, [id](const auto& pair) noexcept { return pair.first == id; }) - ->second; + const auto& adjacent_edges = stdr::find_if(m_adjacent_edges, [id](const auto& pair) noexcept { + return pair.first == id; + })->second; return adjacent_edges; } @@ -502,10 +504,12 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template constexpr auto DAG::dump(Closures closures) const noexcept -> std::string { - auto out = std::string { "digraph G {\n" - " rankdir = LR\n" - " bgcolor = black\n" - " node [shape=box, fontname=\"helvetica\", fontsize=12];\n\n" }; + auto out = std::string { + "digraph G {\n" + " rankdir = LR\n" + " bgcolor = black\n" + " node [shape=box, fontname=\"helvetica\", fontsize=12];\n\n" + }; if (closures.format_value) for (const auto& [id, value] : m_vertices) { diff --git a/modules/stormkit/core/errors.cppm b/modules/stormkit/core/errors.cppm index 65ecd9576..e781bf46d 100644 --- a/modules/stormkit/core/errors.cppm +++ b/modules/stormkit/core/errors.cppm @@ -164,8 +164,8 @@ namespace std { template template STORMKIT_FORCE_INLINE - inline auto formatter, CharT>::format(const stormkit::core::Error& error, - FormatContext& ctx) const -> decltype(ctx.out()) { + inline auto formatter, CharT>::format(const stormkit::core::Error& error, FormatContext& ctx) + const -> decltype(ctx.out()) { return formatter::format(error.code, ctx); } diff --git a/modules/stormkit/core/functional/monadic.cppm b/modules/stormkit/core/functional/monadic.cppm index a0c406e02..cb12bf6e4 100644 --- a/modules/stormkit/core/functional/monadic.cppm +++ b/modules/stormkit/core/functional/monadic.cppm @@ -332,8 +332,7 @@ namespace stormkit { inline namespace core { namespace monadic { ///////////////////////////////////// ///////////////////////////////////// template - STORMKIT_FORCE_INLINE - STORMKIT_PURE + STORMKIT_FORCE_INLINE STORMKIT_PURE constexpr auto either(meta::IsUnaryPredicate auto&& predicate, std::invocable auto&& true_, std::invocable auto&& false_) noexcept -> decltype(auto) { diff --git a/modules/stormkit/core/math/combinatoric.cppm b/modules/stormkit/core/math/combinatoric.cppm index 205cb2269..e96151221 100644 --- a/modules/stormkit/core/math/combinatoric.cppm +++ b/modules/stormkit/core/math/combinatoric.cppm @@ -24,8 +24,9 @@ export namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////////////////////////////////// namespace stormkit { inline namespace core { namespace math { - constexpr auto FTABLE = std::array { 1, 1, 2, 6, 24, 120, 720, - 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800 }; + constexpr auto FTABLE = std::array { + 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800 + }; ///////////////////////////////////// ///////////////////////////////////// diff --git a/modules/stormkit/core/math/linear-matrix.cppm b/modules/stormkit/core/math/linear-matrix.cppm index 06330de91..a5bfeee77 100644 --- a/modules/stormkit/core/math/linear-matrix.cppm +++ b/modules/stormkit/core/math/linear-matrix.cppm @@ -562,8 +562,10 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m template STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto as_view(const T& value) noexcept -> std::span { - return std::span { stdr::data(value), - T::EXTENTS[0] * T::EXTENTS[1] }; + return std::span { + stdr::data(value), + T::EXTENTS[0] * T::EXTENTS[1] + }; } //////////////////////////////////////// @@ -571,8 +573,10 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m template STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto as_view_mut(T& value) noexcept -> std::span { - return std::span { stdr::data(value), - T::EXTENTS[0] * T::EXTENTS[1] }; + return std::span { + stdr::data(value), + T::EXTENTS[0] * T::EXTENTS[1] + }; } //////////////////////////////////////// diff --git a/modules/stormkit/core/meta/concepts.cppm b/modules/stormkit/core/meta/concepts.cppm index 05c6ee51d..d27b00236 100644 --- a/modules/stormkit/core/meta/concepts.cppm +++ b/modules/stormkit/core/meta/concepts.cppm @@ -307,18 +307,19 @@ export namespace stormkit { inline namespace core { namespace meta { concept IsCharType = IsAnyOf; template - concept IsColorComponent = IsAnyOf; + >; template concept IsConst = std::is_const_v; diff --git a/modules/stormkit/core/parallelism/locked.cppm b/modules/stormkit/core/parallelism/locked.cppm index 1fa29fa4e..88a3304c9 100644 --- a/modules/stormkit/core/parallelism/locked.cppm +++ b/modules/stormkit/core/parallelism/locked.cppm @@ -305,10 +305,9 @@ namespace stormkit { inline namespace core { template template class Lock, typename... LockArgs> STORMKIT_FORCE_INLINE - auto Locked::assign(ConstReferenceType value, - LockArgs&&... lock_args) noexcept(noexcept(std::is_nothrow_assignable_v)) - -> void { + auto Locked:: + assign(ConstReferenceType value, + LockArgs&&... lock_args) noexcept(noexcept(std::is_nothrow_assignable_v)) -> void { *write(std::forward(lock_args)...) = value; } diff --git a/modules/stormkit/core/typesafe/strong_type.cppm b/modules/stormkit/core/typesafe/strong_type.cppm index 8abbd2ca8..99b4dae21 100644 --- a/modules/stormkit/core/typesafe/strong_type.cppm +++ b/modules/stormkit/core/typesafe/strong_type.cppm @@ -223,15 +223,15 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr StrongType::~StrongType() noexcept(meta::IsNoexceptDestructible< - ValueType>) = default; + constexpr StrongType:: + ~StrongType() noexcept(meta::IsNoexceptDestructible) = default; //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr StrongType::StrongType(const StrongType&) noexcept(meta::IsNoexceptCopyConstructible< - ValueType>) + constexpr StrongType:: + StrongType(const StrongType&) noexcept(meta::IsNoexceptCopyConstructible) requires(meta::IsCopyConstructible) = default; @@ -248,8 +248,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr StrongType::StrongType(StrongType&&) noexcept(meta::IsNoexceptMoveConstructible< - ValueType>) + constexpr StrongType:: + StrongType(StrongType&&) noexcept(meta::IsNoexceptMoveConstructible) requires(meta::IsMoveConstructible) = default; @@ -257,8 +257,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto StrongType::operator=(StrongType&&) noexcept(meta::IsNoexceptMoveAssignable< - ValueType>) -> StrongType& + constexpr auto StrongType:: + operator=(StrongType&&) noexcept(meta::IsNoexceptMoveAssignable) -> StrongType& requires(meta::IsMoveAssignable) = default; diff --git a/modules/stormkit/core/utils/dynamic_loader.cppm b/modules/stormkit/core/utils/dynamic_loader.cppm index 540c87c57..2e7b38447 100644 --- a/modules/stormkit/core/utils/dynamic_loader.cppm +++ b/modules/stormkit/core/utils/dynamic_loader.cppm @@ -100,16 +100,18 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// inline auto DynamicLoader::allocate_and_load(std::filesystem::path filepath) noexcept -> Expected> { - return load(std::move(filepath)) - .transform([](auto&& loader) { return std::make_unique(std::move(loader)); }); + return load(std::move(filepath)).transform([](auto&& loader) { + return std::make_unique(std::move(loader)); + }); } ///////////////////////////////////// ///////////////////////////////////// template inline auto DynamicLoader::func(std::string_view name) const noexcept -> Expected> { - return c_func(name) - .transform([](T&& value) { return std::function { std::forward(value) }; }); + return c_func(name).transform([](T&& value) { + return std::function { std::forward(value) }; + }); } ///////////////////////////////////// @@ -118,8 +120,9 @@ namespace stormkit { inline namespace core { inline auto DynamicLoader::c_func(std::string_view name) const noexcept -> Expected { EXPECTS(not std::empty(name)); - return do_get_func(name) - .transform([](T&& value) { return std::bit_cast(std::forward(value)); }); + return do_get_func(name).transform([](T&& value) { + return std::bit_cast(std::forward(value)); + }); } ///////////////////////////////////// diff --git a/modules/stormkit/entities.cppm b/modules/stormkit/entities.cppm index 5f3fea0c7..9532cb2a5 100644 --- a/modules/stormkit/entities.cppm +++ b/modules/stormkit/entities.cppm @@ -530,8 +530,8 @@ namespace stormkit::entities { auto it = stdr::find_if(m_components, [type = type](const auto& pair) noexcept { return pair.type == type; }); if (it == stdr::cend(m_components)) - it = m_components - .emplace(stdr::cend(m_components), Store { type, stdr::size(component), {}, {}, std::move(delete_func) }); + it = m_components.emplace(stdr::cend(m_components), + Store { type, stdr::size(component), {}, {}, std::move(delete_func) }); ENSURES(it != stdr::cend(m_components)); diff --git a/modules/stormkit/gpu/core/base.cppm b/modules/stormkit/gpu/core/base.cppm index 8cb2ec392..987f59132 100644 --- a/modules/stormkit/gpu/core/base.cppm +++ b/modules/stormkit/gpu/core/base.cppm @@ -480,8 +480,8 @@ namespace stormkit::gpu { template requires(meta::HasOwnerType) STORMKIT_FORCE_INLINE - inline GpuObjectViewImplementation::GpuObjectViewImplementation(const GpuObjectViewImplementation& - other) noexcept = default; + inline GpuObjectViewImplementation< + Tag>::GpuObjectViewImplementation(const GpuObjectViewImplementation& other) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// diff --git a/modules/stormkit/gpu/core/vulkan/enums.cppm b/modules/stormkit/gpu/core/vulkan/enums.cppm index c505dc746..f50f4976e 100644 --- a/modules/stormkit/gpu/core/vulkan/enums.cppm +++ b/modules/stormkit/gpu/core/vulkan/enums.cppm @@ -877,10 +877,9 @@ export { } template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::AttachmentLoadOperation - value) noexcept -> std::string_view { + STORMKIT_FORCE_INLINE STORMKIT_CONST + constexpr auto stormkit::core::as_string< + stormkit::gpu::AttachmentLoadOperation>(stormkit::gpu::AttachmentLoadOperation value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; @@ -891,8 +890,8 @@ export { template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentLoadOperation - value) noexcept -> std::string { + constexpr auto stormkit::core::to_string< + stormkit::gpu::AttachmentLoadOperation>(stormkit::gpu::AttachmentLoadOperation value) noexcept -> std::string { switch (value) { case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; @@ -914,10 +913,9 @@ export { } template<> - STORMKIT_FORCE_INLINE - STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::AttachmentStoreOperation - value) noexcept -> std::string_view { + STORMKIT_FORCE_INLINE STORMKIT_CONST + constexpr auto stormkit::core::as_string< + stormkit::gpu::AttachmentStoreOperation>(stormkit::gpu::AttachmentStoreOperation value) noexcept -> std::string_view { switch (value) { case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; @@ -927,8 +925,8 @@ export { template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::AttachmentStoreOperation - value) noexcept -> std::string { + constexpr auto stormkit::core::to_string< + stormkit::gpu::AttachmentStoreOperation>(stormkit::gpu::AttachmentStoreOperation value) noexcept -> std::string { switch (value) { case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; diff --git a/modules/stormkit/gpu/execution/command_buffer.cppm b/modules/stormkit/gpu/execution/command_buffer.cppm index 8641ce297..15fb72fdd 100644 --- a/modules/stormkit/gpu/execution/command_buffer.cppm +++ b/modules/stormkit/gpu/execution/command_buffer.cppm @@ -438,7 +438,8 @@ namespace stormkit::gpu { std::optional fence) noexcept -> Expected { auto cmbs = as_views(self); auto submit_infos = std::array { - Queue::SubmitInfo { .wait_semaphores = wait_semaphores, + Queue::SubmitInfo { + .wait_semaphores = wait_semaphores, .wait_dst_stages = wait_dst_stages, .command_buffers = cmbs, .signal_semaphores = signal_semaphores } diff --git a/modules/stormkit/image.cppm b/modules/stormkit/image.cppm index 6ca408cac..985b216ba 100644 --- a/modules/stormkit/image.cppm +++ b/modules/stormkit/image.cppm @@ -682,8 +682,8 @@ namespace stormkit::image { template template -auto std::formatter::format(const stormkit::image::Image::Error& error, - FormatContext& ctx) const noexcept -> decltype(ctx.out()) { +auto std::formatter::format(const stormkit::image::Image::Error& error, FormatContext& ctx) + const noexcept -> decltype(ctx.out()) { auto&& out = ctx.out(); return format_to(out, "{}", error.str_error); } diff --git a/src/gpu/core/debug_callback.cpp b/src/gpu/core/debug_callback.cpp index 2f51209ef..c7dfdb760 100644 --- a/src/gpu/core/debug_callback.cpp +++ b/src/gpu/core/debug_callback.cpp @@ -44,10 +44,8 @@ namespace stormkit::gpu { .pUserData = user_data, }; - m_vk_handle = Try(vk::call_checked(vkCreateDebugUtilsMessengerEXT, - owner(), - &create_info, - nullptr)); + m_vk_handle = Try(vk::call_checked< + VkDebugUtilsMessengerEXT>(vkCreateDebugUtilsMessengerEXT, owner(), &create_info, nullptr)); Return {}; } } // namespace stormkit::gpu diff --git a/src/gpu/core/device.cpp b/src/gpu/core/device.cpp index a31b3e4e7..f84b858dd 100644 --- a/src/gpu/core/device.cpp +++ b/src/gpu/core/device.cpp @@ -216,14 +216,13 @@ namespace stormkit::gpu { const auto device_table = this->device_table(); const auto _fences = transform(fences, vk::monadic::to_vk()); - const auto result = Try((vk::call_checked(device_table.vkWaitForFences, - *this, - stdr::size(_fences), - stdr::data(_fences), - wait_all, - std::chrono::duration_cast< - std::chrono::nanoseconds>(timeout) - .count()))); + const auto result = Try((vk::call_checked( + device_table.vkWaitForFences, + *this, + stdr::size(_fences), + stdr::data(_fences), + wait_all, + std::chrono::duration_cast(timeout).count()))); return vk::from_vk(result); } diff --git a/src/gpu/core/fence.cpp b/src/gpu/core/fence.cpp index ddbcd0c10..1ebb0b3c2 100644 --- a/src/gpu/core/fence.cpp +++ b/src/gpu/core/fence.cpp @@ -41,13 +41,13 @@ namespace stormkit::gpu { const auto handle = Base::native_handle(); const auto - result = Try((vk::call_checked(device_table.vkWaitForFences, - device, - 1u, - &handle, - true, - std::chrono::duration_cast(wait_for) - .count()))); + result = Try((vk::call_checked(device_table.vkWaitForFences, + device, + 1u, + &handle, + true, + std::chrono::duration_cast(wait_for).count()))); Return vk::from_vk(result); } @@ -73,9 +73,11 @@ namespace stormkit::gpu { auto FenceImplementation::do_init(PrivateTag, bool signaled) noexcept -> Expected { const auto flags = (signaled) ? VkFenceCreateFlags { VK_FENCE_CREATE_SIGNALED_BIT } : VkFenceCreateFlags {}; - const auto create_info = VkFenceCreateInfo { .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, - .pNext = nullptr, - .flags = flags }; + const auto create_info = VkFenceCreateInfo { + .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, + .pNext = nullptr, + .flags = flags + }; const auto& device = owner(); const auto& device_table = device.device_table(); diff --git a/src/gpu/core/instance.cpp b/src/gpu/core/instance.cpp index c7b36b985..9dd202811 100644 --- a/src/gpu/core/instance.cpp +++ b/src/gpu/core/instance.cpp @@ -37,9 +37,8 @@ namespace stormkit::gpu { // constexpr auto VALIDATION_FEATURES = into_array_of(VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT, // VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT); - constexpr auto STORMKIT_VK_VERSION = vk::make_version(STORMKIT_MAJOR_VERSION, - STORMKIT_MINOR_VERSION, - STORMKIT_PATCH_VERSION); + constexpr auto + STORMKIT_VK_VERSION = vk::make_version(STORMKIT_MAJOR_VERSION, STORMKIT_MINOR_VERSION, STORMKIT_PATCH_VERSION); constexpr auto BASE_EXTENSIONS = into_array_of(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME #ifdef STORMKIT_OS_APPLE diff --git a/src/gpu/core/physical_device.cpp b/src/gpu/core/physical_device.cpp index 615934144..579f79912 100644 --- a/src/gpu/core/physical_device.cpp +++ b/src/gpu/core/physical_device.cpp @@ -105,16 +105,16 @@ namespace stormkit::gpu { capabilities.limits.max_per_stage_descriptor_storage_buffers = properties.limits.maxPerStageDescriptorStorageBuffers; capabilities.limits.max_per_stage_descriptor_sampled_images = properties.limits.maxPerStageDescriptorSampledImages; capabilities.limits.max_per_stage_descriptor_storage_images = properties.limits.maxPerStageDescriptorStorageImages; - capabilities.limits - .max_per_stage_descriptor_input_attachments = properties.limits.maxPerStageDescriptorInputAttachments; + capabilities.limits.max_per_stage_descriptor_input_attachments + = properties.limits.maxPerStageDescriptorInputAttachments; capabilities.limits.max_per_stage_resources = properties.limits.maxPerStageResources; capabilities.limits.max_descriptor_set_samplers = properties.limits.maxDescriptorSetSamplers; capabilities.limits.max_descriptor_set_uniform_buffers = properties.limits.maxDescriptorSetUniformBuffers; - capabilities.limits - .max_descriptor_set_uniform_buffers_dynamic = properties.limits.maxDescriptorSetUniformBuffersDynamic; + capabilities.limits.max_descriptor_set_uniform_buffers_dynamic + = properties.limits.maxDescriptorSetUniformBuffersDynamic; capabilities.limits.max_descriptor_set_storage_buffers = properties.limits.maxDescriptorSetStorageBuffers; - capabilities.limits - .max_descriptor_set_storage_buffers_dynamic = properties.limits.maxDescriptorSetStorageBuffersDynamic; + capabilities.limits.max_descriptor_set_storage_buffers_dynamic + = properties.limits.maxDescriptorSetStorageBuffersDynamic; capabilities.limits.max_descriptor_set_sampled_images = properties.limits.maxDescriptorSetSampledImages; capabilities.limits.max_descriptor_set_storage_images = properties.limits.maxDescriptorSetStorageImages; capabilities.limits.max_descriptor_set_input_attachments = properties.limits.maxDescriptorSetInputAttachments; @@ -125,25 +125,22 @@ namespace stormkit::gpu { capabilities.limits.max_vertex_output_components = properties.limits.maxVertexOutputComponents; capabilities.limits.max_tessellation_generation_level = properties.limits.maxTessellationGenerationLevel; capabilities.limits.max_tessellation_patch_size = properties.limits.maxTessellationPatchSize; - capabilities.limits - .max_tessellation_control_per_vertex_input_components = properties.limits - .maxTessellationControlPerVertexInputComponents; - capabilities.limits - .max_tessellation_control_per_vertex_output_components = properties.limits - .maxTessellationControlPerVertexOutputComponents; - capabilities.limits - .max_tessellation_control_per_patch_output_components = properties.limits - .maxTessellationControlPerPatchOutputComponents; - capabilities.limits - .max_tessellation_control_total_output_components = properties.limits.maxTessellationControlTotalOutputComponents; - capabilities.limits - .max_tessellation_evaluation_input_components = properties.limits.maxTessellationEvaluationInputComponents; - capabilities.limits - .max_tessellation_evaluation_output_components = properties.limits.maxTessellationEvaluationOutputComponents; - capabilities.limits.max_geometry_shader_invocations = properties.limits.maxGeometryShaderInvocations; - capabilities.limits.max_geometry_input_components = properties.limits.maxGeometryInputComponents; - capabilities.limits.max_geometry_output_components = properties.limits.maxGeometryOutputComponents; - capabilities.limits.max_geometry_output_vertices = properties.limits.maxGeometryOutputVertices; + capabilities.limits.max_tessellation_control_per_vertex_input_components + = properties.limits.maxTessellationControlPerVertexInputComponents; + capabilities.limits.max_tessellation_control_per_vertex_output_components + = properties.limits.maxTessellationControlPerVertexOutputComponents; + capabilities.limits.max_tessellation_control_per_patch_output_components + = properties.limits.maxTessellationControlPerPatchOutputComponents; + capabilities.limits.max_tessellation_control_total_output_components + = properties.limits.maxTessellationControlTotalOutputComponents; + capabilities.limits.max_tessellation_evaluation_input_components + = properties.limits.maxTessellationEvaluationInputComponents; + capabilities.limits.max_tessellation_evaluation_output_components + = properties.limits.maxTessellationEvaluationOutputComponents; + capabilities.limits.max_geometry_shader_invocations = properties.limits.maxGeometryShaderInvocations; + capabilities.limits.max_geometry_input_components = properties.limits.maxGeometryInputComponents; + capabilities.limits.max_geometry_output_components = properties.limits.maxGeometryOutputComponents; + capabilities.limits.max_geometry_output_vertices = properties.limits.maxGeometryOutputVertices; capabilities.limits.max_geometry_total_output_components = properties.limits.maxGeometryTotalOutputComponents; capabilities.limits.max_fragment_input_components = properties.limits.maxFragmentInputComponents; capabilities.limits.max_fragment_output_attachments = properties.limits.maxFragmentOutputAttachments; @@ -178,24 +175,23 @@ namespace stormkit::gpu { capabilities.limits.max_framebuffer_width = properties.limits.maxFramebufferWidth; capabilities.limits.max_framebuffer_height = properties.limits.maxFramebufferHeight; capabilities.limits.max_framebuffer_layers = properties.limits.maxFramebufferLayers; - capabilities.limits - .framebuffer_color_sample_counts = narrow(properties.limits.framebufferColorSampleCounts); - capabilities.limits - .framebuffer_depth_sample_counts = narrow(properties.limits.framebufferDepthSampleCounts); - capabilities.limits - .framebuffer_stencil_sample_counts = narrow(properties.limits.framebufferStencilSampleCounts); - capabilities.limits - .framebuffer_no_attachments_sample_counts = narrow(properties.limits - .framebufferNoAttachmentsSampleCounts); - capabilities.limits.max_color_attachments = properties.limits.maxColorAttachments; - capabilities.limits - .sampled_image_color_sample_counts = narrow(properties.limits.sampledImageColorSampleCounts); - capabilities.limits - .sampled_image_integer_sample_counts = narrow(properties.limits.sampledImageIntegerSampleCounts); - capabilities.limits - .sampled_image_depth_sample_counts = narrow(properties.limits.sampledImageDepthSampleCounts); - capabilities.limits - .sampled_image_stencil_sample_counts = narrow(properties.limits.sampledImageStencilSampleCounts); + capabilities.limits.framebuffer_color_sample_counts = narrow< + SampleCountFlag>(properties.limits.framebufferColorSampleCounts); + capabilities.limits.framebuffer_depth_sample_counts = narrow< + SampleCountFlag>(properties.limits.framebufferDepthSampleCounts); + capabilities.limits.framebuffer_stencil_sample_counts = narrow< + SampleCountFlag>(properties.limits.framebufferStencilSampleCounts); + capabilities.limits.framebuffer_no_attachments_sample_counts = narrow< + SampleCountFlag>(properties.limits.framebufferNoAttachmentsSampleCounts); + capabilities.limits.max_color_attachments = properties.limits.maxColorAttachments; + capabilities.limits.sampled_image_color_sample_counts = narrow< + SampleCountFlag>(properties.limits.sampledImageColorSampleCounts); + capabilities.limits.sampled_image_integer_sample_counts = narrow< + SampleCountFlag>(properties.limits.sampledImageIntegerSampleCounts); + capabilities.limits.sampled_image_depth_sample_counts = narrow< + SampleCountFlag>(properties.limits.sampledImageDepthSampleCounts); + capabilities.limits.sampled_image_stencil_sample_counts = narrow< + SampleCountFlag>(properties.limits.sampledImageStencilSampleCounts); capabilities.limits.storage_image_sample_counts = narrow(properties.limits.storageImageSampleCounts); capabilities.limits.max_sample_mask_words = properties.limits.maxSampleMaskWords; capabilities.limits.timestamp_compute_and_engine = properties.limits.timestampComputeAndGraphics; @@ -278,8 +274,9 @@ namespace stormkit::gpu { const auto vk_memory_properties = vk::call(vkGetPhysicalDeviceMemoryProperties, handle); - return transform(std::span { vk_memory_properties.memoryTypes, 32 }, - [](const auto& type) static noexcept { return narrow(type.propertyFlags); }); + return transform(std::span { vk_memory_properties.memoryTypes, 32 }, [](const auto& type) static noexcept { + return narrow(type.propertyFlags); + }); } auto queue_families(const PhysicalDeviceImplementation& physical_device) noexcept -> std::vector { diff --git a/src/gpu/execution/command_buffer.cpp b/src/gpu/execution/command_buffer.cpp index 95076b31f..fa1204037 100644 --- a/src/gpu/execution/command_buffer.cpp +++ b/src/gpu/execution/command_buffer.cpp @@ -127,14 +127,14 @@ namespace stormkit::gpu { vk_rendering_inheritance_info.pColorAttachmentFormats = stdr::data(rendering_color_attachments); if (inheritance_info.depth_attachment) - vk_rendering_inheritance_info - .depthAttachmentFormat = gpu::vk::to_vk(*inheritance_info.depth_attachment); + vk_rendering_inheritance_info.depthAttachmentFormat = gpu::vk::to_vk< + VkFormat>(*inheritance_info.depth_attachment); if (inheritance_info.stencil_attachment) - vk_rendering_inheritance_info - .stencilAttachmentFormat = gpu::vk::to_vk(*inheritance_info.stencil_attachment); + vk_rendering_inheritance_info.stencilAttachmentFormat = gpu::vk::to_vk< + VkFormat>(*inheritance_info.stencil_attachment); - vk_rendering_inheritance_info - .rasterizationSamples = gpu::vk::to_vk(inheritance_info.rasterization_samples); + vk_rendering_inheritance_info.rasterizationSamples = gpu::vk::to_vk< + VkSampleCountFlagBits>(inheritance_info.rasterization_samples); } return info; }(); @@ -269,25 +269,22 @@ namespace stormkit::gpu { attachment_info.resolveImageLayout = vk::to_vk(resolve.layout); } if (attachment.clear_value) { - attachment_info - .clearValue = std::visit(Overloaded { - [](const ClearColor& clear_color) static noexcept -> decltype(auto) { - return VkClearValue { - .color = VkClearColorValue { .float32 = { clear_color.color.r, - clear_color.color.b, - clear_color.color.g, - clear_color.color.a } }, - }; - }, - [](const ClearDepthStencil& clear_depth_stencil) static noexcept -> decltype(auto) { - return VkClearValue { - .depthStencil = VkClearDepthStencilValue { .depth = clear_depth_stencil - .depth, - .stencil = clear_depth_stencil - .stencil }, - }; - } }, - *attachment.clear_value); + attachment_info.clearValue = std:: + visit(Overloaded { [](const ClearColor& clear_color) static noexcept -> decltype(auto) { + return VkClearValue { + .color = VkClearColorValue { .float32 = { clear_color.color.r, + clear_color.color.b, + clear_color.color.g, + clear_color.color.a } }, + }; + }, + [](const ClearDepthStencil& clear_depth_stencil) static noexcept -> decltype(auto) { + return VkClearValue { + .depthStencil = VkClearDepthStencilValue { .depth = clear_depth_stencil.depth, + .stencil = clear_depth_stencil.stencil }, + }; + } }, + *attachment.clear_value); } return attachment_info; @@ -333,24 +330,23 @@ namespace stormkit::gpu { const auto& device = Base::owner(); const auto& device_table = device.device_table(); - const auto - vk_clear_values = transform(clear_values, - cmonadic::either( - [](const ClearColor& clear_color) static noexcept -> decltype(auto) { - return VkClearValue { - .color = VkClearColorValue { .float32 = { clear_color.color.r, - clear_color.color.b, - clear_color.color.g, - clear_color.color.a } }, - }; - }, - [](const ClearDepthStencil& clear_depth_stencil) static noexcept -> decltype(auto) { - return VkClearValue { - .depthStencil = VkClearDepthStencilValue { .depth = clear_depth_stencil.depth, - .stencil = clear_depth_stencil - .stencil }, - }; - })); + const auto vk_clear_values = transform( + clear_values, + cmonadic::either( + [](const ClearColor& clear_color) static noexcept -> decltype(auto) { + return VkClearValue { + .color = VkClearColorValue { .float32 = { clear_color.color.r, + clear_color.color.b, + clear_color.color.g, + clear_color.color.a } }, + }; + }, + [](const ClearDepthStencil& clear_depth_stencil) static noexcept -> decltype(auto) { + return VkClearValue { + .depthStencil = VkClearDepthStencilValue { .depth = clear_depth_stencil.depth, + .stencil = clear_depth_stencil.stencil }, + }; + })); const auto begin_info = VkRenderPassBeginInfo { .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, @@ -421,8 +417,9 @@ namespace stormkit::gpu { const auto& device = Base::owner(); const auto& device_table = device.device_table(); - const auto bind_point = (pipeline.type() == Pipeline::Type::RASTER) ? VK_PIPELINE_BIND_POINT_GRAPHICS - : VK_PIPELINE_BIND_POINT_COMPUTE; + const auto bind_point = (pipeline.type() == Pipeline::Type::RASTER) + ? VK_PIPELINE_BIND_POINT_GRAPHICS + : VK_PIPELINE_BIND_POINT_COMPUTE; vk::call(device_table.vkCmdBindPipeline, *this, bind_point, pipeline); return *this; @@ -602,11 +599,9 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto CommandBufferInterface::draw_indexed(u32 index_count, - u32 instance_count, - u32 first_index, - i32 vertex_offset, - u32 first_instance) const noexcept -> const CommandBufferInterface& { + auto CommandBufferInterface:: + draw_indexed(u32 index_count, u32 instance_count, u32 first_index, i32 vertex_offset, u32 first_instance) const noexcept + -> const CommandBufferInterface& { EXPECTS(index_count > 0); const auto state = this->state(); @@ -656,9 +651,8 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto CommandBufferInterface::bind_vertex_buffers(std::span buffers, - std::span offsets) const noexcept - -> const CommandBufferInterface& { + auto CommandBufferInterface::bind_vertex_buffers(std::span buffers, std::span offsets) + const noexcept -> const CommandBufferInterface& { EXPECTS(not std::empty(buffers)); EXPECTS(std::size(buffers) == std::size(offsets)); @@ -712,8 +706,9 @@ namespace stormkit::gpu { const auto& device = Base::owner(); const auto& device_table = device.device_table(); - const auto bind_point = (pipeline.type() == Pipeline::Type::RASTER) ? VK_PIPELINE_BIND_POINT_GRAPHICS - : VK_PIPELINE_BIND_POINT_COMPUTE; + const auto bind_point = (pipeline.type() == Pipeline::Type::RASTER) + ? VK_PIPELINE_BIND_POINT_GRAPHICS + : VK_PIPELINE_BIND_POINT_COMPUTE; const auto vk_descriptor_sets = transform(descriptor_sets, vk::monadic::to_vk()); @@ -775,12 +770,14 @@ namespace stormkit::gpu { .layerCount = buffer_image_copy.subresource_layers.layer_count, }; - return VkBufferImageCopy { .bufferOffset = buffer_image_copy.buffer_offset, - .bufferRowLength = buffer_image_copy.buffer_row_length, - .bufferImageHeight = buffer_image_copy.buffer_image_height, - .imageSubresource = image_subresource, - .imageOffset = vk::to_vk(buffer_image_copy.offset), - .imageExtent = vk::to_vk(buffer_image_copy.extent) }; + return VkBufferImageCopy { + .bufferOffset = buffer_image_copy.buffer_offset, + .bufferRowLength = buffer_image_copy.buffer_row_length, + .bufferImageHeight = buffer_image_copy.buffer_image_height, + .imageSubresource = image_subresource, + .imageOffset = vk::to_vk(buffer_image_copy.offset), + .imageExtent = vk::to_vk(buffer_image_copy.extent) + }; }); vk::call(device_table.vkCmdCopyBufferToImage, @@ -820,12 +817,14 @@ namespace stormkit::gpu { .layerCount = buffer_image_copy.subresource_layers.layer_count, }; - return VkBufferImageCopy { .bufferOffset = buffer_image_copy.buffer_offset, - .bufferRowLength = buffer_image_copy.buffer_row_length, - .bufferImageHeight = buffer_image_copy.buffer_image_height, - .imageSubresource = image_subresource, - .imageOffset = vk::to_vk(buffer_image_copy.offset), - .imageExtent = vk::to_vk(buffer_image_copy.extent) }; + return VkBufferImageCopy { + .bufferOffset = buffer_image_copy.buffer_offset, + .bufferRowLength = buffer_image_copy.buffer_row_length, + .bufferImageHeight = buffer_image_copy.buffer_image_height, + .imageSubresource = image_subresource, + .imageOffset = vk::to_vk(buffer_image_copy.offset), + .imageExtent = vk::to_vk(buffer_image_copy.extent) + }; }); vk::call(device_table.vkCmdCopyImageToBuffer, diff --git a/src/gpu/execution/descriptor_set_layout.cpp b/src/gpu/execution/descriptor_set_layout.cpp index be17da3c4..63cfab177 100644 --- a/src/gpu/execution/descriptor_set_layout.cpp +++ b/src/gpu/execution/descriptor_set_layout.cpp @@ -50,10 +50,8 @@ namespace stormkit::gpu { const auto& device = owner(); const auto& device_table = device.device_table(); - m_vk_handle = Try(vk::call_checked(device_table.vkCreateDescriptorSetLayout, - device, - &create_info, - nullptr)); + m_vk_handle = Try(vk::call_checked< + VkDescriptorSetLayout>(device_table.vkCreateDescriptorSetLayout, device, &create_info, nullptr)); Return {}; } diff --git a/src/gpu/execution/pipeline.cpp b/src/gpu/execution/pipeline.cpp index c3af0859e..5f6e684eb 100644 --- a/src/gpu/execution/pipeline.cpp +++ b/src/gpu/execution/pipeline.cpp @@ -55,17 +55,17 @@ namespace stormkit::gpu { }; }); - out - .input_attribute_descriptions = transform(state.vertex_input_state.input_attribute_descriptions, - [](auto&& input_attribute_description) static noexcept { - return VkVertexInputAttributeDescription { - .location = input_attribute_description.location, - .binding = input_attribute_description.binding, - .format = vk::to_vk(input_attribute_description.format), - .offset = input_attribute_description.offset - }; - }); - out.vertex_input_info = VkPipelineVertexInputStateCreateInfo { + out.input_attribute_descriptions = transform(state.vertex_input_state.input_attribute_descriptions, + [](auto&& input_attribute_description) static noexcept { + return VkVertexInputAttributeDescription { + .location = input_attribute_description.location, + .binding = input_attribute_description.binding, + .format = vk::to_vk< + VkFormat>(input_attribute_description.format), + .offset = input_attribute_description.offset + }; + }); + out.vertex_input_info = VkPipelineVertexInputStateCreateInfo { .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, .pNext = nullptr, .flags = 0, diff --git a/src/gpu/execution/pipeline_cache.cpp b/src/gpu/execution/pipeline_cache.cpp index 66b273d5c..1e7801611 100644 --- a/src/gpu/execution/pipeline_cache.cpp +++ b/src/gpu/execution/pipeline_cache.cpp @@ -72,10 +72,8 @@ namespace stormkit::gpu { .pInitialData = nullptr, }; - m_vk_handle = TryTransformError(vk::call_checked(device_table.vkCreatePipelineCache, - device, - &create_info, - nullptr), + m_vk_handle = TryTransformError(vk::call_checked< + VkPipelineCache>(device_table.vkCreatePipelineCache, device, &create_info, nullptr), result_to_load_error); Return {}; @@ -115,10 +113,8 @@ namespace stormkit::gpu { .pInitialData = stdr::data(data), }; - m_vk_handle = TryTransformError(vk::call_checked(device_table.vkCreatePipelineCache, - device, - &create_info, - nullptr), + m_vk_handle = TryTransformError(vk::call_checked< + VkPipelineCache>(device_table.vkCreatePipelineCache, device, &create_info, nullptr), result_to_load_error); Return {}; diff --git a/src/gpu/execution/queue.cpp b/src/gpu/execution/queue.cpp index 30b8d5d0d..2e03e32d0 100644 --- a/src/gpu/execution/queue.cpp +++ b/src/gpu/execution/queue.cpp @@ -80,22 +80,22 @@ namespace stormkit::gpu { auto vec = stdp::vector { &memory_resource }; vec.reserve(stdr::size(submit_infos)); for (auto&& submit_info : submit_infos) { - auto& wait_semaphores = wait_semaphores_buf - .emplace_back(std::from_range, - submit_info.wait_semaphores | stdv::transform(vk::monadic::to_vk())); + auto& wait_semaphores = wait_semaphores_buf.emplace_back(std::from_range, + submit_info.wait_semaphores + | stdv::transform(vk::monadic::to_vk())); - auto& wait_dst_stages = wait_dst_stages_buf - .emplace_back(std::from_range, - submit_info.wait_dst_stages - | stdv::transform(vk::monadic::to_vk())); + auto& wait_dst_stages = wait_dst_stages_buf.emplace_back(std::from_range, + submit_info.wait_dst_stages + | stdv::transform(vk::monadic::to_vk< + VkPipelineStageFlagBits>())); - auto& command_buffers = command_buffers_buf - .emplace_back(std::from_range, - submit_info.command_buffers | stdv::transform(vk::monadic::to_vk())); + auto& command_buffers = command_buffers_buf.emplace_back(std::from_range, + submit_info.command_buffers + | stdv::transform(vk::monadic::to_vk())); - auto& signal_semaphores = signal_semaphores_buf - .emplace_back(std::from_range, - submit_info.signal_semaphores | stdv::transform(vk::monadic::to_vk())); + auto& signal_semaphores = signal_semaphores_buf.emplace_back(std::from_range, + submit_info.signal_semaphores + | stdv::transform(vk::monadic::to_vk())); vec.emplace_back(SubmitInfoRange { .wait_semaphores = wait_semaphores, @@ -152,12 +152,16 @@ namespace stormkit::gpu { const auto bytes_count = swapchains_count * sizeof(VkSwapchainKHR) + wait_semaphores_count * sizeof(VkSemaphore); auto memory_resource = stdp::monotonic_buffer_resource { bytes_count }; - const auto vk_swapchains = stdp::vector { std::from_range, - swapchains | stdv::transform(vk::monadic::to_vk()), - &memory_resource }; - const auto vk_semaphores = stdp::vector { std::from_range, - wait_semaphores | stdv::transform(vk::monadic::to_vk()), - &memory_resource }; + const auto vk_swapchains = stdp::vector { + std::from_range, + swapchains | stdv::transform(vk::monadic::to_vk()), + &memory_resource + }; + const auto vk_semaphores = stdp::vector { + std::from_range, + wait_semaphores | stdv::transform(vk::monadic::to_vk()), + &memory_resource + }; const auto present_info = VkPresentInfoKHR { .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, @@ -172,11 +176,11 @@ namespace stormkit::gpu { const auto& device = Base::owner(); const auto& device_table = device.device_table(); - const auto result = Try((vk::call_checked(device_table - .vkQueuePresentKHR, - *this, - &present_info))); - Return vk::from_vk(result); + const auto + result = Try((vk::call_checked(device_table.vkQueuePresentKHR, + *this, + &present_info))); + Return vk::from_vk(result); } template class QueueInterface; diff --git a/src/gpu/execution/render_pass.cpp b/src/gpu/execution/render_pass.cpp index 515dd7fe9..c1e87c01a 100644 --- a/src/gpu/execution/render_pass.cpp +++ b/src/gpu/execution/render_pass.cpp @@ -65,10 +65,10 @@ namespace stormkit::gpu { subpasses_deps.reserve(stdr::size(m_description->subpasses)); for (const auto& subpass : m_description->subpasses) { - auto& color_attachment_ref = color_attachment_refs - .emplace_back(transform(subpass.color_attachment_refs, monadic::vk_ref())); - auto& resolve_attachment_ref = resolve_attachment_refs - .emplace_back(transform(subpass.resolve_attachment_refs, monadic::vk_ref())); + auto& color_attachment_ref = color_attachment_refs.emplace_back(transform(subpass.color_attachment_refs, + monadic::vk_ref())); + auto& resolve_attachment_ref = resolve_attachment_refs.emplace_back(transform(subpass.resolve_attachment_refs, + monadic::vk_ref())); if (subpass.depth_attachment_ref) depth_attachment_ref = monadic::vk_ref()(*subpass.depth_attachment_ref); subpasses.emplace_back(VkSubpassDescription { diff --git a/src/gpu/execution/swapchain.cpp b/src/gpu/execution/swapchain.cpp index 5bfd6f9bb..e567b5834 100644 --- a/src/gpu/execution/swapchain.cpp +++ b/src/gpu/execution/swapchain.cpp @@ -80,14 +80,14 @@ namespace stormkit::gpu { const auto& device_table = device.device_table(); auto id = u32 { 0 }; - const auto result = Try((vk::call_checked(device_table - .vkAcquireNextImageKHR, - device, - *this, - wait.count(), - image_available, - nullptr, - &id))); + const auto result = Try((vk::call_checked( + device_table.vkAcquireNextImageKHR, + device, + *this, + wait.count(), + image_available, + nullptr, + &id))); Return SwapChain::NextImage { .result = vk::from_vk(result), .id = id }; } diff --git a/src/gpu/resource/shader.cpp b/src/gpu/resource/shader.cpp index c9ebecb96..9781680a7 100644 --- a/src/gpu/resource/shader.cpp +++ b/src/gpu/resource/shader.cpp @@ -36,10 +36,8 @@ namespace stormkit::gpu { }; const auto& device = owner(); - m_vk_handle = Try(vk::call_checked(device.device_table().vkCreateShaderModule, - device, - &create_info, - nullptr)); + m_vk_handle = Try(vk::call_checked< + VkShaderModule>(device.device_table().vkCreateShaderModule, device, &create_info, nullptr)); Return {}; } } // namespace stormkit::gpu diff --git a/src/image/image.cpp b/src/image/image.cpp index b6c2e834a..f32dbc8c7 100644 --- a/src/image/image.cpp +++ b/src/image/image.cpp @@ -414,15 +414,14 @@ namespace stormkit::image { m_data.mip_levels = 1u; m_data.format = format; - m_data.data - .resize(m_data.extent.width - * m_data.extent.height - * m_data.extent.depth - * m_data.layers - * m_data.faces - * m_data.mip_levels - * m_data.channel_count - * m_data.bytes_per_channel); + m_data.data.resize(m_data.extent.width + * m_data.extent.height + * m_data.extent.depth + * m_data.layers + * m_data.faces + * m_data.mip_levels + * m_data.channel_count + * m_data.bytes_per_channel); } ///////////////////////////////////// diff --git a/src/image/png.cppm b/src/image/png.cppm index 814aea850..f78a82443 100644 --- a/src/image/png.cppm +++ b/src/image/png.cppm @@ -239,7 +239,8 @@ namespace stormkit::image::details { auto rows = std::vector { data.extent.height, nullptr }; for (auto i : range(data.extent.height)) rows[i] = const_cast< - Byte*>(&data.data[i * data.extent.width * data.channel_count * data.bytes_per_channel]); // TODO Fix this shit + Byte*>(&data.data[i * data.extent.width * data.channel_count * data.bytes_per_channel]); // TODO Fix + // this shit png_set_rows(png_ptr, info_ptr, std::bit_cast(std::data(rows))); png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, nullptr); diff --git a/src/wsi/linux/wayland/context.cpp b/src/wsi/linux/wayland/context.cpp index f92a577b8..fc3b52cde 100644 --- a/src/wsi/linux/wayland/context.cpp +++ b/src/wsi/linux/wayland/context.cpp @@ -83,9 +83,9 @@ namespace stormkit::wsi::linux::wayland::wl { }; struct RegistryBinder { - const wl_interface* interface; + const wl_interface* interface; std23::function_ref bind; - u32 version = 1; + u32 version = 1; std23::function_ref after_bind = monadic::noop(); }; diff --git a/src/wsi/linux/wayland/wayland.cppm b/src/wsi/linux/wayland/wayland.cppm index 6dc0b8898..8b0e7ec6d 100644 --- a/src/wsi/linux/wayland/wayland.cppm +++ b/src/wsi/linux/wayland/wayland.cppm @@ -33,23 +33,25 @@ export namespace stormkit::wsi::linux::wayland::wl { RAIICapsule; using Output = stormkit::RAIICapsule; using XDGWmBase = stormkit::RAIICapsule; - using XDGDecorationManager = stormkit::RAIICapsule; - using Buffer = stormkit::RAIICapsule; + using XDGDecorationManager = stormkit::RAIICapsule< + zxdg_decoration_manager_v1*, + monadic::noop(), + zxdg_decoration_manager_v1_destroy, + struct XDGDescorationManagerTag, + nullptr>; + using Buffer = stormkit::RAIICapsule; using Keyboard = stormkit::RAIICapsule; using Pointer = stormkit::RAIICapsule; using Touch = stormkit::RAIICapsule; using Shm = stormkit::RAIICapsule; using Seat = stormkit::RAIICapsule; - using SinglePixelBufferManager = stormkit::RAIICapsule; - using Viewporter = stormkit:: + using SinglePixelBufferManager = stormkit::RAIICapsule< + wp_single_pixel_buffer_manager_v1*, + monadic::noop(), + wp_single_pixel_buffer_manager_v1_destroy, + struct SinglePixelBufferManagerTag, + nullptr>; + using Viewporter = stormkit:: RAIICapsule; using ContentTypeManager = stormkit::RAIICapsule; using PointerWarp = stormkit:: RAIICapsule; - using RelativePointerManager = stormkit::RAIICapsule; + using RelativePointerManager = stormkit::RAIICapsule< + zwp_relative_pointer_manager_v1*, + monadic::noop(), + zwp_relative_pointer_manager_v1_destroy, + struct RelativePointerManagerTag, + nullptr>; using Surface = stormkit:: RAIICapsule; @@ -89,27 +92,28 @@ export namespace stormkit::wsi::linux::wayland::wl { RAIICapsule; using XDGTopLevel = stormkit:: RAIICapsule; - using XDGTopLevelDecoration = stormkit::RAIICapsule; - using LockedPointer = stormkit::RAIICapsule; - using ConfinedPointer = stormkit::RAIICapsule; - using RelativePointer = stormkit::RAIICapsule; - using Viewport = stormkit:: + using XDGTopLevelDecoration = stormkit::RAIICapsule< + zxdg_toplevel_decoration_v1*, + zxdg_decoration_manager_v1_get_toplevel_decoration, + zxdg_toplevel_decoration_v1_destroy, + struct XDGTopLevelDecorationTag, + nullptr>; + using LockedPointer = stormkit::RAIICapsule; + using ConfinedPointer = stormkit::RAIICapsule; + using RelativePointer = stormkit::RAIICapsule; + using Viewport = stormkit:: RAIICapsule; using ContentType = stormkit::RAIICapsuletimestamp); - auto output = Output::create(globals.connection, output_cookie, nullptr); + auto + output_cookie = xcb_randr_get_output_info(globals.connection, outputs[j], xcb_monitors.handle()->timestamp); + auto output = Output::create(globals.connection, output_cookie, nullptr); if (!output) continue; if (output.handle()->connection != XCB_RANDR_CONNECTION_CONNECTED) continue; diff --git a/src/wsi/linux/x11/window.cpp b/src/wsi/linux/x11/window.cpp index 02c8b7b09..770cb2271 100644 --- a/src/wsi/linux/x11/window.cpp +++ b/src/wsi/linux/x11/window.cpp @@ -77,28 +77,32 @@ namespace stormkit::wsi::linux::x11 { [[maybe_unused]] constexpr auto _NET_WM_STATE_TOGGLE = 2; // toggle property - constexpr auto MOUSE_RAW_EVENTS = u32 { XCB_INPUT_XI_EVENT_MASK_RAW_BUTTON_PRESS - | XCB_INPUT_XI_EVENT_MASK_RAW_BUTTON_RELEASE - | XCB_INPUT_XI_EVENT_MASK_RAW_MOTION }; - constexpr auto KEYBOARD_RAW_EVENTS = u32 { XCB_INPUT_XI_EVENT_MASK_RAW_KEY_PRESS - | XCB_INPUT_XI_EVENT_MASK_RAW_KEY_RELEASE }; - constexpr auto KEYBOARD_EVENTS = u32 { XCB_INPUT_XI_EVENT_MASK_KEY_PRESS | XCB_INPUT_XI_EVENT_MASK_KEY_RELEASE }; + constexpr auto MOUSE_RAW_EVENTS = u32 { + XCB_INPUT_XI_EVENT_MASK_RAW_BUTTON_PRESS + | XCB_INPUT_XI_EVENT_MASK_RAW_BUTTON_RELEASE + | XCB_INPUT_XI_EVENT_MASK_RAW_MOTION + }; + constexpr auto KEYBOARD_RAW_EVENTS = u32 { + XCB_INPUT_XI_EVENT_MASK_RAW_KEY_PRESS | XCB_INPUT_XI_EVENT_MASK_RAW_KEY_RELEASE + }; + constexpr auto KEYBOARD_EVENTS = u32 { XCB_INPUT_XI_EVENT_MASK_KEY_PRESS | XCB_INPUT_XI_EVENT_MASK_KEY_RELEASE }; constexpr auto XINPUT_MASK_MODIFIERS = u32 { XCB_INPUT_MODIFIER_MASK_ANY }; - constexpr const auto EVENTS = XCB_EVENT_MASK_FOCUS_CHANGE - | XCB_EVENT_MASK_BUTTON_PRESS - | XCB_EVENT_MASK_BUTTON_RELEASE - | XCB_EVENT_MASK_BUTTON_MOTION - | XCB_EVENT_MASK_POINTER_MOTION - | XCB_EVENT_MASK_KEY_PRESS - | XCB_EVENT_MASK_KEY_RELEASE - | XCB_EVENT_MASK_STRUCTURE_NOTIFY - | XCB_EVENT_MASK_ENTER_WINDOW - | XCB_EVENT_MASK_LEAVE_WINDOW - | XCB_EVENT_MASK_VISIBILITY_CHANGE - | XCB_EVENT_MASK_PROPERTY_CHANGE - | XCB_EVENT_MASK_EXPOSURE; + constexpr const auto + EVENTS = XCB_EVENT_MASK_FOCUS_CHANGE + | XCB_EVENT_MASK_BUTTON_PRESS + | XCB_EVENT_MASK_BUTTON_RELEASE + | XCB_EVENT_MASK_BUTTON_MOTION + | XCB_EVENT_MASK_POINTER_MOTION + | XCB_EVENT_MASK_KEY_PRESS + | XCB_EVENT_MASK_KEY_RELEASE + | XCB_EVENT_MASK_STRUCTURE_NOTIFY + | XCB_EVENT_MASK_ENTER_WINDOW + | XCB_EVENT_MASK_LEAVE_WINDOW + | XCB_EVENT_MASK_VISIBILITY_CHANGE + | XCB_EVENT_MASK_PROPERTY_CHANGE + | XCB_EVENT_MASK_EXPOSURE; constexpr auto REQUIRED_MAP_PARTS = u16 { XCB_XKB_MAP_PART_KEY_TYPES @@ -791,10 +795,8 @@ namespace stormkit::wsi::linux::x11 { const auto device_id = xkb_x11_get_core_keyboard_device_id(globals.connection); - m_keymap = common::xkb::Keymap::take(xkb_x11_keymap_new_from_device(globals.xkb_context, - globals.connection, - device_id, - XKB_KEYMAP_COMPILE_NO_FLAGS)); + m_keymap = common::xkb::Keymap:: + take(xkb_x11_keymap_new_from_device(globals.xkb_context, globals.connection, device_id, XKB_KEYMAP_COMPILE_NO_FLAGS)); if (not m_keymap) { elog("Failed to compile a keymap"); return; From f2bf280eab77326aaee1af9f5dbe4b1a168f709c Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 27 Mar 2026 17:03:58 +0100 Subject: [PATCH 191/194] (core) add type aliases for array, vector and string types --- examples/entities/gameoflife/src/App.cpp | 2 +- examples/entities/gameoflife/src/App.cppm | 2 +- .../entities/gameoflife/src/Constants.cppm | 4 +- examples/entities/gameoflife/src/Renderer.cpp | 6 +- .../entities/gameoflife/src/Renderer.cppm | 10 +- examples/entities/gameoflife/src/main.cpp | 2 +- examples/gpu/common/app.cppm | 9 +- examples/gpu/imgui/src/main.cpp | 96 +++--- examples/gpu/textured_cube/src/main.cpp | 75 ++--- examples/gpu/triangle/src/main.cpp | 35 +-- examples/log/console-logger/src/main.cpp | 6 +- examples/log/file-logger/src/main.cpp | 6 +- examples/lua/wsi/events/src/main.cpp | 2 +- examples/wsi/events/src/main.cpp | 133 ++++---- examples/wsi/framebuffer/src/main.cpp | 8 +- include/stormkit/core/format_macro.hpp | 4 +- include/stormkit/core/platform_macro.hpp | 8 +- modules/stormkit/core/console/style.cppm | 8 +- modules/stormkit/core/containers.cppm | 1 + modules/stormkit/core/containers/aliases.cppm | 28 ++ modules/stormkit/core/containers/dag.cppm | 86 +++--- .../core/containers/multi_buffer.cppm | 36 +-- .../stormkit/core/containers/ringbuffer.cppm | 12 +- .../stormkit/core/containers/shmbuffer.cppm | 20 +- modules/stormkit/core/containers/tree.cppm | 44 ++- modules/stormkit/core/containers/utils.cppm | 60 ++-- modules/stormkit/core/coroutines.cppm | 10 +- modules/stormkit/core/errors.cppm | 16 +- .../core/functional/error_handling.cppm | 16 +- modules/stormkit/core/hash/map.cppm | 4 +- modules/stormkit/core/hash/string.cppm | 50 +-- modules/stormkit/core/math/combinatoric.cppm | 2 +- modules/stormkit/core/math/extent.cppm | 48 +-- modules/stormkit/core/math/geometry.cppm | 8 +- modules/stormkit/core/math/linear-matrix.cppm | 22 +- modules/stormkit/core/math/linear-vector.cppm | 42 +-- modules/stormkit/core/math/linear.cppm | 24 +- modules/stormkit/core/meta/concepts.cppm | 30 +- modules/stormkit/core/meta/type_query.cppm | 14 + modules/stormkit/core/meta/type_traits.cppm | 16 +- .../stormkit/core/parallelism/threadpool.cppm | 12 +- .../core/parallelism/threadutils.cppm | 13 +- modules/stormkit/core/string.cppm | 2 +- modules/stormkit/core/string/aliases.cppm | 35 +++ .../core/string/constexpr_string.cppm | 38 ++- modules/stormkit/core/string/czstring.cppm | 12 - modules/stormkit/core/string/encodings.cppm | 44 +-- modules/stormkit/core/string/format.cppm | 2 +- modules/stormkit/core/string/operations.cppm | 93 +++--- modules/stormkit/core/typesafe/byte.cppm | 126 ++++---- modules/stormkit/core/typesafe/flags.cppm | 59 ++-- modules/stormkit/core/typesafe/ref.cppm | 145 +++++---- modules/stormkit/core/typesafe/safecasts.cppm | 28 +- modules/stormkit/core/utils/algorithms.cppm | 11 +- modules/stormkit/core/utils/allocation.cppm | 4 +- modules/stormkit/core/utils/app.cppm | 4 +- modules/stormkit/core/utils/color.cppm | 14 +- modules/stormkit/core/utils/contract.cppm | 40 +-- modules/stormkit/core/utils/deferinit.cppm | 2 +- .../stormkit/core/utils/dynamic_loader.cppm | 10 +- modules/stormkit/core/utils/filesystem.cppm | 52 ++-- modules/stormkit/entities.cppm | 119 ++++--- modules/stormkit/gpu/core/base.cppm | 26 +- modules/stormkit/gpu/core/device.cppm | 18 +- modules/stormkit/gpu/core/instance.cppm | 78 ++--- modules/stormkit/gpu/core/structs.cppm | 22 +- modules/stormkit/gpu/core/vulkan/enums.cppm | 292 +++++++++--------- .../stormkit/gpu/core/vulkan/enums.cppm.tpl | 6 +- modules/stormkit/gpu/core/vulkan/utils.cppm | 50 +-- .../gpu/execution/command_buffer.cppm | 126 ++++---- .../stormkit/gpu/execution/descriptors.cppm | 24 +- modules/stormkit/gpu/execution/pipeline.cppm | 2 +- .../gpu/execution/raster_pipeline.cppm | 26 +- .../stormkit/gpu/execution/render_pass.cppm | 50 +-- modules/stormkit/gpu/execution/swapchain.cppm | 8 +- modules/stormkit/gpu/resource/buffer.cppm | 17 +- modules/stormkit/gpu/resource/shader.cppm | 62 ++-- modules/stormkit/image.cppm | 42 +-- modules/stormkit/log.cppm | 36 +-- modules/stormkit/lua.cppm | 2 +- modules/stormkit/test.cppm | 77 +++-- modules/stormkit/wsi/core.cppm | 12 +- modules/stormkit/wsi/keyboard.cppm | 10 +- modules/stormkit/wsi/monitor.cppm | 24 +- modules/stormkit/wsi/mouse.cppm | 10 +- modules/stormkit/wsi/window.cppm | 33 +- src/core/contract.cppm | 3 +- src/core/darwin/threadutils.cpp | 12 +- src/core/dynamic_loader.cpp | 2 +- src/core/linux/threadutils.cpp | 20 +- src/core/posix/shmbuffer.cpp | 4 +- src/core/stacktrace.cpp | 4 +- src/core/win32/shmbuffer.cpp | 4 +- src/core/win32/threadutils.cpp | 18 +- src/entities/system.cpp | 2 +- src/gpu/core/device.cpp | 16 +- src/gpu/core/instance.cpp | 32 +- src/gpu/core/physical_device.cpp | 18 +- src/gpu/execution/command_buffer.cpp | 78 ++--- src/gpu/execution/command_pool.cpp | 2 +- src/gpu/execution/descriptor_pool.cpp | 4 +- src/gpu/execution/descriptor_set.cpp | 8 +- src/gpu/execution/descriptor_set_layout.cpp | 2 +- src/gpu/execution/frame_buffer.cpp | 6 +- src/gpu/execution/pipeline.cpp | 30 +- src/gpu/execution/pipeline_cache.cpp | 4 +- src/gpu/execution/queue.cpp | 32 +- src/gpu/execution/render_pass.cpp | 8 +- src/gpu/execution/swapchain.cpp | 4 +- src/gpu/resource/buffer.cpp | 2 +- src/gpu/resource/shader.cpp | 2 +- src/image/hdr.cppm | 8 +- src/image/image.cpp | 20 +- src/image/jpg.cppm | 22 +- src/image/ktx.cppm | 10 +- src/image/png.cppm | 24 +- src/image/ppm.cppm | 10 +- src/image/qoi.cppm | 36 +-- src/image/tga.cppm | 8 +- src/log/console_logger.cpp | 8 +- src/log/file_logger.cpp | 8 +- src/log/logger.cpp | 2 +- src/lua/core/color.cpp | 2 +- src/lua/core/math.cpp | 14 +- src/lua/entities.cpp | 18 +- src/lua/log.cpp | 20 +- src/lua/lua.cpp | 22 +- src/lua/wsi/window.cpp | 2 +- src/main/linux/main_linux.cpp | 14 +- src/main/macos/stormkit_core.cpp | 2 +- src/main/macos/stormkit_core.hpp | 2 +- src/main/win32/main_win.cpp | 6 +- src/test/main.cpp | 4 +- src/wsi/common/input_base.cppm | 4 +- src/wsi/common/window_base.cppm | 14 +- src/wsi/core.cpp | 2 +- src/wsi/ios/window_impl.hpp | 6 +- src/wsi/linux/common/xkb.cppm | 2 +- src/wsi/linux/monitor.cppm | 2 +- src/wsi/linux/wayland/context.cpp | 2 +- src/wsi/linux/wayland/context.cppm | 12 +- src/wsi/linux/wayland/inputs.cpp | 8 +- src/wsi/linux/wayland/inputs.cppm | 6 +- src/wsi/linux/wayland/monitor.cppm | 6 +- src/wsi/linux/wayland/window.cpp | 14 +- src/wsi/linux/wayland/window.cppm | 12 +- src/wsi/linux/window.cppm | 16 +- src/wsi/linux/x11/context.cpp | 14 +- src/wsi/linux/x11/context.cppm | 10 +- src/wsi/linux/x11/monitor.cppm | 4 +- src/wsi/linux/x11/window.cpp | 26 +- src/wsi/linux/x11/window.cppm | 8 +- src/wsi/linux/x11/xcb.cppm | 6 +- src/wsi/macos/monitor.cppm | 2 +- src/wsi/macos/swift/CppBridge.cpp | 6 +- src/wsi/macos/window.cppm | 8 +- src/wsi/monitor.cpp | 2 +- src/wsi/win32/keyboard.cppm | 2 +- src/wsi/win32/monitor.cppm | 8 +- src/wsi/win32/window.cpp | 6 +- src/wsi/win32/window.cppm | 6 +- src/wsi/window.cpp | 10 +- tests/core/containers/dag.cpp | 35 ++- tests/core/containers/tree.cpp | 2 +- tests/core/parallelism/threadpool.cpp | 2 +- tests/core/typesafe/ref.cpp | 12 +- tests/core/typesafe/safecasts.integer.cpp | 60 ++-- tools/terra/src/main.cpp | 6 +- 168 files changed, 1958 insertions(+), 1885 deletions(-) create mode 100644 modules/stormkit/core/containers/aliases.cppm create mode 100644 modules/stormkit/core/string/aliases.cppm delete mode 100644 modules/stormkit/core/string/czstring.cppm diff --git a/examples/entities/gameoflife/src/App.cpp b/examples/entities/gameoflife/src/App.cpp index 35394fa67..d1545f474 100644 --- a/examples/entities/gameoflife/src/App.cpp +++ b/examples/entities/gameoflife/src/App.cpp @@ -25,7 +25,7 @@ App::~App() { ilog("Cleaning"); } -auto App::run([[maybe_unused]] const int argc, [[maybe_unused]] CZString argv[]) -> i32 { +auto App::run([[maybe_unused]] const int argc, [[maybe_unused]] czstring argv[]) -> i32 { using Clock = std::chrono::high_resolution_clock; using namespace stormkit::literals; diff --git a/examples/entities/gameoflife/src/App.cppm b/examples/entities/gameoflife/src/App.cppm index 591a0e84e..ef52d2ecd 100644 --- a/examples/entities/gameoflife/src/App.cppm +++ b/examples/entities/gameoflife/src/App.cppm @@ -31,7 +31,7 @@ export { App(); ~App() override; - auto run(const int argc, CZString argv[]) -> stormkit::i32 override; + auto run(const int argc, czstring argv[]) -> stormkit::i32 override; private: auto do_initWindow() -> void; diff --git a/examples/entities/gameoflife/src/Constants.cppm b/examples/entities/gameoflife/src/Constants.cppm index eddf70094..ca6ac6433 100644 --- a/examples/entities/gameoflife/src/Constants.cppm +++ b/examples/entities/gameoflife/src/Constants.cppm @@ -24,10 +24,10 @@ export { = sizeof(stormkit::math::fvec2) + sizeof(stormkit::fvec3); inline constexpr auto WINDOW_TITLE = "StormKit GameOfLife Example"; inline constexpr auto MESH_VERTEX_BUFFER_SIZE = VERTEX_SIZE * 3; - inline constexpr auto MESH_VERTEX_BINDING_DESCRIPTIONS = std::array { + inline constexpr auto MESH_VERTEX_BINDING_DESCRIPTIONS = array { stormkit::gpu::VertexBindingDescription { .binding = 0, .stride = VERTEX_SIZE } }; - inline constexpr auto MESH_VERTEX_ATTRIBUTE_DESCRIPTIONS = std::array { + inline constexpr auto MESH_VERTEX_ATTRIBUTE_DESCRIPTIONS = array { stormkit::gpu::VertexInputAttributeDescription { .location = 0, .binding = 0, .format = stormkit::gpu::format::f322, diff --git a/examples/entities/gameoflife/src/Renderer.cpp b/examples/entities/gameoflife/src/Renderer.cpp index 6aa4e4520..cc93afd5c 100644 --- a/examples/entities/gameoflife/src/Renderer.cpp +++ b/examples/entities/gameoflife/src/Renderer.cpp @@ -36,7 +36,7 @@ auto Renderer::renderFrame() -> void { } const auto viewports = [&] { - auto v = std::vector {}; + auto v = dyn_array {}; v.emplace_back(gpu::Viewport { .extent = surface_extentf, .depth = { 0, 1 } @@ -46,7 +46,7 @@ auto Renderer::renderFrame() -> void { }(); const auto scissors = [&] { - auto s = std::vector {}; + auto s = dyn_array {}; s.emplace_back(gpu::Scissor { .extent = surface_extent }); return s; @@ -150,7 +150,7 @@ auto Renderer::do_initMeshRenderObjects() -> void { .descriptor_count = 1 }); m_descriptor_set_layout->bake(); m_descriptor_pool = m_device->allocateDescriptorPool( - std::array { + array { gpu::DescriptorPool::Size { gpu::DescriptorType::Combined_Image_Sampler, 1 } }, 1); diff --git a/examples/entities/gameoflife/src/Renderer.cppm b/examples/entities/gameoflife/src/Renderer.cppm index 8d7f8558b..a45a6437c 100644 --- a/examples/entities/gameoflife/src/Renderer.cppm +++ b/examples/entities/gameoflife/src/Renderer.cppm @@ -46,7 +46,7 @@ export { stormkit::gpu::Fence* m_current_fence = nullptr; const stormkit::gpu::Queue* m_queue = nullptr; - std::vector m_surface_views; + dyn_array m_surface_views; std::unique_ptr m_descriptor_set_layout; std::unique_ptr m_descriptor_pool; @@ -54,8 +54,8 @@ export { std::unique_ptr m_render_pass; struct Board { - std::vector images; - std::vector image_views; + dyn_array images; + dyn_array image_views; std::unique_ptr sampler; stormkit::u32 current_image = 0; @@ -68,8 +68,8 @@ export { std::unique_ptr descriptor_set; } m_board; - std::vector m_command_buffers; - std::vector m_framebuffers; + dyn_array m_command_buffers; + dyn_array m_framebuffers; }; #ifdef STORMKIT_BUILD_MODULES diff --git a/examples/entities/gameoflife/src/main.cpp b/examples/entities/gameoflife/src/main.cpp index 13eee9992..4be3cea29 100644 --- a/examples/entities/gameoflife/src/main.cpp +++ b/examples/entities/gameoflife/src/main.cpp @@ -14,7 +14,7 @@ import App; #include "App.mpp" #endif -auto main([[maybe_unused]] std::span args) -> int { +auto main([[maybe_unused]] array_view args) -> int { using namespace stormkit; setup_signal_handler(); diff --git a/examples/gpu/common/app.cppm b/examples/gpu/common/app.cppm index ec59caf15..4f227a21f 100644 --- a/examples/gpu/common/app.cppm +++ b/examples/gpu/common/app.cppm @@ -46,7 +46,7 @@ extern "C" auto debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, export namespace base { class Application { public: - auto run(this auto& self, std::span args) { + auto run(this auto& self, array_view args) { wsi::parse_args(args); log::parse_args(args); @@ -79,7 +79,7 @@ export namespace base { DeferInit m_command_pool; private: - auto init_window(std::string_view example_name) noexcept -> void { + auto init_window(string_view example_name) noexcept -> void { m_window = wsi::Window::open(std::format("Stormkit GPU {} example", example_name), { 800_u32, 600_u32 }, wsi::WindowFlag::DEFAULT | wsi::WindowFlag::EXTERNAL_CONTEXT); @@ -88,13 +88,12 @@ export namespace base { }); } - auto init_gpu(std::string_view example_name) noexcept -> void { + auto init_gpu(string_view example_name) noexcept -> void { // initialize gpu backend (vulkan or webgpu depending the platform) TryDiscardAssert(gpu::initialize_backend(), "Failed to initialize gpu backend"); // create gpu instance and attach surface to window - m_instance = TryAssert(gpu::Instance::create(std::string { example_name }, true), - "Failed to initialize gpu instance"); + m_instance = TryAssert(gpu::Instance::create(string { example_name }, true), "Failed to initialize gpu instance"); m_debug_callback = TryAssert(gpu::DebugCallback::create(m_instance, debug_callback), "Failed to initialize gpu instance"); diff --git a/examples/gpu/imgui/src/main.cpp b/examples/gpu/imgui/src/main.cpp index 681b21085..cef2eeace 100644 --- a/examples/gpu/imgui/src/main.cpp +++ b/examples/gpu/imgui/src/main.cpp @@ -37,7 +37,7 @@ struct SwapchainImageResource { namespace { constexpr auto BUFFERING_COUNT = 2_u32; - constexpr auto POOL_SIZES = std::array { + constexpr auto POOL_SIZES = array { gpu::DescriptorPool::Size { .type = gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, .descriptor_count = BUFFERING_COUNT } }; } // namespace @@ -55,7 +55,7 @@ class Application: public base::Application { "Failed to create descriptor pool!"); // create present engine resources - m_submission_resources = init_by>([&](auto& out) noexcept { + m_submission_resources = init_by>([&](auto& out) noexcept { out.reserve(BUFFERING_COUNT); for (auto _ : range(BUFFERING_COUNT)) { out.push_back({ @@ -84,12 +84,11 @@ class Application: public base::Application { for (const auto& swap_image : images) { auto view = TryAssert(gpu::ImageView::create(m_device, swap_image), "Failed to create swapchain image view!"); - m_image_resources - .push_back({ .image = swap_image, - .view = std::move(view), - .render_finished = TryAssert(gpu::Semaphore::create(m_device), - "Failed to create render " - "signal semaphore!") }); + m_image_resources.push_back({ .image = swap_image, + .view = std::move(view), + .render_finished = TryAssert(gpu::Semaphore::create(m_device), + "Failed to create render " + "signal semaphore!") }); auto& transition_cmb = transition_cmbs[image_index]; TryDiscardAssert((transition_cmb.record([&](auto cmb) noexcept { @@ -163,39 +162,40 @@ class Application: public base::Application { ImGui_ImplVulkan_LoadFunctions(VK_API_VERSION_1_1, gpu::vk::imgui_vk_loader, &*m_device); ImGui_ImplVulkan_Init(&init_info); - m_window - ->on(wsi::KeyDownEventFunc { [this, &io](u8 /*id*/, wsi::Key key, char c) mutable noexcept { - if (key == wsi::Key::ESCAPE) m_window->close(); - io.AddInputCharactersUTF8(&c); - } }, - wsi::MouseMovedEventFunc { [&io](u8 /*id*/, const math::ivec2& position) mutable noexcept { - const auto _position = position.to(); - - io.AddMouseSourceEvent(ImGuiMouseSource_Mouse); - io.AddMousePosEvent(_position.x, _position.y); - } }, - wsi::MouseButtonDownEventFunc { [&io](u8 /*id*/, wsi::MouseButton button, const math::ivec2&) mutable noexcept { - auto mouse_button = -1; - if (button == wsi::MouseButton::LEFT) mouse_button = 0; - if (button == wsi::MouseButton::RIGHT) mouse_button = 1; - if (button == wsi::MouseButton::MIDDLE) mouse_button = 2; - if (button == wsi::MouseButton::BUTTON_1) mouse_button = 3; - if (button == wsi::MouseButton::BUTTON_2) mouse_button = 4; - if (mouse_button == -1) return; - io.AddMouseSourceEvent(ImGuiMouseSource_Mouse); - io.AddMouseButtonEvent(mouse_button, true); - } }, - wsi::MouseButtonUpEventFunc { [&io](u8 /*id*/, wsi::MouseButton button, const math::ivec2&) mutable noexcept { - auto mouse_button = -1; - if (button == wsi::MouseButton::LEFT) mouse_button = 0; - if (button == wsi::MouseButton::RIGHT) mouse_button = 1; - if (button == wsi::MouseButton::MIDDLE) mouse_button = 2; - if (button == wsi::MouseButton::BUTTON_1) mouse_button = 3; - if (button == wsi::MouseButton::BUTTON_2) mouse_button = 4; - if (mouse_button == -1) return; - io.AddMouseSourceEvent(ImGuiMouseSource_Mouse); - io.AddMouseButtonEvent(mouse_button, false); - } }); + m_window->on(wsi::KeyDownEventFunc { [this, &io](u8 /*id*/, wsi::Key key, char c) mutable noexcept { + if (key == wsi::Key::ESCAPE) m_window->close(); + io.AddInputCharactersUTF8(&c); + } }, + wsi::MouseMovedEventFunc { [&io](u8 /*id*/, const math::ivec2& position) mutable noexcept { + const auto _position = position.to(); + + io.AddMouseSourceEvent(ImGuiMouseSource_Mouse); + io.AddMousePosEvent(_position.x, _position.y); + } }, + wsi::MouseButtonDownEventFunc { + [&io](u8 /*id*/, wsi::MouseButton button, const math::ivec2&) mutable noexcept { + auto mouse_button = -1; + if (button == wsi::MouseButton::LEFT) mouse_button = 0; + if (button == wsi::MouseButton::RIGHT) mouse_button = 1; + if (button == wsi::MouseButton::MIDDLE) mouse_button = 2; + if (button == wsi::MouseButton::BUTTON_1) mouse_button = 3; + if (button == wsi::MouseButton::BUTTON_2) mouse_button = 4; + if (mouse_button == -1) return; + io.AddMouseSourceEvent(ImGuiMouseSource_Mouse); + io.AddMouseButtonEvent(mouse_button, true); + } }, + wsi::MouseButtonUpEventFunc { + [&io](u8 /*id*/, wsi::MouseButton button, const math::ivec2&) mutable noexcept { + auto mouse_button = -1; + if (button == wsi::MouseButton::LEFT) mouse_button = 0; + if (button == wsi::MouseButton::RIGHT) mouse_button = 1; + if (button == wsi::MouseButton::MIDDLE) mouse_button = 2; + if (button == wsi::MouseButton::BUTTON_1) mouse_button = 3; + if (button == wsi::MouseButton::BUTTON_2) mouse_button = 4; + if (mouse_button == -1) return; + io.AddMouseSourceEvent(ImGuiMouseSource_Mouse); + io.AddMouseButtonEvent(mouse_button, false); + } }); } auto run_example() { @@ -221,7 +221,7 @@ class Application: public base::Application { const auto& swapchain_image_resource = m_image_resources[image_index]; const auto& signal = swapchain_image_resource.render_finished; - static constexpr auto PIPELINE_FLAGS = std::array { gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT }; + static constexpr auto PIPELINE_FLAGS = array { gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT }; const auto window_extent = m_window->extent().to(); const auto rendering_info = gpu::RenderingInfo { @@ -268,16 +268,16 @@ class Application: public base::Application { ImGui::DestroyContext(); } - constexpr auto example_name() const noexcept -> std::string_view { return "Imgui"; } + constexpr auto example_name() const noexcept -> string_view { return "Imgui"; } private: - DeferInit m_descriptor_pool; - std::vector m_submission_resources; - std::vector m_image_resources; - usize m_current_frame = 0_usize; + DeferInit m_descriptor_pool; + dyn_array m_submission_resources; + dyn_array m_image_resources; + usize m_current_frame = 0_usize; }; -auto main(std::span args) -> int { +auto main(array_view args) -> int { auto app = Application {}; app.run(args); return 0; diff --git a/examples/gpu/textured_cube/src/main.cpp b/examples/gpu/textured_cube/src/main.cpp index f6a5dc6d7..c12a22ccd 100644 --- a/examples/gpu/textured_cube/src/main.cpp +++ b/examples/gpu/textured_cube/src/main.cpp @@ -52,7 +52,7 @@ struct Vertex { math::fvec3 position; math::fvec2 uv; - static constexpr auto attribute_descriptions() noexcept -> std::array { + static constexpr auto attribute_descriptions() noexcept -> array { return to_array({ { .location = 0, .binding = 0, .format = gpu::PixelFormat::RGB32F, .offset = offsetof(Vertex, position) }, { .location = 1, .binding = 0, .format = gpu::PixelFormat::RG32F, .offset = offsetof(Vertex, uv) } @@ -80,7 +80,7 @@ struct ViewerData { namespace { const auto SHADER = stdfs::path { SHADER_DIR } / "textured_cube.spv"; const auto TEXTURE = stdfs::path { RESOURCE_DIR } / "textures/cube.png"; - constexpr auto VERTICES = std::array { + constexpr auto VERTICES = array { Vertex { { -1.f, -1.f, -1.f }, { 2.f / 3.f, 3.f / 4.f } }, // -X side { { -1.f, -1.f, 1.f }, { 1.f / 3.f, 3.f / 4.f } }, { { -1.f, 1.f, 1.f }, { 1.f / 3.f, 1.f } }, @@ -137,8 +137,8 @@ namespace { } }); - constexpr auto OFFSETS = std::array { 0_u64 }; - constexpr auto PIPELINE_FLAGS = std::array { gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT }; + constexpr auto OFFSETS = array { 0_u64 }; + constexpr auto PIPELINE_FLAGS = array { gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT }; } // namespace class Application: public base::Application { @@ -172,9 +172,9 @@ class Application: public base::Application { // initialize render pass const auto depth_format = [this] { const auto formats_properties = m_physical_device->formats_properties(); - const auto candidates = std::array { gpu::PixelFormat::DEPTH32F, - gpu::PixelFormat::DEPTH32F_STENCIL8U, - gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U }; + const auto candidates = array { gpu::PixelFormat::DEPTH32F, + gpu::PixelFormat::DEPTH32F_STENCIL8U, + gpu::PixelFormat::DEPTH24_UNORM_STENCIL8U }; for (const auto format : candidates) { const auto properties = stdr::find_if(formats_properties, [format](const auto& pair) { @@ -266,7 +266,7 @@ class Application: public base::Application { auto copy_cmb = TryAssert(m_command_pool->create_command_buffer(), "Failed to allocate copy texture buffer"); TryDiscardAssert((copy_cmb.record([&](auto cmb) noexcept { - const auto copy = std::array { + const auto copy = array { gpu::BufferImageCopy { .buffer_offset = 0, .buffer_row_length = 0, @@ -298,25 +298,25 @@ class Application: public base::Application { m_texture_view = TryAssert(gpu::ImageView::create(m_device, m_texture), "Failed to create texture view!"); m_sampler = TryAssert(gpu::Sampler::create(m_device, gpu::Sampler::Settings {}), "Failed to create sampler!"); - m_submission_resources = std::vector {}; + m_submission_resources = dyn_array {}; m_submission_resources.reserve(BUFFERING_COUNT); for (auto _ : range(BUFFERING_COUNT)) { - m_submission_resources - .push_back({ .in_flight = TryAssert(gpu::Fence::create_signaled(m_device), "Failed to create swapchain image!"), - .image_available = TryAssert(gpu::Semaphore::create(m_device), "Failed to create present image!"), - .render_cmb = TryAssert(m_command_pool->create_command_buffer(), "Failed to create buffers!"), - .viewer_buffer = TryAssert(gpu::Buffer::create(m_device, - gpu::Buffer::CreateInfo { - .usages = gpu::BufferUsageFlag::UNIFORM, - .size = sizeof(ViewerData), - .persistently_mapped = true, - }), - "Failed to allocate gpu viewer buffer!"), - .descriptor_set = TryAssert(m_descriptor_pool->create_descriptor_set(m_descriptor_set_layout), - "Failed to create descriptor set!") }); + m_submission_resources.push_back( + { .in_flight = TryAssert(gpu::Fence::create_signaled(m_device), "Failed to create swapchain image!"), + .image_available = TryAssert(gpu::Semaphore::create(m_device), "Failed to create present image!"), + .render_cmb = TryAssert(m_command_pool->create_command_buffer(), "Failed to create buffers!"), + .viewer_buffer = TryAssert(gpu::Buffer::create(m_device, + gpu::Buffer::CreateInfo { + .usages = gpu::BufferUsageFlag::UNIFORM, + .size = sizeof(ViewerData), + .persistently_mapped = true, + }), + "Failed to allocate gpu viewer buffer!"), + .descriptor_set = TryAssert(m_descriptor_pool->create_descriptor_set(m_descriptor_set_layout), + "Failed to create descriptor set!") }); auto& res = m_submission_resources.back(); - const auto sets = std::array { + const auto sets = array { gpu::BufferDescriptor { .binding = 0, .buffer = res.viewer_buffer, @@ -339,7 +339,7 @@ class Application: public base::Application { auto transition_cmbs = TryAssert(m_command_pool->create_command_buffers(image_count), "Failed to create transition command buffers!"); - m_image_resources = std::vector {}; + m_image_resources = dyn_array {}; m_image_resources.reserve(stdr::size(images)); auto image_index = 0u; @@ -359,12 +359,12 @@ class Application: public base::Application { gpu::ImageSubresourceRange { .aspect_mask = depth_aspect_flag }), "Failed to create depth image view!"); - m_image_resources - .push_back({ .image = swap_image, - .view = std::move(view), - .depth_image = std::move(depth_image), - .depth_view = std::move(depth_view), - .render_finished = TryAssert(gpu::Semaphore::create(m_device), "Failed to create render!") }); + m_image_resources.push_back({ .image = swap_image, + .view = std::move(view), + .depth_image = std::move(depth_image), + .depth_view = std::move(depth_view), + .render_finished = TryAssert(gpu::Semaphore::create(m_device), + "Failed to create render!") }); const auto& resources = m_image_resources.back(); @@ -461,9 +461,10 @@ class Application: public base::Application { const auto& signal = swapchain_image_resource.render_finished; // update viewer data and upload - const auto time = stdc::duration_cast(current_time - m_start_time).count(); - viewer_data - .model = math::rotate(math::fmat4::identity(), time * math::angle::radians(90.f), math::fvec3 { 0.f, 1.f, 0.f }); + const auto time = stdc::duration_cast(current_time - m_start_time).count(); + viewer_data.model = math::rotate(math::fmat4::identity(), + time * math::angle::radians(90.f), + math::fvec3 { 0.f, 1.f, 0.f }); auto& viewer_buffer = submission_resource.viewer_buffer; TryAssert(viewer_buffer.upload(viewer_data), "Failed to upload texture to gpu!"); @@ -511,7 +512,7 @@ class Application: public base::Application { if (++m_current_frame >= BUFFERING_COUNT) m_current_frame = 0; } - constexpr auto example_name() const noexcept -> std::string_view { return "Textured Cube"; } + constexpr auto example_name() const noexcept -> string_view { return "Textured Cube"; } private: DeferInit m_descriptor_pool; @@ -524,14 +525,14 @@ class Application: public base::Application { DeferInit m_texture; DeferInit m_texture_view; DeferInit m_sampler; - std::vector m_submission_resources; - std::vector m_image_resources; + dyn_array m_submission_resources; + dyn_array m_image_resources; DeferInit m_vertex_buffer; usize m_current_frame = 0_usize; decltype(clock::now()) m_start_time = clock::now(); }; -auto main(std::span args) -> int { +auto main(array_view args) -> int { auto app = Application {}; app.run(args); return 0; diff --git a/examples/gpu/triangle/src/main.cpp b/examples/gpu/triangle/src/main.cpp index 21e80da16..7f7f0bba6 100644 --- a/examples/gpu/triangle/src/main.cpp +++ b/examples/gpu/triangle/src/main.cpp @@ -87,7 +87,7 @@ class Application: public base::Application { "Failed to create raster pipeline!"); // create present engine resources - m_submission_resources = init_by>([&](auto& out) noexcept { + m_submission_resources = init_by>([&](auto& out) noexcept { out.reserve(BUFFERING_COUNT); for (auto _ : range(BUFFERING_COUNT)) { out.push_back({ @@ -116,12 +116,11 @@ class Application: public base::Application { for (const auto& swap_image : images) { auto view = TryAssert(gpu::ImageView::create(m_device, swap_image), "Failed to create swapchain image view!"); - m_image_resources - .push_back({ .image = swap_image, - .view = std::move(view), - .render_finished = TryAssert(gpu::Semaphore::create(m_device), - "Failed to create render " - "signal semaphore!") }); + m_image_resources.push_back({ .image = swap_image, + .view = std::move(view), + .render_finished = TryAssert(gpu::Semaphore::create(m_device), + "Failed to create render " + "signal semaphore!") }); auto& transition_cmb = transition_cmbs[image_index]; TryDiscardAssert((transition_cmb.record([&](auto cmb) noexcept { @@ -165,7 +164,7 @@ class Application: public base::Application { const auto& swapchain_image_resource = m_image_resources[image_index]; const auto& signal = swapchain_image_resource.render_finished; - static constexpr auto PIPELINE_FLAGS = std::array { gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT }; + static constexpr auto PIPELINE_FLAGS = array { gpu::PipelineStageFlag::COLOR_ATTACHMENT_OUTPUT }; const auto window_extent = m_window->extent().to(); const auto rendering_info = gpu::RenderingInfo { @@ -205,20 +204,20 @@ class Application: public base::Application { if (++m_current_frame >= BUFFERING_COUNT) m_current_frame = 0; } - constexpr auto example_name() const noexcept -> std::string_view { return "Triangle"; } + constexpr auto example_name() const noexcept -> string_view { return "Triangle"; } private: - DeferInit m_vertex_shader; - DeferInit m_fragment_shader; - DeferInit m_pipeline_layout; - DeferInit m_render_pass; - DeferInit m_pipeline; - std::vector m_submission_resources; - std::vector m_image_resources; - usize m_current_frame = 0_usize; + DeferInit m_vertex_shader; + DeferInit m_fragment_shader; + DeferInit m_pipeline_layout; + DeferInit m_render_pass; + DeferInit m_pipeline; + dyn_array m_submission_resources; + dyn_array m_image_resources; + usize m_current_frame = 0_usize; }; -auto main(std::span args) -> int { +auto main(array_view args) -> int { auto app = Application {}; app.run(args); return 0; diff --git a/examples/log/console-logger/src/main.cpp b/examples/log/console-logger/src/main.cpp index 73a9d3568..f1a8be34f 100644 --- a/examples/log/console-logger/src/main.cpp +++ b/examples/log/console-logger/src/main.cpp @@ -11,7 +11,7 @@ import stormkit; using namespace stormkit; struct Bar { - std::string d = "FooBar"; + string d = "FooBar"; }; template @@ -39,11 +39,11 @@ namespace stdv = std::views; //////////////////////////////////////// //////////////////////////////////////// -auto main(std::span args) -> int { +auto main(array_view args) -> int { using log::operator""_module; // force debug - auto args2 = std::vector { std::from_range, args }; + auto args2 = dyn_array { std::from_range, args }; args2.emplace_back("--debug"); log::parse_args(args2); diff --git a/examples/log/file-logger/src/main.cpp b/examples/log/file-logger/src/main.cpp index 10f90698d..7b033ab0c 100644 --- a/examples/log/file-logger/src/main.cpp +++ b/examples/log/file-logger/src/main.cpp @@ -13,7 +13,7 @@ import stormkit; using namespace stormkit; struct Bar { - std::string d = "FooBar"; + string d = "FooBar"; }; template @@ -43,11 +43,11 @@ static const auto LOG_DIR = std::filesystem::path { "log/" }; //////////////////////////////////////// //////////////////////////////////////// -auto main(std::span args) -> int { +auto main(array_view args) -> int { using log::operator""_module; // force debug - auto args2 = std::vector { std::from_range, args }; + auto args2 = dyn_array { std::from_range, args }; args2.emplace_back("--debug"); log::parse_args(args2); diff --git a/examples/lua/wsi/events/src/main.cpp b/examples/lua/wsi/events/src/main.cpp index b1374d93c..642a3c72d 100644 --- a/examples/lua/wsi/events/src/main.cpp +++ b/examples/lua/wsi/events/src/main.cpp @@ -26,7 +26,7 @@ using namespace stormkit; //////////////////////////////////////// //////////////////////////////////////// -auto main(std::span args) -> int { +auto main(array_view args) -> int { wsi::parse_args(args); log::parse_args(args); diff --git a/examples/wsi/events/src/main.cpp b/examples/wsi/events/src/main.cpp index 71bfa75d7..49cb38c3e 100644 --- a/examples/wsi/events/src/main.cpp +++ b/examples/wsi/events/src/main.cpp @@ -18,7 +18,7 @@ namespace stdr = std::ranges; //////////////////////////////////////// //////////////////////////////////////// -auto main(std::span args) -> int { +auto main(array_view args) -> int { wsi::parse_args(args); log::parse_args(args); @@ -39,73 +39,72 @@ auto main(std::span args) -> int { }); auto foo = 0; - window - .on(wsi::ResizedEventFunc { [](const math::uextent2& extent) static noexcept { ilog("Resize event: {}", extent); } }, - wsi::MonitorChangedEventFunc { [](const wsi::Monitor& monitor) noexcept { - ilog("Monitor changed event: {}", monitor); - } }, - wsi::MouseMovedEventFunc { [](u8 /*id*/, const math::ivec2& position) noexcept { - ilog("Mouse move event: {}", position); - } }, - wsi::MouseButtonDownEventFunc { [](u8 /*id*/, wsi::MouseButton button, const math::ivec2& position) noexcept { - ilog("Mouse button down event: {} {}", button, position); - } }, - wsi::MouseButtonUpEventFunc { [](u8 /*id*/, wsi::MouseButton button, const math::ivec2& position) noexcept { - ilog("Mouse button up event: {} {}", button, position); - } }, - wsi::RestoredEventFunc { [] noexcept { ilog("Restored event"); } }, - wsi::MinimizedEventFunc { [] noexcept { ilog("Minimized event"); } }, - wsi::ActivateEventFunc { [] noexcept { ilog("Activate event"); } }, - wsi::DeactivateEventFunc { [] noexcept { ilog("Deactivate event"); } }, - wsi::KeyDownEventFunc { [&window, &foo](u8 /*id*/, wsi::Key key, char c) mutable noexcept { - switch (key) { - case wsi::Key::ESCAPE: - window.close(); - ilog("Closing window"); - break; - case wsi::Key::W: { - auto extent = window.extent(); - extent.width += 10; - window.set_extent(extent); - } break; - case wsi::Key::T: { - window.set_title(std::format("StormKit WSI Events Example | T pressed {} times", ++foo)); - } break; - case wsi::Key::H: { - auto extent = window.extent(); - extent.height += 10; - window.set_extent(extent); - } break; - case wsi::Key::F11: - window.toggle_fullscreen(); - ilog("Toggling fullscreen to {}", window.fullscreen()); - break; - case wsi::Key::F1: - window.toggle_hidden_mouse(); - ilog("Toggling hidden mouse to {}", window.is_mouse_hidden()); - break; - case wsi::Key::F2: - window.toggle_locked_mouse(); - ilog("Toggling locked mouse to {}", window.is_mouse_locked()); - break; - case wsi::Key::F3: - window.toggle_confined_mouse(); - ilog("Toggling confined mouse to {}", window.is_mouse_confined()); - break; - case wsi::Key::F4: - window.toggle_relative_mouse(); - ilog("Toggling relative mouse to {}", window.is_mouse_relative()); - break; - case wsi::Key::F5: - window.toggle_key_repeat(); - ilog("Toggling key repeat to {}", window.is_key_repeat_enabled()); - break; - default: break; - } + window.on(wsi::ResizedEventFunc { [](const math::uextent2& extent) static noexcept { ilog("Resize event: {}", extent); } }, + wsi::MonitorChangedEventFunc { [](const wsi::Monitor& monitor) noexcept { + ilog("Monitor changed event: {}", monitor); + } }, + wsi::MouseMovedEventFunc { [](u8 /*id*/, const math::ivec2& position) noexcept { + ilog("Mouse move event: {}", position); + } }, + wsi::MouseButtonDownEventFunc { [](u8 /*id*/, wsi::MouseButton button, const math::ivec2& position) noexcept { + ilog("Mouse button down event: {} {}", button, position); + } }, + wsi::MouseButtonUpEventFunc { [](u8 /*id*/, wsi::MouseButton button, const math::ivec2& position) noexcept { + ilog("Mouse button up event: {} {}", button, position); + } }, + wsi::RestoredEventFunc { [] noexcept { ilog("Restored event"); } }, + wsi::MinimizedEventFunc { [] noexcept { ilog("Minimized event"); } }, + wsi::ActivateEventFunc { [] noexcept { ilog("Activate event"); } }, + wsi::DeactivateEventFunc { [] noexcept { ilog("Deactivate event"); } }, + wsi::KeyDownEventFunc { [&window, &foo](u8 /*id*/, wsi::Key key, char c) mutable noexcept { + switch (key) { + case wsi::Key::ESCAPE: + window.close(); + ilog("Closing window"); + break; + case wsi::Key::W: { + auto extent = window.extent(); + extent.width += 10; + window.set_extent(extent); + } break; + case wsi::Key::T: { + window.set_title(std::format("StormKit WSI Events Example | T pressed {} times", ++foo)); + } break; + case wsi::Key::H: { + auto extent = window.extent(); + extent.height += 10; + window.set_extent(extent); + } break; + case wsi::Key::F11: + window.toggle_fullscreen(); + ilog("Toggling fullscreen to {}", window.fullscreen()); + break; + case wsi::Key::F1: + window.toggle_hidden_mouse(); + ilog("Toggling hidden mouse to {}", window.is_mouse_hidden()); + break; + case wsi::Key::F2: + window.toggle_locked_mouse(); + ilog("Toggling locked mouse to {}", window.is_mouse_locked()); + break; + case wsi::Key::F3: + window.toggle_confined_mouse(); + ilog("Toggling confined mouse to {}", window.is_mouse_confined()); + break; + case wsi::Key::F4: + window.toggle_relative_mouse(); + ilog("Toggling relative mouse to {}", window.is_mouse_relative()); + break; + case wsi::Key::F5: + window.toggle_key_repeat(); + ilog("Toggling key repeat to {}", window.is_key_repeat_enabled()); + break; + default: break; + } - ilog("Key down --\n code: {}\n value: '{}'\n raw_value: 0x{:0x})", key, c, c); - } }, - wsi::KeyUpEventFunc { [](u8 /*id*/, wsi::Key key, char /*c*/) noexcept { ilog("Key up --\n code: {}", key); } }); + ilog("Key down --\n code: {}\n value: '{}'\n raw_value: 0x{:0x})", key, c, c); + } }, + wsi::KeyUpEventFunc { [](u8 /*id*/, wsi::Key key, char /*c*/) noexcept { ilog("Key up --\n code: {}", key); } }); window.event_loop([&] mutable { window.clear(); }); diff --git a/examples/wsi/framebuffer/src/main.cpp b/examples/wsi/framebuffer/src/main.cpp index 19c4c4153..d526d0f29 100644 --- a/examples/wsi/framebuffer/src/main.cpp +++ b/examples/wsi/framebuffer/src/main.cpp @@ -16,7 +16,7 @@ using namespace std::literals; namespace stdr = std::ranges; -auto update_pixels(stormkit::ThreadPool& pool, std::vector& pixels, const auto& extent) noexcept { +auto update_pixels(stormkit::ThreadPool& pool, dyn_array& pixels, const auto& extent) noexcept { const auto rect_width = extent.width / 5; const auto rect_height = extent.height / 5; @@ -29,7 +29,7 @@ auto update_pixels(stormkit::ThreadPool& pool, std::vector& pixels, pixels.resize(extent.height * extent.width, colors::RED); - auto data = std::mdspan { stdr::data(pixels), extent.height, extent.width }; + auto data = mdarray_view { stdr::data(pixels), extent.height, extent.width }; parallel_for(pool, range(extent.width * extent.height), [&rect, data, &extent](auto x_y) mutable noexcept { const auto x = as(x_y % extent.width); const auto y = as(x_y / extent.width); @@ -50,7 +50,7 @@ auto update_pixels(stormkit::ThreadPool& pool, std::vector& pixels, }); } -auto main(std::span args) -> int { +auto main(array_view args) -> int { wsi::parse_args(args); log::parse_args(args); @@ -64,7 +64,7 @@ auto main(std::span args) -> int { ilog("wm: {}", window.wm()); auto pool = core::ThreadPool {}; - auto pixels = std::vector {}; + auto pixels = dyn_array {}; update_pixels(pool, pixels, window.extent()); auto active = true; window.on(wsi::ResizedEventFunc { [&](const math::uextent2& extent) mutable noexcept { diff --git a/include/stormkit/core/format_macro.hpp b/include/stormkit/core/format_macro.hpp index 28d5783c5..1bc519bbb 100644 --- a/include/stormkit/core/format_macro.hpp +++ b/include/stormkit/core/format_macro.hpp @@ -45,7 +45,7 @@ #define FORMATTER_INHERIT_DEFINE_FORMAT_AS_STRING(_Parent, _From) \ FORMATTER_INHERIT_DEFINE_FORMAT(_From) { \ - return formatter<_Parent, CharT>::format(stormkit::as(std::forward(data)), ctx); \ + return formatter<_Parent, CharT>::format(stormkit::as(std::forward(data)), ctx); \ } #define FORMATTER_DEFINE_FORMAT_AS_STRING(_From) \ @@ -53,7 +53,7 @@ return ctx.begin(); \ } \ FORMATTER_DEFINE_FORMAT(_From) { \ - return std::format_to(ctx.out(), "{}", stormkit::as(std::forward(data))); \ + return std::format_to(ctx.out(), "{}", stormkit::as(std::forward(data))); \ } #define FORMATTER(_From) \ diff --git a/include/stormkit/core/platform_macro.hpp b/include/stormkit/core/platform_macro.hpp index 846d9b0fc..51a6c6f2e 100644 --- a/include/stormkit/core/platform_macro.hpp +++ b/include/stormkit/core/platform_macro.hpp @@ -35,7 +35,7 @@ #define STORMKIT_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]] #define STORMKIT_PUSH_WARNINGS _Pragma("warning(push)") #define STORMKIT_POP_WARNINGS _Pragma("warning(pop)") - #define STORMKIT_ARRAY_IF_MSVC std::array + #define STORMKIT_ARRAY_IF_MSVC array #elif defined(_MSC_VER) and defined(__clang__) #if defined(_LIBCPP_VERSION) #define STORMKIT_COMPILER_LIBCPP "libc++" @@ -44,7 +44,7 @@ #else #define STORMKIT_COMPILER_MSSTL "MSSTL" #define STORMKIT_COMPILER_CXXLIB STORMKIT_COMPILER_MSSTL - #define STORMKIT_ARRAY_IF_MSVC std::array + #define STORMKIT_ARRAY_IF_MSVC array #endif #define STORMKIT_EXPORT __declspec(dllexport) #define STORMKIT_IMPORT __declspec(dllimport) @@ -124,7 +124,7 @@ #if defined(__MINGW32__) #define STORMKIT_COMPILER STORMKIT_COMPILER_MINGW #if defined(__clang__) - #define STORMKIT_COMPILER_CLANG std::string { "MinGW Clang " } + __clang_version__ + #define STORMKIT_COMPILER_CLANG string { "MinGW Clang " } + __clang_version__ #define STORMKIT_COMPILER STORMKIT_COMPILER_CLANG #define STORMKIT_PUSH_WARNINGS _Pragma("clang diagnostic push") #define STORMKIT_POP_WARNINGS _Pragma("clang diagnostic pop") @@ -143,7 +143,7 @@ #endif #define STORMKIT_COMPILER_MINGW STORMKIT_COMPILER #elif defined(__clang__) - #define STORMKIT_COMPILER_CLANG std::string { "Clang " } + __clang_version__ + #define STORMKIT_COMPILER_CLANG string { "Clang " } + __clang_version__ #define STORMKIT_COMPILER STORMKIT_COMPILER_CLANG #define STORMKIT_PUSH_WARNINGS _Pragma("clang diagnostic push") #define STORMKIT_POP_WARNINGS _Pragma("clang diagnostic pop") diff --git a/modules/stormkit/core/console/style.cppm b/modules/stormkit/core/console/style.cppm index 0c670775b..35a826385 100644 --- a/modules/stormkit/core/console/style.cppm +++ b/modules/stormkit/core/console/style.cppm @@ -52,7 +52,7 @@ export { template struct Stylized { - constexpr auto render() const noexcept -> std::string; + constexpr auto render() const noexcept -> string; constexpr auto render_into(stdr::output_range auto& out) const noexcept -> void; T value; @@ -156,8 +156,8 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - constexpr auto Stylized::render() const noexcept -> std::string { - auto out = std::string {}; + constexpr auto Stylized::render() const noexcept -> string { + auto out = string {}; const auto size = [this] noexcept { if constexpr (requires { stdr::size(value); }) return stdr::size(value); else if constexpr (requires { std::char_traits>::length(value); }) @@ -183,7 +183,7 @@ namespace stormkit { inline namespace core { if (check_flag_bit(modifiers, StyleModifier::ITALIC)) out.append(ecma48::ITALIC); if (check_flag_bit(modifiers, StyleModifier::INVERSE)) out.append(ecma48::INVERSE); if (check_flag_bit(modifiers, StyleModifier::UNDERLINE)) out.append(ecma48::UNDERLINE); - if constexpr (meta::IsStringLike) out.append_range(std::string_view { value }); + if constexpr (meta::IsStringLike) out.append_range(string_view { value }); else out.append_range(std::format("{}", value)); diff --git a/modules/stormkit/core/containers.cppm b/modules/stormkit/core/containers.cppm index bffa4cdf7..4985b8133 100644 --- a/modules/stormkit/core/containers.cppm +++ b/modules/stormkit/core/containers.cppm @@ -9,6 +9,7 @@ export import :containers.ringbuffer; export import :containers.tree; export import :containers.dag; export import :containers.utils; +export import :containers.aliases; export import :containers.raii_capsule; export import :containers.shmbuffer; diff --git a/modules/stormkit/core/containers/aliases.cppm b/modules/stormkit/core/containers/aliases.cppm new file mode 100644 index 000000000..fbdfd2e16 --- /dev/null +++ b/modules/stormkit/core/containers/aliases.cppm @@ -0,0 +1,28 @@ +// Copyright (C) 2023 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +export module stormkit.core:containers.aliases; + +import std; + +namespace stdr = std::ranges; +namespace stdp = std::pmr; + +export namespace stormkit { inline namespace core { + using std::array; + + template> + using dyn_array = std::vector; + + template + using array_view = std::span; + + template> + using mdarray_view = std::mdspan; + + namespace pmr { + template + using dyn_array = std::vector>>; + } // namespace pmr +}} // namespace stormkit::core diff --git a/modules/stormkit/core/containers/dag.cppm b/modules/stormkit/core/containers/dag.cppm index 95f13cfa6..fd5acf7e2 100644 --- a/modules/stormkit/core/containers/dag.cppm +++ b/modules/stormkit/core/containers/dag.cppm @@ -46,8 +46,8 @@ export namespace stormkit { inline namespace core { class DAG { public: using Vertex = dag::Vertex; - using ColorizeClosure = std23::function_ref; - using FormatValueClosure = std23::function_ref; + using ColorizeClosure = std23::function_ref; + using FormatValueClosure = std23::function_ref; using ValueType = Vertex; @@ -94,34 +94,34 @@ export namespace stormkit { inline namespace core { constexpr auto add_edge(dag::VertexID from, dag::VertexID to) noexcept -> void; constexpr auto has_edge(dag::VertexID from, dag::VertexID to) const noexcept -> bool; constexpr auto remove_edge(dag::VertexID from, dag::VertexID to) noexcept -> void; - constexpr auto adjacent_edges(dag::VertexID vertex) const noexcept -> const std::vector&; + constexpr auto adjacent_edges(dag::VertexID vertex) const noexcept -> const dyn_array&; - constexpr auto vertices() const noexcept -> const std::vector&; + constexpr auto vertices() const noexcept -> const dyn_array&; constexpr auto vertices_count() const noexcept -> usize; - constexpr auto edges() const noexcept -> const std::vector&; + constexpr auto edges() const noexcept -> const dyn_array&; constexpr auto edges_count() const noexcept -> usize; - constexpr auto topological_sort() const noexcept -> std::expected, std::vector>; - constexpr auto find_cycle() const noexcept -> std::optional>; + constexpr auto topological_sort() const noexcept -> std::expected, dyn_array>; + constexpr auto find_cycle() const noexcept -> std::optional>; constexpr auto reverse_view() const noexcept -> DAG>; constexpr auto reverse_clone() const noexcept -> DAG; - constexpr auto dump(Closures closures = {}) const noexcept -> std::string; + constexpr auto dump(Closures closures = {}) const noexcept -> string; // FIXME find a way to make it not accessible to user template static constexpr auto reverse_from(dag::VertexID, - const std::vector&, - const std::vector&) noexcept -> DAG; + const dyn_array&, + const dyn_array&) noexcept -> DAG; private: dag::VertexID m_next_id = 0; - std::vector m_vertices; - std::vector m_edges; - std::vector>> m_adjacent_edges; + dyn_array m_vertices; + dyn_array m_edges; + dyn_array>> m_adjacent_edges; }; namespace dag { @@ -132,11 +132,11 @@ export namespace stormkit { inline namespace core { auto format_as(const dag::Vertex& vertex, FormatContext&) noexcept -> FormatContext::iterator; [[nodiscard]] - constexpr auto to_string(const Edge& edge) noexcept -> std::string; + constexpr auto to_string(const Edge& edge) noexcept -> string; template [[nodiscard]] - constexpr auto to_string(const dag::Vertex& vertex) noexcept -> std::string; + constexpr auto to_string(const dag::Vertex& vertex) noexcept -> string; } // namespace dag }} // namespace stormkit::core @@ -192,7 +192,7 @@ namespace stormkit { inline namespace core { { const auto id = m_next_id++; m_vertices.emplace_back(id, vertex); - m_adjacent_edges.emplace_back(id, std::vector {}); + m_adjacent_edges.emplace_back(id, dyn_array {}); return id; } @@ -204,7 +204,7 @@ namespace stormkit { inline namespace core { { const auto id = m_next_id++; m_vertices.emplace_back(id, std::move(vertex)); - m_adjacent_edges.emplace_back(id, std::vector {}); + m_adjacent_edges.emplace_back(id, dyn_array {}); return id; } @@ -271,7 +271,7 @@ namespace stormkit { inline namespace core { constexpr auto DAG::remove_vertex(dag::VertexID id) noexcept -> void { expects(has_vertex(id), std::format("Unknown DAG vertex id: {}!", id)); - auto touching = std::vector {}; + auto touching = dyn_array {}; for (auto&& edge : m_edges) if (edge.from == id or edge.to == id) touching.emplace_back(edge); @@ -336,7 +336,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - constexpr auto DAG::adjacent_edges(dag::VertexID id) const noexcept -> const std::vector& { + constexpr auto DAG::adjacent_edges(dag::VertexID id) const noexcept -> const dyn_array& { expects(has_vertex(id), std::format("Unknown DAG vertex id: {}!", id)); const auto& adjacent_edges = stdr::find_if(m_adjacent_edges, [id](const auto& pair) noexcept { @@ -349,7 +349,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto DAG::vertices() const noexcept -> const std::vector& { + constexpr auto DAG::vertices() const noexcept -> const dyn_array& { return m_vertices; } @@ -365,7 +365,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto DAG::edges() const noexcept -> const std::vector& { + constexpr auto DAG::edges() const noexcept -> const dyn_array& { return m_edges; } @@ -381,7 +381,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template constexpr auto DAG::topological_sort() const noexcept - -> std::expected, std::vector> { + -> std::expected, dyn_array> { if (auto result = find_cycle(); result.has_value()) return std::unexpected { std::move(*result) }; struct Degree { @@ -389,7 +389,7 @@ namespace stormkit { inline namespace core { u32 d = 0; }; - auto in_degree = std::vector {}; + auto in_degree = dyn_array {}; in_degree.reserve(stdr::size(m_vertices)); for (const auto& [id, _] : m_vertices) { in_degree.emplace_back(id, 0); } @@ -412,7 +412,7 @@ namespace stormkit { inline namespace core { if (d == 0) queue.push(id); } - auto ordered_vertices = std::vector {}; + auto ordered_vertices = dyn_array {}; ordered_vertices.reserve(stdr::size(m_vertices)); while (not stdr::empty(queue)) { auto id = queue.front(); @@ -438,12 +438,12 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - constexpr auto DAG::find_cycle() const noexcept -> std::optional> { - auto out = std::optional> { std::nullopt }; + constexpr auto DAG::find_cycle() const noexcept -> std::optional> { + auto out = std::optional> { std::nullopt }; - auto visited = std::vector {}; + auto visited = dyn_array {}; visited.reserve(stdr::size(m_vertices)); - auto stack = std::vector {}; + auto stack = dyn_array {}; auto dfs = [&visited, &stack, &out, this](auto&& dfs, auto&& id) mutable noexcept -> bool { visited.emplace_back(id); @@ -459,13 +459,13 @@ namespace stormkit { inline namespace core { if (dfs(dfs, w)) { return true; } else if (auto it = stdr::find(stack, w); it != stdr::cend(stack)) { - auto cycle = std::vector(it, stdr::end(stack)); + auto cycle = dyn_array(it, stdr::end(stack)); cycle.emplace_back(w); out = std::move(cycle); return true; } } else if (auto it = stdr::find(stack, w); it != stdr::cend(stack)) { - auto cycle = std::vector(it, stdr::end(stack)); + auto cycle = dyn_array(it, stdr::end(stack)); cycle.emplace_back(w); out = std::move(cycle); return true; @@ -503,13 +503,11 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - constexpr auto DAG::dump(Closures closures) const noexcept -> std::string { - auto out = std::string { - "digraph G {\n" - " rankdir = LR\n" - " bgcolor = black\n" - " node [shape=box, fontname=\"helvetica\", fontsize=12];\n\n" - }; + constexpr auto DAG::dump(Closures closures) const noexcept -> string { + auto out = string { "digraph G {\n" + " rankdir = LR\n" + " bgcolor = black\n" + " node [shape=box, fontname=\"helvetica\", fontsize=12];\n\n" }; if (closures.format_value) for (const auto& [id, value] : m_vertices) { @@ -538,9 +536,9 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template template - constexpr auto DAG::reverse_from(dag::VertexID next_id, - const std::vector& vertices, - const std::vector& edges) noexcept -> DAG { + constexpr auto DAG::reverse_from(dag::VertexID next_id, + const dyn_array& vertices, + const dyn_array& edges) noexcept -> DAG { auto out = DAG {}; out.m_next_id = next_id; @@ -548,12 +546,12 @@ namespace stormkit { inline namespace core { if constexpr (AS_REF) { for (const auto& [id, vertice] : vertices) { out.m_vertices.emplace_back(id, as_ref(vertice)); - out.m_adjacent_edges.emplace_back(id, std::vector {}); + out.m_adjacent_edges.emplace_back(id, dyn_array {}); } } else { for (const auto& [id, vertice] : vertices) { out.m_vertices.emplace_back(id, auto(vertice)); - out.m_adjacent_edges.emplace_back(id, std::vector {}); + out.m_adjacent_edges.emplace_back(id, dyn_array {}); } } @@ -595,7 +593,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto to_string(const dag::Edge& edge) noexcept -> std::string { + constexpr auto to_string(const dag::Edge& edge) noexcept -> string { return std::format("{}", edge); } @@ -603,7 +601,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto to_string(const dag::Vertex& vertex) noexcept -> std::string { + constexpr auto to_string(const dag::Vertex& vertex) noexcept -> string { return std::format("{}", vertex); } } // namespace dag diff --git a/modules/stormkit/core/containers/multi_buffer.cppm b/modules/stormkit/core/containers/multi_buffer.cppm index e0a702ef5..95cf0ede4 100644 --- a/modules/stormkit/core/containers/multi_buffer.cppm +++ b/modules/stormkit/core/containers/multi_buffer.cppm @@ -24,7 +24,7 @@ export namespace stormkit { inline namespace core { template class MultiBuffer { public: - explicit constexpr MultiBuffer(std::array sizes_in_bytes); + explicit constexpr MultiBuffer(array sizes_in_bytes); constexpr ~MultiBuffer(); constexpr MultiBuffer(const MultiBuffer&); @@ -37,26 +37,26 @@ export namespace stormkit { inline namespace core { constexpr auto size() const noexcept -> usize; template [[nodiscard]] - constexpr auto data(this Self& self) noexcept -> const meta::ForwardConst*; + constexpr auto data(this Self& self) noexcept -> const meta::ForwardConst*; template - constexpr auto init_range(V&& init_data) noexcept -> std::span; + constexpr auto init_range(V&& init_data) noexcept -> array_view; template - constexpr auto init_range(V&& init_data) noexcept -> std::span; + constexpr auto init_range(V&& init_data) noexcept -> array_view; template [[nodiscard]] - constexpr auto range(this Self& self) noexcept -> std::span>; + constexpr auto range(this Self& self) noexcept -> array_view>; template [[nodiscard]] - constexpr auto range(this Self& self) noexcept -> std::span>; + constexpr auto range(this Self& self) noexcept -> array_view>; private: - std::array m_ranges_sizes; - std::array m_ranges_begin; - usize m_size = 0; - ByteDynArray m_data; + array m_ranges_sizes; + array m_ranges_begin; + usize m_size = 0; + byte_dyn_array m_data; }; }} // namespace stormkit::core @@ -69,7 +69,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr MultiBuffer::MultiBuffer(std::array sizes_in_bytes) + constexpr MultiBuffer::MultiBuffer(array sizes_in_bytes) : m_ranges_sizes { sizes_in_bytes } { auto i = 0uz; for (auto&& size : m_ranges_sizes) { @@ -122,7 +122,7 @@ namespace stormkit { inline namespace core { template template STORMKIT_FORCE_INLINE - constexpr auto MultiBuffer::data(this Self& self) noexcept -> const meta::ForwardConst* { + constexpr auto MultiBuffer::data(this Self& self) noexcept -> const meta::ForwardConst* { return stdr::data(self.m_data); } @@ -130,7 +130,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template template - constexpr auto MultiBuffer::init_range(V&& init_data) noexcept -> std::span { + constexpr auto MultiBuffer::init_range(V&& init_data) noexcept -> array_view { static_assert(meta::IsAnyOf, "U should be a type contained by MultiBuffer"); static_assert(meta::Is>, "range V should be of type U"); static constexpr auto TYPE_INDEX = meta::find_type_index_of(); @@ -141,9 +141,9 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template template - constexpr auto MultiBuffer::init_range(V&& init_data) noexcept -> std::span { + constexpr auto MultiBuffer::init_range(V&& init_data) noexcept -> array_view { static_assert(TYPE_INDEX < sizeof...(T), "Index is out of bounds"); - auto span = std::span { stdr::data(m_data) + m_ranges_begin[TYPE_INDEX], m_ranges_sizes[TYPE_INDEX] }; + auto span = byte_mut_view { stdr::data(m_data) + m_ranges_begin[TYPE_INDEX], m_ranges_sizes[TYPE_INDEX] }; auto begin = stdr::begin(span); for (auto&& bytes : std::forward(init_data) | stdv::transform(monadic::as_bytes(Force {}))) { @@ -158,7 +158,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template template - constexpr auto MultiBuffer::range(this Self& self) noexcept -> std::span> { + constexpr auto MultiBuffer::range(this Self& self) noexcept -> array_view> { static_assert(meta::IsAnyOf, "U should be a type contained by MultiBuffer"); static constexpr auto TYPE_INDEX = meta::find_type_index_of(); return self.template range(); @@ -168,12 +168,12 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template template - constexpr auto MultiBuffer::range(this Self& self) noexcept -> std::span> { + constexpr auto MultiBuffer::range(this Self& self) noexcept -> array_view> { static_assert(TYPE_INDEX < sizeof...(T), "Index is out of bounds"); using U = T...[TYPE_INDEX]; using OutType = meta::ForwardConst; const auto ptr = stdr::begin(self.m_data) + as(self.m_ranges_begin[TYPE_INDEX]); - return std::span { + return array_view { #if defined(__cpp_lib_start_lifetime_as) and __cpp_lib_start_lifetime_as >= 202207L std::start_lifetime_as_array(ptr, self.m_ranges_sizes[TYPE_INDEX] / sizeof(U)), #else diff --git a/modules/stormkit/core/containers/ringbuffer.cppm b/modules/stormkit/core/containers/ringbuffer.cppm index 91451496b..af98e13f0 100644 --- a/modules/stormkit/core/containers/ringbuffer.cppm +++ b/modules/stormkit/core/containers/ringbuffer.cppm @@ -64,7 +64,7 @@ export namespace stormkit { inline namespace core { auto get(this Self& self) noexcept -> decltype(auto); [[nodiscard]] - auto data() const noexcept -> std::span; + auto data() const noexcept -> array_view; private: template @@ -74,7 +74,7 @@ export namespace stormkit { inline namespace core { ExtentType m_capacity = 0; ExtentType m_count = 0; - std::vector m_buffer; + byte_dyn_array m_buffer; ExtentType m_write = 0; ExtentType m_read = 0; @@ -140,7 +140,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template RingBuffer::RingBuffer(RingBuffer&& moved) noexcept { - m_buffer = std::exchange(moved.m_buffer, std::vector {}); + m_buffer = std::exchange(moved.m_buffer, byte_dyn_array {}); m_capacity = std::exchange(moved.m_capacity, 0); m_count = std::exchange(moved.m_count, 0); @@ -154,7 +154,7 @@ namespace stormkit { inline namespace core { auto RingBuffer::operator=(RingBuffer&& moved) noexcept -> RingBuffer& { if (&moved == this) return *this; - m_buffer = std::exchange(moved.m_buffer, std::vector {}); + m_buffer = std::exchange(moved.m_buffer, byte_dyn_array {}); m_capacity = std::exchange(moved.m_capacity, 0); m_count = std::exchange(moved.m_count, 0); @@ -262,8 +262,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - auto RingBuffer::data() const noexcept -> std::span { - return std::span { get_ptr(0), m_capacity }; + auto RingBuffer::data() const noexcept -> array_view { + return array_view { get_ptr(0), m_capacity }; } //////////////////////////////////////// diff --git a/modules/stormkit/core/containers/shmbuffer.cppm b/modules/stormkit/core/containers/shmbuffer.cppm index 568a08218..c36a4e783 100644 --- a/modules/stormkit/core/containers/shmbuffer.cppm +++ b/modules/stormkit/core/containers/shmbuffer.cppm @@ -51,22 +51,22 @@ export namespace stormkit { inline namespace core { auto size() const noexcept -> usize; template - auto data(this Self&) noexcept -> std::span>; + auto data(this Self&) noexcept -> array_view>; template auto native_handle(this Self&) noexcept -> meta::ForwardConst*; - auto name() const noexcept -> std::string_view; + auto name() const noexcept -> string_view; auto access() const noexcept -> io::Access; constexpr SHMBuffer(PrivateTag) noexcept; - auto do_init(PrivateTag, usize, std::string, io::Access = io::Access::READ | io::Access::WRITE) noexcept + auto do_init(PrivateTag, usize, string, io::Access = io::Access::READ | io::Access::WRITE) noexcept -> std::expected; private: - io::Access m_access; - void* m_handle = nullptr; - usize m_size; - std::string m_name; - std::span m_data; + io::Access m_access; + void* m_handle = nullptr; + usize m_size; + string m_name; + array_view m_data; }; }} // namespace stormkit::core @@ -169,7 +169,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto SHMBuffer::data(this Self& self) noexcept -> std::span> { + inline auto SHMBuffer::data(this Self& self) noexcept -> array_view> { EXPECTS(self.m_handle); return std::forward(self).m_data; } @@ -185,7 +185,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto SHMBuffer::name() const noexcept -> std::string_view { + inline auto SHMBuffer::name() const noexcept -> string_view { return m_name; } diff --git a/modules/stormkit/core/containers/tree.cppm b/modules/stormkit/core/containers/tree.cppm index b03f6c1be..c2237ca52 100644 --- a/modules/stormkit/core/containers/tree.cppm +++ b/modules/stormkit/core/containers/tree.cppm @@ -33,8 +33,8 @@ export namespace stormkit { inline namespace core { static constexpr auto INVALID_INDEX = IndexType { IndexType::INVALID_HANDLE_VALUE }; [[nodiscard]] - auto name() const noexcept -> const std::string&; - auto set_name(std::string name) noexcept -> void; + auto name() const noexcept -> const string&; + auto set_name(string name) noexcept -> void; [[nodiscard]] auto parent() const noexcept -> IndexType; @@ -57,7 +57,7 @@ export namespace stormkit { inline namespace core { IndexType m_first_child = INVALID_INDEX; DirtyBitType m_dirty_bits = 0; - std::string m_name; + string m_name; }; template @@ -107,21 +107,19 @@ export namespace stormkit { inline namespace core { auto clear_dirties() noexcept -> void; [[nodiscard]] - auto dirties() const noexcept -> std::span; + auto dirties() const noexcept -> array_view; - auto gen_dot_file(stdfs::path filepath, - std23::function_ref colorize_node) const noexcept + auto gen_dot_file(stdfs::path filepath, std23::function_ref colorize_node) const noexcept -> io::Expected; - auto gen_dot_file(stdfs::path filepath, - core::u32 highlight, - std23::function_ref colorize_node) const noexcept - -> io::Expected; + auto gen_dot_file(stdfs::path filepath, + core::u32 highlight, + std23::function_ref colorize_node) const noexcept -> io::Expected; private: - TreeNodeIndexType m_first_free_index = 0; - std::vector m_tree; - std::vector m_dirties; + TreeNodeIndexType m_first_free_index = 0; + dyn_array m_tree; + dyn_array m_dirties; }; }} // namespace stormkit::core @@ -132,13 +130,13 @@ export namespace stormkit { inline namespace core { namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - inline auto TreeNode::name() const noexcept -> const std::string& { + inline auto TreeNode::name() const noexcept -> const string& { return m_name; } //////////////////////////////////////// //////////////////////////////////////// - inline auto TreeNode::set_name(std::string name) noexcept -> void { + inline auto TreeNode::set_name(string name) noexcept -> void { m_name = std::move(name); } @@ -435,18 +433,18 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - auto Tree::dirties() const noexcept -> std::span { + auto Tree::dirties() const noexcept -> array_view { return m_dirties; } //////////////////////////////////////// //////////////////////////////////////// template - auto Tree::gen_dot_file(stdfs::path filepath, - std23::function_ref colorize_node) const noexcept + auto Tree::gen_dot_file(stdfs::path filepath, + std23::function_ref colorize_node) const noexcept -> io::Expected { using namespace stormkit::literals; - auto out = std::string {}; + auto out = string {}; out.reserve(1_kb); out += "digraph G { \n" @@ -483,12 +481,12 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - auto Tree::gen_dot_file(stdfs::path filepath, - core::u32 highlight, - std23::function_ref colorize_node) const noexcept + auto Tree::gen_dot_file(stdfs::path filepath, + core::u32 highlight, + std23::function_ref colorize_node) const noexcept -> io::Expected { using namespace stormkit::literals; - auto out = std::string {}; + auto out = string {}; out.reserve(1_kb); out += "digraph G { \n" diff --git a/modules/stormkit/core/containers/utils.cppm b/modules/stormkit/core/containers/utils.cppm index 78f881b11..92ca6b9da 100644 --- a/modules/stormkit/core/containers/utils.cppm +++ b/modules/stormkit/core/containers/utils.cppm @@ -18,57 +18,57 @@ namespace stdr = std::ranges; export namespace stormkit { inline namespace core { // template typename Container = std::inplace_vector, typename T> - template typename Container = std::vector, typename T> + template typename Container = dyn_array, typename T> constexpr auto filled_with(usize size, T value) noexcept -> Container; template - constexpr auto filled_with(T value) noexcept -> std::array; + constexpr auto filled_with(T value) noexcept -> array; template constexpr auto merge(Out& output, const Inputs&... ranges) noexcept -> void; - template typename Out = std::vector, stdr::input_range... Inputs> + template typename Out = dyn_array, stdr::input_range... Inputs> constexpr auto concat(const Inputs&... inputs) noexcept -> Out>>; template constexpr auto move_and_merge(Out& output, Inputs&&... ranges) noexcept -> void; - template typename Out = std::vector, stdr::input_range... Inputs> + template typename Out = dyn_array, stdr::input_range... Inputs> constexpr auto move_and_concat(Inputs&&... inputs) noexcept -> Out>>; using std::to_array; template - constexpr auto to_dyn_array(T&& range) noexcept -> std::vector>; + constexpr auto to_dyn_array(T&& range) noexcept -> dyn_array>; template requires(sizeof...(Args) > 0) - constexpr auto into_array(Args&&... args) noexcept -> std::array, sizeof...(Args)>; + constexpr auto into_array(Args&&... args) noexcept -> array, sizeof...(Args)>; template requires(sizeof...(Args) > 0) - constexpr auto into_array_of(Args&&... args) noexcept -> std::array; + constexpr auto into_array_of(Args&&... args) noexcept -> array; template requires(sizeof...(Args) > 0) - constexpr auto into_dyn_array(Args&&... args) noexcept -> std::vector>; + constexpr auto into_dyn_array(Args&&... args) noexcept -> dyn_array>; template requires(sizeof...(Args) > 0) - constexpr auto into_dyn_array_of(Args&&... args) noexcept -> std::vector; + constexpr auto into_dyn_array_of(Args&&... args) noexcept -> dyn_array; template - constexpr auto as_view(T& range) noexcept -> std::string_view; + constexpr auto as_view(T& range) noexcept -> string_view; template requires(not stdr::range) - constexpr auto as_view(T& value) noexcept -> std::span; + constexpr auto as_view(T& value) noexcept -> array_view; template - constexpr auto as_view(T& range) noexcept -> std::span>>; + constexpr auto as_view(T& range) noexcept -> array_view>>; template - constexpr auto as_view(T& range, Force) noexcept -> std::span>>; + constexpr auto as_view(T& range, Force) noexcept -> array_view>>; }} // namespace stormkit::core //////////////////////////////////////////////////////////////////// @@ -91,8 +91,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto filled_with(T value) noexcept -> std::array { - auto out = std::array {}; + constexpr auto filled_with(T value) noexcept -> array { + auto out = array {}; std::ranges::fill(out, value); return out; } @@ -146,8 +146,8 @@ namespace stormkit { inline namespace core { template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto to_dyn_array(T&& range) noexcept -> std::vector> { - return std::forward(range) | stdr::to(); + constexpr auto to_dyn_array(T&& range) noexcept -> dyn_array> { + return std::forward(range) | stdr::to>>(); } ///////////////////////////////////// @@ -156,11 +156,11 @@ namespace stormkit { inline namespace core { requires(sizeof...(Args) > 0) STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto into_array(Args&&... args) noexcept -> std::array, sizeof...(Args)> { + constexpr auto into_array(Args&&... args) noexcept -> array, sizeof...(Args)> { static_assert((not meta::IsLValueReference and ...), "lvalue reference can't be passed to into_ functions as it take " "ownership"); - return std::array { std::move(args)... }; + return array { std::move(args)... }; } ///////////////////////////////////// @@ -169,8 +169,8 @@ namespace stormkit { inline namespace core { requires(sizeof...(Args) > 0) STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto into_array_of(Args&&... args) noexcept -> std::array { - return std::array { T { std::move(args) }... }; + constexpr auto into_array_of(Args&&... args) noexcept -> array { + return array { T { std::move(args) }... }; } ///////////////////////////////////// @@ -178,11 +178,11 @@ namespace stormkit { inline namespace core { template requires(sizeof...(Args) > 0) STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto into_dyn_array(Args&&... args) noexcept -> std::vector> { + constexpr auto into_dyn_array(Args&&... args) noexcept -> dyn_array> { static_assert((not meta::IsLValueReference and ...), "lvalue reference can't be passed to into_ functions as it take " "ownership"); - return std::vector { std::move(args)... }; + return dyn_array { std::move(args)... }; } ///////////////////////////////////// @@ -190,8 +190,8 @@ namespace stormkit { inline namespace core { template requires(sizeof...(Args) > 0) STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto into_dyn_array_of(Args&&... args) noexcept -> std::vector { - return std::vector { T { std::move(args) }... }; + constexpr auto into_dyn_array_of(Args&&... args) noexcept -> dyn_array { + return dyn_array { T { std::move(args) }... }; } ///////////////////////////////////// @@ -199,8 +199,8 @@ namespace stormkit { inline namespace core { template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto as_view(T& range) noexcept -> std::string_view { - return std::string_view { range }; + constexpr auto as_view(T& range) noexcept -> string_view { + return string_view { range }; } ///////////////////////////////////// @@ -208,7 +208,7 @@ namespace stormkit { inline namespace core { template requires(not stdr::range) STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto as_view(T& value) noexcept -> std::span { + constexpr auto as_view(T& value) noexcept -> array_view { return { &value, 1 }; } @@ -216,7 +216,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto as_view(T& range) noexcept -> std::span>> { + constexpr auto as_view(T& range) noexcept -> array_view>> { return { range }; } @@ -224,7 +224,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto as_view(T& range, Force) noexcept -> std::span>> { + constexpr auto as_view(T& range, Force) noexcept -> array_view>> { return { range }; } }} // namespace stormkit::core diff --git a/modules/stormkit/core/coroutines.cppm b/modules/stormkit/core/coroutines.cppm index 1ebbda94e..b62b5fd1b 100644 --- a/modules/stormkit/core/coroutines.cppm +++ b/modules/stormkit/core/coroutines.cppm @@ -316,13 +316,13 @@ export namespace std { void await_transform() = delete; }; - template + template struct __generator_promise; - template - struct __generator_promise, _ByteAllocator, _ExplicitAllocator> final + template + struct __generator_promise, _byteAllocator, _ExplicitAllocator> final : public __generator_promise_base<_Ref>, - public __promise_base_alloc<_ByteAllocator> { + public __promise_base_alloc<_byteAllocator> { __generator_promise() noexcept : __generator_promise_base<_Ref>(coroutine_handle<__generator_promise>::from_promise(*this)) {} @@ -571,7 +571,7 @@ export namespace std { sentinel end() noexcept { return {}; } private: - template + template friend struct __generator_promise; template diff --git a/modules/stormkit/core/errors.cppm b/modules/stormkit/core/errors.cppm index e781bf46d..93ad5d9f9 100644 --- a/modules/stormkit/core/errors.cppm +++ b/modules/stormkit/core/errors.cppm @@ -20,6 +20,8 @@ export module stormkit.core:errors; import std; +import :string.aliases; + export { namespace stormkit { inline namespace core { #if (defined(__clang__) or defined(__GNUC__)) @@ -89,8 +91,8 @@ export { template struct DecoratedError { - Error error; - std::string message = ""; + Error error; + string message = ""; }; template<> @@ -98,10 +100,10 @@ export { explicit DecoratedError(Error _error) noexcept; Error error; - std::string message; + string message; }; - auto to_string(const SystemError& error) noexcept -> std::string; + auto to_string(const SystemError& error) noexcept -> string; }} // namespace stormkit::core namespace std { @@ -146,12 +148,12 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto to_string(const SystemError& error) noexcept -> std::string { + inline auto to_string(const SystemError& error) noexcept -> string { const auto code = static_cast(error.code); #ifdef STORMKIT_OS_WINDOWS - thread_local auto STRERROR_BUFFER = std::array {}; + thread_local auto STRERROR_BUFFER = array {}; strerror_s(stdr::data(STRERROR_BUFFER), stdr::size(STRERROR_BUFFER), code); - return std::string { stdr::data(STRERROR_BUFFER) }; + return string { stdr::data(STRERROR_BUFFER) }; #else return std::strerror(code); #endif diff --git a/modules/stormkit/core/functional/error_handling.cppm b/modules/stormkit/core/functional/error_handling.cppm index 44e1a82f7..17f37ba97 100644 --- a/modules/stormkit/core/functional/error_handling.cppm +++ b/modules/stormkit/core/functional/error_handling.cppm @@ -17,16 +17,16 @@ import :utils.contract; export namespace stormkit { inline namespace core { namespace monadic { [[nodiscard]] - constexpr auto assert(std::optional message = std::nullopt, - std::source_location location = std::source_location::current()) noexcept -> decltype(auto); + constexpr auto assert(std::optional message = std::nullopt, + std::source_location location = std::source_location::current()) noexcept -> decltype(auto); template [[nodiscard]] - constexpr auto assert(std::optional message = std::nullopt, - std::source_location location = std::source_location::current()) noexcept -> decltype(auto); + constexpr auto assert(std::optional message = std::nullopt, + std::source_location location = std::source_location::current()) noexcept -> decltype(auto); [[nodiscard]] - constexpr auto log(std::invocable auto&& logger, std::string&& message) noexcept -> decltype(auto); + constexpr auto log(std::invocable auto&& logger, string&& message) noexcept -> decltype(auto); [[nodiscard]] constexpr auto throw_as_exception() noexcept -> decltype(auto); @@ -47,7 +47,7 @@ namespace stormkit { inline namespace core { namespace monadic { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto assert(std::optional message, std::source_location location) noexcept -> decltype(auto) { + constexpr auto assert(std::optional message, std::source_location location) noexcept -> decltype(auto) { return [message = std::move(message), location = std::move(location)] NORETURN_LAMBDA(const E& error) -> T { if (message.has_value()) core::assert(false, std::format("{} ({})", *message, error), std::move(location)); else @@ -60,7 +60,7 @@ namespace stormkit { inline namespace core { namespace monadic { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto assert(std::optional message, std::source_location location) noexcept -> decltype(auto) { + constexpr auto assert(std::optional message, std::source_location location) noexcept -> decltype(auto) { return [message = std::move(message), location = std::move(location)] NORETURN_LAMBDA(const E& error) -> E { if (message.has_value()) core::assert(false, std::format("{} ({})", *message, error), std::move(location)); else @@ -73,7 +73,7 @@ namespace stormkit { inline namespace core { namespace monadic { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto log(std::invocable auto&& logger, std::string&& message) noexcept -> decltype(auto) { + constexpr auto log(std::invocable auto&& logger, string&& message) noexcept -> decltype(auto) { return [logger = std::forward, message = std::move(message)](auto&& error) -> std::expected> { logger(message, error); diff --git a/modules/stormkit/core/hash/map.cppm b/modules/stormkit/core/hash/map.cppm index e93d39fc0..96895a9ed 100644 --- a/modules/stormkit/core/hash/map.cppm +++ b/modules/stormkit/core/hash/map.cppm @@ -14,11 +14,11 @@ export namespace stormkit { inline namespace core { class Hash = ankerl::unordered_dense::hash, class KeyEqual = std::equal_to, class AllocatorOrContainer = std::allocator>> - using HashMap = ankerl::unordered_dense::map; + using hash_map = ankerl::unordered_dense::map; template, class KeyEqual = std::equal_to, class AllocatorOrContainer = std::allocator> - using HashSet = ankerl::unordered_dense::set; + using hash_set = ankerl::unordered_dense::set; }} // namespace stormkit::core diff --git a/modules/stormkit/core/hash/string.cppm b/modules/stormkit/core/hash/string.cppm index bbcfc2bd4..bfae7caad 100644 --- a/modules/stormkit/core/hash/string.cppm +++ b/modules/stormkit/core/hash/string.cppm @@ -10,7 +10,7 @@ export module stormkit.core:hash.string; import :hash.base; -import :string.czstring; +import :string.aliases; import :typesafe.integer; import :typesafe.safecasts; @@ -24,29 +24,29 @@ export namespace stormkit { inline namespace core { using is_avalanching = void; [[nodiscard]] - static constexpr auto operator()(std::string_view value, u64 seed = 0) noexcept -> u64; + static constexpr auto operator()(string_view value, u64 seed = 0) noexcept -> u64; }; - template - using StringHashMap = ankerl::unordered_dense:: + template + using string_hash_map = ankerl::unordered_dense:: map, std::remove_cvref_t, StringHash, std::equal_to<>>; - template - using FrozenStringHashMap = frozen:: + template + using Frozenstring_hash_map = frozen:: unordered_map, std::remove_cvref_t, Size, StringHash, std::equal_to<>>; - template - using StringHashSet = ankerl::unordered_dense::set, StringHash, std::equal_to<>>; + template + using string_hash_set = ankerl::unordered_dense::set, StringHash, std::equal_to<>>; - template - using FrozenStringHashSet = frozen::unordered_set, Size, StringHash, std::equal_to<>>; + template + using frozen_string_hash_set = frozen::unordered_set, Size, StringHash, std::equal_to<>>; template - constexpr auto hasher(std::string_view value) noexcept -> Ret; + constexpr auto hasher(string_view value) noexcept -> Ret; namespace literals { - constexpr auto operator""_hash32(CZString str, usize size) -> hash32; - constexpr auto operator""_hash64(CZString str, usize size) -> hash64; + constexpr auto operator""_hash32(czstring str, usize size) -> hash32; + constexpr auto operator""_hash64(czstring str, usize size) -> hash64; } // namespace literals }} // namespace stormkit::core @@ -62,12 +62,12 @@ namespace stormkit { inline namespace core { : m_hash { basis } {} STORMKIT_FORCE_INLINE - constexpr auto bytes(std::span bytes) noexcept -> void { + constexpr auto bytes(array_view bytes) noexcept -> void { bytes_4(bytes); } STORMKIT_FORCE_INLINE - constexpr auto bytes_4(std::span bytes) noexcept -> void { + constexpr auto bytes_4(array_view bytes) noexcept -> void { const auto val = u64(bytes[0]) << 0 | u64(bytes[1]) << 8 | u64(bytes[2]) << 16 | u64(bytes[3]) << 24; dword(val); } @@ -98,7 +98,7 @@ namespace stormkit { inline namespace core { template STORMKIT_FORCE_INLINE - constexpr auto hash_selected_characters(u8 mask, Hasher& hasher, CZString s, usize size) noexcept -> void { + constexpr auto hash_selected_characters(u8 mask, Hasher& hasher, czstring s, usize size) noexcept -> void { if (std::popcount(mask) == 4) { auto dword = u64 { 0 }; auto i = i32 { 0 }; @@ -164,8 +164,8 @@ namespace stormkit { inline namespace core { hasher.dword(dword); } else { - std::array bytes; - auto i = usize { 0 }; + array bytes; + auto i = usize { 0 }; if (mask & (1 << 0)) bytes[i++] = static_cast(s[0]); if (mask & (1 << 1)) bytes[i++] = static_cast(s[1]); @@ -175,14 +175,14 @@ namespace stormkit { inline namespace core { if (mask & (1 << 4)) bytes[i++] = static_cast(size); - hasher.bytes(std::span { std::data(bytes), i }); + hasher.bytes(array_view { std::data(bytes), i }); } } //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto StringHash::operator()(std::string_view value, u64 seed) noexcept -> u64 { + constexpr auto StringHash::operator()(string_view value, u64 seed) noexcept -> u64 { auto mask = u8 { 0b01111 }; auto hasher = Lehmer128Hasher { seed }; hash_selected_characters(mask, hasher, std::data(value), std::size(value)); @@ -193,7 +193,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto hasher(std::string_view value) noexcept -> Ret { + constexpr auto hasher(string_view value) noexcept -> Ret { return StringHash::operator()(value); } @@ -201,15 +201,15 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto operator""_hash32(CZString str, usize size) -> hash32 { - return hash(std::string_view { str, size }); + constexpr auto operator""_hash32(czstring str, usize size) -> hash32 { + return hash(string_view { str, size }); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto operator""_hash64(CZString str, usize size) -> hash64 { - return hash(std::string_view { str, size }); + constexpr auto operator""_hash64(czstring str, usize size) -> hash64 { + return hash(string_view { str, size }); } } // namespace literals }} // namespace stormkit::core diff --git a/modules/stormkit/core/math/combinatoric.cppm b/modules/stormkit/core/math/combinatoric.cppm index e96151221..d8b2a6915 100644 --- a/modules/stormkit/core/math/combinatoric.cppm +++ b/modules/stormkit/core/math/combinatoric.cppm @@ -24,7 +24,7 @@ export namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////////////////////////////////// namespace stormkit { inline namespace core { namespace math { - constexpr auto FTABLE = std::array { + constexpr auto FTABLE = array { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800 }; diff --git a/modules/stormkit/core/math/extent.cppm b/modules/stormkit/core/math/extent.cppm index 1b27b3204..76e02d86c 100644 --- a/modules/stormkit/core/math/extent.cppm +++ b/modules/stormkit/core/math/extent.cppm @@ -26,7 +26,7 @@ export { struct extent; template - struct alignas(std::array) extent { + struct alignas(array) extent { static constexpr auto RANK = 2uz; using ValueType = T; using OrderingType = meta::ArithmeticOrderingType; @@ -55,7 +55,7 @@ export { using iextent2 = extent2; template - struct alignas(std::array) extent { + struct alignas(array) extent { static constexpr auto RANK = 3uz; using ValueType = T; using OrderingType = meta::ArithmeticOrderingType; @@ -155,10 +155,10 @@ export { constexpr auto operator/=(Extent& extent, typename Extent::ValueType factor) noexcept -> Extent&; template - auto to_string(const Extent& extent) noexcept -> std::string; + auto to_string(const Extent& extent) noexcept -> string; template - auto to_string(const Extent& extent) noexcept -> std::string; + auto to_string(const Extent& extent) noexcept -> string; template auto format_as(const extent& extent, FormatContext& ctx) noexcept -> decltype(ctx.out()); @@ -204,8 +204,8 @@ namespace stormkit { inline namespace core { namespace math { STORMKIT_PURE constexpr auto extent::to() const noexcept -> extent { using Out = extent; - using Array = std::array; - using OtherArray = std::array; + using Array = array; + using OtherArray = array; auto out = Out {}; @@ -245,8 +245,8 @@ namespace stormkit { inline namespace core { namespace math { STORMKIT_PURE constexpr auto extent::to() const noexcept -> extent { using Out = extent; - using Array = std::array; - using OtherArray = std::array; + using Array = array; + using OtherArray = array; auto out = Out {}; @@ -266,7 +266,7 @@ namespace stormkit { inline namespace core { namespace math { template STORMKIT_PURE constexpr auto operator<=>(const Extent& first, const Extent& second) noexcept -> typename Extent::OrderingType { - using Array = std::array; + using Array = array; using OrderingType = typename Extent::OrderingType; static constexpr auto RANK = Extent::RANK; @@ -284,7 +284,7 @@ namespace stormkit { inline namespace core { namespace math { template STORMKIT_PURE constexpr auto operator==(const Extent& first, const Extent& second) noexcept -> bool { - using Array = std::array; + using Array = array; static constexpr auto RANK = Extent::RANK; const auto& values = *std::bit_cast(&first); @@ -319,7 +319,7 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto operator*=(Extent& extent, typename Extent::ValueType factor) noexcept -> Extent& { using ValueType = typename Extent::ValueType; static constexpr auto RANK = Extent::RANK; - auto& values = *std::bit_cast>(&extent); + auto& values = *std::bit_cast>(&extent); for (auto&& val : values) val *= factor; return extent; } @@ -331,7 +331,7 @@ namespace stormkit { inline namespace core { namespace math { constexpr auto operator/=(Extent& extent, typename Extent::ValueType factor) noexcept -> Extent& { using ValueType = typename Extent::ValueType; static constexpr auto RANK = Extent::RANK; - auto& values = *std::bit_cast>(&extent); + auto& values = *std::bit_cast>(&extent); for (auto&& val : values) val /= factor; return extent; } @@ -340,7 +340,7 @@ namespace stormkit { inline namespace core { namespace math { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto to_string(const Extent& extent) noexcept -> std::string { + inline auto to_string(const Extent& extent) noexcept -> string { return std::format("{}", extent); } @@ -348,7 +348,7 @@ namespace stormkit { inline namespace core { namespace math { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto to_string(const Extent& extent) noexcept -> std::string { + inline auto to_string(const Extent& extent) noexcept -> string { return std::format("{}", extent); } @@ -385,20 +385,20 @@ namespace stormkit { inline namespace core { namespace math { } }}} // namespace stormkit::core::math -static_assert(sizeof(math::uextent2) == sizeof(std::array)); -static_assert(sizeof(math::uextent3) == sizeof(std::array)); +static_assert(sizeof(math::uextent2) == sizeof(array)); +static_assert(sizeof(math::uextent3) == sizeof(array)); -static_assert(sizeof(math::iextent2) == sizeof(std::array)); -static_assert(sizeof(math::iextent3) == sizeof(std::array)); +static_assert(sizeof(math::iextent2) == sizeof(array)); +static_assert(sizeof(math::iextent3) == sizeof(array)); -static_assert(sizeof(math::extent2) == sizeof(std::array)); -static_assert(sizeof(math::extent3) == sizeof(std::array)); +static_assert(sizeof(math::extent2) == sizeof(array)); +static_assert(sizeof(math::extent3) == sizeof(array)); -static_assert(sizeof(math::extent2) == sizeof(std::array)); -static_assert(sizeof(math::extent3) == sizeof(std::array)); +static_assert(sizeof(math::extent2) == sizeof(array)); +static_assert(sizeof(math::extent3) == sizeof(array)); -static_assert(sizeof(math::fextent2) == sizeof(std::array)); -static_assert(sizeof(math::fextent3) == sizeof(std::array)); +static_assert(sizeof(math::fextent2) == sizeof(array)); +static_assert(sizeof(math::fextent3) == sizeof(array)); static_assert(math::fextent2::RANK == 2); static_assert(math::fextent3::RANK == 3); diff --git a/modules/stormkit/core/math/geometry.cppm b/modules/stormkit/core/math/geometry.cppm index 29d8ae926..a014e0c04 100644 --- a/modules/stormkit/core/math/geometry.cppm +++ b/modules/stormkit/core/math/geometry.cppm @@ -64,10 +64,10 @@ export namespace stormkit { inline namespace core { namespace math { using fbounding_rect = bounding_rect; template - auto to_string(const rect& value) noexcept -> std::string; + auto to_string(const rect& value) noexcept -> string; template - auto to_string(const bounding_rect& value) noexcept -> std::string; + auto to_string(const bounding_rect& value) noexcept -> string; template constexpr auto hasher(const rect& value) noexcept -> Ret; @@ -154,7 +154,7 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto to_string(const rect& value) noexcept -> std::string { + inline auto to_string(const rect& value) noexcept -> string { return std::format("{}", value); } @@ -162,7 +162,7 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto to_string(const bounding_rect& value) noexcept -> std::string { + inline auto to_string(const bounding_rect& value) noexcept -> string { return std::format("{}", value); } diff --git a/modules/stormkit/core/math/linear-matrix.cppm b/modules/stormkit/core/math/linear-matrix.cppm index a5bfeee77..ea1299556 100644 --- a/modules/stormkit/core/math/linear-matrix.cppm +++ b/modules/stormkit/core/math/linear-matrix.cppm @@ -31,9 +31,9 @@ export { // M => rows // N => columns template - struct alignas(std::array) mat { + struct alignas(array) mat { using ValueType = T; - using StorageType = std::array; + using StorageType = array; using SizeType = usize; using ExtentType = u8; @@ -42,7 +42,7 @@ export { using size_type = SizeType; using extent_type = ExtentType; - static constexpr auto EXTENTS = std::array { M, N }; + static constexpr auto EXTENTS = array { M, N }; StorageType values; @@ -226,11 +226,11 @@ export { template [[nodiscard]] constexpr auto as_view(const T& value) noexcept - -> std::span; + -> array_view; template [[nodiscard]] - constexpr auto as_view_mut(T& value) noexcept -> std::span; + constexpr auto as_view_mut(T& value) noexcept -> array_view; template [[nodiscard]] @@ -243,7 +243,7 @@ export { constexpr auto as_mdspan(T& value) noexcept -> MatrixSpan; template - auto to_string(const T& value) noexcept -> std::string; + auto to_string(const T& value) noexcept -> string; template constexpr auto hasher(const T& value) noexcept -> Ret; @@ -561,8 +561,8 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto as_view(const T& value) noexcept -> std::span { - return std::span { + constexpr auto as_view(const T& value) noexcept -> array_view { + return array_view { stdr::data(value), T::EXTENTS[0] * T::EXTENTS[1] }; @@ -572,8 +572,8 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto as_view_mut(T& value) noexcept -> std::span { - return std::span { + constexpr auto as_view_mut(T& value) noexcept -> array_view { + return array_view { stdr::data(value), T::EXTENTS[0] * T::EXTENTS[1] }; @@ -599,7 +599,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m //////////////////////////////////////// //////////////////////////////////////// template - inline auto to_string(const T& value) noexcept -> std::string { + inline auto to_string(const T& value) noexcept -> string { return std::format("{}", value); } diff --git a/modules/stormkit/core/math/linear-vector.cppm b/modules/stormkit/core/math/linear-vector.cppm index e005d8967..6511ca63e 100644 --- a/modules/stormkit/core/math/linear-vector.cppm +++ b/modules/stormkit/core/math/linear-vector.cppm @@ -25,7 +25,7 @@ import :string.format; export namespace stormkit { inline namespace core { namespace math { inline namespace vector { template - struct alignas(std::array) vec2 { + struct alignas(array) vec2 { using ValueType = T; using SizeType = usize; using ExtentType = u8; @@ -34,7 +34,7 @@ export namespace stormkit { inline namespace core { namespace math { using size_type = SizeType; using extent_type = ExtentType; - static constexpr auto EXTENT = std::array { 2uz }; + static constexpr auto EXTENT = array { 2uz }; ValueType x; ValueType y; @@ -51,7 +51,7 @@ export namespace stormkit { inline namespace core { namespace math { using uvec2 = vec2; template - struct alignas(std::array) vec3 { + struct alignas(array) vec3 { using ValueType = T; using SizeType = usize; using ExtentType = u8; @@ -60,7 +60,7 @@ export namespace stormkit { inline namespace core { namespace math { using size_type = SizeType; using extent_type = ExtentType; - static constexpr auto EXTENT = std::array { 3uz }; + static constexpr auto EXTENT = array { 3uz }; ValueType x; ValueType y; @@ -78,7 +78,7 @@ export namespace stormkit { inline namespace core { namespace math { using uvec3 = vec3; template - struct alignas(std::array) vec4 { + struct alignas(array) vec4 { using ValueType = T; using SizeType = usize; using ExtentType = u8; @@ -87,7 +87,7 @@ export namespace stormkit { inline namespace core { namespace math { using size_type = SizeType; using extent_type = ExtentType; - static constexpr auto EXTENT = std::array { 4uz }; + static constexpr auto EXTENT = array { 4uz }; ValueType x; ValueType y; @@ -155,11 +155,11 @@ export namespace stormkit { inline namespace core { namespace math { template [[nodiscard]] - constexpr auto as_view(const T& value) noexcept -> std::span; + constexpr auto as_view(const T& value) noexcept -> array_view; template [[nodiscard]] - constexpr auto as_view_mut(T& value) noexcept -> std::span; + constexpr auto as_view_mut(T& value) noexcept -> array_view; template [[nodiscard]] @@ -171,13 +171,13 @@ export namespace stormkit { inline namespace core { namespace math { constexpr auto as_mdspan_mut(T& value) noexcept -> VectorSpan; template - auto to_string(const vec2& value) noexcept -> std::string; + auto to_string(const vec2& value) noexcept -> string; template - auto to_string(const vec3& value) noexcept -> std::string; + auto to_string(const vec3& value) noexcept -> string; template - auto to_string(const vec4& value) noexcept -> std::string; + auto to_string(const vec4& value) noexcept -> string; template constexpr auto hasher(const vec2& value) noexcept -> Ret; @@ -233,7 +233,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v template STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto vec2::operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst& { - static constexpr auto members = std::array { &vec2::x, &vec2::y }; + static constexpr auto members = array { &vec2::x, &vec2::y }; return std::forward_like(self.*members[i]); } @@ -253,7 +253,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v template STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto vec3::operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst& { - static constexpr auto members = std::array { &vec3::x, &vec3::y, &vec3::z }; + static constexpr auto members = array { &vec3::x, &vec3::y, &vec3::z }; return std::forward_like(self.*members[i]); } @@ -273,7 +273,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v template STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto vec4::operator[](this Self& self, usize i) noexcept -> core::meta::ForwardConst& { - static constexpr auto members = std::array { &vec4::x, &vec4::y, &vec4::z, &vec4::w }; + static constexpr auto members = array { &vec4::x, &vec4::y, &vec4::z, &vec4::w }; return std::forward_like(self.*members[i]); } @@ -371,16 +371,16 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto as_view(const T& value) noexcept -> std::span { - return std::span { &value.x, T::EXTENT[0] }; + constexpr auto as_view(const T& value) noexcept -> array_view { + return array_view { &value.x, T::EXTENT[0] }; } //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_PURE STORMKIT_FORCE_INLINE - constexpr auto as_view_mut(T& value) noexcept -> std::span { - return std::span { &value.x, T::EXTENT[0] }; + constexpr auto as_view_mut(T& value) noexcept -> array_view { + return array_view { &value.x, T::EXTENT[0] }; } //////////////////////////////////////// @@ -404,7 +404,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v //////////////////////////////////////// template STORMKIT_FORCE_INLINE - auto to_string(const vec2& value) noexcept -> std::string { + auto to_string(const vec2& value) noexcept -> string { return std::format("{}", value); } @@ -412,7 +412,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v //////////////////////////////////////// template STORMKIT_FORCE_INLINE - auto to_string(const vec3& value) noexcept -> std::string { + auto to_string(const vec3& value) noexcept -> string { return std::format("{}", value); } @@ -420,7 +420,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace v //////////////////////////////////////// template STORMKIT_FORCE_INLINE - auto to_string(const vec4& value) noexcept -> std::string { + auto to_string(const vec4& value) noexcept -> string { return std::format("{}", value); } diff --git a/modules/stormkit/core/math/linear.cppm b/modules/stormkit/core/math/linear.cppm index 1f263f0ed..b8e75c7ce 100644 --- a/modules/stormkit/core/math/linear.cppm +++ b/modules/stormkit/core/math/linear.cppm @@ -35,7 +35,7 @@ export namespace stormkit { inline namespace core { namespace math { template requires(sizeof...(Sizes) >= 1) - using TensorSpan = std::mdspan>; + using TensorSpan = mdarray_view>; template using VectorSpan = TensorSpan; @@ -53,17 +53,17 @@ export namespace stormkit { inline namespace core { namespace math { // template // [[nodiscard]] - // constexpr auto as_span(TensorSpan& tensor) noexcept -> std::span& tensor) noexcept -> array_view; template [[nodiscard]] - constexpr auto as_span(const TensorSpan& tensor) noexcept -> std::span; + constexpr auto as_span(const TensorSpan& tensor) noexcept -> array_view; template requires(not core::meta::IsConst) [[nodiscard]] - constexpr auto as_span_mut(TensorSpan tensor) noexcept -> std::span; + constexpr auto as_span_mut(TensorSpan tensor) noexcept -> array_view; template requires(core::meta::IsArithmetic>) @@ -210,12 +210,12 @@ namespace stormkit { inline namespace core { namespace math { } // namespace angle template - using MatData = std::array; + using MatData = array; template using SMatData = MatData; template - using VecData = std::array; + using VecData = array; template using vec2data = VecData; @@ -231,16 +231,16 @@ namespace stormkit { inline namespace core { namespace math { // template // [[nodiscard]] // constexpr auto as_span(const TensorSpan& tensor) noexcept - // -> std::span { - // return std::span { tensor.data_handle(), (Sizes * ...) }; + // -> array_view { + // return array_view { tensor.data_handle(), (Sizes * ...) }; // } //////////////////////////////////////// //////////////////////////////////////// template [[nodiscard]] - constexpr auto as_span(const TensorSpan& tensor) noexcept -> std::span { - return std::span { tensor.data_handle(), (Sizes * ...) }; + constexpr auto as_span(const TensorSpan& tensor) noexcept -> array_view { + return array_view { tensor.data_handle(), (Sizes * ...) }; } //////////////////////////////////////// @@ -248,8 +248,8 @@ namespace stormkit { inline namespace core { namespace math { template requires(not core::meta::IsConst) [[nodiscard]] - constexpr auto as_span_mut(TensorSpan tensor) noexcept -> std::span { - return std::span { tensor.data_handle(), (Sizes * ...) }; + constexpr auto as_span_mut(TensorSpan tensor) noexcept -> array_view { + return array_view { tensor.data_handle(), (Sizes * ...) }; } //////////////////////////////////////// diff --git a/modules/stormkit/core/meta/concepts.cppm b/modules/stormkit/core/meta/concepts.cppm index d27b00236..1fd77193b 100644 --- a/modules/stormkit/core/meta/concepts.cppm +++ b/modules/stormkit/core/meta/concepts.cppm @@ -116,13 +116,13 @@ export namespace stormkit { inline namespace core { namespace meta { concept SameAsAnyOf = (SameAs or ...); template - concept IsByte = SameAs; + concept Isbyte = SameAs; template - concept IsByteSized = sizeof(T) == sizeof(std::byte); + concept IsbyteSized = sizeof(T) == sizeof(std::byte); template - concept IsNotByte = not IsByte; + concept IsNotbyte = not Isbyte; template concept IsStringLike = std::convertible_to; @@ -136,6 +136,9 @@ export namespace stormkit { inline namespace core { namespace meta { template concept IsStdVariant = IsSpecializationOf; + template + concept IsStdSpan = IsSpecializationOfNTTP_TV; + template concept IsStdMdspan = IsSpecializationOf; @@ -199,6 +202,9 @@ export namespace stormkit { inline namespace core { namespace meta { template concept IsIndirection = IsLValueReference or IsPointer; + template + concept IsIndirectionTo = IsIndirection and SameAs>, U>; + template concept AreIndirections = ((IsLValueReference or IsPointer) and ...); @@ -226,6 +232,12 @@ export namespace stormkit { inline namespace core { namespace meta { template concept IsContainerOrPointerOf = IsContainerOf or IsPointerOf; + template + concept IsContainerOrIndirection = IsContainer or IsIndirection; + + template + concept IsContainerOrIndirectionOf = IsContainerOf or IsIndirectionTo; + template concept IsPolymorphic = std::is_polymorphic_v; @@ -248,16 +260,16 @@ export namespace stormkit { inline namespace core { namespace meta { concept IsNotIndirection = not IsIndirection; template - concept IsScopedEnumeration = std::is_scoped_enum_v and IsNotByte; + concept IsScopedEnumeration = std::is_scoped_enum_v and IsNotbyte; template - concept IsPlainEnumeration = not IsScopedEnumeration and std::is_enum_v and IsNotByte; + concept IsPlainEnumeration = not IsScopedEnumeration and std::is_enum_v and IsNotbyte; template - concept IsEnumeration = std::is_enum_v and IsNotByte; + concept IsEnumeration = std::is_enum_v and IsNotbyte; template - concept IsIntegral = (std::integral and not SameAs and not IsByte) + concept IsIntegral = (std::integral and not SameAs and not Isbyte) or Is>> or Is>> #if defined(STORMKIT_COMPILER_MSVC) @@ -364,8 +376,8 @@ export namespace stormkit { inline namespace core { namespace meta { concept IsSignNarrowing = (IsSigned ? not IsSigned : IsSigned and sizeof(From) == sizeof(To)); template - concept IsByteNarrowing = ((IsArithmetic and IsByte) or (IsByte and IsArithmetic)) - and (IsByte and sizeof(To) != sizeof(From)); + concept IsbyteNarrowing = ((IsArithmetic and Isbyte) or (Isbyte and IsArithmetic)) + and (Isbyte and sizeof(To) != sizeof(From)); template concept IsNarrowing = (IsFloatingPoint and IsIntegral) diff --git a/modules/stormkit/core/meta/type_query.cppm b/modules/stormkit/core/meta/type_query.cppm index 57c5f05a0..3e706ec9b 100644 --- a/modules/stormkit/core/meta/type_query.cppm +++ b/modules/stormkit/core/meta/type_query.cppm @@ -65,6 +65,17 @@ namespace stormkit { inline namespace core { namespace meta { using Type = typename T::value_type; }; + template + struct ContainedOrPointedOrTType { + using Type = T; + }; + + template + struct ContainedOrPointedOrTType: ContainedType {}; + + template + struct ContainedOrPointedOrTType: PointedType {}; + template struct ContainedOrPointedType; @@ -188,6 +199,9 @@ namespace stormkit { inline namespace core { namespace meta { template using ContainedOrPointedType = details::ContainedOrPointedType::Type; + template + using ContainedOrPointedOrTType = details::ContainedOrPointedOrTType::Type; + template using ReturnType = details::CallableTrait::ReturnType; diff --git a/modules/stormkit/core/meta/type_traits.cppm b/modules/stormkit/core/meta/type_traits.cppm index 2fb10d879..5a46eabf5 100644 --- a/modules/stormkit/core/meta/type_traits.cppm +++ b/modules/stormkit/core/meta/type_traits.cppm @@ -26,42 +26,42 @@ import :meta.type_query; // struct ArithmeticTraitInterface { // template // static auto add(Ts...) noexcept -> decltype(auto) { -// static_assert(false, std::string { "add not implemented for " } + name_of()); +// static_assert(false, string { "add not implemented for " } + name_of()); // } // template // static auto add_eq(Ts...) noexcept -> decltype(auto) { -// static_assert(false, std::string { "add_eq not implemented for " } + name_of()); +// static_assert(false, string { "add_eq not implemented for " } + name_of()); // } // template // static auto sub(Ts...) noexcept -> decltype(auto) { -// static_assert(false, std::string { "sub not implemented for " } + name_of()); +// static_assert(false, string { "sub not implemented for " } + name_of()); // } // template // static auto sub_eq(Ts...) noexcept -> decltype(auto) { -// static_assert(false, std::string { "sub_eq not implemented for " } + name_of()); +// static_assert(false, string { "sub_eq not implemented for " } + name_of()); // } // template // static auto div(Ts...) noexcept -> decltype(auto) { -// static_assert(false, std::string { "div not implemented for " } + name_of()); +// static_assert(false, string { "div not implemented for " } + name_of()); // } // template // static auto div_eq(Ts...) noexcept -> decltype(auto) { -// static_assert(false, std::string { "div_eq not implemented for " } + name_of()); +// static_assert(false, string { "div_eq not implemented for " } + name_of()); // } // template // static auto mul(Ts...) noexcept -> decltype(auto) { -// static_assert(false, std::string { "mul not implemented for " } + name_of()); +// static_assert(false, string { "mul not implemented for " } + name_of()); // } // template // static auto mul_eq(Ts...) noexcept -> decltype(auto) { -// static_assert(false, std::string { "mul_eq not implemented for " } + name_of()); +// static_assert(false, string { "mul_eq not implemented for " } + name_of()); // } // }; diff --git a/modules/stormkit/core/parallelism/threadpool.cppm b/modules/stormkit/core/parallelism/threadpool.cppm index 9bddb56ec..9cc0525cf 100644 --- a/modules/stormkit/core/parallelism/threadpool.cppm +++ b/modules/stormkit/core/parallelism/threadpool.cppm @@ -52,7 +52,7 @@ export namespace stormkit { inline namespace core { auto wait_idle(bool cancel_tasks = false) noexcept -> void; - auto set_name(std::string_view name) noexcept -> void; + auto set_name(string_view name) noexcept -> void; private: struct Task { @@ -84,7 +84,7 @@ export namespace stormkit { inline namespace core { u32 m_worker_count = 0; - std::vector m_workers; + dyn_array m_workers; mutable std::mutex m_mutex; std::condition_variable m_work_signal; @@ -96,7 +96,7 @@ export namespace stormkit { inline namespace core { auto parallel_for(ThreadPool& pool, Range&& range, F&& f) noexcept -> void; template&> F> - auto parallel_for_async(ThreadPool& pool, Range& range, F&& f) noexcept -> std::vector>; + auto parallel_for_async(ThreadPool& pool, Range& range, F&& f) noexcept -> dyn_array>; }} // namespace stormkit::core //////////////////////////////////////////////////////////////////// @@ -133,7 +133,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto ThreadPool::set_name(std::string_view name) noexcept -> void { + inline auto ThreadPool::set_name(string_view name) noexcept -> void { // for (auto&& [i, worker] : stdv::enumerate(m_workers)) for (auto i : range(m_worker_count)) set_thread_name(m_workers[i], std::format("{}:{}", name, i)); } @@ -201,12 +201,12 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template&> F> - inline auto parallel_for_async(ThreadPool& pool, Range& range, F&& f) noexcept -> std::vector> { + inline auto parallel_for_async(ThreadPool& pool, Range& range, F&& f) noexcept -> dyn_array> { const auto size = stdr::size(range); const auto chunk_size = size / pool.worker_count(); const auto chunk_count = size / chunk_size; - auto out = std::vector> {}; + auto out = dyn_array> {}; out.reserve(chunk_count); for (auto chunk : stormkit::range(chunk_count)) { diff --git a/modules/stormkit/core/parallelism/threadutils.cppm b/modules/stormkit/core/parallelism/threadutils.cppm index d0a85a4a5..0fd29b201 100644 --- a/modules/stormkit/core/parallelism/threadutils.cppm +++ b/modules/stormkit/core/parallelism/threadutils.cppm @@ -12,20 +12,21 @@ export module stormkit.core:parallelism.threadutils; import std; import :meta; +import :string.aliases; export namespace stormkit { inline namespace core { STORMKIT_CORE_API - auto set_current_thread_name(std::string_view name) noexcept -> void; + auto set_current_thread_name(string_view name) noexcept -> void; STORMKIT_CORE_API - auto set_thread_name(std::thread& thread, std::string_view name) noexcept -> void; + auto set_thread_name(std::thread& thread, string_view name) noexcept -> void; STORMKIT_CORE_API - auto set_thread_name(std::jthread& thread, std::string_view name) noexcept -> void; + auto set_thread_name(std::jthread& thread, string_view name) noexcept -> void; STORMKIT_CORE_API - auto get_current_thread_name() noexcept -> std::string; + auto get_current_thread_name() noexcept -> string; STORMKIT_CORE_API - auto get_thread_name(const std::thread& thread) noexcept -> std::string; + auto get_thread_name(const std::thread& thread) noexcept -> string; STORMKIT_CORE_API - auto get_thread_name(const std::jthread& thread) noexcept -> std::string; + auto get_thread_name(const std::jthread& thread) noexcept -> string; template requires(meta::IsSpecializationOf, std::future>) diff --git a/modules/stormkit/core/string.cppm b/modules/stormkit/core/string.cppm index e7655cd8a..150a9e66c 100644 --- a/modules/stormkit/core/string.cppm +++ b/modules/stormkit/core/string.cppm @@ -5,7 +5,7 @@ export module stormkit.core:string; export import :string.constexpr_string; -export import :string.czstring; export import :string.encodings; export import :string.format; export import :string.operations; +export import :string.aliases; diff --git a/modules/stormkit/core/string/aliases.cppm b/modules/stormkit/core/string/aliases.cppm new file mode 100644 index 000000000..6bb860ba3 --- /dev/null +++ b/modules/stormkit/core/string/aliases.cppm @@ -0,0 +1,35 @@ +// Copyright (C) 2023 Arthur LAURENT +// This file is subject to the license terms in the LICENSE file +// found in the top-level of this distribution + +export module stormkit.core:string.aliases; + +import std; + +namespace stdp = std::pmr; + +export namespace stormkit { inline namespace core { + using std::string; + using std::string_view; + using std::u16string; + using std::u16string_view; + using std::u32string; + using std::u32string_view; + using std::u8string; + using std::u8string_view; + using std::wstring; + using std::wstring_view; + + namespace pmr { + using stdp::string; + using stdp::u16string; + using stdp::u32string; + using stdp::u8string; + using stdp::wstring; + } // namespace pmr + + using czstring = const char*; + using zstring = char*; + using cwzstring = const wchar_t*; + using wzstring = wchar_t*; +}} // namespace stormkit::core diff --git a/modules/stormkit/core/string/constexpr_string.cppm b/modules/stormkit/core/string/constexpr_string.cppm index 75f7fc718..83346e843 100644 --- a/modules/stormkit/core/string/constexpr_string.cppm +++ b/modules/stormkit/core/string/constexpr_string.cppm @@ -10,10 +10,14 @@ export module stormkit.core:string.constexpr_string; import std; +import :containers.aliases; +import :string.aliases; +import :typesafe.integer; + namespace stdr = std::ranges; export namespace stormkit { inline namespace core { namespace meta { - template + template struct ConstexprString { consteval ConstexprString() noexcept = default; consteval ConstexprString(const char (&new_str)[N]) noexcept; @@ -23,20 +27,20 @@ export namespace stormkit { inline namespace core { namespace meta { [[nodiscard]] constexpr auto end(this auto& self) noexcept -> decltype(auto); [[nodiscard]] - constexpr auto size() const noexcept -> std::size_t; + constexpr auto size() const noexcept -> usize; [[nodiscard]] - constexpr auto view() const noexcept -> std::string_view; + constexpr auto view() const noexcept -> string_view; [[nodiscard]] - constexpr operator std::string_view() const noexcept; + constexpr operator string_view() const noexcept; constexpr auto update_size() noexcept -> void; static constexpr auto STATIC_SIZE = N - 1u; - std::array data = {}; - std::size_t m_size = 0; + array data = {}; + usize m_size = 0; }; }}} // namespace stormkit::core::meta @@ -47,7 +51,7 @@ export namespace stormkit { inline namespace core { namespace meta { namespace stormkit { inline namespace core { namespace meta { ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE consteval ConstexprString::ConstexprString(const char (&new_str)[N]) noexcept { std::copy_n(new_str, STATIC_SIZE, std::data(data)); @@ -56,7 +60,7 @@ namespace stormkit { inline namespace core { namespace meta { ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE constexpr auto ConstexprString::begin(this auto& self) noexcept -> decltype(auto) { return stdr::begin(self.data); @@ -64,7 +68,7 @@ namespace stormkit { inline namespace core { namespace meta { ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE constexpr auto ConstexprString::end(this auto& self) noexcept -> decltype(auto) { return stdr::begin(self.data) + static_cast(self.size()); @@ -72,31 +76,31 @@ namespace stormkit { inline namespace core { namespace meta { ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr auto ConstexprString::size() const noexcept -> std::size_t { + constexpr auto ConstexprString::size() const noexcept -> usize { return m_size; } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr auto ConstexprString::view() const noexcept -> std::string_view { - return std::string_view { begin(), end() }; + constexpr auto ConstexprString::view() const noexcept -> string_view { + return string_view { begin(), end() }; } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr ConstexprString::operator std::string_view() const noexcept { + constexpr ConstexprString::operator string_view() const noexcept { return view(); } ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE constexpr auto ConstexprString::update_size() noexcept -> void { m_size = std::char_traits::length(stdr::data(data)); diff --git a/modules/stormkit/core/string/czstring.cppm b/modules/stormkit/core/string/czstring.cppm deleted file mode 100644 index 934dfa94f..000000000 --- a/modules/stormkit/core/string/czstring.cppm +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (C) 2023 Arthur LAURENT -// This file is subject to the license terms in the LICENSE file -// found in the top-level of this distribution - -export module stormkit.core:string.czstring; - -export namespace stormkit { inline namespace core { - using CZString = const char*; - using ZString = char*; - using CWZString = const wchar_t*; - using WZString = wchar_t*; -}} // namespace stormkit::core diff --git a/modules/stormkit/core/string/encodings.cppm b/modules/stormkit/core/string/encodings.cppm index 2f841a481..09b1dfb97 100644 --- a/modules/stormkit/core/string/encodings.cppm +++ b/modules/stormkit/core/string/encodings.cppm @@ -18,19 +18,19 @@ import :typesafe.integer; import :typesafe.byte; export namespace stormkit { inline namespace core { - auto ascii_to_utf16(std::string_view) -> std::u16string; - auto utf16_to_ascii(std::u16string_view) -> std::string; + auto ascii_to_utf16(string_view) -> u16string; + auto utf16_to_ascii(u16string_view) -> string; - auto ascii_to_wide(std::string_view) -> std::wstring; - auto wide_to_ascii(std::wstring_view) -> std::string; + auto ascii_to_wide(string_view) -> wstring; + auto wide_to_ascii(wstring_view) -> string; - auto ascii_to_utf8(std::string_view) -> std::u8string; - auto utf8_to_ascii(std::u8string_view) -> std::string; + auto ascii_to_utf8(string_view) -> u8string; + auto utf8_to_ascii(u8string_view) -> string; #ifdef STORMKIT_COMPILER_MSVC - auto to_native_encoding(std::string_view) -> std::u16string; + auto to_native_encoding(string_view) -> u16string; #else - auto to_native_encoding(std::string_view) -> std::u8string; + auto to_native_encoding(string_view) -> u8string; #endif }} // namespace stormkit::core @@ -44,8 +44,8 @@ namespace stdr = std::ranges; namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - inline auto ascii_to_utf16(std::string_view input) -> std::u16string { - auto output = std::u16string {}; + inline auto ascii_to_utf16(string_view input) -> u16string { + auto output = u16string {}; #if not defined(STORMKIT_COMPILER_CLANG) auto state = std::mbstate_t {}; output.resize(stdr::size(input)); @@ -63,8 +63,8 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - inline auto utf16_to_ascii(std::u16string_view input) -> std::string { - auto output = std::string {}; + inline auto utf16_to_ascii(u16string_view input) -> string { + auto output = string {}; #if not defined(STORMKIT_COMPILER_CLANG) auto state = std::mbstate_t {}; output.resize(stdr::size(input)); @@ -79,10 +79,10 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - inline auto ascii_to_wide(std::string_view input) -> std::wstring { + inline auto ascii_to_wide(string_view input) -> wstring { [[maybe_unused]] auto state = std::mbstate_t {}; - auto output = std::wstring {}; + auto output = wstring {}; output.resize(stdr::size(input)); [[maybe_unused]] @@ -106,11 +106,11 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - inline auto wide_to_ascii(std::wstring_view input) -> std::string { + inline auto wide_to_ascii(wstring_view input) -> string { [[maybe_unused]] auto state = std::mbstate_t {}; [[maybe_unused]] - auto output = std::string {}; + auto output = string {}; output.resize(stdr::size(input)); #if defined(STORMKIT_COMPILER_MSVC) @@ -126,9 +126,9 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - inline auto ascii_to_utf8(std::string_view input) -> std::u8string { + inline auto ascii_to_utf8(string_view input) -> u8string { [[maybe_unused]] - auto output = std::u8string {}; + auto output = u8string {}; output.resize(stdr::size(input) * narrow(MB_LEN_MAX)); #if defined(STORMKIT_COMPILER_MSVC) @@ -151,9 +151,9 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - inline auto utf8_to_ascii(std::u8string_view input) -> std::string { + inline auto utf8_to_ascii(u8string_view input) -> string { [[maybe_unused]] - auto output = std::string {}; + auto output = string {}; output.resize(stdr::size(input)); #if defined(STORMKIT_COMPILER_MSVC) @@ -175,14 +175,14 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto to_native_encoding(std::string_view input) -> std::u16string { + inline auto to_native_encoding(string_view input) -> u16string { return ascii_to_utf16(input); } #else //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto to_native_encoding(std::string_view input) -> std::u8string { + inline auto to_native_encoding(string_view input) -> u8string { return ascii_to_utf8(input); } #endif diff --git a/modules/stormkit/core/string/format.cppm b/modules/stormkit/core/string/format.cppm index 4d370bed9..ce29fdea0 100644 --- a/modules/stormkit/core/string/format.cppm +++ b/modules/stormkit/core/string/format.cppm @@ -149,7 +149,7 @@ template auto std::formatter::format(const T& value, FormatContext& ctx) const -> decltype(ctx.out()) { auto&& out = ctx.out(); if constexpr (requires { - { as_string(value) } -> meta::Is; + { as_string(value) } -> meta::Is; }) { const auto strvalue = as_string(value); return format_to(out, "{}", strvalue); diff --git a/modules/stormkit/core/string/operations.cppm b/modules/stormkit/core/string/operations.cppm index 23586cd01..f79d08e3a 100644 --- a/modules/stormkit/core/string/operations.cppm +++ b/modules/stormkit/core/string/operations.cppm @@ -16,7 +16,7 @@ import :meta; import :typesafe.integer; -import :string.czstring; +import :string.aliases; import :typesafe.safecasts; @@ -25,60 +25,60 @@ namespace stdv = std::views; export namespace stormkit { inline namespace core { [[nodiscard]] - constexpr auto split(std::string_view string, std::string_view delim) noexcept -> std::vector; + constexpr auto split(string_view str, string_view delim) noexcept -> dyn_array; [[nodiscard]] - constexpr auto to_lower(std::string_view string) noexcept -> std::string; + constexpr auto to_lower(string_view str) noexcept -> string; [[nodiscard]] - constexpr auto to_upper(std::string_view string) noexcept -> std::string; + constexpr auto to_upper(string_view str) noexcept -> string; [[nodiscard]] - auto to_lower(std::string_view string, const std::locale& locale) noexcept -> std::string; + auto to_lower(string_view str, const std::locale& locale) noexcept -> string; [[nodiscard]] - auto to_upper(std::string_view string, const std::locale& locale) noexcept -> std::string; + auto to_upper(string_view str, const std::locale& locale) noexcept -> string; [[nodiscard]] - constexpr auto replace(std::string_view in, std::string_view pattern, std::string_view replacement) noexcept -> std::string; + constexpr auto replace(string_view in, string_view pattern, string_view replacement) noexcept -> string; template [[nodiscard]] - constexpr auto as_string(T) noexcept -> std::string_view = delete; + constexpr auto as_string(T) noexcept -> string_view = delete; template [[nodiscard]] - constexpr auto to_string(T) noexcept -> std::string = delete; + constexpr auto to_string(T) noexcept -> string = delete; template [[nodiscard]] - constexpr auto from_string(std::string_view) noexcept -> T = delete; + constexpr auto from_string(string_view) noexcept -> T = delete; template requires(as_string(std::declval())) [[nodiscard]] - constexpr auto to_string(T&& value) noexcept -> std::string; + constexpr auto to_string(T&& value) noexcept -> string; template [[nodiscard]] - constexpr auto to_string(T value, i32 base = 10) noexcept -> std::expected; + constexpr auto to_string(T value, i32 base = 10) noexcept -> std::expected; template [[nodiscard]] - auto to_string(T value, std::chars_format fmt = std::chars_format::general) noexcept -> std::expected; + auto to_string(T value, std::chars_format fmt = std::chars_format::general) noexcept -> std::expected; template [[nodiscard]] - constexpr auto from_string(std::string_view data, i32 base = 10) noexcept -> std::expected; + constexpr auto from_string(string_view data, i32 base = 10) noexcept -> std::expected; template [[nodiscard]] - auto from_string(std::string_view data, std::chars_format fmt = std::chars_format::general) noexcept + auto from_string(string_view data, std::chars_format fmt = std::chars_format::general) noexcept -> std::expected; [[nodiscard]] - constexpr auto as_czstring(std::string_view value) noexcept -> CZString; + constexpr auto as_czstring(string_view value) noexcept -> czstring; template requires(as_string(std::declval())) [[nodiscard]] - constexpr auto as_czstring(T&& value) noexcept -> CZString; + constexpr auto as_czstring(T&& value) noexcept -> czstring; template constexpr auto is_text(T c) noexcept -> bool; @@ -107,29 +107,27 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - constexpr auto split(std::string_view string, std::string_view delim) noexcept -> std::vector { - return std::string_view { string } + constexpr auto split(string_view str, string_view delim) noexcept -> dyn_array { + return str | stdv::split(delim) - | stdv::transform([](auto&& subrange) { - return std::string_view { stdr::cbegin(subrange), stdr::cend(subrange) }; - }) - | stdr::to(); + | stdv::transform([](auto&& subrange) { return string_view { stdr::cbegin(subrange), stdr::cend(subrange) }; }) + | stdr::to>(); } //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto to_lower(std::string_view string) noexcept -> std::string { - auto result = std::string { string }; + constexpr auto to_lower(string_view str) noexcept -> string { + auto result = string { str }; for (auto& c : result) c = to_lower(c); return result; } //////////////////////////////////////// //////////////////////////////////////// - inline auto to_lower(std::string_view string, const std::locale& locale) noexcept -> std::string { - auto result = std::string { string }; - auto& facet = std::use_facet>(locale); + inline auto to_lower(string_view str, const std::locale& locale) noexcept -> string { + auto result = string { str }; + auto& facet = std::use_facet>(locale); facet.tolower(&result[0], &result[0] + stdr::size(result)); return result; @@ -138,17 +136,17 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto to_upper(std::string_view string) noexcept -> std::string { - auto result = std::string { string }; + constexpr auto to_upper(string_view str) noexcept -> string { + auto result = string { str }; for (auto& c : result) c = to_upper(c); return result; } //////////////////////////////////////// //////////////////////////////////////// - inline auto to_upper(std::string_view string, const std::locale& locale) noexcept -> std::string { - auto result = std::string { string }; - auto& facet = std::use_facet>(locale); + inline auto to_upper(string_view str, const std::locale& locale) noexcept -> string { + auto result = string { str }; + auto& facet = std::use_facet>(locale); facet.toupper(&result[0], &result[0] + stdr::size(result)); return result; @@ -156,20 +154,19 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - inline constexpr auto replace(std::string_view in, std::string_view pattern, std::string_view replacement) noexcept - -> std::string { + inline constexpr auto replace(string_view in, string_view pattern, string_view replacement) noexcept -> string { return in | stdv::split(pattern) | stdv::transform([replacement](auto&& substr) noexcept { - auto out = std::string {}; + auto out = string {}; out.reserve(stdr::size(replacement) + stdr::size(substr)); out += replacement; - out += std::string_view { stdr::cbegin(substr), stdr::cend(substr) }; + out += string_view { stdr::cbegin(substr), stdr::cend(substr) }; return out; }) | stdv::join | stdv::drop(stdr::size(replacement)) - | stdr::to(); + | stdr::to(); } //////////////////////////////////////// @@ -177,15 +174,15 @@ namespace stormkit { inline namespace core { template requires(as_string(std::declval())) STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto to_string(T&& value) noexcept -> std::string { - return std::string { as_string(std::forward(value)) }; + constexpr auto to_string(T&& value) noexcept -> string { + return string { as_string(std::forward(value)) }; } //////////////////////////////////////// //////////////////////////////////////// template - constexpr auto to_string(T value, int base) noexcept -> std::expected { - auto out = std::expected { std::in_place }; + constexpr auto to_string(T value, int base) noexcept -> std::expected { + auto out = std::expected { std::in_place }; out->resize(16); auto&& [ptr, errc] = std::to_chars(stdr::data(*out), stdr::data(*out) + stdr::size(*out), value, base); if (errc != std::errc {}) [[unlikely]] @@ -203,8 +200,8 @@ namespace stormkit { inline namespace core { // TODO add an argument to customize string buffer size template [[nodiscard]] - auto to_string(T value, std::chars_format fmt) noexcept -> std::expected { - auto out = std::expected { std::in_place }; + auto to_string(T value, std::chars_format fmt) noexcept -> std::expected { + auto out = std::expected { std::in_place }; out->resize(16, '\0'); auto&& [ptr, errc] = std::to_chars(stdr::data(*out), stdr::data(*out) + stdr::size(*out), value, fmt); @@ -221,7 +218,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - inline constexpr auto from_string(std::string_view data, i32 base) noexcept -> std::expected { + inline constexpr auto from_string(string_view data, i32 base) noexcept -> std::expected { auto value = T {}; auto&& [_, errc] = std::from_chars(stdr::data(data), stdr::data(data) + stdr::size(data), value, base); if (errc != std::errc {}) [[unlikely]] @@ -233,7 +230,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - inline auto from_string(std::string_view data, std::chars_format fmt) noexcept -> std::expected { + inline auto from_string(string_view data, std::chars_format fmt) noexcept -> std::expected { auto value = T {}; auto&& [_, errc] = std::from_chars(stdr::data(data), stdr::data(data) + stdr::size(data), value, fmt); if (errc != std::errc {}) [[unlikely]] @@ -245,7 +242,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto as_czstring(std::string_view value) noexcept -> CZString { + constexpr auto as_czstring(string_view value) noexcept -> czstring { return stdr::data(value); } @@ -254,7 +251,7 @@ namespace stormkit { inline namespace core { template requires(as_string(std::declval())) STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto as_czstring(T value) noexcept -> CZString { + constexpr auto as_czstring(T value) noexcept -> czstring { return stdr::data(as_string(std::forward(value))); } diff --git a/modules/stormkit/core/typesafe/byte.cppm b/modules/stormkit/core/typesafe/byte.cppm index 8f3903528..fc50adf93 100644 --- a/modules/stormkit/core/typesafe/byte.cppm +++ b/modules/stormkit/core/typesafe/byte.cppm @@ -16,10 +16,13 @@ import :meta; import :typesafe.integer; +import :containers.aliases; + import :utils.contract; import :utils.tags; namespace stdr = std::ranges; +namespace stdp = std::pmr; template consteval auto get_byte_extent_value_of() { @@ -32,12 +35,18 @@ consteval auto get_byte_extent_value_of() { export namespace stormkit { inline namespace core { using std::byte; - using Byte = std::byte; - using ByteView = std::span; + + template + using byte_view = array_view; template - using ByteArray = std::array; - using ByteDynArray = std::vector; - using MutableByteView = std::span; + using byte_array = array; + using byte_dyn_array = dyn_array; + template + using byte_mut_view = array_view; + + namespace pmr { + using byte_dyn_array = dyn_array; + } // namespace pmr template constexpr auto zero_bytes(T& value) noexcept -> void; @@ -49,73 +58,72 @@ export namespace stormkit { inline namespace core { [[nodiscard]] constexpr auto byte_swap(const T& value) noexcept -> T; - // std::span + // array_view using std::as_bytes; template [[nodiscard]] - constexpr auto as_bytes(const T* const ptr, usize size = 1) noexcept -> std::span; + constexpr auto as_bytes(const T* const ptr, usize size = 1) noexcept -> byte_view<>; template [[nodiscard]] - constexpr auto as_bytes(const Range& range) noexcept -> std::span; + constexpr auto as_bytes(const Range& range) noexcept -> byte_view<>; [[nodiscard]] - constexpr auto as_bytes(std::string_view string) noexcept -> std::span; + constexpr auto as_bytes(string_view string) noexcept -> byte_view<>; template [[nodiscard]] - constexpr auto as_bytes(const T& value) noexcept -> std::span; + constexpr auto as_bytes(const T& value) noexcept -> byte_view; - // std::span + // array_view template [[nodiscard]] - constexpr auto as_bytes_mut(std::span container) noexcept - -> std::span()>; + constexpr auto as_bytes_mut(array_view container) noexcept -> byte_mut_view()>; template [[nodiscard]] - constexpr auto as_bytes_mut(Range& range) noexcept -> std::span; + constexpr auto as_bytes_mut(Range& range) noexcept -> byte_mut_view<>; template [[nodiscard]] - constexpr auto as_bytes_mut(T* const ptr, usize size = 1) noexcept -> std::span; + constexpr auto as_bytes_mut(T* const ptr, usize size = 1) noexcept -> byte_mut_view<>; template [[nodiscard]] - constexpr auto as_bytes_mut(T& value) noexcept -> std::span; + constexpr auto as_bytes_mut(T& value) noexcept -> byte_mut_view; template [[nodiscard]] - constexpr auto bytes_as(std::span bytes) noexcept -> const T&; + constexpr auto bytes_as(byte_view bytes) noexcept -> const T&; template requires(meta::SameAs>, byte>) [[nodiscard]] - constexpr auto bytes_as_span(const Range& bytes) noexcept -> std::span; + constexpr auto bytes_as_span(const Range& bytes) noexcept -> array_view; template [[nodiscard]] - constexpr auto bytes_as_span(std::span bytes) noexcept - -> std::span; + constexpr auto bytes_as_span(byte_view bytes) noexcept + -> array_view; template [[nodiscard]] - constexpr auto bytes_mut_as(std::span bytes) noexcept -> T&; + constexpr auto bytes_mut_as(byte_mut_view bytes) noexcept -> T&; template requires(meta::SameAs, byte> and not meta::IsConst) [[nodiscard]] - constexpr auto bytes_mut_as_span(Range& range) noexcept -> std::span; + constexpr auto bytes_mut_as_span(Range& range) noexcept -> array_view; template [[nodiscard]] - constexpr auto bytes_mut_as_span(std::span bytes) noexcept - -> std::span; + constexpr auto bytes_mut_as_span(byte_mut_view bytes) noexcept + -> array_view; template [[nodiscard]] - constexpr auto into_bytes(const T (&bytes)[N]) noexcept -> ByteArray; + constexpr auto into_bytes(const T (&bytes)[N]) noexcept -> byte_array; namespace literals { [[nodiscard]] @@ -173,7 +181,7 @@ namespace stormkit { inline namespace core { constexpr auto byte_swap(const T& value) noexcept -> T { if constexpr (meta::IsIntegral) return std::byteswap(value); else { - auto repr = std::bit_cast>(value); + auto repr = std::bit_cast>(value); stdr::reverse(repr); @@ -185,38 +193,38 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto as_bytes(const T* const ptr, usize size) noexcept -> std::span { - return std::as_bytes(std::span { ptr, size }); + constexpr auto as_bytes(const T* const ptr, usize size) noexcept -> byte_view<> { + return std::as_bytes(array_view { ptr, size }); } ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto as_bytes(const Range& range) noexcept -> std::span { - return as_bytes(std::span { range }); + constexpr auto as_bytes(const Range& range) noexcept -> byte_view<> { + return as_bytes(array_view { range }); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto as_bytes(std::string_view value) noexcept -> std::span { - return std::as_bytes(std::span { stdr::data(value), stdr::size(value) }); + constexpr auto as_bytes(string_view value) noexcept -> byte_view<> { + return std::as_bytes(array_view { stdr::data(value), stdr::size(value) }); } ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto as_bytes(const T& value) noexcept -> std::span { - return std::as_bytes(std::span { &value, 1 }); + constexpr auto as_bytes(const T& value) noexcept -> byte_view { + return std::as_bytes(array_view { &value, 1 }); } ///////////////////////////////////// ///////////////////////////////////// template - constexpr auto as_bytes_mut(std::span container) noexcept - -> std::span()> { + constexpr auto as_bytes_mut(array_view container) noexcept + -> byte_mut_view()> { return std::as_writable_bytes(container); } @@ -224,31 +232,31 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto as_bytes_mut(Range& range) noexcept -> std::span { - return as_bytes_mut(std::span { range }); + constexpr auto as_bytes_mut(Range& range) noexcept -> byte_mut_view<> { + return as_bytes_mut(array_view { range }); } ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto as_bytes_mut(T* const ptr, usize size) noexcept -> std::span { - return std::as_writable_bytes(std::span { ptr, size }); + constexpr auto as_bytes_mut(T* const ptr, usize size) noexcept -> byte_mut_view<> { + return std::as_writable_bytes(array_view { ptr, size }); } ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto as_bytes_mut(T& value) noexcept -> std::span { - return std::as_writable_bytes(std::span { &value, 1 }); + constexpr auto as_bytes_mut(T& value) noexcept -> byte_mut_view { + return std::as_writable_bytes(array_view { &value, 1 }); } ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto bytes_as(std::span bytes) noexcept -> const T& { + constexpr auto bytes_as(byte_view bytes) noexcept -> const T& { if constexpr (EXTENT != std::dynamic_extent) EXPECTS(EXTENT == sizeof(T)); EXPECTS(stdr::size(bytes) == sizeof(T)); return *std::launder(std::bit_cast(stdr::data(bytes))); @@ -259,28 +267,28 @@ namespace stormkit { inline namespace core { template requires(meta::SameAs>, byte>) STORMKIT_FORCE_INLINE - constexpr auto bytes_as_span(const Range& bytes) noexcept -> std::span { - return std::span { std::launder(std::bit_cast(stdr::data(bytes))), stdr::size(bytes) / sizeof(T) }; + constexpr auto bytes_as_span(const Range& bytes) noexcept -> array_view { + return array_view { std::launder(std::bit_cast(stdr::data(bytes))), stdr::size(bytes) / sizeof(T) }; } ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto bytes_as_span(std::span bytes) noexcept - -> std::span { + constexpr auto bytes_as_span(byte_view bytes) noexcept + -> array_view { if constexpr (EXTENT != std::dynamic_extent) - return std::span { std::bit_cast(stdr::data(bytes)), - EXTENT / sizeof(T) }; + return array_view { std::bit_cast(stdr::data(bytes)), + EXTENT / sizeof(T) }; else - return std::span { std::launder(std::bit_cast(stdr::data(bytes))), stdr::size(bytes) / sizeof(T) }; + return array_view { std::launder(std::bit_cast(stdr::data(bytes))), stdr::size(bytes) / sizeof(T) }; } ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto bytes_mut_as(std::span bytes) noexcept -> T& { + constexpr auto bytes_mut_as(byte_mut_view bytes) noexcept -> T& { if constexpr (EXTENT != std::dynamic_extent) EXPECTS(EXTENT == sizeof(T)); EXPECTS(stdr::size(bytes) == sizeof(T)); return *std::launder(std::bit_cast(stdr::data(bytes))); @@ -291,29 +299,29 @@ namespace stormkit { inline namespace core { template requires(meta::SameAs, byte> and not meta::IsConst) STORMKIT_FORCE_INLINE - constexpr auto bytes_mut_as_span(Range& bytes) noexcept -> std::span { - return std::span { std::launder(std::bit_cast(stdr::data(bytes))), stdr::size(bytes) / sizeof(T) }; + constexpr auto bytes_mut_as_span(Range& bytes) noexcept -> array_view { + return array_view { std::launder(std::bit_cast(stdr::data(bytes))), stdr::size(bytes) / sizeof(T) }; } ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto bytes_mut_as_span(std::span bytes) noexcept - -> std::span { + constexpr auto bytes_mut_as_span(byte_mut_view bytes) noexcept + -> array_view { if constexpr (EXTENT != std::dynamic_extent) - return std::span { std::bit_cast(stdr::data(bytes)), EXTENT / sizeof(T) }; + return array_view { std::bit_cast(stdr::data(bytes)), EXTENT / sizeof(T) }; else - return std::span { std::launder(std::bit_cast(stdr::data(bytes))), stdr::size(bytes) / sizeof(T) }; + return array_view { std::launder(std::bit_cast(stdr::data(bytes))), stdr::size(bytes) / sizeof(T) }; } ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto into_bytes(const T (&bytes)[N]) noexcept -> ByteArray { + constexpr auto into_bytes(const T (&bytes)[N]) noexcept -> byte_array { EXPECTS(static_cast(static_cast(bytes[0])) == bytes[0]); - auto out = ByteArray {}; + auto out = byte_array {}; auto i = 0_usize; for (auto&& byte : bytes) out[i++] = static_cast(byte); return out; diff --git a/modules/stormkit/core/typesafe/flags.cppm b/modules/stormkit/core/typesafe/flags.cppm index 4439f9983..ce0cccccb 100644 --- a/modules/stormkit/core/typesafe/flags.cppm +++ b/modules/stormkit/core/typesafe/flags.cppm @@ -13,6 +13,7 @@ import std; import :meta; import :string.constexpr_string; +import :string.aliases; import :math.combinatoric; @@ -51,13 +52,13 @@ export { constexpr auto next_value(const T& value) noexcept -> T; template - consteval auto generate_substitutions_as_string_for(std::string_view prefix, - const std::array, N>& mapping, + consteval auto generate_substitutions_as_string_for(string_view prefix, + const array, N>& mapping, char separator = '|') noexcept -> decltype(auto); template - consteval auto generate_substitutions_as_string_for(std::string_view prefix, - const std::array, N>& mapping, + consteval auto generate_substitutions_as_string_for(string_view prefix, + const array, N>& mapping, char separator = '|') noexcept -> decltype(auto); }} // namespace stormkit::core @@ -112,8 +113,8 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - consteval auto generate_substitutions_as_string_for(std::string_view prefix, - const std::array, N>& mapping, + consteval auto generate_substitutions_as_string_for(string_view prefix, + const array, N>& mapping, char separator) noexcept -> decltype(auto) { constexpr auto OUT_SIZE = [] { auto res = 0uz; @@ -128,22 +129,22 @@ namespace stormkit { inline namespace core { return res + 1; }(); - auto out = std::array>, OUT_SIZE> {}; - auto queue = std::vector> {}; - for (const auto& [k, v] : mapping) queue.emplace_back(k, std::string { v }, true); + auto out = array>, OUT_SIZE> {}; + auto queue = dyn_array> {}; + for (const auto& [k, v] : mapping) queue.emplace_back(k, string { v }, true); auto i = 0uz; while (not stdr::empty(queue)) { - const auto [key, string, single_value] = queue.back(); + const auto [key, str, single_value] = queue.back(); if (not stdr::any_of(out, [&key](auto& pair) noexcept { return pair.first == key; })) { auto& [k, v] = out[i]; k = key; - auto out_string = std::string { prefix }; - if (single_value) out_string += string; + auto out_string = string { prefix }; + if (single_value) out_string += str; else { out_string += "("; - out_string += string; + out_string += str; out_string += ")"; } @@ -160,14 +161,14 @@ namespace stormkit { inline namespace core { })); if (not has_key) { - auto str = string; + auto str2 = str; if (k != DEFAULT_VALUE) { - str += " "; - str += separator; - str += " "; - str += v; + str2 += " "; + str2 += separator; + str2 += " "; + str2 += v; } - queue.emplace(stdr::begin(queue), key | k, str, false); + queue.emplace(stdr::begin(queue), key | k, str2, false); } } } @@ -179,8 +180,8 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - consteval auto generate_substitutions_as_string_for(std::string_view prefix, - const std::array, N>& mapping, + consteval auto generate_substitutions_as_string_for(string_view prefix, + const array, N>& mapping, char separator) noexcept -> decltype(auto) { constexpr auto OUT_SIZE = [] { auto res = 0uz; @@ -191,22 +192,22 @@ namespace stormkit { inline namespace core { return res; }(); - auto out = std::array>, OUT_SIZE> {}; - auto queue = std::vector> {}; - for (const auto& [k, v] : mapping) queue.emplace_back(k, std::string { v }, true); + auto out = array>, OUT_SIZE> {}; + auto queue = dyn_array> {}; + for (const auto& [k, v] : mapping) queue.emplace_back(k, string { v }, true); auto i = 0uz; while (not stdr::empty(queue)) { - const auto [key, string, single_value] = queue.back(); + const auto [key, str, single_value] = queue.back(); if (not stdr::any_of(out, [&key](auto& pair) noexcept { return pair.first == key; })) { auto& [k, v] = out[i]; k = key; - auto out_string = std::string { prefix }; - if (single_value) out_string += string; + auto out_string = string { prefix }; + if (single_value) out_string += str; else { out_string += "("; - out_string += string; + out_string += str; out_string += ")"; } @@ -221,7 +222,7 @@ namespace stormkit { inline namespace core { return _key == _k; }); - if (not has_key) queue.emplace(stdr::begin(queue), key | k, string + " " + separator + " " + v, false); + if (not has_key) queue.emplace(stdr::begin(queue), key | k, str + " " + separator + " " + v, false); } queue.pop_back(); } diff --git a/modules/stormkit/core/typesafe/ref.cppm b/modules/stormkit/core/typesafe/ref.cppm index 5955fd653..69968c30e 100644 --- a/modules/stormkit/core/typesafe/ref.cppm +++ b/modules/stormkit/core/typesafe/ref.cppm @@ -21,6 +21,9 @@ import :typesafe.integer; import :hash; +namespace stdr = std::ranges; +namespace stdv = std::views; + export { namespace stormkit { inline namespace core { template @@ -297,65 +300,65 @@ export { [[nodiscard]] constexpr auto unref_mut(T& value) noexcept -> meta::PointedType&; - template typename Out = std::array, typename... Args> - requires(not std::ranges::range and ...) + template typename Out = array, typename... Args> + requires(not stdr::range and ...) [[nodiscard]] constexpr auto as_refs(Args&&... args) noexcept -> decltype(auto); - template typename Out = std::vector, typename... Args> - requires(not std::ranges::range and ...) + template typename Out = dyn_array, typename... Args> + requires(not stdr::range and ...) [[nodiscard]] constexpr auto to_refs(Args&&... args) noexcept -> decltype(auto); - template typename Out = std::array, typename... Args> - requires(not std::ranges::range and ...) + template typename Out = array, typename... Args> + requires(not stdr::range and ...) [[nodiscard]] constexpr auto as_ref_muts(Args&&... args) noexcept -> decltype(auto); - template typename Out = std::vector, typename... Args> - requires(not std::ranges::range and ...) + template typename Out = dyn_array, typename... Args> + requires(not stdr::range and ...) [[nodiscard]] constexpr auto to_ref_muts(Args&&... args) noexcept -> decltype(auto); - template class Out = std::vector, std::ranges::range T> - requires(std::ranges::range>) + template class Out = dyn_array, stdr::range T> + requires(stdr::range>) [[nodiscard]] constexpr auto to_refs(const T& range) noexcept -> decltype(auto); - template class Out = std::vector, std::ranges::range T> - requires(std::ranges::range>) + template class Out = dyn_array, stdr::range T> + requires(stdr::range>) [[nodiscard]] constexpr auto to_mut_refs(T& range) noexcept -> decltype(auto); - template typename Out = std::array, typename... Args> - requires(not std::ranges::range and ...) + template typename Out = array, typename... Args> + requires(not stdr::range and ...) [[nodiscard]] constexpr auto as_optrefs(Args&&... args) noexcept -> decltype(auto); - template typename Out = std::vector, typename... Args> - requires(not std::ranges::range and ...) + template typename Out = dyn_array, typename... Args> + requires(not stdr::range and ...) [[nodiscard]] - constexpr auto to_opt_refs(Args&&... args) noexcept -> decltype(auto); + constexpr auto to_optrefs(Args&&... args) noexcept -> decltype(auto); - template typename Out = std::array, typename... Args> - requires(not std::ranges::range and ...) + template typename Out = array, typename... Args> + requires(not stdr::range and ...) [[nodiscard]] constexpr auto as_optref_muts(Args&&... args) noexcept -> decltype(auto); - template typename Out = std::vector, typename... Args> - requires(not std::ranges::range and ...) + template typename Out = dyn_array, typename... Args> + requires(not stdr::range and ...) [[nodiscard]] - constexpr auto to_opt_ref_muts(Args&&... args) noexcept -> decltype(auto); + constexpr auto to_optref_muts(Args&&... args) noexcept -> decltype(auto); - template class Out = std::vector, std::ranges::range T> - requires(std::ranges::range>) + template class Out = dyn_array, stdr::range T> + requires(stdr::range>) [[nodiscard]] - constexpr auto to_opt_refs(const T& range) noexcept -> decltype(auto); + constexpr auto to_optrefs(const T& range) noexcept -> decltype(auto); - template class Out = std::vector, std::ranges::range T> - requires(std::ranges::range>) + template class Out = dyn_array, stdr::range T> + requires(stdr::range>) [[nodiscard]] - constexpr auto to_mut_opt_refs(T& range) noexcept -> decltype(auto); + constexpr auto to_mut_optrefs(T& range) noexcept -> decltype(auto); template constexpr auto hasher(const ref& value) noexcept -> Ret; @@ -941,125 +944,135 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template typename Out, typename... Args> - requires(not std::ranges::range and ...) + requires(not stdr::range and ...) STORMKIT_FORCE_INLINE constexpr auto as_refs(Args&&... args) noexcept -> decltype(auto) { - return Out { as_ref(std::forward(args))... }; + using ValueType = std::common_type_t>...>; + return Out, sizeof...(args)> { as_ref(std::forward(args))... }; } ///////////////////////////////////// ///////////////////////////////////// template typename Out, typename... Args> - requires(not std::ranges::range and ...) + requires(not stdr::range and ...) STORMKIT_FORCE_INLINE constexpr auto to_refs(Args&&... args) noexcept -> decltype(auto) { - return Out { { as_ref(std::forward(args))... } }; + using ValueType = std::common_type_t>...>; + return Out> { as_ref(std::forward(args))... }; } ///////////////////////////////////// ///////////////////////////////////// template typename Out, typename... Args> - requires(not std::ranges::range and ...) + requires(not stdr::range and ...) STORMKIT_FORCE_INLINE constexpr auto as_ref_muts(Args&&... args) noexcept -> decltype(auto) { - return Out { { as_ref_mut(std::forward(args))... } }; + using ValueType = std::common_type_t>...>; + return Out, sizeof...(args)> { as_ref_mut(std::forward(args))... }; } ///////////////////////////////////// ///////////////////////////////////// template typename Out, typename... Args> - requires(not std::ranges::range and ...) + requires(not stdr::range and ...) STORMKIT_FORCE_INLINE constexpr auto to_ref_muts(Args&&... args) noexcept -> decltype(auto) { - return Out { { as_ref_mut(std::forward(args))... } }; + using ValueType = std::common_type_t>...>; + return Out> { as_ref_mut(std::forward(args))... }; } ///////////////////////////////////// ///////////////////////////////////// - template class Out, std::ranges::range T> - requires(std::ranges::range>) + template class Out, stdr::range T> + requires(stdr::range>) STORMKIT_FORCE_INLINE constexpr auto to_refs(const T& range) noexcept -> decltype(auto) { + using ValueType = stdr::range_value_t; return range - | std::views::transform([](U&& val) static noexcept -> decltype(auto) { - return as_ref(std::forward(val)); - }) - | std::ranges::to(); + | stdv::transform([](U&& val) static noexcept -> decltype(auto) { return as_ref(std::forward(val)); }) + | stdr::to>>(); } ///////////////////////////////////// ///////////////////////////////////// - template class Out, std::ranges::range T> - requires(std::ranges::range>) + template class Out, stdr::range T> + requires(stdr::range>) STORMKIT_FORCE_INLINE constexpr auto to_mut_refs(T& range) noexcept -> decltype(auto) { + using ValueType = stdr::range_value_t; return range - | std::views::transform([](U&& val) static noexcept -> decltype(auto) { + | stdv::transform([](U&& val) static noexcept -> decltype(auto) { return as_ref_mut(std::forward(val)); }) - | std::ranges::to(); + | stdr::to>>(); } ///////////////////////////////////// ///////////////////////////////////// template typename Out, typename... Args> - requires(not std::ranges::range and ...) + requires(not stdr::range and ...) STORMKIT_FORCE_INLINE constexpr auto as_optrefs(Args&&... args) noexcept -> decltype(auto) { - return Out { as_optref(std::forward(args))... }; + using ValueType = std::common_type_t>...>; + return Out, sizeof...(args)> { as_optref(std::forward(args))... }; } ///////////////////////////////////// ///////////////////////////////////// template typename Out, typename... Args> - requires(not std::ranges::range and ...) + requires(not stdr::range and ...) STORMKIT_FORCE_INLINE - constexpr auto to_opt_refs(Args&&... args) noexcept -> decltype(auto) { - return Out { { as_optref(std::forward(args))... } }; + constexpr auto to_optrefs(Args&&... args) noexcept -> decltype(auto) { + using ValueType = std::common_type_t>...>; + return Out> { optas_ref(std::forward(args))... }; } ///////////////////////////////////// ///////////////////////////////////// template typename Out, typename... Args> - requires(not std::ranges::range and ...) + requires(not stdr::range and ...) STORMKIT_FORCE_INLINE constexpr auto as_optref_muts(Args&&... args) noexcept -> decltype(auto) { - return Out { { as_optref_mut(std::forward(args))... } }; + using ValueType = std::common_type_t>...>; + return Out, sizeof...(args)> { as_optref_mut(std::forward(args))... }; } ///////////////////////////////////// ///////////////////////////////////// template typename Out, typename... Args> - requires(not std::ranges::range and ...) + requires(not stdr::range and ...) STORMKIT_FORCE_INLINE - constexpr auto to_opt_ref_muts(Args&&... args) noexcept -> decltype(auto) { - return Out { { as_optref_mut(std::forward(args))... } }; + constexpr auto to_optref_muts(Args&&... args) noexcept -> decltype(auto) { + using ValueType = std::common_type_t>...>; + return Out> { as_optref_mut(std::forward(args))... }; } ///////////////////////////////////// ///////////////////////////////////// - template class Out, std::ranges::range T> - requires(std::ranges::range>) + template class Out, stdr::range T> + requires(stdr::range>) STORMKIT_FORCE_INLINE - constexpr auto to_opt_refs(const T& range) noexcept -> decltype(auto) { + constexpr auto to_optrefs(const T& range) noexcept -> decltype(auto) { + using ValueType = stdr::range_value_t; return range - | std::views::transform([](U&& val) static noexcept -> decltype(auto) { + | stdv::transform([](U&& val) static noexcept -> decltype(auto) { return as_optref(std::forward(val)); }) - | std::ranges::to(); + | stdr::to>>(); } ///////////////////////////////////// ///////////////////////////////////// - template class Out, std::ranges::range T> - requires(std::ranges::range>) + template class Out, stdr::range T> + requires(stdr::range>) STORMKIT_FORCE_INLINE - constexpr auto to_mut_opt_refs(T& range) noexcept -> decltype(auto) { + constexpr auto to_mut_optrefs(T& range) noexcept -> decltype(auto) { + using ValueType = stdr::range_value_t; return range - | std::views::transform([](U&& val) static noexcept -> decltype(auto) { + | stdv::transform([](U&& val) static noexcept -> decltype(auto) { return as_optref_mut(std::forward(val)); }) - | std::ranges::to(); + | stdr::to>>(); } ///////////////////////////////////// diff --git a/modules/stormkit/core/typesafe/safecasts.cppm b/modules/stormkit/core/typesafe/safecasts.cppm index e5ea5dba4..3203d9833 100644 --- a/modules/stormkit/core/typesafe/safecasts.cppm +++ b/modules/stormkit/core/typesafe/safecasts.cppm @@ -155,7 +155,7 @@ export { [[nodiscard]] constexpr auto is_equal_impl(T first, T second) noexcept -> bool; - template T, meta::ConvertibleTo U> + template T, meta::ConvertibleTo U> [[nodiscard]] constexpr auto is_equal_impl(T&& first, U&& second) noexcept -> bool; @@ -170,23 +170,23 @@ export { //////////////////////////////////////////////////////////////////// /// BYTES /// //////////////////////////////////////////////////////////////////// - template + template [[nodiscard]] constexpr auto is_impl(T first, T second) noexcept -> bool; - template + template [[nodiscard]] constexpr auto as_impl(U value, const std::source_location&) noexcept -> T; - template + template [[nodiscard]] constexpr auto as_impl(U value, const std::source_location&) noexcept -> T; - template + template [[nodiscard]] constexpr auto narrow_impl(U value) noexcept -> T; - template + template [[nodiscard]] constexpr auto narrow_impl(U value) noexcept -> T; @@ -246,9 +246,9 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - requires((meta::IsArithmetic or meta::IsByte) and (meta::IsArithmetic or meta::IsByte)) + requires((meta::IsArithmetic or meta::Isbyte) and (meta::IsArithmetic or meta::Isbyte)) constexpr auto isSafeNarrowing(const From& from) noexcept -> Boolean { - if constexpr ((meta::IsArithmetic and meta::IsByte) or (meta::IsByte and meta::IsArithmetic)) + if constexpr ((meta::IsArithmetic and meta::Isbyte) or (meta::Isbyte and meta::IsArithmetic)) return (static_cast(static_cast(from)) == from); else if constexpr (meta::IsArithmetic and meta::IsArithmetic) return (static_cast(static_cast(from)) == from) @@ -366,10 +366,10 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template T, meta::ConvertibleTo U> + template T, meta::ConvertibleTo U> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto is_equal_impl(T&& first, U&& second) noexcept -> bool { - return std::string_view { std::forward(first) } == std::string_view { std::forward(second) }; + return string_view { std::forward(first) } == string_view { std::forward(second) }; } ///////////////////////////////////// @@ -399,7 +399,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////////////////////////////////// ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto as_impl(U value, const std::source_location& location) noexcept -> T { if constexpr (meta::IsNarrowing>) @@ -413,7 +413,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto as_impl(U value, const std::source_location& location) noexcept -> T { if constexpr (meta::IsNarrowing>) @@ -427,7 +427,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE STORMKIT_CONST STORMKIT_INTRINSIC constexpr auto narrow_impl(U value) noexcept -> T { return static_cast(value); @@ -435,7 +435,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE STORMKIT_CONST STORMKIT_INTRINSIC constexpr auto narrow_impl(U value) noexcept -> T { return static_cast(value); diff --git a/modules/stormkit/core/utils/algorithms.cppm b/modules/stormkit/core/utils/algorithms.cppm index 17bb0e4a3..889d5a604 100644 --- a/modules/stormkit/core/utils/algorithms.cppm +++ b/modules/stormkit/core/utils/algorithms.cppm @@ -7,6 +7,7 @@ export module stormkit.core:utils.algorithms; import std; import :meta; +import :containers.aliases; namespace stdr = std::ranges; namespace stdv = std::views; @@ -42,14 +43,18 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// template::value_type> Predicate> constexpr auto copy_if(Range&& input, Predicate&& predicate) noexcept -> decltype(auto) { - return std::forward(input) | stdv::filter(std::forward(predicate)) | stdr::to(); + return std::forward(input) + | stdv::filter(std::forward(predicate)) + | stdr::to>(); } ///////////////////////////////////// ///////////////////////////////////// template::value_type&> Lambda> constexpr auto transform(Range&& input, Lambda&& lambda) noexcept -> decltype(auto) { - return std::forward(input) | stdv::transform(lambda) | stdr::to(); + return std::forward(input) + | stdv::transform(lambda) + | stdr::to::value_type>>>(); } ///////////////////////////////////// @@ -61,7 +66,7 @@ namespace stormkit { inline namespace core { return std::forward(input) | stdv::filter(std::forward(predicate)) | stdv::transform(std::forward(lambda)) - | stdr::to(); + | stdr::to::value_type>>>(); } ///////////////////////////////////// diff --git a/modules/stormkit/core/utils/allocation.cppm b/modules/stormkit/core/utils/allocation.cppm index f39c5c762..e0dcd5f39 100644 --- a/modules/stormkit/core/utils/allocation.cppm +++ b/modules/stormkit/core/utils/allocation.cppm @@ -18,8 +18,8 @@ import :typesafe.integer; export namespace stormkit { inline namespace core { struct MemoryAllocationError { - std::string_view type; - usize size; + string_view type; + usize size; }; template diff --git a/modules/stormkit/core/utils/app.cppm b/modules/stormkit/core/utils/app.cppm index f0f137022..c251ab075 100644 --- a/modules/stormkit/core/utils/app.cppm +++ b/modules/stormkit/core/utils/app.cppm @@ -13,6 +13,8 @@ export module stormkit.core:utils.app; import std; import :typesafe.integer; +import :containers.aliases; +import :string.aliases; export namespace stormkit { inline namespace core { class STORMKIT_CORE_API App { @@ -26,6 +28,6 @@ export namespace stormkit { inline namespace core { App(const App&) noexcept = delete; auto operator=(const App&) noexcept -> App& = delete; - virtual auto run(std::span args) -> i32 = 0; + virtual auto run(array_view args) -> i32 = 0; }; }} // namespace stormkit::core diff --git a/modules/stormkit/core/utils/color.cppm b/modules/stormkit/core/utils/color.cppm index 6ec042e6f..a4a65a280 100644 --- a/modules/stormkit/core/utils/color.cppm +++ b/modules/stormkit/core/utils/color.cppm @@ -190,11 +190,11 @@ export namespace stormkit { inline namespace core { using ucolor_bgra = color_bgra; using ucolor_abgr = color_abgr; - constexpr auto as_string(ColorLayout layout) noexcept -> std::string_view; - constexpr auto to_string(ColorLayout layout) noexcept -> std::string; + constexpr auto as_string(ColorLayout layout) noexcept -> string_view; + constexpr auto to_string(ColorLayout layout) noexcept -> string; template - constexpr auto to_string(const color& color) noexcept -> std::string; + constexpr auto to_string(const color& color) noexcept -> string; template auto format_as(const color& color, FormatContext& ctx) noexcept -> decltype(ctx.out()); @@ -509,7 +509,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto as_string(ColorLayout layout) noexcept -> std::string_view { + constexpr auto as_string(ColorLayout layout) noexcept -> string_view { switch (layout) { case ColorLayout::R: return "R"; case ColorLayout::RG: return "RG"; @@ -527,15 +527,15 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto to_string(ColorLayout layout) noexcept -> std::string { - return std::string { as_string(layout) }; + constexpr auto to_string(ColorLayout layout) noexcept -> string { + return string { as_string(layout) }; } ///////////////////////////////////// ///////////////////////////////////// template STORMKIT_FORCE_INLINE - constexpr auto to_string(const color& color) noexcept -> std::string { + constexpr auto to_string(const color& color) noexcept -> string { return std::format("{}", color); } diff --git a/modules/stormkit/core/utils/contract.cppm b/modules/stormkit/core/utils/contract.cppm index 84c7790ad..6b8cfe08b 100644 --- a/modules/stormkit/core/utils/contract.cppm +++ b/modules/stormkit/core/utils/contract.cppm @@ -17,6 +17,8 @@ import std; import frozen; import :utils.stracktrace; +import :containers.aliases; +import :string.aliases; import :meta; @@ -29,37 +31,37 @@ export namespace stormkit { inline namespace core { PostCondition, }; - constexpr auto as_string(AssertType type) noexcept -> std::string_view; - constexpr auto to_string(AssertType type) noexcept -> std::string; + constexpr auto as_string(AssertType type) noexcept -> string_view; + constexpr auto to_string(AssertType type) noexcept -> string; STORMKIT_CORE_API auto assert_base(bool cond, AssertType type, - std::string_view message, + string_view message, const std::source_location& location = std::source_location::current()) noexcept -> void; - consteval auto consteval_assert_base(bool cond, AssertType type, std::string_view message) noexcept -> void; + consteval auto consteval_assert_base(bool cond, AssertType type, string_view message) noexcept -> void; constexpr auto assert(bool cond, - std::string_view message, + string_view message, const std::source_location& location = std::source_location::current()) noexcept -> void; constexpr auto assert(bool cond, const std::source_location& location = std::source_location::current()) noexcept -> void; constexpr auto expects(bool cond, - std::string_view message, + string_view message, const std::source_location& location = std::source_location::current()) noexcept -> void; constexpr auto expects(bool cond, const std::source_location& location = std::source_location::current()) noexcept -> void; constexpr auto ensures(bool cond, - std::string_view message, + string_view message, const std::source_location& location = std::source_location::current()) noexcept -> void; constexpr auto ensures(bool cond, const std::source_location& location = std::source_location::current()) noexcept -> void; namespace casts::core { - template To> + template To> [[nodiscard]] constexpr auto as(AssertType t) noexcept -> To; } @@ -83,10 +85,10 @@ namespace stormkit { inline namespace core { } // namespace casts::core struct StringLiteral { - std::array buff; - std::size_t size; + array buff; + std::size_t size; - consteval auto view() noexcept -> std::string_view { return { std::data(buff), size }; } + consteval auto view() noexcept -> string_view { return { std::data(buff), size }; } }; auto constevalFailure(StringLiteral) -> void; @@ -94,7 +96,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto as_string(AssertType type) noexcept -> std::string_view { + constexpr auto as_string(AssertType type) noexcept -> string_view { const auto t = casts::core::AssertTypeToContractName.at(type); return { stdr::data(t), stdr::size(t) }; } @@ -102,16 +104,16 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto to_string(AssertType type) noexcept -> std::string { + constexpr auto to_string(AssertType type) noexcept -> string { const auto t = casts::core::AssertTypeToContractName.at(type); return { stdr::data(t), stdr::size(t) }; } ///////////////////////////////////// ///////////////////////////////////// - consteval auto generateConstevalMessage(AssertType type, std::string_view message) noexcept -> StringLiteral { + consteval auto generateConstevalMessage(AssertType type, string_view message) noexcept -> StringLiteral { auto result = StringLiteral {}; - const auto str = "[Assertion]"s + to_string(type) + ": " + std::string { message }; + const auto str = "[Assertion]"s + to_string(type) + ": " + string { message }; std::ranges::copy(str, std::begin(result.buff)); result.size = std::size(str); return result; @@ -120,14 +122,14 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - consteval auto consteval_assert_base(bool cond, AssertType type, std::string_view message) noexcept -> void { + consteval auto consteval_assert_base(bool cond, AssertType type, string_view message) noexcept -> void { if (not cond) [[unlikely]] { constevalFailure(generateConstevalMessage(type, message)); } } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto assert(bool cond, std::string_view message, [[maybe_unused]] const std::source_location& location) noexcept + constexpr auto assert(bool cond, string_view message, [[maybe_unused]] const std::source_location& location) noexcept -> void { #ifdef STORMKIT_COMPILER_MSVC if constexpr (std::is_constant_evaluated()) { @@ -150,7 +152,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto expects(bool cond, std::string_view message, const std::source_location& location) noexcept -> void { + constexpr auto expects(bool cond, string_view message, const std::source_location& location) noexcept -> void { #ifdef STORMKIT_COMPILER_MSVC if constexpr (std::is_constant_evaluated()) { #else @@ -172,7 +174,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto ensures(bool cond, std::string_view message, const std::source_location& location) noexcept -> void { + constexpr auto ensures(bool cond, string_view message, const std::source_location& location) noexcept -> void { #ifdef STORMKIT_COMPILER_MSVC if constexpr (std::is_constant_evaluated()) { #else diff --git a/modules/stormkit/core/utils/deferinit.cppm b/modules/stormkit/core/utils/deferinit.cppm index 27e9c7105..a207197df 100644 --- a/modules/stormkit/core/utils/deferinit.cppm +++ b/modules/stormkit/core/utils/deferinit.cppm @@ -16,7 +16,7 @@ import :utils.contract; export namespace stormkit { inline namespace core { template - using DeferInitDefaultStorage = std::array; + using DeferInitDefaultStorage = array; template> class [[nodiscard]] DeferInit { diff --git a/modules/stormkit/core/utils/dynamic_loader.cppm b/modules/stormkit/core/utils/dynamic_loader.cppm index 2e7b38447..8fc61fe5d 100644 --- a/modules/stormkit/core/utils/dynamic_loader.cppm +++ b/modules/stormkit/core/utils/dynamic_loader.cppm @@ -38,11 +38,11 @@ export namespace stormkit { inline namespace core { template [[nodiscard]] - auto func(std::string_view name) const noexcept -> Expected>; + auto func(string_view name) const noexcept -> Expected>; template [[nodiscard]] - auto c_func(std::string_view name) const noexcept -> Expected; + auto c_func(string_view name) const noexcept -> Expected; [[nodiscard]] auto filepath() const noexcept -> const std::filesystem::path&; @@ -51,7 +51,7 @@ export namespace stormkit { inline namespace core { DynamicLoader() noexcept; auto do_load(std::filesystem::path filepath) -> Expected; - auto do_get_func(std::string_view name) const -> Expected; + auto do_get_func(string_view name) const -> Expected; std::filesystem::path m_filepath; void* m_library_handle = nullptr; @@ -108,7 +108,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - inline auto DynamicLoader::func(std::string_view name) const noexcept -> Expected> { + inline auto DynamicLoader::func(string_view name) const noexcept -> Expected> { return c_func(name).transform([](T&& value) { return std::function { std::forward(value) }; }); @@ -117,7 +117,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// template - inline auto DynamicLoader::c_func(std::string_view name) const noexcept -> Expected { + inline auto DynamicLoader::c_func(string_view name) const noexcept -> Expected { EXPECTS(not std::empty(name)); return do_get_func(name).transform([](T&& value) { diff --git a/modules/stormkit/core/utils/filesystem.cppm b/modules/stormkit/core/utils/filesystem.cppm index 2df73be60..4bbed7bf2 100644 --- a/modules/stormkit/core/utils/filesystem.cppm +++ b/modules/stormkit/core/utils/filesystem.cppm @@ -91,16 +91,16 @@ export { auto close() noexcept; - auto read_to(std::span out) noexcept -> Expected; - auto read_to(std::span out) noexcept -> Expected + auto read_to(byte_mut_view<> out) noexcept -> Expected; + auto read_to(array_view out) noexcept -> Expected requires(mode == Mode::UTF8 or mode == Mode::AINSI); - auto read_to(std::span out) noexcept -> Expected + auto read_to(array_view out) noexcept -> Expected requires(mode == Mode::WIDE); - auto write(std::span bytes) noexcept -> Expected; - auto write(std::span bytes) noexcept -> Expected + auto write(byte_view<> bytes) noexcept -> Expected; + auto write(array_view bytes) noexcept -> Expected requires(mode == Mode::UTF8 or mode == Mode::AINSI); - auto write(std::span bytes) noexcept -> Expected + auto write(array_view bytes) noexcept -> Expected requires(mode == Mode::WIDE); auto flush() noexcept -> void; @@ -125,17 +125,17 @@ export { using TextFile = Descriptor; template - auto read_text_to(const stdfs::path& path, std::span> output) noexcept -> Expected; + auto read_text_to(const stdfs::path& path, array_view> output) noexcept -> Expected; template - auto read_text(const stdfs::path& path) noexcept -> Expected>>; + auto read_text(const stdfs::path& path) noexcept -> Expected>>; - auto read_to(const stdfs::path& path, std::span output) noexcept -> Expected; - auto read(const stdfs::path& path) noexcept -> Expected>; + auto read_to(const stdfs::path& path, byte_mut_view<> output) noexcept -> Expected; + auto read(const stdfs::path& path) noexcept -> Expected; template - auto write_text(const stdfs::path& path, std::span> data) noexcept + auto write_text(const stdfs::path& path, array_view> data) noexcept -> Expected; - auto write(const stdfs::path& path, std::span data) noexcept -> Expected; + auto write(const stdfs::path& path, byte_view<> data) noexcept -> Expected; } // namespace io }} // namespace stormkit::core @@ -229,7 +229,7 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Descriptor::read_to(std::span out) noexcept -> Expected { + inline auto Descriptor::read_to(byte_mut_view<> out) noexcept -> Expected { EXPECTS(m_descriptor != 0); const auto ret = #ifdef STORMKIT_OS_WINDOWS @@ -247,7 +247,7 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Descriptor::read_to(std::span out) noexcept -> Expected + inline auto Descriptor::read_to(array_view out) noexcept -> Expected requires(mode == Mode::UTF8 or mode == Mode::AINSI) { return read_to(as_bytes_mut(out)); @@ -257,7 +257,7 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Descriptor::read_to(std::span out) noexcept -> Expected + inline auto Descriptor::read_to(array_view out) noexcept -> Expected requires(mode == Mode::WIDE) { return read_to(as_bytes_mut(out)); @@ -267,7 +267,7 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Descriptor::write(std::span data) noexcept -> Expected { + inline auto Descriptor::write(byte_view<> data) noexcept -> Expected { EXPECTS(m_descriptor != 0); const auto ret = #ifdef STORMKIT_OS_WINDOWS @@ -285,7 +285,7 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Descriptor::write(std::span data) noexcept -> Expected + inline auto Descriptor::write(array_view data) noexcept -> Expected requires(mode == Mode::UTF8 or mode == Mode::AINSI) { return write(as_bytes(data)); @@ -295,7 +295,7 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Descriptor::write(std::span data) noexcept -> Expected + inline auto Descriptor::write(array_view data) noexcept -> Expected requires(mode == Mode::WIDE) { return write(as_bytes(data)); @@ -422,7 +422,7 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto read_text_to(const stdfs::path& path, std::span> out) noexcept -> Expected { + inline auto read_text_to(const stdfs::path& path, array_view> out) noexcept -> Expected { auto file = Try((TextFile::open(path, Access::READ))); ENSURES(stdr::size(out) >= file.size()); Return Try(file.read_to(out)); @@ -432,9 +432,9 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto read_text(const stdfs::path& path) noexcept -> Expected>> { + inline auto read_text(const stdfs::path& path) noexcept -> Expected>> { auto file = Try((TextFile::open(path, Access::READ))); - auto out = std::vector> {}; + auto out = dyn_array> {}; out.resize(file.size()); auto readed = Try(file.read_to(out)); out.resize(readed); @@ -444,7 +444,7 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto read_to(const stdfs::path& path, std::span out) noexcept -> Expected { + inline auto read_to(const stdfs::path& path, byte_mut_view<> out) noexcept -> Expected { auto file = Try((File::open(path, Access::READ))); Return Try(file.read_to(out)); } @@ -452,9 +452,9 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto read(const stdfs::path& path) noexcept -> Expected> { + inline auto read(const stdfs::path& path) noexcept -> Expected { auto file = Try((File::open(path, Access::READ))); - auto out = std::vector {}; + auto out = byte_dyn_array {}; out.resize(file.size()); auto readed = Try(file.read_to(out)); out.resize(readed); @@ -465,7 +465,7 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto write_text(const stdfs::path& path, std::span> data) noexcept + inline auto write_text(const stdfs::path& path, array_view> data) noexcept -> Expected { auto file = Try((TextFile::open(path, Access::WRITE))); Return Try(file.write(data)); @@ -474,7 +474,7 @@ namespace stormkit { inline namespace core { namespace io { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto write(const stdfs::path& path, std::span data) noexcept -> Expected { + inline auto write(const stdfs::path& path, byte_view<> data) noexcept -> Expected { auto file = Try((File::open(path, Access::WRITE))); Return Try(file.write(data)); } diff --git a/modules/stormkit/entities.cppm b/modules/stormkit/entities.cppm index 9532cb2a5..9a0bb38eb 100644 --- a/modules/stormkit/entities.cppm +++ b/modules/stormkit/entities.cppm @@ -46,7 +46,7 @@ export namespace stormkit::entities { #endif using Entity = u32; - using Entities = std::vector; + using Entities = dyn_array; inline constexpr auto INVALID_ENTITY = Entity { 0 }; class System; @@ -106,7 +106,7 @@ export namespace stormkit::entities { class STORMKIT_ENTITIES_API System { public: - using ComponentTypes = std::vector; + using ComponentTypes = dyn_array; using PreUpdateClosure = std::function; using UpdateClosure = std::function; @@ -120,7 +120,7 @@ export namespace stormkit::entities { OnMessageReceived on_message_received = monadic::noop(); }; - System(std::string name, ComponentTypes types, Closures&& closures) noexcept; + System(string name, ComponentTypes types, Closures&& closures) noexcept; System(const System&) = delete; auto operator=(const System&) -> System& = delete; @@ -131,7 +131,7 @@ export namespace stormkit::entities { ~System() noexcept; [[nodiscard]] - auto name() const noexcept -> const std::string&; + auto name() const noexcept -> const string&; [[nodiscard]] auto components_used() const noexcept -> const ComponentTypes&; @@ -145,7 +145,7 @@ export namespace stormkit::entities { auto on_message_received(EntityManager&, const Message&) noexcept -> void; - std::string m_name; + string m_name; ComponentTypes m_types; @@ -188,74 +188,71 @@ export namespace stormkit::entities { template auto add_component(Entity entity, T&& component) noexcept -> cmeta::ToPlainType&; - auto destroy_component(Entity entity, std::string_view name) noexcept -> void; + auto destroy_component(Entity entity, string_view name) noexcept -> void; auto destroy_component(Entity entity, ComponentType type) noexcept -> void; template auto has_component(Entity entity) const noexcept -> bool; - auto has_component(Entity entity, std::string_view name) const noexcept -> bool; + auto has_component(Entity entity, string_view name) const noexcept -> bool; auto has_component(Entity entity, ComponentType type) const noexcept -> bool; auto entities() const noexcept -> const Entities&; auto entities_with_component(ComponentType type) const noexcept -> Entities; - auto entities_with_component(std::string_view name) const noexcept -> Entities; + auto entities_with_component(string_view name) const noexcept -> Entities; template auto get_component(this Self& self, Entity entity) noexcept -> cmeta::ForwardConst&; template auto get_component(this Self& self, Entity entity, ComponentType) noexcept -> cmeta::ForwardConst&; template - auto get_component(this Self& self, Entity entity, std::string_view) noexcept -> cmeta::ForwardConst&; + auto get_component(this Self& self, Entity entity, string_view) noexcept -> cmeta::ForwardConst&; template - auto components_of_type(this Self& self) noexcept -> std::vector>>; + auto components_of_type(this Self& self) noexcept -> dyn_array>>; template - auto components_of_type(this Self& self, ComponentType type) noexcept -> std::vector>>; + auto components_of_type(this Self& self, ComponentType type) noexcept -> dyn_array>>; template - auto components_of_type(this Self& self, std::string_view name) noexcept - -> std::vector>>; + auto components_of_type(this Self& self, string_view name) noexcept -> dyn_array>>; - auto components_types_of(Entity entity) const noexcept -> std::vector; + auto components_types_of(Entity entity) const noexcept -> dyn_array; template - auto add_system(std::string name, System::ComponentTypes types, T& system) noexcept -> System&; - auto add_system(std::string name, System::ComponentTypes types, System::Closures&& closures) noexcept -> System&; - auto has_system(std::string_view name) const noexcept -> bool; - auto remove_system(std::string_view name) noexcept -> void; + auto add_system(string name, System::ComponentTypes types, T& system) noexcept -> System&; + auto add_system(string name, System::ComponentTypes types, System::Closures&& closures) noexcept -> System&; + auto has_system(string_view name) const noexcept -> bool; + auto remove_system(string_view name) noexcept -> void; template - auto systems(this Self& self) noexcept -> std::vector>>; + auto systems(this Self& self) noexcept -> dyn_array>>; template - auto get_system(this Self& self, std::string_view name) noexcept -> cmeta::ForwardConst; + auto get_system(this Self& self, string_view name) noexcept -> cmeta::ForwardConst; auto flush() noexcept -> void; auto step(fsecond delta) noexcept -> void; auto entity_count() const noexcept -> usize; - auto add_raw_component(Entity entity, - ComponentType type, - std::span component, - DeleteFunc delete_func) noexcept -> std::span; + auto add_raw_component(Entity entity, ComponentType type, byte_view<> component, DeleteFunc delete_func) noexcept + -> byte_mut_view<>; template auto get_raw_component(this Self& self, Entity entity, ComponentType type) noexcept - -> std::span>; + -> array_view>; private: using ComponentKey = u64; struct Store { - ComponentType type; - usize size; - Entities entities; - std::vector data; - DeleteFunc delete_func; + ComponentType type; + usize size; + Entities entities; + byte_dyn_array data; + DeleteFunc delete_func; }; - using ComponentStore = std::vector; + using ComponentStore = dyn_array; auto purpose_to_systems(Entity e) noexcept -> void; auto remove_from_systems(Entity e) noexcept -> void; @@ -267,11 +264,11 @@ export namespace stormkit::entities { Entities m_free_entities; - HashSet m_added_entities; - HashSet m_updated_entities; - HashSet m_removed_entities; + hash_set m_added_entities; + hash_set m_updated_entities; + hash_set m_removed_entities; - std::vector m_systems; + dyn_array m_systems; ComponentStore m_components; @@ -298,7 +295,7 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - inline auto System::name() const noexcept -> const std::string& { + inline auto System::name() const noexcept -> const string& { return m_name; } @@ -324,7 +321,7 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - inline auto EntityManager::destroy_component(Entity entity, std::string_view name) noexcept -> void { + inline auto EntityManager::destroy_component(Entity entity, string_view name) noexcept -> void { destroy_component(entity, hash(name)); } @@ -337,7 +334,7 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - inline auto EntityManager::has_component(Entity entity, std::string_view name) const noexcept -> bool { + inline auto EntityManager::has_component(Entity entity, string_view name) const noexcept -> bool { return has_component(entity, hash(name)); } @@ -353,13 +350,13 @@ namespace stormkit::entities { // clang-format off return entities() | stdv::filter([this, type](auto entity) noexcept { return has_component(entity, type); }) - | stdr::to(); + | stdr::to(); // clang-format on } ///////////////////////////////////// ///////////////////////////////////// - inline auto EntityManager::entities_with_component(std::string_view name) const noexcept -> Entities { + inline auto EntityManager::entities_with_component(string_view name) const noexcept -> Entities { return entities_with_component(hash(name)); } @@ -383,7 +380,7 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// template - auto EntityManager::get_component(this Self& self, Entity entity, std::string_view name) noexcept + auto EntityManager::get_component(this Self& self, Entity entity, string_view name) noexcept -> cmeta::ForwardConst& { return self.template get_component(entity, hash(name)); } @@ -391,7 +388,7 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// template - auto EntityManager::components_of_type(this Self& self) noexcept -> std::vector>> { + auto EntityManager::components_of_type(this Self& self) noexcept -> dyn_array>> { return self.template components_of_type(T::type()); } @@ -399,31 +396,31 @@ namespace stormkit::entities { ///////////////////////////////////// template auto EntityManager::components_of_type(this Self& self, ComponentType type) noexcept - -> std::vector>> { + -> dyn_array>> { // clang-format off return self.m_entities | stdv::filter([&self, type](auto entity) noexcept { return self.has_component(entity, type); }) | stdv::transform([&self, type](auto entity) noexcept { return self.template get_component(entity, type); }) // | stdv::transform(monadic::forward_like()) | stdv::transform(monadic::as_ref()) - | stdr::to(); + | stdr::to(); // clang-format on } ///////////////////////////////////// ///////////////////////////////////// template - auto EntityManager::components_of_type(this Self& self, std::string_view name) noexcept - -> std::vector>> { + auto EntityManager::components_of_type(this Self& self, string_view name) noexcept + -> dyn_array>> { return self.template components_of_type(hash(name)); } ///////////////////////////////////// ///////////////////////////////////// - inline auto EntityManager::components_types_of(Entity entity) const noexcept -> std::vector { + inline auto EntityManager::components_types_of(Entity entity) const noexcept -> dyn_array { EXPECTS(has_entity(entity)); - auto out = std::vector {}; + auto out = dyn_array {}; for (auto&& [type, _, entities, _, _] : m_components) { for (auto e : entities) if (e == entity) { @@ -452,7 +449,7 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// template - inline auto EntityManager::add_system(std::string name, System::ComponentTypes types, T& system) noexcept -> System& { + inline auto EntityManager::add_system(string name, System::ComponentTypes types, T& system) noexcept -> System& { auto closures = System::Closures { .update = bind_front(&T::update, &system), }; @@ -466,7 +463,7 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - inline auto EntityManager::add_system(std::string name, System::ComponentTypes types, System::Closures&& closures) noexcept + inline auto EntityManager::add_system(string name, System::ComponentTypes types, System::Closures&& closures) noexcept -> System& { auto& system = m_systems.emplace_back(std::move(name), std::move(types), std::move(closures)); @@ -477,13 +474,13 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - inline auto EntityManager::has_system(std::string_view name) const noexcept -> bool { + inline auto EntityManager::has_system(string_view name) const noexcept -> bool { return stdr::any_of(m_systems, [name](const auto& system) noexcept { return system.name() == name; }); } ///////////////////////////////////// ///////////////////////////////////// - inline auto EntityManager::remove_system(std::string_view name) noexcept -> void { + inline auto EntityManager::remove_system(string_view name) noexcept -> void { auto&& [begin, end] = stdr::remove_if(m_systems, [&name](const auto& system) { return name == system.name(); }); m_systems.erase(begin, end); } @@ -491,20 +488,20 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// template - auto EntityManager::systems(this Self& self) noexcept -> std::vector>> { + auto EntityManager::systems(this Self& self) noexcept -> dyn_array>> { constexpr auto as_refer = [] { if constexpr (cmeta::IsConst) return monadic::as_ref(); else return monadic::as_ref_mut(); }(); - return self.m_systems | stdv::transform(as_refer) | stdr::to(); + return self.m_systems | stdv::transform(as_refer) | stdr::to>>>(); } ///////////////////////////////////// ///////////////////////////////////// template - auto EntityManager::get_system(this Self& self, std::string_view name) noexcept -> cmeta::ForwardConst { + auto EntityManager::get_system(this Self& self, string_view name) noexcept -> cmeta::ForwardConst { EXPECTS(self.has_system(name)); const auto it = stdr::find_if(self.m_systems, [name](const auto& system) noexcept { return system.name() == name; }); @@ -519,10 +516,10 @@ namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - auto EntityManager::add_raw_component(Entity entity, - ComponentType type, - std::span component, - DeleteFunc delete_func) noexcept -> std::span { + auto EntityManager::add_raw_component(Entity entity, + ComponentType type, + byte_view<> component, + DeleteFunc delete_func) noexcept -> byte_mut_view<> { EXPECTS(has_entity(entity)); EXPECTS(not has_component(entity, type)); @@ -542,7 +539,7 @@ namespace stormkit::entities { components.resize(old_size + sizeof(Entity) + size); new (stdr::data(components) + old_size) Entity { entity }; - auto _component = std::span { stdr::data(components) + old_size + sizeof(Entity), _size }; + auto _component = array_view { stdr::data(components) + old_size + sizeof(Entity), _size }; stdr::copy(component, stdr::begin(_component)); entities.emplace_back(entity); @@ -556,7 +553,7 @@ namespace stormkit::entities { ///////////////////////////////////// template auto EntityManager::get_raw_component(this Self& self, Entity entity, ComponentType type) noexcept - -> std::span> { + -> array_view> { EXPECTS(self.has_entity(entity)); EXPECTS(self.has_component(entity, type)); diff --git a/modules/stormkit/gpu/core/base.cppm b/modules/stormkit/gpu/core/base.cppm index 987f59132..56868c696 100644 --- a/modules/stormkit/gpu/core/base.cppm +++ b/modules/stormkit/gpu/core/base.cppm @@ -227,15 +227,15 @@ export namespace stormkit::gpu { auto as_view(const T& value) noexcept -> trait::GpuObject>::TagType>::ViewType; - template class Out = std::array, typename... Args> + template class Out = array, typename... Args> requires(not stdr::range and ...) auto as_views(Args&&... args) noexcept -> decltype(auto); - template class Out = std::vector, typename... Args> + template class Out = dyn_array, typename... Args> requires(not stdr::range and ...) auto to_views(Args&&... args) noexcept -> decltype(auto); - template class Out = std::vector, stdr::range Range> + template class Out = dyn_array, stdr::range Range> auto to_views(const Range& range) noexcept -> decltype(auto); template @@ -663,16 +663,24 @@ namespace stormkit::gpu { requires(not stdr::range and ...) STORMKIT_FORCE_INLINE inline auto as_views(Args&&... args) noexcept -> decltype(auto) { - return Out { gpu::as_view(std::forward(args))... }; + using ValueType = std::common_type_t>...>; + using TagType = typename ValueType::TagType; + using ViewType = trait::GpuObject::ViewType; + + return Out { gpu::as_view(std::forward(args))... }; } ///////////////////////////////////// ///////////////////////////////////// - template class Out = std::vector, typename... Args> + template class Out, typename... Args> requires(not stdr::range and ...) STORMKIT_FORCE_INLINE inline auto to_views(Args&&... args) noexcept -> decltype(auto) { - return Out { gpu::as_view(std::forward(args))... }; + using ValueType = std::common_type_t>...>; + using TagType = typename ValueType::TagType; + using ViewType = trait::GpuObject::ViewType; + + return Out { gpu::as_view(std::forward(args))... }; } ///////////////////////////////////// @@ -680,9 +688,13 @@ namespace stormkit::gpu { template class Out, stdr::range Range> STORMKIT_FORCE_INLINE inline auto to_views(const Range& range) noexcept -> decltype(auto) { + using ValueType = stdr::range_value_t; + using TagType = typename ValueType::TagType; + using ViewType = trait::GpuObject::ViewType; + return range | stdv::transform([](T&& val) static noexcept { return gpu::as_view(std::forward(val)); }) - | stdr::to(); + | stdr::to>(); } ///////////////////////////////////// diff --git a/modules/stormkit/gpu/core/device.cppm b/modules/stormkit/gpu/core/device.cppm index 019d70e20..7cb4ef1d1 100644 --- a/modules/stormkit/gpu/core/device.cppm +++ b/modules/stormkit/gpu/core/device.cppm @@ -46,7 +46,7 @@ namespace stormkit::gpu { auto wait_idle() const noexcept -> Expected; - auto wait_for_fences(std::span fences, + auto wait_for_fences(array_view fences, bool wait_all = true, const std::chrono::milliseconds& timeout = std::chrono::milliseconds::max()) const noexcept -> Expected; @@ -54,16 +54,16 @@ namespace stormkit::gpu { const std::chrono::milliseconds& timeout = std::chrono::milliseconds::max()) const noexcept -> Expected; - auto reset_fences(std::span fences) const noexcept -> Expected; + auto reset_fences(array_view fences) const noexcept -> Expected; auto reset_fence(view::Fence fence) const noexcept -> Expected; template - auto set_object_name(const T& object, std::string_view name) const noexcept -> Expected; + auto set_object_name(const T& object, string_view name) const noexcept -> Expected; - auto set_object_name(u64 object, DebugObjectType type, std::string_view name) const noexcept -> Expected; + auto set_object_name(u64 object, DebugObjectType type, string_view name) const noexcept -> Expected; [[nodiscard]] - auto queue_entries() const noexcept -> std::span; + auto queue_entries() const noexcept -> array_view; [[nodiscard]] auto device_table() const noexcept -> const VolkDeviceTable&; @@ -100,7 +100,7 @@ namespace stormkit::gpu { auto operator=(DeviceImplementation&&) noexcept -> DeviceImplementation&; protected: - std::vector m_queue_entries; + dyn_array m_queue_entries; VolkDeviceTable m_vk_device_table = {}; VmaVulkanFunctions m_vma_function_table = {}; @@ -122,7 +122,7 @@ namespace stormkit::gpu { auto operator=(DeviceImplementation&&) noexcept -> DeviceImplementation&; protected: - std::span m_queue_entries; + array_view m_queue_entries; VolkDeviceTable m_vk_device_table; vk::Observer m_vma_allocator; @@ -140,7 +140,7 @@ namespace stormkit::gpu { template template STORMKIT_FORCE_INLINE - inline auto DeviceInterface::set_object_name(const T& object, std::string_view name) const noexcept -> Expected { + inline auto DeviceInterface::set_object_name(const T& object, string_view name) const noexcept -> Expected { if (not vkSetDebugUtilsObjectNameEXT) return {}; const auto vk_object = vk::to_vk(object); @@ -153,7 +153,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto DeviceInterface::queue_entries() const noexcept -> std::span { + inline auto DeviceInterface::queue_entries() const noexcept -> array_view { return Base::m_queue_entries; } diff --git a/modules/stormkit/gpu/core/instance.cppm b/modules/stormkit/gpu/core/instance.cppm index dc0ab62a2..8602ba589 100644 --- a/modules/stormkit/gpu/core/instance.cppm +++ b/modules/stormkit/gpu/core/instance.cppm @@ -36,26 +36,26 @@ namespace stormkit::gpu { using TagType = PhysicalDeviceTag; [[nodiscard]] - auto check_extension_support(std::string_view extension) const noexcept -> bool; + auto check_extension_support(string_view extension) const noexcept -> bool; [[nodiscard]] - auto check_extension_support(std::span extensions) const noexcept - -> std::optional>; + auto check_extension_support(array_view extensions) const noexcept + -> std::optional>; [[nodiscard]] - auto check_extension_support(std::span extensions) const noexcept - -> std::optional>; + auto check_extension_support(array_view extensions) const noexcept + -> std::optional>; [[nodiscard]] auto info() const noexcept -> const PhysicalDeviceInfo&; [[nodiscard]] auto capabilities() const noexcept -> const RenderCapabilities&; [[nodiscard]] - auto memory_types() const noexcept -> std::span; + auto memory_types() const noexcept -> array_view; [[nodiscard]] - auto queue_families() const noexcept -> std::span; + auto queue_families() const noexcept -> array_view; [[nodiscard]] - auto extensions() const noexcept -> std::span; + auto extensions() const noexcept -> array_view; [[nodiscard]] - auto formats_properties() const noexcept -> std::span>; + auto formats_properties() const noexcept -> array_view>; }; template @@ -66,17 +66,17 @@ namespace stormkit::gpu { using TagType = InstanceTag; [[nodiscard]] - auto extensions() const noexcept -> std::span; + auto extensions() const noexcept -> array_view; [[nodiscard]] - auto physical_devices() const noexcept -> std::span; + auto physical_devices() const noexcept -> array_view; }; } class STORMKIT_GPU_API InstanceImplementation: public GpuObjectImplementation { public: explicit InstanceImplementation(PrivateTag) noexcept; - auto do_init(PrivateTag, std::string = "", bool = (STORMKIT_BUILD_TYPE == "DEBUG")) noexcept -> Expected; + auto do_init(PrivateTag, string = "", bool = (STORMKIT_BUILD_TYPE == "DEBUG")) noexcept -> Expected; ~InstanceImplementation() noexcept; InstanceImplementation(const InstanceImplementation&) noexcept = delete; @@ -86,8 +86,8 @@ namespace stormkit::gpu { auto operator=(InstanceImplementation&&) noexcept -> InstanceImplementation&; protected: - std::vector m_extensions; - std::vector m_physical_devices; + dyn_array m_extensions; + dyn_array m_physical_devices; friend class view::InstanceImplementation; @@ -112,8 +112,8 @@ namespace stormkit::gpu { auto operator=(InstanceImplementation&&) noexcept -> InstanceImplementation&; protected: - std::span m_extensions; - std::span m_physical_devices; + array_view m_extensions; + array_view m_physical_devices; }; } // namespace view @@ -135,11 +135,11 @@ namespace stormkit::gpu { auto operator=(PhysicalDeviceImplementation&&) noexcept -> PhysicalDeviceImplementation&; protected: - Heap m_data; - std::vector m_memory_types; - std::vector m_queue_families; - std::vector m_extensions; - std::vector> m_format_properties; + Heap m_data; + dyn_array m_memory_types; + dyn_array m_queue_families; + dyn_array m_extensions; + dyn_array> m_format_properties; friend class InstanceInterface; friend class view::PhysicalDeviceImplementation; @@ -160,11 +160,11 @@ namespace stormkit::gpu { auto operator=(PhysicalDeviceImplementation&&) noexcept -> PhysicalDeviceImplementation&; protected: - ref m_data; - std::span m_memory_types; - std::span m_queue_families; - std::span m_extensions; - std::span> m_format_properties; + ref m_data; + array_view m_memory_types; + array_view m_queue_families; + array_view m_extensions; + array_view> m_format_properties; }; } // namespace view @@ -194,16 +194,16 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto PhysicalDeviceInterface::check_extension_support(std::string_view extension) const noexcept -> bool { + inline auto PhysicalDeviceInterface::check_extension_support(string_view extension) const noexcept -> bool { return stdr::any_of(extensions(), [extension](const auto& e) { return e == extension; }); } ///////////////////////////////////// ///////////////////////////////////// template - inline auto PhysicalDeviceInterface::check_extension_support(std::span extensions) - const noexcept -> std::optional> { - auto required_extensions = HashSet { stdr::begin(extensions), stdr::end(extensions) }; + inline auto PhysicalDeviceInterface::check_extension_support(array_view extensions) const noexcept + -> std::optional> { + auto required_extensions = hash_set { stdr::begin(extensions), stdr::end(extensions) }; for (const auto& extension : this->extensions()) required_extensions.erase(extension); @@ -215,9 +215,9 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - inline auto PhysicalDeviceInterface::check_extension_support(std::span extensions) const noexcept - -> std::optional> { - const auto ext = transform(extensions, cmonadic::init()); + inline auto PhysicalDeviceInterface::check_extension_support(array_view extensions) const noexcept + -> std::optional> { + const auto ext = transform(extensions, cmonadic::init()); return check_extension_support(ext); } @@ -241,7 +241,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto PhysicalDeviceInterface::memory_types() const noexcept -> std::span { + inline auto PhysicalDeviceInterface::memory_types() const noexcept -> array_view { return Base::m_memory_types; } @@ -249,7 +249,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto PhysicalDeviceInterface::queue_families() const noexcept -> std::span { + inline auto PhysicalDeviceInterface::queue_families() const noexcept -> array_view { return Base::m_queue_families; } @@ -257,7 +257,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto PhysicalDeviceInterface::extensions() const noexcept -> std::span { + inline auto PhysicalDeviceInterface::extensions() const noexcept -> array_view { return Base::m_extensions; } @@ -266,7 +266,7 @@ namespace stormkit::gpu { template STORMKIT_FORCE_INLINE inline auto PhysicalDeviceInterface::formats_properties() const noexcept - -> std::span> { + -> array_view> { return Base::m_format_properties; } @@ -274,7 +274,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto InstanceInterface::extensions() const noexcept -> std::span { + inline auto InstanceInterface::extensions() const noexcept -> array_view { return Base::m_extensions; } @@ -282,7 +282,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto InstanceInterface::physical_devices() const noexcept -> std::span { + inline auto InstanceInterface::physical_devices() const noexcept -> array_view { return Base::m_physical_devices; } diff --git a/modules/stormkit/gpu/core/structs.cppm b/modules/stormkit/gpu/core/structs.cppm index 8c75ab26f..9fb9114fe 100644 --- a/modules/stormkit/gpu/core/structs.cppm +++ b/modules/stormkit/gpu/core/structs.cppm @@ -143,9 +143,9 @@ export { u32 max_fragment_dual_src_attachments; u32 max_fragment_combined_output_resources; u32 max_compute_shared_memory_size; - std::array max_compute_work_group_count; + array max_compute_work_group_count; u32 max_compute_work_group_invocations; - std::array max_compute_work_group_size; + array max_compute_work_group_size; std::optional sub_pixel_precision_bits; std::optional sub_texel_precision_bits; std::optional mipmap_precision_bits; @@ -154,8 +154,8 @@ export { f32 max_sampler_lod_bias; f32 max_sampler_anisotropy; u32 max_viewports; - std::array max_viewport_dimensions; - std::array viewport_bounds_range; + array max_viewport_dimensions; + array viewport_bounds_range; std::optional viewport_sub_pixel_bits; std::optional min_memory_map_alignment; std::optional min_texel_buffer_offset_alignment; @@ -188,8 +188,8 @@ export { u32 max_cull_distances; u32 max_combined_clip_and_cull_distances; u32 discrete_queue_priorities; - std::array point_size_range; - std::array line_width_range; + array point_size_range; + array line_width_range; f32 point_size_granularity; f32 line_width_granularity; bool strict_lines; @@ -289,10 +289,10 @@ export { }; struct PhysicalDeviceInfo { - u64 device_id; - std::string device_name; - u64 vendor_id; - std::string vendor_name; + u64 device_id; + string device_name; + u64 vendor_id; + string vendor_name; u32 api_major_version; u32 api_minor_version; @@ -302,7 +302,7 @@ export { u32 driver_minor_version; u32 driver_patch_version; - std::array pipeline_cache_uuid; + array pipeline_cache_uuid; PhysicalDeviceType type; }; diff --git a/modules/stormkit/gpu/core/vulkan/enums.cppm b/modules/stormkit/gpu/core/vulkan/enums.cppm index f50f4976e..03a28278c 100644 --- a/modules/stormkit/gpu/core/vulkan/enums.cppm +++ b/modules/stormkit/gpu/core/vulkan/enums.cppm @@ -789,7 +789,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ, stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE, stormkit::gpu::AccessFlag::DEPTH_STENCIL_ATTACHMENT_READ, @@ -814,8 +814,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::AccessFlag value) noexcept - -> std::string_view { + constexpr auto stormkit::core::as_string(stormkit::gpu::AccessFlag value) noexcept -> string_view { switch (value) { case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: return "AccessFlag::COLOR_ATTACHMENT_WRITE"; @@ -840,7 +839,7 @@ export { template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::AccessFlag value) noexcept -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::AccessFlag value) noexcept -> string { switch (value) { case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_READ: return "AccessFlag::COLOR_ATTACHMENT_READ"; case stormkit::gpu::AccessFlag::COLOR_ATTACHMENT_WRITE: return "AccessFlag::COLOR_ATTACHMENT_WRITE"; @@ -868,7 +867,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::AttachmentLoadOperation::CLEAR, stormkit::gpu::AttachmentLoadOperation::DONT_CARE, stormkit::gpu::AttachmentLoadOperation::LOAD, @@ -879,7 +878,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string< - stormkit::gpu::AttachmentLoadOperation>(stormkit::gpu::AttachmentLoadOperation value) noexcept -> std::string_view { + stormkit::gpu::AttachmentLoadOperation>(stormkit::gpu::AttachmentLoadOperation value) noexcept -> string_view { switch (value) { case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; @@ -891,7 +890,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string< - stormkit::gpu::AttachmentLoadOperation>(stormkit::gpu::AttachmentLoadOperation value) noexcept -> std::string { + stormkit::gpu::AttachmentLoadOperation>(stormkit::gpu::AttachmentLoadOperation value) noexcept -> string { switch (value) { case stormkit::gpu::AttachmentLoadOperation::CLEAR: return "AttachmentLoadOperation::CLEAR"; case stormkit::gpu::AttachmentLoadOperation::DONT_CARE: return "AttachmentLoadOperation::DONT_CARE"; @@ -905,7 +904,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::AttachmentStoreOperation::DONT_CARE, stormkit::gpu::AttachmentStoreOperation::STORE, @@ -915,7 +914,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string< - stormkit::gpu::AttachmentStoreOperation>(stormkit::gpu::AttachmentStoreOperation value) noexcept -> std::string_view { + stormkit::gpu::AttachmentStoreOperation>(stormkit::gpu::AttachmentStoreOperation value) noexcept -> string_view { switch (value) { case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; @@ -926,7 +925,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string< - stormkit::gpu::AttachmentStoreOperation>(stormkit::gpu::AttachmentStoreOperation value) noexcept -> std::string { + stormkit::gpu::AttachmentStoreOperation>(stormkit::gpu::AttachmentStoreOperation value) noexcept -> string { switch (value) { case stormkit::gpu::AttachmentStoreOperation::DONT_CARE: return "AttachmentStoreOperation::DONT_CARE"; case stormkit::gpu::AttachmentStoreOperation::STORE: return "AttachmentStoreOperation::STORE"; @@ -939,7 +938,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::BlendFactor::CONSTANT_ALPHA, stormkit::gpu::BlendFactor::CONSTANT_COLOR, stormkit::gpu::BlendFactor::DST_ALPHA, @@ -967,7 +966,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::BlendFactor value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::BlendFactor::CONSTANT_ALPHA: return "BlendFactor::CONSTANT_ALPHA"; case stormkit::gpu::BlendFactor::CONSTANT_COLOR: return "BlendFactor::CONSTANT_COLOR"; @@ -994,8 +993,7 @@ export { template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::BlendFactor value) noexcept - -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::BlendFactor value) noexcept -> string { switch (value) { case stormkit::gpu::BlendFactor::CONSTANT_ALPHA: return "BlendFactor::CONSTANT_ALPHA"; case stormkit::gpu::BlendFactor::CONSTANT_COLOR: return "BlendFactor::CONSTANT_COLOR"; @@ -1025,7 +1023,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::BlendOperation::ADD, stormkit::gpu::BlendOperation::MAX, stormkit::gpu::BlendOperation::MIN, stormkit::gpu::BlendOperation::REVERSE_SUBTRACT, stormkit::gpu::BlendOperation::SUBTRACT, @@ -1037,7 +1035,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::BlendOperation value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::BlendOperation::ADD: return "BlendOperation::ADD"; case stormkit::gpu::BlendOperation::MAX: return "BlendOperation::MAX"; @@ -1051,7 +1049,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::BlendOperation value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::BlendOperation::ADD: return "BlendOperation::ADD"; case stormkit::gpu::BlendOperation::MAX: return "BlendOperation::MAX"; @@ -1067,7 +1065,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK, stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE, stormkit::gpu::BorderColor::FLOAT_TRANSPARENT_BLACK, stormkit::gpu::BorderColor::INT_OPAQUE_BLACK, stormkit::gpu::BorderColor::INT_OPAQUE_WHITE, stormkit::gpu::BorderColor::INT_TRANSPARENT_BLACK, @@ -1079,7 +1077,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::BorderColor value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: return "BorderColor::FLOAT_OPAQUE_BLACK"; case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: return "BorderColor::FLOAT_OPAQUE_WHITE"; @@ -1093,8 +1091,7 @@ export { template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::BorderColor value) noexcept - -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::BorderColor value) noexcept -> string { switch (value) { case stormkit::gpu::BorderColor::FLOAT_OPAQUE_BLACK: return "BorderColor::FLOAT_OPAQUE_BLACK"; case stormkit::gpu::BorderColor::FLOAT_OPAQUE_WHITE: return "BorderColor::FLOAT_OPAQUE_WHITE"; @@ -1111,7 +1108,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::BufferUsageFlag::INDEX, stormkit::gpu::BufferUsageFlag::INDIRECT, stormkit::gpu::BufferUsageFlag::STORAGE, stormkit::gpu::BufferUsageFlag::STORAGE_TEXEL, stormkit::gpu::BufferUsageFlag::TRANSFER_DST, stormkit::gpu::BufferUsageFlag::TRANSFER_SRC, @@ -1125,7 +1122,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::BufferUsageFlag value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::BufferUsageFlag::INDEX: return "BufferUsageFlag::INDEX"; case stormkit::gpu::BufferUsageFlag::INDIRECT: return "BufferUsageFlag::INDIRECT"; @@ -1143,7 +1140,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::BufferUsageFlag value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::BufferUsageFlag::INDEX: return "BufferUsageFlag::INDEX"; case stormkit::gpu::BufferUsageFlag::INDIRECT: return "BufferUsageFlag::INDIRECT"; @@ -1163,7 +1160,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::ColorComponentFlag::A, stormkit::gpu::ColorComponentFlag::B, stormkit::gpu::ColorComponentFlag::G, stormkit::gpu::ColorComponentFlag::NONE, stormkit::gpu::ColorComponentFlag::R, stormkit::gpu::ColorComponentFlag::RG, @@ -1176,7 +1173,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::ColorComponentFlag value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::ColorComponentFlag::A: return "ColorComponentFlag::A"; case stormkit::gpu::ColorComponentFlag::B: return "ColorComponentFlag::B"; @@ -1193,7 +1190,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::ColorComponentFlag value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::ColorComponentFlag::A: return "ColorComponentFlag::A"; case stormkit::gpu::ColorComponentFlag::B: return "ColorComponentFlag::B"; @@ -1212,7 +1209,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::ColorSpace::ADOBERGB_LINEAR, stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR, stormkit::gpu::ColorSpace::BT2020_LINEAR, @@ -1236,8 +1233,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ColorSpace value) noexcept - -> std::string_view { + constexpr auto stormkit::core::as_string(stormkit::gpu::ColorSpace value) noexcept -> string_view { switch (value) { case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: return "ColorSpace::ADOBERGB_NONLINEAR"; @@ -1261,7 +1257,7 @@ export { template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ColorSpace value) noexcept -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::ColorSpace value) noexcept -> string { switch (value) { case stormkit::gpu::ColorSpace::ADOBERGB_LINEAR: return "ColorSpace::ADOBERGB_LINEAR"; case stormkit::gpu::ColorSpace::ADOBERGB_NONLINEAR: return "ColorSpace::ADOBERGB_NONLINEAR"; @@ -1288,7 +1284,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::CommandBufferLevel::PRIMARY, stormkit::gpu::CommandBufferLevel::SECONDARY, @@ -1299,7 +1295,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::CommandBufferLevel value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::CommandBufferLevel::PRIMARY: return "CommandBufferLevel::PRIMARY"; case stormkit::gpu::CommandBufferLevel::SECONDARY: return "CommandBufferLevel::SECONDARY"; @@ -1310,7 +1306,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::CommandBufferLevel value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::CommandBufferLevel::PRIMARY: return "CommandBufferLevel::PRIMARY"; case stormkit::gpu::CommandBufferLevel::SECONDARY: return "CommandBufferLevel::SECONDARY"; @@ -1323,7 +1319,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::CompareOperation::ALWAYS, stormkit::gpu::CompareOperation::EQUAL, stormkit::gpu::CompareOperation::GREATER, stormkit::gpu::CompareOperation::GREATER_OR_EQUAL, stormkit::gpu::CompareOperation::LESS, stormkit::gpu::CompareOperation::LESS_OR_EQUAL, @@ -1336,7 +1332,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::CompareOperation value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::CompareOperation::ALWAYS: return "CompareOperation::ALWAYS"; case stormkit::gpu::CompareOperation::EQUAL: return "CompareOperation::EQUAL"; @@ -1353,7 +1349,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::CompareOperation value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::CompareOperation::ALWAYS: return "CompareOperation::ALWAYS"; case stormkit::gpu::CompareOperation::EQUAL: return "CompareOperation::EQUAL"; @@ -1372,7 +1368,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::CullModeFlag::BACK, stormkit::gpu::CullModeFlag::FRONT, stormkit::gpu::CullModeFlag::FRONT_BACK, @@ -1385,7 +1381,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::CullModeFlag value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::CullModeFlag::BACK: return "CullModeFlag::BACK"; case stormkit::gpu::CullModeFlag::FRONT: return "CullModeFlag::FRONT"; @@ -1397,8 +1393,7 @@ export { template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::CullModeFlag value) noexcept - -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::CullModeFlag value) noexcept -> string { switch (value) { case stormkit::gpu::CullModeFlag::BACK: return "CullModeFlag::BACK"; case stormkit::gpu::CullModeFlag::FRONT: return "CullModeFlag::FRONT"; @@ -1413,7 +1408,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::DebugObjectType::BUFFER, stormkit::gpu::DebugObjectType::BUFFER_VIEW, stormkit::gpu::DebugObjectType::COMMAND_BUFFER, @@ -1453,7 +1448,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::DebugObjectType value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::DebugObjectType::BUFFER: return "DebugObjectType::BUFFER"; case stormkit::gpu::DebugObjectType::BUFFER_VIEW: return "DebugObjectType::BUFFER_VIEW"; @@ -1493,7 +1488,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::DebugObjectType value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::DebugObjectType::BUFFER: return "DebugObjectType::BUFFER"; case stormkit::gpu::DebugObjectType::BUFFER_VIEW: return "DebugObjectType::BUFFER_VIEW"; @@ -1535,7 +1530,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::DependencyFlag::BY_REGION, stormkit::gpu::DependencyFlag::DEVICE_GROUP, stormkit::gpu::DependencyFlag::NONE, @@ -1548,7 +1543,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::DependencyFlag value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::DependencyFlag::BY_REGION: return "DependencyFlag::BY_REGION"; case stormkit::gpu::DependencyFlag::DEVICE_GROUP: return "DependencyFlag::DEVICE_GROUP"; @@ -1561,7 +1556,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::DependencyFlag value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::DependencyFlag::BY_REGION: return "DependencyFlag::BY_REGION"; case stormkit::gpu::DependencyFlag::DEVICE_GROUP: return "DependencyFlag::DEVICE_GROUP"; @@ -1576,7 +1571,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER, stormkit::gpu::DescriptorType::INPUT_ATTACHMENT, stormkit::gpu::DescriptorType::SAMPLED_IMAGE, stormkit::gpu::DescriptorType::SAMPLER, stormkit::gpu::DescriptorType::STORAGE_BUFFER, stormkit::gpu::DescriptorType::STORAGE_BUFFER_DYNAMIC, @@ -1591,7 +1586,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::DescriptorType value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: return "DescriptorType::COMBINED_IMAGE_SAMPLER"; case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: return "DescriptorType::INPUT_ATTACHMENT"; @@ -1611,7 +1606,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::DescriptorType value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::DescriptorType::COMBINED_IMAGE_SAMPLER: return "DescriptorType::COMBINED_IMAGE_SAMPLER"; case stormkit::gpu::DescriptorType::INPUT_ATTACHMENT: return "DescriptorType::INPUT_ATTACHMENT"; @@ -1633,7 +1628,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::DynamicState::BLEND_CONSTANTS, stormkit::gpu::DynamicState::DEPTH_BIAS, stormkit::gpu::DynamicState::DEPTH_BOUNDS, stormkit::gpu::DynamicState::LINE_WIDTH, stormkit::gpu::DynamicState::SCISSOR, stormkit::gpu::DynamicState::STENCIL_COMPARE_MASK, @@ -1647,7 +1642,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::DynamicState value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::DynamicState::BLEND_CONSTANTS: return "DynamicState::BLEND_CONSTANTS"; case stormkit::gpu::DynamicState::DEPTH_BIAS: return "DynamicState::DEPTH_BIAS"; @@ -1664,8 +1659,7 @@ export { template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::DynamicState value) noexcept - -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::DynamicState value) noexcept -> string { switch (value) { case stormkit::gpu::DynamicState::BLEND_CONSTANTS: return "DynamicState::BLEND_CONSTANTS"; case stormkit::gpu::DynamicState::DEPTH_BIAS: return "DynamicState::DEPTH_BIAS"; @@ -1685,7 +1679,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::Filter::CUBIC_IMG, stormkit::gpu::Filter::LINEAR, stormkit::gpu::Filter::NEAREST, @@ -1696,7 +1690,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::Filter value) noexcept -> std::string_view { + constexpr auto stormkit::core::as_string(stormkit::gpu::Filter value) noexcept -> string_view { switch (value) { case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; case stormkit::gpu::Filter::LINEAR: return "Filter::LINEAR"; @@ -1707,7 +1701,7 @@ export { template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::Filter value) noexcept -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::Filter value) noexcept -> string { switch (value) { case stormkit::gpu::Filter::CUBIC_IMG: return "Filter::CUBIC_IMG"; case stormkit::gpu::Filter::LINEAR: return "Filter::LINEAR"; @@ -1721,7 +1715,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::FormatFeatureFlag::BLIT_DST, stormkit::gpu::FormatFeatureFlag::BLIT_SRC, stormkit::gpu::FormatFeatureFlag::COLOR_ATTACHMENT, @@ -1753,7 +1747,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::FormatFeatureFlag value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::FormatFeatureFlag::BLIT_DST: return "FormatFeatureFlag::BLIT_DST"; case stormkit::gpu::FormatFeatureFlag::BLIT_SRC: return "FormatFeatureFlag::BLIT_SRC"; @@ -1792,7 +1786,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::FormatFeatureFlag value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::FormatFeatureFlag::BLIT_DST: return "FormatFeatureFlag::BLIT_DST"; case stormkit::gpu::FormatFeatureFlag::BLIT_SRC: return "FormatFeatureFlag::BLIT_SRC"; @@ -1833,7 +1827,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::FrontFace::CLOCKWISE, stormkit::gpu::FrontFace::COUNTER_CLOCKWISE, @@ -1843,8 +1837,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::FrontFace value) noexcept - -> std::string_view { + constexpr auto stormkit::core::as_string(stormkit::gpu::FrontFace value) noexcept -> string_view { switch (value) { case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; case stormkit::gpu::FrontFace::COUNTER_CLOCKWISE: return "FrontFace::COUNTER_CLOCKWISE"; @@ -1854,7 +1847,7 @@ export { template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::FrontFace value) noexcept -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::FrontFace value) noexcept -> string { switch (value) { case stormkit::gpu::FrontFace::CLOCKWISE: return "FrontFace::CLOCKWISE"; case stormkit::gpu::FrontFace::COUNTER_CLOCKWISE: return "FrontFace::COUNTER_CLOCKWISE"; @@ -1867,7 +1860,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION, stormkit::gpu::GeometryFlag::OPAQUE, @@ -1878,7 +1871,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::GeometryFlag value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION: return "GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION"; @@ -1889,8 +1882,7 @@ export { template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryFlag value) noexcept - -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryFlag value) noexcept -> string { switch (value) { case stormkit::gpu::GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION: return "GeometryFlag::NO_DUPLICATE_ANY_HIT_INVOCATION"; @@ -1904,7 +1896,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::GeometryType::AABBS, stormkit::gpu::GeometryType::INSTANCES, stormkit::gpu::GeometryType::TRIANGLES, @@ -1916,7 +1908,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::GeometryType value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::GeometryType::AABBS: return "GeometryType::AABBS"; case stormkit::gpu::GeometryType::INSTANCES: return "GeometryType::INSTANCES"; @@ -1927,8 +1919,7 @@ export { template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryType value) noexcept - -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::GeometryType value) noexcept -> string { switch (value) { case stormkit::gpu::GeometryType::AABBS: return "GeometryType::AABBS"; case stormkit::gpu::GeometryType::INSTANCES: return "GeometryType::INSTANCES"; @@ -1942,7 +1933,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::ImageAspectFlag::COLOR, stormkit::gpu::ImageAspectFlag::DEPTH, stormkit::gpu::ImageAspectFlag::NONE, @@ -1955,7 +1946,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::ImageAspectFlag value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::ImageAspectFlag::COLOR: return "ImageAspectFlag::COLOR"; case stormkit::gpu::ImageAspectFlag::DEPTH: return "ImageAspectFlag::DEPTH"; @@ -1968,7 +1959,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::ImageAspectFlag value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::ImageAspectFlag::COLOR: return "ImageAspectFlag::COLOR"; case stormkit::gpu::ImageAspectFlag::DEPTH: return "ImageAspectFlag::DEPTH"; @@ -1983,7 +1974,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::ImageCreateFlag::ALIAS, stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE, stormkit::gpu::ImageCreateFlag::BLOCK_TEXEL_VIEW_COMPATIBLE, @@ -2005,7 +1996,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::ImageCreateFlag value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::ImageCreateFlag::ALIAS: return "ImageCreateFlag::ALIAS"; case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; @@ -2029,7 +2020,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::ImageCreateFlag value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::ImageCreateFlag::ALIAS: return "ImageCreateFlag::ALIAS"; case stormkit::gpu::ImageCreateFlag::ARRAY_2D_COMPATIBLE: return "ImageCreateFlag::ARRAY_2D_COMPATIBLE"; @@ -2055,7 +2046,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL, stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL, stormkit::gpu::ImageLayout::DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, @@ -2078,7 +2069,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::ImageLayout value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL: return "ImageLayout::ATTACHMENT_OPTIMAL"; case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; @@ -2104,8 +2095,7 @@ export { template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageLayout value) noexcept - -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageLayout value) noexcept -> string { switch (value) { case stormkit::gpu::ImageLayout::ATTACHMENT_OPTIMAL: return "ImageLayout::ATTACHMENT_OPTIMAL"; case stormkit::gpu::ImageLayout::COLOR_ATTACHMENT_OPTIMAL: return "ImageLayout::COLOR_ATTACHMENT_OPTIMAL"; @@ -2134,7 +2124,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::ImageTiling::LINEAR, stormkit::gpu::ImageTiling::OPTIMAL, @@ -2145,7 +2135,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::ImageTiling value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::ImageTiling::LINEAR: return "ImageTiling::LINEAR"; case stormkit::gpu::ImageTiling::OPTIMAL: return "ImageTiling::OPTIMAL"; @@ -2155,8 +2145,7 @@ export { template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageTiling value) noexcept - -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageTiling value) noexcept -> string { switch (value) { case stormkit::gpu::ImageTiling::LINEAR: return "ImageTiling::LINEAR"; case stormkit::gpu::ImageTiling::OPTIMAL: return "ImageTiling::OPTIMAL"; @@ -2169,7 +2158,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::ImageType::T1D, stormkit::gpu::ImageType::T2D, stormkit::gpu::ImageType::T3D, @@ -2180,8 +2169,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::ImageType value) noexcept - -> std::string_view { + constexpr auto stormkit::core::as_string(stormkit::gpu::ImageType value) noexcept -> string_view { switch (value) { case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; case stormkit::gpu::ImageType::T2D: return "ImageType::T2D"; @@ -2192,7 +2180,7 @@ export { template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::ImageType value) noexcept -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::ImageType value) noexcept -> string { switch (value) { case stormkit::gpu::ImageType::T1D: return "ImageType::T1D"; case stormkit::gpu::ImageType::T2D: return "ImageType::T2D"; @@ -2206,7 +2194,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT, stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT, stormkit::gpu::ImageUsageFlag::INPUT_ATTACHMENT, stormkit::gpu::ImageUsageFlag::SAMPLED, stormkit::gpu::ImageUsageFlag::STORAGE, stormkit::gpu::ImageUsageFlag::TRANSFER_DST, @@ -2219,7 +2207,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::ImageUsageFlag value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: return "ImageUsageFlag::COLOR_ATTACHMENT"; case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; @@ -2236,7 +2224,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::ImageUsageFlag value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::ImageUsageFlag::COLOR_ATTACHMENT: return "ImageUsageFlag::COLOR_ATTACHMENT"; case stormkit::gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT: return "ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT"; @@ -2255,7 +2243,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::ImageViewType::CUBE, stormkit::gpu::ImageViewType::CUBE_ARRAY, stormkit::gpu::ImageViewType::T1D, stormkit::gpu::ImageViewType::T1D_ARRAY, stormkit::gpu::ImageViewType::T2D, stormkit::gpu::ImageViewType::T2D_ARRAY, @@ -2268,7 +2256,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::ImageViewType value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::ImageViewType::CUBE: return "ImageViewType::CUBE"; case stormkit::gpu::ImageViewType::CUBE_ARRAY: return "ImageViewType::CUBE_ARRAY"; @@ -2284,7 +2272,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::ImageViewType value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::ImageViewType::CUBE: return "ImageViewType::CUBE"; case stormkit::gpu::ImageViewType::CUBE_ARRAY: return "ImageViewType::CUBE_ARRAY"; @@ -2302,7 +2290,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::LogicOperation::AND, stormkit::gpu::LogicOperation::AND_INVERTED, stormkit::gpu::LogicOperation::AND_REVERSE, stormkit::gpu::LogicOperation::CLEAR, stormkit::gpu::LogicOperation::COPY, stormkit::gpu::LogicOperation::COPY_INVERTED, @@ -2319,7 +2307,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::LogicOperation value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::LogicOperation::AND: return "LogicOperation::AND"; case stormkit::gpu::LogicOperation::AND_INVERTED: return "LogicOperation::AND_INVERTED"; @@ -2344,7 +2332,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::LogicOperation value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::LogicOperation::AND: return "LogicOperation::AND"; case stormkit::gpu::LogicOperation::AND_INVERTED: return "LogicOperation::AND_INVERTED"; @@ -2371,7 +2359,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL, stormkit::gpu::MemoryPropertyFlag::HOST_CACHED, stormkit::gpu::MemoryPropertyFlag::HOST_COHERENT, @@ -2384,7 +2372,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::MemoryPropertyFlag value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: return "MemoryPropertyFlag::DEVICE_LOCAL"; case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: return "MemoryPropertyFlag::HOST_CACHED"; @@ -2397,7 +2385,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::MemoryPropertyFlag value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::MemoryPropertyFlag::DEVICE_LOCAL: return "MemoryPropertyFlag::DEVICE_LOCAL"; case stormkit::gpu::MemoryPropertyFlag::HOST_CACHED: return "MemoryPropertyFlag::HOST_CACHED"; @@ -2412,7 +2400,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::PhysicalDeviceType::CPU, stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU, stormkit::gpu::PhysicalDeviceType::INTEGRATED_GPU, @@ -2426,7 +2414,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::PhysicalDeviceType value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::PhysicalDeviceType::CPU: return "PhysicalDeviceType::CPU"; case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: return "PhysicalDeviceType::DISCRETE_GPU"; @@ -2440,7 +2428,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::PhysicalDeviceType value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::PhysicalDeviceType::CPU: return "PhysicalDeviceType::CPU"; case stormkit::gpu::PhysicalDeviceType::DISCRETE_GPU: return "PhysicalDeviceType::DISCRETE_GPU"; @@ -2456,7 +2444,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::PipelineBindPoint::COMPUTE, stormkit::gpu::PipelineBindPoint::GRAPHICS, @@ -2467,7 +2455,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::PipelineBindPoint value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::PipelineBindPoint::COMPUTE: return "PipelineBindPoint::COMPUTE"; case stormkit::gpu::PipelineBindPoint::GRAPHICS: return "PipelineBindPoint::GRAPHICS"; @@ -2478,7 +2466,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineBindPoint value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::PipelineBindPoint::COMPUTE: return "PipelineBindPoint::COMPUTE"; case stormkit::gpu::PipelineBindPoint::GRAPHICS: return "PipelineBindPoint::GRAPHICS"; @@ -2491,7 +2479,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::PipelineStageFlag::ALL_COMMANDS, stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS, stormkit::gpu::PipelineStageFlag::BOTTOM_OF_PIPE, @@ -2517,7 +2505,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::PipelineStageFlag value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: return "PipelineStageFlag::ALL_COMMANDS"; case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: return "PipelineStageFlag::ALL_GRAPHICS"; @@ -2545,7 +2533,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::PipelineStageFlag value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::PipelineStageFlag::ALL_COMMANDS: return "PipelineStageFlag::ALL_COMMANDS"; case stormkit::gpu::PipelineStageFlag::ALL_GRAPHICS: return "PipelineStageFlag::ALL_GRAPHICS"; @@ -2575,7 +2563,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16, stormkit::gpu::PixelFormat::A2_RGB10I_PACK32, stormkit::gpu::PixelFormat::A2_RGB10_SNORM_PACK32, @@ -2656,7 +2644,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::PixelFormat value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; @@ -2736,8 +2724,7 @@ export { template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::PixelFormat value) noexcept - -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::PixelFormat value) noexcept -> string { switch (value) { case stormkit::gpu::PixelFormat::A1_RGB5_UNORM_PACK16: return "PixelFormat::A1_RGB5_UNORM_PACK16"; case stormkit::gpu::PixelFormat::A2_RGB10I_PACK32: return "PixelFormat::A2_RGB10I_PACK32"; @@ -2820,7 +2807,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::PolygonMode::FILL, stormkit::gpu::PolygonMode::LINE, stormkit::gpu::PolygonMode::POINT, @@ -2832,7 +2819,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::PolygonMode value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::PolygonMode::FILL: return "PolygonMode::FILL"; case stormkit::gpu::PolygonMode::LINE: return "PolygonMode::LINE"; @@ -2843,8 +2830,7 @@ export { template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::PolygonMode value) noexcept - -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::PolygonMode value) noexcept -> string { switch (value) { case stormkit::gpu::PolygonMode::FILL: return "PolygonMode::FILL"; case stormkit::gpu::PolygonMode::LINE: return "PolygonMode::LINE"; @@ -2858,7 +2844,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::PresentMode::FIFO, stormkit::gpu::PresentMode::FIFO_RELAXED, stormkit::gpu::PresentMode::IMMEDIATE, @@ -2873,7 +2859,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::PresentMode value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::PresentMode::FIFO: return "PresentMode::FIFO"; case stormkit::gpu::PresentMode::FIFO_RELAXED: return "PresentMode::FIFO_RELAXED"; @@ -2887,8 +2873,7 @@ export { template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::PresentMode value) noexcept - -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::PresentMode value) noexcept -> string { switch (value) { case stormkit::gpu::PresentMode::FIFO: return "PresentMode::FIFO"; case stormkit::gpu::PresentMode::FIFO_RELAXED: return "PresentMode::FIFO_RELAXED"; @@ -2905,7 +2890,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::PrimitiveTopology::LINE_LIST, stormkit::gpu::PrimitiveTopology::LINE_STRIP, stormkit::gpu::PrimitiveTopology::POINT_LIST, stormkit::gpu::PrimitiveTopology::TRIANGLE_FAN, stormkit::gpu::PrimitiveTopology::TRIANGLE_LIST, stormkit::gpu::PrimitiveTopology::TRIANGLE_STRIP, @@ -2917,7 +2902,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::PrimitiveTopology value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::PrimitiveTopology::LINE_LIST: return "PrimitiveTopology::LINE_LIST"; case stormkit::gpu::PrimitiveTopology::LINE_STRIP: return "PrimitiveTopology::LINE_STRIP"; @@ -2932,7 +2917,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::PrimitiveTopology value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::PrimitiveTopology::LINE_LIST: return "PrimitiveTopology::LINE_LIST"; case stormkit::gpu::PrimitiveTopology::LINE_STRIP: return "PrimitiveTopology::LINE_STRIP"; @@ -2949,7 +2934,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::QueueFlag::COMPUTE, stormkit::gpu::QueueFlag::GRAPHICS, stormkit::gpu::QueueFlag::NONE, stormkit::gpu::QueueFlag::PROTECTED, stormkit::gpu::QueueFlag::SPARSE_BINDING, stormkit::gpu::QueueFlag::TRANSFER, @@ -2959,8 +2944,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::QueueFlag value) noexcept - -> std::string_view { + constexpr auto stormkit::core::as_string(stormkit::gpu::QueueFlag value) noexcept -> string_view { switch (value) { case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; case stormkit::gpu::QueueFlag::GRAPHICS: return "QueueFlag::GRAPHICS"; @@ -2974,7 +2958,7 @@ export { template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::QueueFlag value) noexcept -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::QueueFlag value) noexcept -> string { switch (value) { case stormkit::gpu::QueueFlag::COMPUTE: return "QueueFlag::COMPUTE"; case stormkit::gpu::QueueFlag::GRAPHICS: return "QueueFlag::GRAPHICS"; @@ -2991,7 +2975,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::ResolveModeFlag::AVERAGE, stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID, stormkit::gpu::ResolveModeFlag::MAX, stormkit::gpu::ResolveModeFlag::MIN, stormkit::gpu::ResolveModeFlag::NONE, stormkit::gpu::ResolveModeFlag::SAMPLE_ZERO, @@ -3003,7 +2987,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::ResolveModeFlag value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::ResolveModeFlag::AVERAGE: return "ResolveModeFlag::AVERAGE"; case stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID: @@ -3019,7 +3003,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::ResolveModeFlag value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::ResolveModeFlag::AVERAGE: return "ResolveModeFlag::AVERAGE"; case stormkit::gpu::ResolveModeFlag::EXTERNAL_FORMAT_DOWNSAMPLE_ANDROID: @@ -3037,7 +3021,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::Result::ERROR_DEVICE_LOST, stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT, stormkit::gpu::Result::ERROR_FEATURE_NOT_PRESENT, @@ -3081,7 +3065,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::Result value) noexcept -> std::string_view { + constexpr auto stormkit::core::as_string(stormkit::gpu::Result value) noexcept -> string_view { switch (value) { case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: return "Result::ERROR_EXTENSION_NOT_PRESENT"; @@ -3127,7 +3111,7 @@ export { template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::Result value) noexcept -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::Result value) noexcept -> string { switch (value) { case stormkit::gpu::Result::ERROR_DEVICE_LOST: return "Result::ERROR_DEVICE_LOST"; case stormkit::gpu::Result::ERROR_EXTENSION_NOT_PRESENT: return "Result::ERROR_EXTENSION_NOT_PRESENT"; @@ -3176,7 +3160,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::SampleCountFlag::C1, stormkit::gpu::SampleCountFlag::C16, stormkit::gpu::SampleCountFlag::C2, stormkit::gpu::SampleCountFlag::C32, stormkit::gpu::SampleCountFlag::C4, stormkit::gpu::SampleCountFlag::C64, stormkit::gpu::SampleCountFlag::C8, @@ -3188,7 +3172,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::SampleCountFlag value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::SampleCountFlag::C1: return "SampleCountFlag::C1"; case stormkit::gpu::SampleCountFlag::C16: return "SampleCountFlag::C16"; @@ -3204,7 +3188,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::SampleCountFlag value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::SampleCountFlag::C1: return "SampleCountFlag::C1"; case stormkit::gpu::SampleCountFlag::C16: return "SampleCountFlag::C16"; @@ -3222,7 +3206,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER, stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE, stormkit::gpu::SamplerAddressMode::MIRROR_CLAMP_TO_EDGE, @@ -3236,7 +3220,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::SamplerAddressMode value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; @@ -3250,7 +3234,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerAddressMode value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::SamplerAddressMode::CLAMP_TO_BORDER: return "SamplerAddressMode::CLAMP_TO_BORDER"; case stormkit::gpu::SamplerAddressMode::CLAMP_TO_EDGE: return "SamplerAddressMode::CLAMP_TO_EDGE"; @@ -3266,7 +3250,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::SamplerMipmapMode::LINEAR, stormkit::gpu::SamplerMipmapMode::NEAREST, @@ -3277,7 +3261,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::SamplerMipmapMode value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::SamplerMipmapMode::LINEAR: return "SamplerMipmapMode::LINEAR"; case stormkit::gpu::SamplerMipmapMode::NEAREST: return "SamplerMipmapMode::NEAREST"; @@ -3288,7 +3272,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::SamplerMipmapMode value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::SamplerMipmapMode::LINEAR: return "SamplerMipmapMode::LINEAR"; case stormkit::gpu::SamplerMipmapMode::NEAREST: return "SamplerMipmapMode::NEAREST"; @@ -3301,7 +3285,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::ShaderStageFlag::COMPUTE, stormkit::gpu::ShaderStageFlag::FRAGMENT, stormkit::gpu::ShaderStageFlag::GEOMETRY, stormkit::gpu::ShaderStageFlag::NONE, stormkit::gpu::ShaderStageFlag::VERTEX, @@ -3313,7 +3297,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::ShaderStageFlag value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::ShaderStageFlag::COMPUTE: return "ShaderStageFlag::COMPUTE"; case stormkit::gpu::ShaderStageFlag::FRAGMENT: return "ShaderStageFlag::FRAGMENT"; @@ -3327,7 +3311,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::ShaderStageFlag value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::ShaderStageFlag::COMPUTE: return "ShaderStageFlag::COMPUTE"; case stormkit::gpu::ShaderStageFlag::FRAGMENT: return "ShaderStageFlag::FRAGMENT"; @@ -3343,7 +3327,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::StencilFaceFlag::BACK, stormkit::gpu::StencilFaceFlag::FRONT, stormkit::gpu::StencilFaceFlag::FRONT_AND_BACK, @@ -3355,7 +3339,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::StencilFaceFlag value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::StencilFaceFlag::BACK: return "StencilFaceFlag::BACK"; case stormkit::gpu::StencilFaceFlag::FRONT: return "StencilFaceFlag::FRONT"; @@ -3367,7 +3351,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::StencilFaceFlag value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::StencilFaceFlag::BACK: return "StencilFaceFlag::BACK"; case stormkit::gpu::StencilFaceFlag::FRONT: return "StencilFaceFlag::FRONT"; @@ -3381,7 +3365,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { stormkit::gpu::VertexInputRate::INSTANCE, stormkit::gpu::VertexInputRate::VERTEX, @@ -3392,7 +3376,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::as_string(stormkit::gpu::VertexInputRate value) noexcept - -> std::string_view { + -> string_view { switch (value) { case stormkit::gpu::VertexInputRate::INSTANCE: return "VertexInputRate::INSTANCE"; case stormkit::gpu::VertexInputRate::VERTEX: return "VertexInputRate::VERTEX"; @@ -3403,7 +3387,7 @@ export { template<> STORMKIT_FORCE_INLINE constexpr auto stormkit::core::to_string(stormkit::gpu::VertexInputRate value) noexcept - -> std::string { + -> string { switch (value) { case stormkit::gpu::VertexInputRate::INSTANCE: return "VertexInputRate::INSTANCE"; case stormkit::gpu::VertexInputRate::VERTEX: return "VertexInputRate::VERTEX"; diff --git a/modules/stormkit/gpu/core/vulkan/enums.cppm.tpl b/modules/stormkit/gpu/core/vulkan/enums.cppm.tpl index f57ddda58..8fabedda1 100644 --- a/modules/stormkit/gpu/core/vulkan/enums.cppm.tpl +++ b/modules/stormkit/gpu/core/vulkan/enums.cppm.tpl @@ -81,7 +81,7 @@ export { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto stormkit::core::meta::enumerate() noexcept -> decltype(auto) { - return std::array { + return array { {% for val_name, value in table.orderpairs(enumeration["values"]) do %}stormkit::gpu::{% outfile:write(name) %}::{% outfile:write(val_name) %}, {% end %} }; @@ -89,7 +89,7 @@ export { template<> STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto stormkit::core::as_string(stormkit::gpu::{% outfile:write(name) %} value) noexcept -> std::string_view { + constexpr auto stormkit::core::as_string(stormkit::gpu::{% outfile:write(name) %} value) noexcept -> string_view { switch(value) { {% for val_name, value in table.orderpairs(enumeration["values"]) do %}case stormkit::gpu::{% outfile:write(name) %}::{% outfile:write(val_name) %}: return "{% outfile:write(name) %}::{% outfile:write(val_name) %}"; {% end %} @@ -98,7 +98,7 @@ export { } template<> STORMKIT_FORCE_INLINE - constexpr auto stormkit::core::to_string(stormkit::gpu::{% outfile:write(name) %} value) noexcept -> std::string { + constexpr auto stormkit::core::to_string(stormkit::gpu::{% outfile:write(name) %} value) noexcept -> string { switch(value) { {% for val_name, value in table.orderpairs(enumeration["values"]) do %}case stormkit::gpu::{% outfile:write(name) %}::{% outfile:write(val_name) %}: return "{% outfile:write(name) %}::{% outfile:write(val_name) %}"; {% end %} diff --git a/modules/stormkit/gpu/core/vulkan/utils.cppm b/modules/stormkit/gpu/core/vulkan/utils.cppm index f0d619ea2..e5b75359e 100644 --- a/modules/stormkit/gpu/core/vulkan/utils.cppm +++ b/modules/stormkit/gpu/core/vulkan/utils.cppm @@ -87,30 +87,30 @@ export namespace stormkit::gpu::vk { template Func> requires(meta::HasNoReturnValue and not cmeta::SameAs) [[nodiscard]] - auto allocate(usize count, const Func& func, Args&&... args) noexcept -> std::vector; + auto allocate(usize count, const Func& func, Args&&... args) noexcept -> dyn_array; template Func> requires(meta::HasResultReturnValue and not cmeta::SameAs) - auto allocate_checked(usize count, const Func& func, Args&&... args) noexcept -> Expected>; + auto allocate_checked(usize count, const Func& func, Args&&... args) noexcept -> Expected>; template Func> requires(meta::HasResultReturnValue and not cmeta::SameAs) [[nodiscard]] - auto allocate_unchecked(usize count, const Func& func, Args&&... args) noexcept -> std::vector; + auto allocate_unchecked(usize count, const Func& func, Args&&... args) noexcept -> dyn_array; template Func> requires(meta::HasNoReturnValue and not cmeta::SameAs) [[nodiscard]] - auto enumerate(const Func& func, Args&&... args) noexcept -> std::vector; + auto enumerate(const Func& func, Args&&... args) noexcept -> dyn_array; template Func> requires(meta::HasResultReturnValue and not cmeta::SameAs) - auto enumerate_checked(const Func& func, Args&&... args) noexcept -> Expected>; + auto enumerate_checked(const Func& func, Args&&... args) noexcept -> Expected>; template Func> requires(meta::HasResultReturnValue and not cmeta::SameAs) [[nodiscard]] - auto enumerate_unchecked(const Func& func, Args&&... args) noexcept -> std::vector; + auto enumerate_unchecked(const Func& func, Args&&... args) noexcept -> dyn_array; template class Owned { @@ -245,7 +245,7 @@ namespace stormkit::gpu::vk { ///////////////////////////////////// template Func> inline auto call_checked(const Func& func, Args&&... args) noexcept -> Expected { - static constexpr auto SUCCESS_RESULTS = std::array { VK_SUCCESS, _SUCCESS_RESULTS... }; + static constexpr auto SUCCESS_RESULTS = array { VK_SUCCESS, _SUCCESS_RESULTS... }; using OutExpected = Expected; auto out_expected = OutExpected { std::in_place }; @@ -261,7 +261,7 @@ namespace stormkit::gpu::vk { ///////////////////////////////////// template Out, VkResult... _SUCCESS_RESULTS, typename... Args, meta::HasResultReturnValue Func> inline auto call_checked(const Func& func, Args&&... args) noexcept -> Expected { - static constexpr auto SUCCESS_RESULTS = std::array { VK_SUCCESS, _SUCCESS_RESULTS... }; + static constexpr auto SUCCESS_RESULTS = array { VK_SUCCESS, _SUCCESS_RESULTS... }; using OutExpected = Expected; auto out_expected = OutExpected { std::in_place }; @@ -280,7 +280,7 @@ namespace stormkit::gpu::vk { template Func> requires meta::HasResultReturnValue inline auto call_checked(const Func& func, Args&&... args) noexcept -> Expected { - static constexpr auto SUCCESS_RESULTS = std::array { VK_SUCCESS, _SUCCESS_RESULTS... }; + static constexpr auto SUCCESS_RESULTS = array { VK_SUCCESS, _SUCCESS_RESULTS... }; using OutExpected = Expected; auto out_expected = OutExpected { std::in_place }; @@ -326,8 +326,8 @@ namespace stormkit::gpu::vk { ///////////////////////////////////// template Func> requires(meta::HasNoReturnValue and not cmeta::SameAs) - inline auto allocate(usize count, const Func& func, Args&&... args) noexcept -> std::vector { - auto out = std::vector {}; + inline auto allocate(usize count, const Func& func, Args&&... args) noexcept -> dyn_array { + auto out = dyn_array {}; out.resize(count, VK_NULL_HANDLE); std::invoke(func, std::forward(args)..., stdr::data(out)); return out; @@ -337,13 +337,13 @@ namespace stormkit::gpu::vk { ///////////////////////////////////// template Func> requires(meta::HasResultReturnValue and not cmeta::SameAs) - inline auto allocate_checked(usize count, const Func& func, Args&&... args) noexcept -> Expected> { - static constexpr auto SUCCESS_RESULTS = std::array { VK_SUCCESS, _SUCCESS_RESULTS... }; + inline auto allocate_checked(usize count, const Func& func, Args&&... args) noexcept -> Expected> { + static constexpr auto SUCCESS_RESULTS = array { VK_SUCCESS, _SUCCESS_RESULTS... }; - using OutExpected = Expected>; + using OutExpected = Expected>; auto out_expected = OutExpected { std::in_place }; - auto out = std::vector {}; + auto out = dyn_array {}; out.resize(count, VK_NULL_HANDLE); const auto result = std::invoke(func, std::forward(args)..., stdr::data(out)); if (not stdr::any_of(SUCCESS_RESULTS, cmonadic::is_equal(result))) [[likely]] @@ -358,8 +358,8 @@ namespace stormkit::gpu::vk { ///////////////////////////////////// template Func> requires(meta::HasResultReturnValue and not cmeta::SameAs) - inline auto allocate_unchecked(usize count, const Func& func, Args&&... args) noexcept -> std::vector { - auto out = std::vector {}; + inline auto allocate_unchecked(usize count, const Func& func, Args&&... args) noexcept -> dyn_array { + auto out = dyn_array {}; out.resize(count, VK_NULL_HANDLE); const auto _ = std::invoke(func, std::forward(args)..., stdr::data(out)); return out; @@ -369,8 +369,8 @@ namespace stormkit::gpu::vk { ///////////////////////////////////// template Func> requires(meta::HasNoReturnValue and not cmeta::SameAs) - inline auto enumerate(const Func& func, Args&&... args) noexcept -> std::vector { - auto out = std::vector {}; + inline auto enumerate(const Func& func, Args&&... args) noexcept -> dyn_array { + auto out = dyn_array {}; auto size = 0_u32; std::invoke(func, std::forward(args)..., &size, nullptr); out.resize(size); @@ -383,13 +383,13 @@ namespace stormkit::gpu::vk { ///////////////////////////////////// template Func> requires(meta::HasResultReturnValue and not cmeta::SameAs) - inline auto enumerate_checked(const Func& func, Args&&... args) noexcept -> Expected> { - static constexpr auto SUCCESS_RESULTS = std::array { VK_SUCCESS, _SUCCESS_RESULTS... }; + inline auto enumerate_checked(const Func& func, Args&&... args) noexcept -> Expected> { + static constexpr auto SUCCESS_RESULTS = array { VK_SUCCESS, _SUCCESS_RESULTS... }; - using OutExpected = Expected>; + using OutExpected = Expected>; auto out_expected = OutExpected { std::in_place }; - auto out = std::vector {}; + auto out = dyn_array {}; auto size = 0_u32; { const auto result = std::invoke(func, std::forward(args)..., &size, nullptr); @@ -412,8 +412,8 @@ namespace stormkit::gpu::vk { ///////////////////////////////////// template Func> requires(meta::HasResultReturnValue and not cmeta::SameAs) - inline auto enumerate_unchecked(const Func& func, Args&&... args) noexcept -> std::vector { - auto out = std::vector {}; + inline auto enumerate_unchecked(const Func& func, Args&&... args) noexcept -> dyn_array { + auto out = dyn_array {}; auto size = 0_u32; const auto _ = std::invoke(func, std::forward(args)..., &size, nullptr); out.resize(size); diff --git a/modules/stormkit/gpu/execution/command_buffer.cppm b/modules/stormkit/gpu/execution/command_buffer.cppm index 15fb72fdd..4bedc295a 100644 --- a/modules/stormkit/gpu/execution/command_buffer.cppm +++ b/modules/stormkit/gpu/execution/command_buffer.cppm @@ -39,7 +39,7 @@ namespace stormkit::gpu { struct RenderingInheritanceInfo { u32 view_mask = 0; - std::vector color_attachments = {}; + dyn_array color_attachments = {}; std::optional depth_attachment = std::nullopt; std::optional stencil_attachment = std::nullopt; SampleCountFlag rasterization_samples = SampleCountFlag::C1; @@ -70,7 +70,7 @@ namespace stormkit::gpu { u32 layer_count = 1u; u32 view_mask = 0u; - std::vector color_attachments = {}; + dyn_array color_attachments = {}; std::optional depth_attachment = std::nullopt; std::optional stencil_attachment = std::nullopt; }; @@ -78,10 +78,10 @@ namespace stormkit::gpu { struct QueueInterfaceBase { struct SubmitInfo { - std::span wait_semaphores = {}; - std::span wait_dst_stages = {}; - std::span command_buffers = {}; - std::span signal_semaphores = {}; + array_view wait_semaphores = {}; + array_view wait_dst_stages = {}; + array_view command_buffers = {}; + array_view signal_semaphores = {}; }; }; @@ -96,16 +96,16 @@ namespace stormkit::gpu { auto wait_idle() const noexcept -> Expected; - auto submit(std::span submit_infos, std::optional fence = std::nullopt) const noexcept + auto submit(array_view submit_infos, std::optional fence = std::nullopt) const noexcept -> Expected; auto submit(const SubmitInfo& submit_info, std::optional fence = std::nullopt) const noexcept -> Expected; [[nodiscard]] - auto present(std::span swapchains, - std::span wait_semaphores, - std::span image_indices) const noexcept -> Expected; + auto present(array_view swapchains, + array_view wait_semaphores, + array_view image_indices) const noexcept -> Expected; [[nodiscard]] auto entry() const noexcept -> const QueueEntry&; @@ -146,17 +146,17 @@ namespace stormkit::gpu { -> Expected; auto end() noexcept -> Expected; - auto begin_debug_region(std::string_view name, const fcolor_rgb& color = colors::WHITE) const noexcept + auto begin_debug_region(string_view name, const fcolor_rgb& color = colors::WHITE) const noexcept -> const CommandBufferInterface&; - auto insert_debug_label(std::string_view name, const fcolor_rgb& color = colors::WHITE) const noexcept + auto insert_debug_label(string_view name, const fcolor_rgb& color = colors::WHITE) const noexcept -> const CommandBufferInterface&; auto end_debug_region() const noexcept -> const CommandBufferInterface&; auto begin_rendering(const RenderingInfo& info, bool secondary_commandbuffers = false) const noexcept -> const CommandBufferInterface&; - auto begin_render_pass(view::RenderPass render_pass, - view::FrameBuffer framebuffer, - std::span clear_values = std::array { ClearValue { + auto begin_render_pass(view::RenderPass render_pass, + view::FrameBuffer framebuffer, + array_view clear_values = array { ClearValue { ClearColor { .color = colors::SILVER } } }, bool secondary_commandbuffers = false) const noexcept -> const CommandBufferInterface&; auto next_subpass() const noexcept -> const CommandBufferInterface&; @@ -164,13 +164,13 @@ namespace stormkit::gpu { auto end_rendering() const noexcept -> const CommandBufferInterface&; auto bind_pipeline(view::Pipeline pipeline) const noexcept -> const CommandBufferInterface&; - auto set_viewport(u32 first_viewport, std::span viewports) const noexcept + auto set_viewport(u32 first_viewport, array_view viewports) const noexcept -> const CommandBufferInterface&; - auto set_scissor(u32 first_scissor, std::span scissors) const noexcept + auto set_scissor(u32 first_scissor, array_view scissors) const noexcept -> const CommandBufferInterface&; auto set_line_width(f32 width) const noexcept -> const CommandBufferInterface&; auto set_depth_bias(f32 constant_factor, f32 clamp, f32 slope_factor) const noexcept -> const CommandBufferInterface&; - auto set_blend_constants(std::span constants) const noexcept -> const CommandBufferInterface&; + auto set_blend_constants(array_view constants) const noexcept -> const CommandBufferInterface&; auto set_depth_bounds(f32 min, f32 max) const noexcept -> const CommandBufferInterface&; auto set_stencil_compare_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBufferInterface&; auto set_stencil_write_mask(StencilFaceFlag face, u32 mask) const noexcept -> const CommandBufferInterface&; @@ -191,24 +191,24 @@ namespace stormkit::gpu { auto draw_indexed_indirect(view::Buffer buffer, usize offset, u32 draw_count, u32 stride) const noexcept -> const CommandBufferInterface&; - auto bind_vertex_buffers(std::span buffers, std::span offsets) const noexcept + auto bind_vertex_buffers(array_view buffers, array_view offsets) const noexcept -> const CommandBufferInterface&; auto bind_index_buffer(view::Buffer buffer, u64 offset = 0, bool large_indices = false) const noexcept -> const CommandBufferInterface&; - auto bind_descriptor_sets(view::Pipeline pipeline, - view::PipelineLayout layout, - std::span descriptor_sets, - std::span dynamic_offsets = {}) const noexcept -> const CommandBufferInterface&; + auto bind_descriptor_sets(view::Pipeline pipeline, + view::PipelineLayout layout, + array_view descriptor_sets, + array_view dynamic_offsets = {}) const noexcept -> const CommandBufferInterface&; auto copy_buffer(view::Buffer src, view::Buffer dst, usize size, u64 src_offset = 0u, u64 dst_offset = 0u) const noexcept -> const CommandBufferInterface&; - auto copy_buffer_to_image(view::Buffer src, - view::Image dst, - std::span buffer_image_copies = {}) const noexcept + auto copy_buffer_to_image(view::Buffer src, + view::Image dst, + array_view buffer_image_copies = {}) const noexcept -> const CommandBufferInterface&; - auto copy_image_to_buffer(view::Image src, - view::Buffer dst, - std::span buffer_image_copies = {}) const noexcept + auto copy_image_to_buffer(view::Image src, + view::Buffer dst, + array_view buffer_image_copies = {}) const noexcept -> const CommandBufferInterface&; auto copy_image(view::Image src, view::Image dst, @@ -226,12 +226,12 @@ namespace stormkit::gpu { const ImageSubresourceLayers& dst_subresource_layers = {}) const noexcept -> const CommandBufferInterface&; - auto blit_image(view::Image src, - view::Image dst, - ImageLayout src_layout, - ImageLayout dst_layout, - std::span regions, - Filter filter) const noexcept -> const CommandBufferInterface&; + auto blit_image(view::Image src, + view::Image dst, + ImageLayout src_layout, + ImageLayout dst_layout, + array_view regions, + Filter filter) const noexcept -> const CommandBufferInterface&; auto transition_image_layout(view::Image image, ImageLayout src_layout, @@ -239,28 +239,26 @@ namespace stormkit::gpu { const ImageSubresourceRange& subresource_range = {}) const noexcept -> const CommandBufferInterface&; - auto execute_sub_command_buffers(std::span commandbuffers) const noexcept + auto execute_sub_command_buffers(array_view commandbuffers) const noexcept -> const CommandBufferInterface&; - auto pipeline_barrier(PipelineStageFlag src_mask, - PipelineStageFlag dst_mask, - DependencyFlag dependency, - std::span memory_barriers, - std::span buffer_memory_barriers, - std::span image_memory_barriers) const noexcept + auto pipeline_barrier(PipelineStageFlag src_mask, + PipelineStageFlag dst_mask, + DependencyFlag dependency, + array_view memory_barriers, + array_view buffer_memory_barriers, + array_view image_memory_barriers) const noexcept -> const CommandBufferInterface&; - auto push_constants(view::PipelineLayout pipeline_layout, - ShaderStageFlag stage, - std::span data, - u32 offset = 0u) const noexcept -> const CommandBufferInterface&; + auto push_constants(view::PipelineLayout pipeline_layout, ShaderStageFlag stage, byte_view<> data, u32 offset = 0u) + const noexcept -> const CommandBufferInterface&; auto submit(this const auto&, - view::Queue queue, - std::span wait_semaphores = {}, - std::span wait_dst_stages = {}, - std::span signal_semaphores = {}, - std::optional fence = std::nullopt) noexcept -> Expected; + view::Queue queue, + array_view wait_semaphores = {}, + array_view wait_dst_stages = {}, + array_view signal_semaphores = {}, + std::optional fence = std::nullopt) noexcept -> Expected; }; template @@ -273,15 +271,15 @@ namespace stormkit::gpu { auto create_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept -> Expected; auto create_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>; + -> Expected>; auto allocate_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept -> Expected>; auto allocate_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>>; + -> Expected>>; protected: - auto create_vk_command_buffers(usize, CommandBufferLevel) const noexcept -> Expected>; + auto create_vk_command_buffers(usize, CommandBufferLevel) const noexcept -> Expected>; static auto delete_vk_command_buffers(view::Device, view::CommandPool, VkCommandBuffer) noexcept -> void; }; @@ -415,7 +413,7 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto QueueInterface::submit(const SubmitInfo& submit_info, std::optional fence) const noexcept -> Expected { - return submit({ &submit_info, 1 }, std::move(fence)); + return QueueInterface::submit(array_view { &submit_info, 1 }, std::move(fence)); } ///////////////////////////////////// @@ -430,14 +428,14 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto CommandBufferInterface::submit(this const auto& self, - view::Queue queue, - std::span wait_semaphores, - std::span wait_dst_stages, - std::span signal_semaphores, - std::optional fence) noexcept -> Expected { + inline auto CommandBufferInterface::submit(this const auto& self, + view::Queue queue, + array_view wait_semaphores, + array_view wait_dst_stages, + array_view signal_semaphores, + std::optional fence) noexcept -> Expected { auto cmbs = as_views(self); - auto submit_infos = std::array { + auto submit_infos = array { Queue::SubmitInfo { .wait_semaphores = wait_semaphores, .wait_dst_stages = wait_dst_stages, @@ -495,7 +493,7 @@ namespace stormkit::gpu { template STORMKIT_FORCE_INLINE inline auto CommandPoolInterface::create_command_buffers(usize count, CommandBufferLevel level) const noexcept - -> Expected> { + -> Expected> { Return transform(Try(create_vk_command_buffers(count, level)), [this, &level](auto vk_handle) noexcept { auto device = Base::owner(); return CommandBuffer::create(std::move(device), level, std::move(vk_handle), delete_vk_command_buffers); @@ -518,7 +516,7 @@ namespace stormkit::gpu { template STORMKIT_FORCE_INLINE inline auto CommandPoolInterface::allocate_command_buffers(usize count, CommandBufferLevel level) const noexcept - -> Expected>> { + -> Expected>> { Return transform(Try(create_vk_command_buffers(count, level)), [this, &level](auto vk_handle) noexcept { auto device = Base::owner(); return CommandBuffer::allocate(std::move(device), level, std::move(vk_handle), delete_vk_command_buffers); diff --git a/modules/stormkit/gpu/execution/descriptors.cppm b/modules/stormkit/gpu/execution/descriptors.cppm index aa3095503..c9cfca3f4 100644 --- a/modules/stormkit/gpu/execution/descriptors.cppm +++ b/modules/stormkit/gpu/execution/descriptors.cppm @@ -61,7 +61,7 @@ namespace stormkit::gpu { using DeviceObject::operator=; using TagType = DescriptorSetTag; - auto update(std::span descriptors) const noexcept -> void; + auto update(array_view descriptors) const noexcept -> void; }; } @@ -83,7 +83,7 @@ namespace stormkit::gpu { using DescriptorSetLayoutInterfaceBase::Size; [[nodiscard]] - auto bindings() const noexcept -> std::span; + auto bindings() const noexcept -> array_view; }; template @@ -95,16 +95,16 @@ namespace stormkit::gpu { auto create_descriptor_set(this const auto&, view::DescriptorSetLayout layout) noexcept -> Expected; auto create_descriptor_sets(this const auto&, usize count, view::DescriptorSetLayout layout) noexcept - -> Expected>; + -> Expected>; auto allocate_descriptor_set(this const auto&, view::DescriptorSetLayout layout) noexcept -> Expected>; auto allocate_descriptor_sets(this const auto&, usize count, view::DescriptorSetLayout layout) noexcept - -> Expected>>; + -> Expected>>; private: auto create_vk_descriptor_sets(usize, view::DescriptorSetLayout&&) const noexcept - -> Expected>; + -> Expected>; static auto delete_vk_descriptor_set(view::Device, view::DescriptorPool, VkDescriptorSet) noexcept -> void; }; @@ -145,7 +145,7 @@ namespace stormkit::gpu { class STORMKIT_GPU_API DescriptorSetLayoutImplementation: public GpuObjectImplementation { public: DescriptorSetLayoutImplementation(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, std::vector&&) noexcept -> Expected; + auto do_init(PrivateTag, dyn_array&&) noexcept -> Expected; ~DescriptorSetLayoutImplementation() noexcept; DescriptorSetLayoutImplementation(const DescriptorSetLayoutImplementation&) = delete; @@ -155,7 +155,7 @@ namespace stormkit::gpu { auto operator=(DescriptorSetLayoutImplementation&&) noexcept -> DescriptorSetLayoutImplementation&; protected: - std::vector m_bindings; + dyn_array m_bindings; }; namespace view { @@ -173,7 +173,7 @@ namespace stormkit::gpu { auto operator=(DescriptorSetLayoutImplementation&&) noexcept -> DescriptorSetLayoutImplementation&; protected: - std::span m_bindings; + array_view m_bindings; }; } // namespace view @@ -182,7 +182,7 @@ namespace stormkit::gpu { using Size = DescriptorSetLayoutInterfaceBase::Size; DescriptorPoolImplementation(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, std::span&&, u32) noexcept -> Expected; + auto do_init(PrivateTag, array_view&&, u32) noexcept -> Expected; ~DescriptorPoolImplementation() noexcept; DescriptorPoolImplementation(const DescriptorPoolImplementation&) = delete; @@ -221,7 +221,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto DescriptorSetLayoutInterface::bindings() const noexcept -> std::span { + inline auto DescriptorSetLayoutInterface::bindings() const noexcept -> array_view { return Base::m_bindings; } @@ -246,7 +246,7 @@ namespace stormkit::gpu { inline auto DescriptorPoolInterface::create_descriptor_sets(this const auto& self, usize count, view::DescriptorSetLayout layout) noexcept - -> Expected> { + -> Expected> { auto device = self.owner(); Return transform(Try(self.create_vk_descriptor_sets(count, std::move(layout))), [&self, device](auto vk_handle) noexcept { return DescriptorSet::create(device, @@ -276,7 +276,7 @@ namespace stormkit::gpu { inline auto DescriptorPoolInterface::allocate_descriptor_sets(this const auto& self, usize count, view::DescriptorSetLayout layout) noexcept - -> Expected>> { + -> Expected>> { auto device = self.owner(); Return transform(Try(self.create_vk_descriptor_sets(count, std::move(layout))), [&self, device](auto vk_handle) noexcept { return DescriptorSet::allocate(device, diff --git a/modules/stormkit/gpu/execution/pipeline.cppm b/modules/stormkit/gpu/execution/pipeline.cppm index b58853939..b7938e702 100644 --- a/modules/stormkit/gpu/execution/pipeline.cppm +++ b/modules/stormkit/gpu/execution/pipeline.cppm @@ -113,7 +113,7 @@ namespace stormkit::gpu { } infos; struct { - std::array value; + array value; } uuid; } m_serialized; diff --git a/modules/stormkit/gpu/execution/raster_pipeline.cppm b/modules/stormkit/gpu/execution/raster_pipeline.cppm index e21c83edb..1294575be 100644 --- a/modules/stormkit/gpu/execution/raster_pipeline.cppm +++ b/modules/stormkit/gpu/execution/raster_pipeline.cppm @@ -35,8 +35,8 @@ export namespace stormkit::gpu { }; struct RasterPipelineVertexInputState { - std::vector binding_descriptions = {}; - std::vector input_attribute_descriptions = {}; + dyn_array binding_descriptions = {}; + dyn_array input_attribute_descriptions = {}; }; struct RasterPipelineInputAssemblyState { @@ -45,8 +45,8 @@ export namespace stormkit::gpu { }; struct RasterPipelineViewportState { - std::vector viewports = {}; - std::vector scissors = {}; + dyn_array viewports = {}; + dyn_array scissors = {}; }; struct RasterPipelineRasterizationState { @@ -82,14 +82,14 @@ export namespace stormkit::gpu { }; struct RasterPipelineColorBlendState { - bool logic_operation_enable = false; - LogicOperation logic_operation = LogicOperation::COPY; - std::vector attachments; - std::array blend_constants = { 0.f, 0.f, 0.f, 0.f }; + bool logic_operation_enable = false; + LogicOperation logic_operation = LogicOperation::COPY; + dyn_array attachments; + array blend_constants = { 0.f, 0.f, 0.f, 0.f }; }; - using RasterPipelineDynamicState = std::vector; - using RasterPipelineShaderState = std::vector; + using RasterPipelineDynamicState = dyn_array; + using RasterPipelineShaderState = dyn_array; struct RasterPipelineDepthStencilState { bool depth_test_enable = false; @@ -105,14 +105,14 @@ export namespace stormkit::gpu { struct RasterPipelineRenderingInfo { u32 view_mask = 0u; - std::vector color_attachment_formats; + dyn_array color_attachment_formats; std::optional depth_attachment_format = std::nullopt; std::optional stencil_attachment_format = std::nullopt; }; struct RasterPipelineLayout { - std::vector descriptor_set_layouts = {}; - std::vector push_constant_ranges = {}; + dyn_array descriptor_set_layouts = {}; + dyn_array push_constant_ranges = {}; }; struct RasterPipelineState { diff --git a/modules/stormkit/gpu/execution/render_pass.cppm b/modules/stormkit/gpu/execution/render_pass.cppm index c286bbb0f..32f0e598f 100644 --- a/modules/stormkit/gpu/execution/render_pass.cppm +++ b/modules/stormkit/gpu/execution/render_pass.cppm @@ -41,7 +41,7 @@ namespace stormkit::gpu { bool resolve = false; }; - using AttachmentDescriptions = std::vector; + using AttachmentDescriptions = dyn_array; struct Subpass { struct Ref { @@ -51,12 +51,12 @@ namespace stormkit::gpu { }; PipelineBindPoint bind_point; - std::vector color_attachment_refs = {}; - std::vector resolve_attachment_refs = {}; + dyn_array color_attachment_refs = {}; + dyn_array resolve_attachment_refs = {}; std::optional depth_attachment_ref = {}; }; - using Subpasses = std::vector; + using Subpasses = dyn_array; struct RenderPassDescription { AttachmentDescriptions attachments; @@ -75,7 +75,7 @@ namespace stormkit::gpu { [[nodiscard]] auto extent() const noexcept -> const math::uextent2&; [[nodiscard]] - auto attachments() const noexcept -> std::span; + auto attachments() const noexcept -> array_view; }; template @@ -86,13 +86,13 @@ namespace stormkit::gpu { using TagType = RenderPassTag; auto create_framebuffer(this const auto&, - view::Device device, - const math::uextent2& extent, - std::vector attachments) noexcept -> Expected; + view::Device device, + const math::uextent2& extent, + dyn_array attachments) noexcept -> Expected; auto allocate_framebuffer(this const auto&, - view::Device device, - const math::uextent2& extent, - std::vector attachments) noexcept -> Expected>; + view::Device device, + const math::uextent2& extent, + dyn_array attachments) noexcept -> Expected>; [[nodiscard]] auto is_compatible(view::RenderPass render_pass) const noexcept -> bool; @@ -107,7 +107,7 @@ namespace stormkit::gpu { class STORMKIT_GPU_API FrameBufferImplementation: public GpuObjectImplementation { public: FrameBufferImplementation(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, view::RenderPass&&, const math::uextent2&, std::vector&&) noexcept + auto do_init(PrivateTag, view::RenderPass&&, const math::uextent2&, dyn_array&&) noexcept -> Expected; ~FrameBufferImplementation() noexcept; @@ -121,8 +121,8 @@ namespace stormkit::gpu { using UseNamedConstructors::allocate; using UseNamedConstructors::create; - math::uextent2 m_extent = { 0, 0 }; - std::vector m_attachments; + math::uextent2 m_extent = { 0, 0 }; + dyn_array m_attachments; friend class RenderPassInterface; friend class RenderPassInterface; @@ -143,8 +143,8 @@ namespace stormkit::gpu { auto operator=(FrameBufferImplementation&&) noexcept -> FrameBufferImplementation&; protected: - math::uextent2 m_extent; - std::span m_attachments; + math::uextent2 m_extent; + array_view m_attachments; }; } // namespace view @@ -212,7 +212,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto FrameBufferInterface::attachments() const noexcept -> std::span { + inline auto FrameBufferInterface::attachments() const noexcept -> array_view { return Base::m_attachments; } @@ -220,10 +220,10 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto RenderPassInterface::create_framebuffer(this const auto& self, - view::Device device, - const math::uextent2& extent, - std::vector attachments) noexcept + inline auto RenderPassInterface::create_framebuffer(this const auto& self, + view::Device device, + const math::uextent2& extent, + dyn_array attachments) noexcept -> Expected { return FrameBuffer::create(std::move(device), gpu::as_view(self), extent, std::move(attachments)); } @@ -232,10 +232,10 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto RenderPassInterface::allocate_framebuffer(this const auto& self, - view::Device device, - const math::uextent2& extent, - std::vector attachments) noexcept + inline auto RenderPassInterface::allocate_framebuffer(this const auto& self, + view::Device device, + const math::uextent2& extent, + dyn_array attachments) noexcept -> Expected> { return FrameBuffer::allocate(std::move(device), gpu::as_view(self), extent, std::move(attachments)); } diff --git a/modules/stormkit/gpu/execution/swapchain.cppm b/modules/stormkit/gpu/execution/swapchain.cppm index 44f58587d..5092d85f5 100644 --- a/modules/stormkit/gpu/execution/swapchain.cppm +++ b/modules/stormkit/gpu/execution/swapchain.cppm @@ -44,7 +44,7 @@ namespace stormkit::gpu { [[nodiscard]] auto pixel_format() const noexcept -> PixelFormat; [[nodiscard]] - auto images() const noexcept -> std::span; + auto images() const noexcept -> array_view; auto acquire_next_image(std::chrono::nanoseconds wait, view::Semaphore image_available) const noexcept -> Expected; }; @@ -70,7 +70,7 @@ namespace stormkit::gpu { PixelFormat m_pixel_format; u32 m_image_count; - std::vector m_images; + dyn_array m_images; }; namespace view { @@ -95,7 +95,7 @@ namespace stormkit::gpu { PixelFormat m_pixel_format; u32 m_image_count; - std::span m_images; + array_view m_images; }; } // namespace view } // namespace stormkit::gpu @@ -117,7 +117,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto SwapChainInterface::images() const noexcept -> std::span { + inline auto SwapChainInterface::images() const noexcept -> array_view { return Base::m_images; } diff --git a/modules/stormkit/gpu/resource/buffer.cppm b/modules/stormkit/gpu/resource/buffer.cppm index 6bc6f3239..e8c5d5f78 100644 --- a/modules/stormkit/gpu/resource/buffer.cppm +++ b/modules/stormkit/gpu/resource/buffer.cppm @@ -52,7 +52,7 @@ namespace stormkit::gpu { auto is_persistently_mapped() const noexcept -> bool; auto map(ioffset offset) noexcept -> Expected; - auto map(ioffset offset, usize size) noexcept -> Expected>; + auto map(ioffset offset, usize size) noexcept -> Expected>; template auto map_as(ioffset offset) noexcept -> Expected>; @@ -64,8 +64,7 @@ namespace stormkit::gpu { auto data(this Self& self) noexcept -> cmeta::ForwardConst*; template [[nodiscard]] - auto data(this Self& self, usize size) noexcept - -> cmeta::If, std::span, std::span>; + auto data(this Self& self, usize size) noexcept -> cmeta::If, byte_mut_view<>, byte_view<>>; template [[nodiscard]] @@ -74,10 +73,10 @@ namespace stormkit::gpu { auto flush(ioffset offset, usize size) const noexcept -> Expected; auto unmap() noexcept -> void; - auto upload(std::span data, ioffset offset = 0) noexcept -> Expected; + auto upload(byte_view<> data, ioffset offset = 0) noexcept -> Expected; template - requires(not stormkit::meta::IsSpecializationWithNTTPOf) + requires(not stormkit::meta::IsStdSpan) auto upload(const T& data, ioffset offset = 0) noexcept -> Expected; [[nodiscard]] @@ -239,7 +238,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto BufferInterface::map(ioffset offset, usize size) noexcept -> Expected> { + inline auto BufferInterface::map(ioffset offset, usize size) noexcept -> Expected> { auto ptr = Try(map(offset)); Return as_bytes_mut(ptr, size); } @@ -281,8 +280,8 @@ namespace stormkit::gpu { template STORMKIT_FORCE_INLINE inline auto BufferInterface::data(this Self& self, usize size) noexcept - -> cmeta::If, std::span, std::span> { - using Out = std::span>; + -> cmeta::If, byte_mut_view<>, byte_view<>> { + using Out = array_view>; return Out { std::bit_cast(self.data()), size }; } @@ -300,7 +299,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template template - requires(not stormkit::meta::IsSpecializationWithNTTPOf) + requires(not stormkit::meta::IsStdSpan) STORMKIT_FORCE_INLINE inline auto BufferInterface::upload(const T& data, ioffset offset) noexcept -> Expected { const auto bytes = as_bytes(data); diff --git a/modules/stormkit/gpu/resource/shader.cppm b/modules/stormkit/gpu/resource/shader.cppm index ce126e8a8..9a41076eb 100644 --- a/modules/stormkit/gpu/resource/shader.cppm +++ b/modules/stormkit/gpu/resource/shader.cppm @@ -36,9 +36,9 @@ namespace stormkit::gpu { [[nodiscard]] auto type() const noexcept -> ShaderStageFlag; [[nodiscard]] - auto source() const noexcept -> std::span; + auto source() const noexcept -> array_view; [[nodiscard]] - auto source_as_bytes() const noexcept -> std::span; + auto source_as_bytes() const noexcept -> byte_view<>; }; class STORMKIT_GPU_API ShaderImplementation: public GpuObjectImplementation { @@ -52,7 +52,7 @@ namespace stormkit::gpu { using LoadExpected = std::expected; ShaderImplementation(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, std::vector&&, ShaderStageFlag) -> Expected; + auto do_init(PrivateTag, dyn_array&&, ShaderStageFlag) -> Expected; ~ShaderImplementation() noexcept; ShaderImplementation(const ShaderImplementation&) noexcept = delete; @@ -63,26 +63,25 @@ namespace stormkit::gpu { static auto load_from_file(view::Device device, const std::filesystem::path& filepath, ShaderStageFlag type) noexcept -> LoadExpected; - static auto load_from_bytes(view::Device device, std::span data, ShaderStageFlag type) noexcept - -> Expected; - static auto load_from_spirv(view::Device device, std::span data, ShaderStageFlag type) noexcept + static auto load_from_bytes(view::Device device, byte_view<> data, ShaderStageFlag type) noexcept -> Expected; + static auto load_from_spirv(view::Device device, array_view data, ShaderStageFlag type) noexcept -> Expected; static auto allocate_and_load_from_file(view::Device device, const std::filesystem::path& filepath, ShaderStageFlag type) noexcept -> LoadExpected>; - static auto allocate_and_load_from_bytes(view::Device device, std::span data, ShaderStageFlag type) noexcept + static auto allocate_and_load_from_bytes(view::Device device, byte_view<> data, ShaderStageFlag type) noexcept -> Expected>; - static auto allocate_and_load_from_spirv(view::Device device, - std::span data, - ShaderStageFlag type) noexcept -> Expected>; + static auto allocate_and_load_from_spirv(view::Device device, + array_view data, + ShaderStageFlag type) noexcept -> Expected>; protected: using UseNamedConstructors::allocate; using UseNamedConstructors::create; - ShaderStageFlag m_type = ShaderStageFlag::NONE; - std::vector m_source = {}; + ShaderStageFlag m_type = ShaderStageFlag::NONE; + dyn_array m_source = {}; }; namespace view { @@ -100,8 +99,8 @@ namespace stormkit::gpu { auto operator=(ShaderImplementation&&) noexcept -> ShaderImplementation&; protected: - ShaderStageFlag m_type; - std::span m_source; + ShaderStageFlag m_type; + array_view m_source; }; } // namespace view } // namespace stormkit::gpu @@ -137,7 +136,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto ShaderInterface::source() const noexcept -> std::span { + inline auto ShaderInterface::source() const noexcept -> array_view { return Base::m_source; } @@ -145,7 +144,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto ShaderInterface::source_as_bytes() const noexcept -> std::span { + inline auto ShaderInterface::source_as_bytes() const noexcept -> byte_view<> { return as_bytes(Base::m_source); } @@ -180,27 +179,26 @@ namespace stormkit::gpu { expects(std::filesystem::is_regular_file(filepath), std::format("{} is not a file", filepath.string())); const auto data = TryTransformError(io::read(filepath), sys_to_load_error); - auto spirv = std::vector { std::from_range, bytes_as_span(data) }; + auto spirv = dyn_array { std::from_range, bytes_as_span(data) }; Return TryTransformError(UseNamedConstructors::create(std::move(device), std::move(spirv), type), result_to_load_error); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto ShaderImplementation::load_from_bytes(view::Device device, - std::span data, - ShaderStageFlag type) noexcept -> Expected { - auto spirv = std::vector { std::from_range, bytes_as_span(data) }; + inline auto ShaderImplementation::load_from_bytes(view::Device device, byte_view<> data, ShaderStageFlag type) noexcept + -> Expected { + auto spirv = dyn_array { std::from_range, bytes_as_span(data) }; return UseNamedConstructors::create(std::move(device), std::move(spirv), type); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto ShaderImplementation::load_from_spirv(view::Device device, - std::span data, - ShaderStageFlag type) noexcept -> Expected { - auto spirv = std::vector { std::from_range, data }; + inline auto ShaderImplementation::load_from_spirv(view::Device device, + array_view data, + ShaderStageFlag type) noexcept -> Expected { + auto spirv = dyn_array { std::from_range, data }; return UseNamedConstructors::create(std::move(device), std::move(spirv), type); } @@ -213,27 +211,27 @@ namespace stormkit::gpu { expects(std::filesystem::is_regular_file(filepath), std::format("{} is not a file", filepath.string())); const auto data = TryTransformError(io::read(filepath), sys_to_load_error); - auto spirv = std::vector { std::from_range, bytes_as_span(data) }; + auto spirv = dyn_array { std::from_range, bytes_as_span(data) }; Return TryTransformError(UseNamedConstructors::allocate(std::move(device), std::move(spirv), type), result_to_load_error); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto ShaderImplementation::allocate_and_load_from_bytes(view::Device device, - std::span data, + inline auto ShaderImplementation::allocate_and_load_from_bytes(view::Device device, + byte_view<> data, ShaderStageFlag type) noexcept -> Expected> { - auto spirv = std::vector { std::from_range, bytes_as_span(data) }; + auto spirv = dyn_array { std::from_range, bytes_as_span(data) }; return UseNamedConstructors::allocate(std::move(device), std::move(spirv), type); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto ShaderImplementation::allocate_and_load_from_spirv(view::Device device, - std::span data, + inline auto ShaderImplementation::allocate_and_load_from_spirv(view::Device device, + array_view data, ShaderStageFlag type) noexcept -> Expected> { - auto spirv = std::vector { std::from_range, data }; + auto spirv = dyn_array { std::from_range, data }; return UseNamedConstructors::allocate(std::move(device), std::move(spirv), type); } diff --git a/modules/stormkit/image.cppm b/modules/stormkit/image.cppm index 985b216ba..bc224b3e2 100644 --- a/modules/stormkit/image.cppm +++ b/modules/stormkit/image.cppm @@ -104,7 +104,7 @@ export namespace stormkit::image { UNKNOWN, } reason; - std::string str_error; + string str_error; }; struct ImageData { @@ -116,14 +116,14 @@ export namespace stormkit::image { u32 mip_levels = 1u; Format format = Format::UNDEFINED; - std::vector data = {}; + byte_dyn_array data = {}; }; Image() noexcept; explicit Image(ImageData&& data) noexcept; Image(const math::uextent3& extent, Format format) noexcept; Image(const std::filesystem::path& filepath, Codec codec = Codec::AUTODETECT) noexcept; - Image(std::span data, Codec codec = Codec::AUTODETECT) noexcept; + Image(byte_view<> data, Codec codec = Codec::AUTODETECT) noexcept; ~Image() noexcept; Image(const Image& rhs) noexcept; @@ -136,14 +136,14 @@ export namespace stormkit::image { auto load_from_file(std::filesystem::path filepath, Codec codec = Codec::AUTODETECT) noexcept -> std::expected; [[nodiscard]] - auto load_from_memory(std::span data, Codec codec = Codec::AUTODETECT) noexcept -> std::expected; + auto load_from_memory(byte_view<> data, Codec codec = Codec::AUTODETECT) noexcept -> std::expected; [[nodiscard]] auto save_to_file(std::filesystem::path filename, Codec codec, CodecArgs args = CodecArgs::BINARY) const noexcept -> std::expected; [[nodiscard]] auto save_to_memory(Codec codec, CodecArgs args = CodecArgs::BINARY) const noexcept - -> std::expected, Error>; + -> std::expected; auto create(math::uextent3 extent, Format format) noexcept -> void; @@ -165,13 +165,13 @@ export namespace stormkit::image { auto rotate_270() const noexcept -> Image; [[nodiscard]] - auto pixel(usize id, u32 layer = 0u, u32 face = 0u, u32 level = 0u) noexcept -> std::span; + auto pixel(usize id, u32 layer = 0u, u32 face = 0u, u32 level = 0u) noexcept -> byte_mut_view<>; [[nodiscard]] - auto pixel(usize id, u32 layer = 0u, u32 face = 0u, u32 level = 0u) const noexcept -> std::span; + auto pixel(usize id, u32 layer = 0u, u32 face = 0u, u32 level = 0u) const noexcept -> byte_view<>; [[nodiscard]] - auto pixel(math::uvec3 position, u32 layer = 0u, u32 face = 0u, u32 level = 0u) noexcept -> std::span; + auto pixel(math::uvec3 position, u32 layer = 0u, u32 face = 0u, u32 level = 0u) noexcept -> byte_mut_view<>; [[nodiscard]] - auto pixel(math::uvec3 position, u32 layer = 0u, u32 face = 0u, u32 level = 0u) const noexcept -> std::span; + auto pixel(math::uvec3 position, u32 layer = 0u, u32 face = 0u, u32 level = 0u) const noexcept -> byte_view<>; [[nodiscard]] auto extent(u32 level = 0u) const noexcept -> math::uextent3; @@ -204,13 +204,13 @@ export namespace stormkit::image { auto size(u32 layer) const noexcept -> usize; [[nodiscard]] - auto data() noexcept -> std::span; + auto data() noexcept -> byte_mut_view<>; [[nodiscard]] - auto data(u32 layer, u32 face, u32 level) noexcept -> std::span; + auto data(u32 layer, u32 face, u32 level) noexcept -> byte_mut_view<>; [[nodiscard]] - auto data() const noexcept -> std::span; + auto data() const noexcept -> byte_view<>; [[nodiscard]] - auto data(u32 layer, u32 face, u32 level) const noexcept -> std::span; + auto data(u32 layer, u32 face, u32 level) const noexcept -> byte_view<>; [[nodiscard]] auto begin() noexcept; @@ -268,7 +268,7 @@ export { namespace stormkit::image { ///////////////////////////////////// ///////////////////////////////////// - inline auto Image::pixel(usize index, u32 layer, u32 face, u32 level) noexcept -> std::span { + inline auto Image::pixel(usize index, u32 layer, u32 face, u32 level) noexcept -> byte_mut_view<> { EXPECTS(m_data.mip_levels > level); EXPECTS(m_data.faces > face); EXPECTS(m_data.layers > layer); @@ -284,7 +284,7 @@ namespace stormkit::image { ///////////////////////////////////// ///////////////////////////////////// - inline auto Image::pixel(usize index, u32 layer, u32 face, u32 level) const noexcept -> std::span { + inline auto Image::pixel(usize index, u32 layer, u32 face, u32 level) const noexcept -> byte_view<> { EXPECTS(m_data.mip_levels > level); EXPECTS(m_data.faces > face); EXPECTS(m_data.layers > layer); @@ -301,7 +301,7 @@ namespace stormkit::image { ///////////////////////////////////// ///////////////////////////////////// - inline auto Image::pixel(math::uvec3 position, u32 layer, u32 face, u32 level) noexcept -> std::span { + inline auto Image::pixel(math::uvec3 position, u32 layer, u32 face, u32 level) noexcept -> byte_mut_view<> { const auto mip_extent = extent(level); const auto id = position.x + (position.y * mip_extent.width) + (mip_extent.width * mip_extent.height * position.z); @@ -311,7 +311,7 @@ namespace stormkit::image { ///////////////////////////////////// ///////////////////////////////////// - inline auto Image::pixel(math::uvec3 position, u32 layer, u32 face, u32 level) const noexcept -> std::span { + inline auto Image::pixel(math::uvec3 position, u32 layer, u32 face, u32 level) const noexcept -> byte_view<> { const auto mip_extent = extent(level); const auto id = position.x + (position.y * mip_extent.width) + (mip_extent.width * mip_extent.height * position.z); @@ -405,13 +405,13 @@ namespace stormkit::image { ///////////////////////////////////// ///////////////////////////////////// - inline auto Image::data() noexcept -> std::span { + inline auto Image::data() noexcept -> byte_mut_view<> { return m_data.data; } ///////////////////////////////////// ///////////////////////////////////// - inline auto Image::data(u32 layer, u32 face, u32 level) noexcept -> std::span { + inline auto Image::data(u32 layer, u32 face, u32 level) noexcept -> byte_mut_view<> { const auto mip_size = size(layer, face, level); auto offset = usize { 0 }; @@ -427,13 +427,13 @@ namespace stormkit::image { ///////////////////////////////////// ///////////////////////////////////// - inline auto Image::data() const noexcept -> std::span { + inline auto Image::data() const noexcept -> byte_view<> { return m_data.data; } ///////////////////////////////////// ///////////////////////////////////// - inline auto Image::data(u32 layer, u32 face, u32 level) const noexcept -> std::span { + inline auto Image::data(u32 layer, u32 face, u32 level) const noexcept -> byte_view<> { const auto mip_size = size(layer, face, level); auto offset = usize { 0 }; diff --git a/modules/stormkit/log.cppm b/modules/stormkit/log.cppm index a6eb7749c..2de7f54cf 100644 --- a/modules/stormkit/log.cppm +++ b/modules/stormkit/log.cppm @@ -29,12 +29,12 @@ export { }; [[nodiscard]] - constexpr auto as_string(Severity severity) noexcept -> std::string_view; + constexpr auto as_string(Severity severity) noexcept -> string_view; [[nodiscard]] - constexpr auto to_string(Severity severity) noexcept -> std::string; + constexpr auto to_string(Severity severity) noexcept -> string; STORMKIT_LOG_API - auto parse_args(std::span args) noexcept -> void; + auto parse_args(array_view args) noexcept -> void; class STORMKIT_LOG_API Logger { public: @@ -44,7 +44,7 @@ export { Logger(LogClock::time_point start, Severity log_level) noexcept; virtual ~Logger() noexcept; - virtual auto write(Severity severity, const Module& module, CZString string) noexcept -> void = 0; + virtual auto write(Severity severity, const Module& module, czstring string) noexcept -> void = 0; virtual auto flush() noexcept -> void = 0; auto set_log_level(Severity log_level) noexcept -> void; @@ -66,13 +66,11 @@ export { static auto allocate_logger_instance(Args&&... param_args) noexcept -> Heap; template - static auto log(Severity severity, - const Module& module, - std::string_view format_string, - Args&&... param_args) noexcept -> void; + static auto log(Severity severity, const Module& module, string_view format_string, Args&&... param_args) noexcept + -> void; template - static auto log(Severity severity, std::string_view format_string, Args&&... param_args) noexcept -> void; + static auto log(Severity severity, string_view format_string, Args&&... param_args) noexcept -> void; template static auto dlog(Args&&... param_args) noexcept -> void; @@ -119,7 +117,7 @@ export { auto flush() const noexcept -> void; - std::string_view name = ""; + string_view name = ""; }; template @@ -138,11 +136,11 @@ export { FileLogger(FileLogger&&) noexcept = delete; auto operator=(FileLogger&&) noexcept -> FileLogger& = delete; - auto write(Severity severity, const Module& module, CZString string) noexcept -> void override; + auto write(Severity severity, const Module& module, czstring string) noexcept -> void override; auto flush() noexcept -> void override; private: - StringHashMap m_streams; + string_hash_map m_streams; std::filesystem::path m_base_path; }; @@ -160,7 +158,7 @@ export { ~ConsoleLogger() noexcept override; - auto write(Severity severity, const Module& module, CZString string) noexcept -> void override; + auto write(Severity severity, const Module& module, czstring string) noexcept -> void override; auto flush() noexcept -> void override; }; } // namespace stormkit::log @@ -177,7 +175,7 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto as_string(Severity severity) noexcept -> std::string_view { + constexpr auto as_string(Severity severity) noexcept -> string_view { switch (severity) { case Severity::INFO: return "Severity::INFO"; case Severity::WARNING: return "Severity::WARNING"; @@ -193,8 +191,8 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto to_string(Severity severity) noexcept -> std::string { - return std::string { as_string(severity) }; + constexpr auto to_string(Severity severity) noexcept -> string { + return string { as_string(severity) }; } //////////////////////////////////////// @@ -251,14 +249,14 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// template - inline auto Logger::log(Severity severity, const Module& m, std::string_view format_string, Args&&... param_args) noexcept + inline auto Logger::log(Severity severity, const Module& m, string_view format_string, Args&&... param_args) noexcept -> void { EXPECTS(has_logger()); const auto log_level = instance().log_level(); if (not check_flag_bit(log_level, severity)) return; - auto memory_buffer = std::string {}; + auto memory_buffer = string {}; memory_buffer.reserve(std::size(format_string)); std::vformat_to(std::back_inserter(memory_buffer), format_string, std::make_format_args(param_args...)); @@ -280,7 +278,7 @@ namespace stormkit::log { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Logger::log(Severity severity, std::string_view format_string, Args&&... param_args) noexcept -> void { + inline auto Logger::log(Severity severity, string_view format_string, Args&&... param_args) noexcept -> void { log(severity, Module {}, format_string, std::forward(param_args)...); } diff --git a/modules/stormkit/lua.cppm b/modules/stormkit/lua.cppm index 8f498c7c4..dcc67ce83 100644 --- a/modules/stormkit/lua.cppm +++ b/modules/stormkit/lua.cppm @@ -59,7 +59,7 @@ export namespace stormkit::lua { Modules m_modules; InitUserLibrariesClosure m_init_user_libraries; - std::vector m_script; + dyn_array m_script; }; template diff --git a/modules/stormkit/test.cppm b/modules/stormkit/test.cppm index 7b0163cd5..355130440 100644 --- a/modules/stormkit/test.cppm +++ b/modules/stormkit/test.cppm @@ -16,32 +16,32 @@ import stormkit.core; import std; import frozen; +using namespace stormkit; + export namespace test { struct TestFunc { - std::string name; + string name; std::function func; }; struct TestSuiteHolder { - auto hasTest(std::string_view name) noexcept; - auto runTest(std::string_view name) noexcept; - auto runTests() noexcept; - std::string name; - std::vector tests; - std::source_location location; + auto hasTest(string_view name) noexcept; + auto runTest(string_view name) noexcept; + auto runTests() noexcept; + string name; + dyn_array tests; + std::source_location location; }; struct TestSuite { - TestSuite(std::string&& name, - std::vector&& tests, + TestSuite(string&& name, + dyn_array&& tests, const std::source_location& location = std::source_location::current()) noexcept; }; - auto expects(bool cond, - std::string_view message, - const std::source_location& location = std::source_location::current()) noexcept; + auto expects(bool cond, string_view message, const std::source_location& location = std::source_location::current()) noexcept; - auto parse_args(std::span args) noexcept -> void; + auto parse_args(array_view args) noexcept -> void; auto runTests() noexcept -> int; } // namespace test @@ -58,26 +58,25 @@ namespace test { }; struct TestState { - std::vector> test_suites; - bool verbose = false; - bool failed = false; - bool plain = false; - std::optional requested_test = std::nullopt; + dyn_array> test_suites; + bool verbose = false; + bool failed = false; + bool plain = false; + std::optional requested_test = std::nullopt; }; namespace { - constexpr auto StyleMap = frozen::make_unordered_map({ - { Status::Passed, stormkit::ConsoleStyle { .fg = stormkit::ConsoleColor::BLACK, .bg = stormkit::ConsoleColor::GREEN } }, - { Status::NotPassed, - stormkit::ConsoleStyle { .fg = stormkit::ConsoleColor::BLACK, .bg = stormkit::ConsoleColor::RED } }, + constexpr auto StyleMap = frozen::make_unordered_map({ + { Status::Passed, ConsoleStyle { .fg = ConsoleColor::BLACK, .bg = ConsoleColor::GREEN } }, + { Status::NotPassed, ConsoleStyle { .fg = ConsoleColor::BLACK, .bg = ConsoleColor::RED } }, { Status::CheckMark, - stormkit::ConsoleStyle { - .fg = stormkit::ConsoleColor::GREEN, - } }, + ConsoleStyle { + .fg = ConsoleColor::GREEN, + } }, { Status::CrossMark, - stormkit::ConsoleStyle { - .fg = stormkit::ConsoleColor::RED, - } }, + ConsoleStyle { + .fg = ConsoleColor::RED, + } }, }); constexpr auto passed = StyleMap.at(Status::Passed) | "Passed"sv; @@ -88,7 +87,7 @@ namespace test { auto state = TestState {}; - auto TestSuiteHolder::hasTest(std::string_view _name) noexcept { + auto TestSuiteHolder::hasTest(string_view _name) noexcept { for (auto&& test : tests) { if (test.name == _name) return true; } @@ -96,7 +95,7 @@ namespace test { return false; } - auto TestSuiteHolder::runTest(std::string_view _name) noexcept { + auto TestSuiteHolder::runTest(string_view _name) noexcept { for (auto&& test : tests) { if (test.name == _name) { if (state.verbose) std::println(" running test {}", test.name); @@ -137,11 +136,11 @@ namespace test { return failed_tests == 0; } - TestSuite::TestSuite(std::string&& _name, std::vector&& tests, const std::source_location& location) noexcept { + TestSuite::TestSuite(string&& _name, dyn_array&& tests, const std::source_location& location) noexcept { state.test_suites.emplace_back(std::make_unique(std::move(_name), std::move(tests), location)); } - auto expects(bool cond, std::string_view message, const std::source_location& location) noexcept { + auto expects(bool cond, string_view message, const std::source_location& location) noexcept { if (not cond) [[unlikely]] { state.failed = true; if (state.verbose) { @@ -154,16 +153,16 @@ namespace test { } } - auto split(std::string_view string, char delim) noexcept -> std::vector { - auto output = std::vector {}; + auto split(string_view str, char delim) noexcept -> dyn_array { + auto output = dyn_array {}; auto first = std::size_t { 0u }; - while (first < string.size()) { - const auto second = string.find_first_of(delim, first); + while (first < str.size()) { + const auto second = str.find_first_of(delim, first); - if (first != second) output.emplace_back(string.substr(first, second - first)); + if (first != second) output.emplace_back(str.substr(first, second - first)); - if (second == std::string_view::npos) break; + if (second == string_view::npos) break; first = second + 1; } @@ -171,7 +170,7 @@ namespace test { return output; } - auto parse_args(std::span args) noexcept -> void { + auto parse_args(array_view args) noexcept -> void { for (auto&& arg : args) { if (arg == "--verbose" or arg == "-v") state.verbose = true; else if (arg == "--plain" or arg == "-p") diff --git a/modules/stormkit/wsi/core.cppm b/modules/stormkit/wsi/core.cppm index b27546f42..2a81971ec 100644 --- a/modules/stormkit/wsi/core.cppm +++ b/modules/stormkit/wsi/core.cppm @@ -26,11 +26,11 @@ export namespace stormkit::wsi { SWITCH, }; - constexpr auto as_string(WM wm) noexcept -> std::string_view; - constexpr auto to_string(WM wm) noexcept -> std::string; + constexpr auto as_string(WM wm) noexcept -> string_view; + constexpr auto to_string(WM wm) noexcept -> string; STORMKIT_WSI_API - auto parse_args(std::span args) noexcept -> void; + auto parse_args(array_view args) noexcept -> void; [[nodiscard]] STORMKIT_WSI_API auto wm() noexcept -> WM; @@ -44,7 +44,7 @@ namespace stormkit::wsi { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto as_string(WM wm) noexcept -> std::string_view { + constexpr auto as_string(WM wm) noexcept -> string_view { switch (wm) { case WM::WIN32: return "WM::WIN32"; case WM::WAYLAND: return "WM::WAYLAND"; @@ -63,7 +63,7 @@ namespace stormkit::wsi { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto to_string(WM wm) noexcept -> std::string { - return std::string { as_string(wm) }; + constexpr auto to_string(WM wm) noexcept -> string { + return string { as_string(wm) }; } } // namespace stormkit::wsi diff --git a/modules/stormkit/wsi/keyboard.cppm b/modules/stormkit/wsi/keyboard.cppm index 65fef7783..e01b8b205 100644 --- a/modules/stormkit/wsi/keyboard.cppm +++ b/modules/stormkit/wsi/keyboard.cppm @@ -142,8 +142,8 @@ export namespace stormkit::wsi { UNKNOWN = std::numeric_limits::max(), }; - constexpr auto as_string(Key key) noexcept -> std::string_view; - constexpr auto to_string(Key key) noexcept -> std::string; + constexpr auto as_string(Key key) noexcept -> string_view; + constexpr auto to_string(Key key) noexcept -> string; } // namespace stormkit::wsi //////////////////////////////////////////////////////////////////// @@ -154,7 +154,7 @@ namespace stormkit::wsi { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto as_string(Key key) noexcept -> std::string_view { + constexpr auto as_string(Key key) noexcept -> string_view { switch (key) { case Key::A: return "Key::A"; case Key::B: return "Key::B"; @@ -288,7 +288,7 @@ namespace stormkit::wsi { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto to_string(Key key) noexcept -> std::string { - return std::string { as_string(key) }; + constexpr auto to_string(Key key) noexcept -> string { + return string { as_string(key) }; } } // namespace stormkit::wsi diff --git a/modules/stormkit/wsi/monitor.cppm b/modules/stormkit/wsi/monitor.cppm index fa7bde96c..4f4087d4c 100644 --- a/modules/stormkit/wsi/monitor.cppm +++ b/modules/stormkit/wsi/monitor.cppm @@ -23,11 +23,11 @@ export { PRIMARY, }; - Flags flags = Flags::NONE; - std::string name; + Flags flags = Flags::NONE; + string name; - std::vector extents; - u32 scale_factor = 1; + dyn_array extents; + u32 scale_factor = 1; [[nodiscard]] constexpr auto operator<=>(const Monitor& other) const noexcept -> std::strong_ordering; @@ -38,16 +38,16 @@ export { void* native_handle = nullptr; }; - constexpr auto as_string(Monitor::Flags flags) noexcept -> std::string_view; - constexpr auto to_string(Monitor::Flags flags) noexcept -> std::string; + constexpr auto as_string(Monitor::Flags flags) noexcept -> string_view; + constexpr auto to_string(Monitor::Flags flags) noexcept -> string; - auto to_string(const Monitor& monitor) noexcept -> std::string; + auto to_string(const Monitor& monitor) noexcept -> string; template auto format_as(const Monitor& monitor, FormatContext& ctx) noexcept -> decltype(ctx.out()); [[nodiscard]] - STORMKIT_WSI_API auto get_monitors(bool update = false) noexcept -> std::span; + STORMKIT_WSI_API auto get_monitors(bool update = false) noexcept -> array_view; [[nodiscard]] STORMKIT_WSI_API auto get_primary_monitor() noexcept -> const Monitor&; @@ -105,7 +105,7 @@ namespace stormkit::wsi { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto as_string(Monitor::Flags flags) noexcept -> std::string_view { + constexpr auto as_string(Monitor::Flags flags) noexcept -> string_view { switch (flags) { case Monitor::Flags::NONE: return "Monitor::Flags::NONE"; case Monitor::Flags::PRIMARY: return "Monitor::Flags::PRIMARY"; @@ -118,14 +118,14 @@ namespace stormkit::wsi { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto to_string(Monitor::Flags flags) noexcept -> std::string { - return std::string { as_string(flags) }; + constexpr auto to_string(Monitor::Flags flags) noexcept -> string { + return string { as_string(flags) }; } //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto to_string(const Monitor& monitor) noexcept -> std::string { + inline auto to_string(const Monitor& monitor) noexcept -> string { return std::format("{}", monitor); } diff --git a/modules/stormkit/wsi/mouse.cppm b/modules/stormkit/wsi/mouse.cppm index d3785f005..77c1f4af2 100644 --- a/modules/stormkit/wsi/mouse.cppm +++ b/modules/stormkit/wsi/mouse.cppm @@ -33,8 +33,8 @@ export namespace stormkit::wsi { BUTTON_12, }; - constexpr auto as_string(MouseButton button) noexcept -> std::string_view; - constexpr auto to_string(MouseButton button) noexcept -> std::string; + constexpr auto as_string(MouseButton button) noexcept -> string_view; + constexpr auto to_string(MouseButton button) noexcept -> string; } // namespace stormkit::wsi //////////////////////////////////////////////////////////////////// @@ -45,7 +45,7 @@ namespace stormkit::wsi { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto as_string(MouseButton button) noexcept -> std::string_view { + constexpr auto as_string(MouseButton button) noexcept -> string_view { switch (button) { case MouseButton::LEFT: return "MouseButton::LEFT"; case MouseButton::RIGHT: return "MouseButton::RIGHT"; @@ -71,7 +71,7 @@ namespace stormkit::wsi { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto to_string(MouseButton button) noexcept -> std::string { - return std::string { as_string(button) }; + constexpr auto to_string(MouseButton button) noexcept -> string { + return string { as_string(button) }; } } // namespace stormkit::wsi diff --git a/modules/stormkit/wsi/window.cppm b/modules/stormkit/wsi/window.cppm index a588513be..d2f491cd8 100644 --- a/modules/stormkit/wsi/window.cppm +++ b/modules/stormkit/wsi/window.cppm @@ -38,8 +38,8 @@ export { RESIZEABLE = 0b100, EXTERNAL_CONTEXT = 0b1000, }; - constexpr auto as_string(WindowFlag button) noexcept -> std::string_view; - constexpr auto to_string(WindowFlag button) noexcept -> std::string; + constexpr auto as_string(WindowFlag button) noexcept -> string_view; + constexpr auto to_string(WindowFlag button) noexcept -> string; enum class EventType : u8 { NONE = 0, @@ -56,8 +56,8 @@ export { ACTIVATE, DEACTIVATE, }; - constexpr auto as_string(EventType type) noexcept -> std::string_view; - constexpr auto to_string(EventType type) noexcept -> std::string; + constexpr auto as_string(EventType type) noexcept -> string_view; + constexpr auto to_string(EventType type) noexcept -> string; using NativeHandle = void*; @@ -132,9 +132,8 @@ export { Window(Window&&) noexcept; auto operator=(Window&&) noexcept -> Window&; - static auto open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> Window; - static auto allocate_and_open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept - -> Heap; + static auto open(string title, const math::uextent2& size, WindowFlag flags) noexcept -> Window; + static auto allocate_and_open(string title, const math::uextent2& size, WindowFlag flags) noexcept -> Heap; auto close() noexcept -> void; [[nodiscard]] @@ -142,7 +141,7 @@ export { auto handle_events() noexcept -> void; auto clear(const ucolor_rgb& color = colors::BLACK) noexcept -> void; - auto fill_framebuffer(std::span colors) noexcept -> void; + auto fill_framebuffer(array_view colors) noexcept -> void; template auto on(T&& callback) noexcept -> void; @@ -161,8 +160,8 @@ export { auto current_monitor() const noexcept -> const Monitor&; [[nodiscard]] - auto title() const noexcept -> const std::string&; - auto set_title(std::string title) noexcept -> void; + auto title() const noexcept -> const string&; + auto set_title(string title) noexcept -> void; auto set_extent(const math::uextent2& extent) noexcept -> void; @@ -257,8 +256,8 @@ namespace stormkit::wsi { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto as_string(WindowFlag flag) noexcept -> std::string_view { - using Pair = std::pair; + constexpr auto as_string(WindowFlag flag) noexcept -> string_view { + using Pair = std::pair; static constexpr auto MAPPING = core::generate_substitutions_as_string_for( "WindowFlag::", { @@ -276,14 +275,14 @@ namespace stormkit::wsi { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto to_string(WindowFlag flag) noexcept -> std::string { - return std::string { as_string(flag) }; + constexpr auto to_string(WindowFlag flag) noexcept -> string { + return string { as_string(flag) }; } //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_CONST - constexpr auto as_string(EventType type) noexcept -> std::string_view { + constexpr auto as_string(EventType type) noexcept -> string_view { switch (type) { case EventType::NONE: return "EventType::NONE"; case EventType::CLOSED: return "EventType::CLOSED"; @@ -306,8 +305,8 @@ namespace stormkit::wsi { //////////////////////////////////////// //////////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr auto to_string(EventType type) noexcept -> std::string { - return std::string { as_string(type) }; + constexpr auto to_string(EventType type) noexcept -> string { + return string { as_string(type) }; } //////////////////////////////////////// diff --git a/src/core/contract.cppm b/src/core/contract.cppm index c9b05c851..9b112ef99 100644 --- a/src/core/contract.cppm +++ b/src/core/contract.cppm @@ -21,8 +21,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - auto assert_base(bool cond, AssertType type, std::string_view message, const std::source_location& location) noexcept - -> void { + auto assert_base(bool cond, AssertType type, string_view message, const std::source_location& location) noexcept -> void { if constexpr (STORMKIT_ASSERT == 1) { constexpr auto ASSERTION_PREFIX = ConsoleStyle { .fg = ConsoleColor::BRIGHT_RED, diff --git a/src/core/darwin/threadutils.cpp b/src/core/darwin/threadutils.cpp index 61d1bf0e2..377d04402 100644 --- a/src/core/darwin/threadutils.cpp +++ b/src/core/darwin/threadutils.cpp @@ -13,39 +13,39 @@ import :parallelism.threadutils; namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - auto set_current_thread_name(std::string_view name) noexcept -> void { + auto set_current_thread_name(string_view name) noexcept -> void { setCurrentNSThreadName(std::data(name)); } //////////////////////////////////////// //////////////////////////////////////// - auto set_thread_name(std::thread&, std::string_view) noexcept -> void { + auto set_thread_name(std::thread&, string_view) noexcept -> void { // auto id = thread.native_handle(); // details::set_thread_name(id, name); } //////////////////////////////////////// //////////////////////////////////////// - auto set_thread_name(std::jthread&, std::string_view) noexcept -> void { + auto set_thread_name(std::jthread&, string_view) noexcept -> void { // auto id = thread.native_handle(); // details::set_thread_name(id, name); } //////////////////////////////////////// //////////////////////////////////////// - auto get_current_thread_name() noexcept -> std::string { + auto get_current_thread_name() noexcept -> string { return {}; } //////////////////////////////////////// //////////////////////////////////////// - auto get_thread_name(std::thread&) noexcept -> std::string { + auto get_thread_name(std::thread&) noexcept -> string { return {}; } //////////////////////////////////////// //////////////////////////////////////// - auto get_thread_name(std::jthread&) noexcept -> std::string { + auto get_thread_name(std::jthread&) noexcept -> string { return {}; } }} // namespace stormkit::core diff --git a/src/core/dynamic_loader.cpp b/src/core/dynamic_loader.cpp index 061f80b7e..b792a89ef 100644 --- a/src/core/dynamic_loader.cpp +++ b/src/core/dynamic_loader.cpp @@ -57,7 +57,7 @@ namespace stormkit { ///////////////////////////////////// ///////////////////////////////////// - auto DynamicLoader::do_get_func(std::string_view name) const -> Expected { + auto DynamicLoader::do_get_func(string_view name) const -> Expected { EXPECTS(m_library_handle); #ifdef STORMKIT_OS_WINDOWS auto func = ::GetProcAddress(std::bit_cast(m_library_handle), std::data(name)); diff --git a/src/core/linux/threadutils.cpp b/src/core/linux/threadutils.cpp index ff63e79b6..fd7bee48f 100644 --- a/src/core/linux/threadutils.cpp +++ b/src/core/linux/threadutils.cpp @@ -11,56 +11,56 @@ namespace stormkit { inline namespace core { namespace details { //////////////////////////////////////// //////////////////////////////////////// - auto set_thread_name(pthread_t id, std::string_view name) noexcept -> void { + auto set_thread_name(pthread_t id, string_view name) noexcept -> void { pthread_setname_np(id, std::data(name)); } //////////////////////////////////////// //////////////////////////////////////// - auto get_thread_name(pthread_t id) noexcept -> std::string { - auto name = std::array {}; + auto get_thread_name(pthread_t id) noexcept -> string { + auto name = array {}; pthread_getname_np(id, std::data(name), std::size(name)); - return std::string { std::begin(name), std::begin(name) + std::strlen(std::data(name)) }; + return string { std::begin(name), std::begin(name) + std::strlen(std::data(name)) }; } } // namespace details //////////////////////////////////////// //////////////////////////////////////// - auto set_current_thread_name(std::string_view name) noexcept -> void { + auto set_current_thread_name(string_view name) noexcept -> void { prctl(PR_SET_NAME, stdr::data(name), 0, 0, 0); } //////////////////////////////////////// //////////////////////////////////////// - auto set_thread_name(std::thread& thread, std::string_view name) noexcept -> void { + auto set_thread_name(std::thread& thread, string_view name) noexcept -> void { const auto id = thread.native_handle(); details::set_thread_name(id, name); } //////////////////////////////////////// //////////////////////////////////////// - auto set_thread_name(std::jthread& thread, std::string_view name) noexcept -> void { + auto set_thread_name(std::jthread& thread, string_view name) noexcept -> void { const auto id = thread.native_handle(); details::set_thread_name(id, name); } //////////////////////////////////////// //////////////////////////////////////// - auto get_current_thread_name() noexcept -> std::string { + auto get_current_thread_name() noexcept -> string { const auto id = pthread_self(); return details::get_thread_name(id); } //////////////////////////////////////// //////////////////////////////////////// - auto get_thread_name(std::thread& thread) noexcept -> std::string { + auto get_thread_name(std::thread& thread) noexcept -> string { const auto id = thread.native_handle(); return details::get_thread_name(id); } //////////////////////////////////////// //////////////////////////////////////// - auto get_thread_name(std::jthread& thread) noexcept -> std::string { + auto get_thread_name(std::jthread& thread) noexcept -> string { const auto id = thread.native_handle(); return details::get_thread_name(id); } diff --git a/src/core/posix/shmbuffer.cpp b/src/core/posix/shmbuffer.cpp index b41215883..b7aa4cf4b 100644 --- a/src/core/posix/shmbuffer.cpp +++ b/src/core/posix/shmbuffer.cpp @@ -30,7 +30,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - auto SHMBuffer::do_init(PrivateTag, usize size, std::string name, io::Access access) noexcept + auto SHMBuffer::do_init(PrivateTag, usize size, string name, io::Access access) noexcept -> std::expected { m_size = size; m_name = std::move(name); @@ -67,7 +67,7 @@ namespace stormkit { inline namespace core { std::error_code { as(errno), std::system_category() } }; - m_data = { std::bit_cast(buf), m_size }; + m_data = { std::bit_cast(buf), m_size }; return {}; } diff --git a/src/core/stacktrace.cpp b/src/core/stacktrace.cpp index abc336e76..4bf8f2b20 100644 --- a/src/core/stacktrace.cpp +++ b/src/core/stacktrace.cpp @@ -20,8 +20,8 @@ import :console; import :string.operations; namespace stormkit { inline namespace core { - auto prettify(std::string_view str) -> std::string { - auto out = std::string { str }; + auto prettify(string_view str) -> string { + auto out = string { str }; out = replace(out, "::__1::", "::"); out = replace(out, "::$_0::", "::"); out = replace(out, "__invoke", "invoke"); diff --git a/src/core/win32/shmbuffer.cpp b/src/core/win32/shmbuffer.cpp index cfacf1e5d..a8ea6c76d 100644 --- a/src/core/win32/shmbuffer.cpp +++ b/src/core/win32/shmbuffer.cpp @@ -26,7 +26,7 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - auto SHMBuffer::do_init(PrivateTag, usize size, std::string name, io::Access access) noexcept + auto SHMBuffer::do_init(PrivateTag, usize size, string name, io::Access access) noexcept -> std::expected { m_size = size; m_name = std::move(name); @@ -56,7 +56,7 @@ namespace stormkit { inline namespace core { std::error_code { as(GetLastError()), std::system_category() } }; - m_data = { std::bit_cast(buf), m_size }; + m_data = { std::bit_cast(buf), m_size }; return {}; } diff --git a/src/core/win32/threadutils.cpp b/src/core/win32/threadutils.cpp index b2cdcab42..88bb97c0d 100644 --- a/src/core/win32/threadutils.cpp +++ b/src/core/win32/threadutils.cpp @@ -25,7 +25,7 @@ namespace stormkit { inline namespace core { namespace details { //////////////////////////////////////// //////////////////////////////////////// - auto set_thread_name(HANDLE handle, std::string_view name) noexcept -> void { + auto set_thread_name(HANDLE handle, string_view name) noexcept -> void { const auto id = ::GetThreadId(handle); auto info = ThreadNameInfo { .szName = std::data(name), .dwThreadId = id }; @@ -39,11 +39,11 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - auto get_thread_name(HANDLE handle) noexcept -> std::string { + auto get_thread_name(HANDLE handle) noexcept -> string { auto data = PWSTR { nullptr }; const auto hr = GetThreadDescription(handle, &data); - auto out = std::string {}; + auto out = string {}; if (SUCCEEDED(hr)) { out = wide_to_ascii(data); @@ -63,42 +63,42 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - auto set_current_thread_name(std::string_view name) noexcept -> void { + auto set_current_thread_name(string_view name) noexcept -> void { const auto handle = ::GetCurrentThread(); details::set_thread_name(handle, name); } //////////////////////////////////////// //////////////////////////////////////// - auto set_thread_name(std::thread& thread, std::string_view name) noexcept -> void { + auto set_thread_name(std::thread& thread, string_view name) noexcept -> void { const auto handle = details::getThreadHandle(thread); details::set_thread_name(handle, name); } //////////////////////////////////////// //////////////////////////////////////// - auto set_thread_name(std::jthread& thread, std::string_view name) noexcept -> void { + auto set_thread_name(std::jthread& thread, string_view name) noexcept -> void { const auto handle = details::getThreadHandle(thread); details::set_thread_name(handle, name); } //////////////////////////////////////// //////////////////////////////////////// - auto get_current_thread_name() noexcept -> std::string { + auto get_current_thread_name() noexcept -> string { const auto handle = ::GetCurrentThread(); return details::get_thread_name(handle); } //////////////////////////////////////// //////////////////////////////////////// - auto get_thread_name(std::thread& thread) noexcept -> std::string { + auto get_thread_name(std::thread& thread) noexcept -> string { const auto handle = details::getThreadHandle(thread); return details::get_thread_name(handle); } //////////////////////////////////////// //////////////////////////////////////// - auto get_thread_name(std::jthread& thread) noexcept -> std::string { + auto get_thread_name(std::jthread& thread) noexcept -> string { const auto handle = details::getThreadHandle(thread); return details::get_thread_name(handle); } diff --git a/src/entities/system.cpp b/src/entities/system.cpp index dc5257ff6..a021e3def 100644 --- a/src/entities/system.cpp +++ b/src/entities/system.cpp @@ -15,7 +15,7 @@ import stormkit.core; namespace stormkit::entities { ///////////////////////////////////// ///////////////////////////////////// - System::System(std::string name, ComponentTypes types, Closures&& closures) noexcept + System::System(string name, ComponentTypes types, Closures&& closures) noexcept : m_name { std::move(name) }, m_types { std::move(types) }, m_closures { std::move(closures) } { } diff --git a/src/gpu/core/device.cpp b/src/gpu/core/device.cpp index f84b858dd..8e5763cb6 100644 --- a/src/gpu/core/device.cpp +++ b/src/gpu/core/device.cpp @@ -28,7 +28,7 @@ namespace stdv = std::views; namespace cmonadic = stormkit::core::monadic; namespace { - constexpr auto RAYTRACING_EXTENSIONS = to_array({ + constexpr auto RAYTRACING_EXTENSIONS = to_array({ VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, VK_KHR_BUFFER_DEVICE_ADDRESS_EXTENSION_NAME, @@ -38,12 +38,12 @@ namespace { VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME, }); - constexpr auto BASE_EXTENSIONS = to_array({ + constexpr auto BASE_EXTENSIONS = to_array({ VK_KHR_MAINTENANCE_3_EXTENSION_NAME, VK_KHR_MAINTENANCE_4_EXTENSION_NAME, VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME, }); - constexpr auto SWAPCHAIN_EXTENSIONS = to_array({ + constexpr auto SWAPCHAIN_EXTENSIONS = to_array({ VK_KHR_SWAPCHAIN_EXTENSION_NAME, }); @@ -210,7 +210,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto DeviceInterface::wait_for_fences(std::span fences, + auto DeviceInterface::wait_for_fences(array_view fences, bool wait_all, const std::chrono::milliseconds& timeout) const noexcept -> Expected { const auto device_table = this->device_table(); @@ -229,7 +229,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto DeviceInterface::reset_fences(std::span fences) const noexcept -> Expected { + auto DeviceInterface::reset_fences(array_view fences) const noexcept -> Expected { const auto device_table = this->device_table(); const auto _fences = transform(fences, vk::monadic::to_vk()); @@ -240,7 +240,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto DeviceInterface::set_object_name(u64 object, DebugObjectType type, std::string_view name) const noexcept + auto DeviceInterface::set_object_name(u64 object, DebugObjectType type, string_view name) const noexcept -> Expected { if (not vkSetDebugUtilsObjectNameEXT) return {}; @@ -266,7 +266,7 @@ namespace stormkit::gpu { const auto& queue_families = physical_device.queue_families(); auto i = 0_u32; - auto priorities = std::vector> {}; + auto priorities = dyn_array> {}; priorities.reserve(stdr::size(queue_families)); const auto queue_create_infos = transform(queue_families, [this, &i, &priorities](const auto& family) noexcept { auto& priority = priorities.emplace_back(); @@ -410,7 +410,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// auto imgui_vk_loader(const char* _func_name, void* user_data) noexcept -> PFN_vkVoidFunction { - const auto func_name = std::string_view { _func_name }; + const auto func_name = string_view { _func_name }; const auto& device = *std::bit_cast(user_data); const auto device_table = device.device_table(); diff --git a/src/gpu/core/instance.cpp b/src/gpu/core/instance.cpp index 9dd202811..d978aa50b 100644 --- a/src/gpu/core/instance.cpp +++ b/src/gpu/core/instance.cpp @@ -27,32 +27,32 @@ namespace cmonadic = stormkit::core::monadic; namespace stormkit::gpu { namespace { - constexpr auto VALIDATION_LAYERS = into_array_of("VK_LAYER_KHRONOS_validation", + constexpr auto VALIDATION_LAYERS = into_array_of("VK_LAYER_KHRONOS_validation", // "VK_LAYER_LUNARG_api_dump", "VK_LAYER_LUNARG_monitor" // "VK_LAYER_MESA_overlay", ); // [[maybe_unused]] - // constexpr auto VALIDATION_FEATURES = into_array_of(VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT, + // constexpr auto VALIDATION_FEATURES = into_array_of(VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT, // VK_VALIDATION_FEATURE_ENABLE_GPU_ASSISTED_EXT); constexpr auto STORMKIT_VK_VERSION = vk::make_version(STORMKIT_MAJOR_VERSION, STORMKIT_MINOR_VERSION, STORMKIT_PATCH_VERSION); - constexpr auto BASE_EXTENSIONS = into_array_of(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME + constexpr auto BASE_EXTENSIONS = into_array_of(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME #ifdef STORMKIT_OS_APPLE , VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME #endif ); - constexpr auto SURFACE_EXTENSIONS = into_array_of(VK_KHR_SURFACE_EXTENSION_NAME, + constexpr auto SURFACE_EXTENSIONS = into_array_of(VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME // VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME, ); - constexpr auto WSI_SURFACE_EXTENSIONS = into_array_of( + constexpr auto WSI_SURFACE_EXTENSIONS = into_array_of( #ifdef STORMKIT_OS_WINDOWS VK_KHR_WIN32_SURFACE_EXTENSION_NAME #elif defined(STORMKIT_OS_LINUX) @@ -67,10 +67,9 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto check_extension_support(std::span supported_extensions, - std::span extensions) noexcept - -> std::optional> { - auto required_extensions = HashSet { stdr::begin(extensions), stdr::end(extensions) }; + auto check_extension_support(array_view supported_extensions, + array_view extensions) noexcept -> std::optional> { + auto required_extensions = hash_set { stdr::begin(extensions), stdr::end(extensions) }; for (const auto& extension : supported_extensions) required_extensions.erase(extension); @@ -81,9 +80,9 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto check_extension_support(std::span supported_extensions, - std::span extensions) noexcept -> std::optional> { - const auto ext = transform(extensions, cmonadic::init()); + auto check_extension_support(array_view supported_extensions, + array_view extensions) noexcept -> std::optional> { + const auto ext = transform(extensions, cmonadic::init()); return check_extension_support(supported_extensions, ext); } } // namespace @@ -93,16 +92,15 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto InstanceImplementation::do_init(PrivateTag, std::string app_name, bool validation_layers_enabled) noexcept - -> Expected { + auto InstanceImplementation::do_init(PrivateTag, string app_name, bool validation_layers_enabled) noexcept -> Expected { const auto exts = Try(vk::enumerate_checked(vkEnumerateInstanceExtensionProperties, nullptr)); - m_extensions = transform(exts, [](const auto& ext) static noexcept { return std::string { ext.extensionName }; }); + m_extensions = transform(exts, [](const auto& ext) static noexcept { return string { ext.extensionName }; }); const auto validation_layers = validation_layers_enabled - ? std::vector() + ? dyn_array() : transform_if( Try(vk::enumerate_checked(vkEnumerateInstanceLayerProperties)), [](const auto& layer) static noexcept { - return stdr::contains(VALIDATION_LAYERS, std::string_view { layer.layerName }); + return stdr::contains(VALIDATION_LAYERS, string_view { layer.layerName }); }, [](const auto& layer) static noexcept { return layer.layerName; }); diff --git a/src/gpu/core/physical_device.cpp b/src/gpu/core/physical_device.cpp index 579f79912..4937ededf 100644 --- a/src/gpu/core/physical_device.cpp +++ b/src/gpu/core/physical_device.cpp @@ -26,7 +26,7 @@ namespace cm = stormkit::core::meta; namespace stormkit::gpu { namespace { - constexpr auto RAYTRACING_EXTENSIONS = std::array { + constexpr auto RAYTRACING_EXTENSIONS = array { "VK_KHR_ray_tracing_pipeline"sv, "VK_KHR_acceleration_structure"sv, "VK_KHR_buffer_device_address"sv, "VK_KHR_deferred_host_operations"sv, "VK_EXT_descriptor_indexing"sv, "VK_KHR_spirv_1_4"sv, "VK_KHR_shader_float_controls"sv @@ -34,7 +34,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto vendor_name_by_id(u64 ID) -> std::string_view { + auto vendor_name_by_id(u64 ID) -> string_view { switch (ID) { case 0x1002: return "AMD"; case 0x1010: return "ImgTex"; @@ -60,7 +60,7 @@ namespace stormkit::gpu { const auto device_name_size = std::char_traits::length(properties.deviceName); device_info.device_name.resize(device_name_size); - stdr::copy(std::string_view { properties.deviceName, device_name_size }, std::begin(device_info.device_name)); + stdr::copy(string_view { properties.deviceName, device_name_size }, std::begin(device_info.device_name)); device_info.vendor_id = vendor_id; device_info.vendor_name = vendor_name_by_id(vendor_id); @@ -269,17 +269,17 @@ namespace stormkit::gpu { return capabilities; } - auto memory_types(const PhysicalDeviceImplementation& physical_device) noexcept -> std::vector { + auto memory_types(const PhysicalDeviceImplementation& physical_device) noexcept -> dyn_array { const auto& handle = physical_device.native_handle(); const auto vk_memory_properties = vk::call(vkGetPhysicalDeviceMemoryProperties, handle); - return transform(std::span { vk_memory_properties.memoryTypes, 32 }, [](const auto& type) static noexcept { + return transform(array_view { vk_memory_properties.memoryTypes, 32 }, [](const auto& type) static noexcept { return narrow(type.propertyFlags); }); } - auto queue_families(const PhysicalDeviceImplementation& physical_device) noexcept -> std::vector { + auto queue_families(const PhysicalDeviceImplementation& physical_device) noexcept -> dyn_array { const auto& handle = physical_device.native_handle(); return transform(vk::enumerate(vkGetPhysicalDeviceQueueFamilyProperties, handle), [](const auto& family) static noexcept { @@ -288,7 +288,7 @@ namespace stormkit::gpu { } auto extensions(const PhysicalDeviceImplementation& physical_device, const PhysicalDeviceInfo& info) noexcept - -> std::vector { + -> dyn_array { const auto& handle = physical_device.native_handle(); const auto extensions = TryAssert(vk::enumerate_checked(vkEnumerateDeviceExtensionProperties, handle, @@ -298,12 +298,12 @@ namespace stormkit::gpu { Return transform(extensions, [](const auto& extension) static noexcept { const auto string_size = std::char_traits::length(extension.extensionName); - return std::string { extension.extensionName, string_size }; + return string { extension.extensionName, string_size }; }); } auto formats_properties(const PhysicalDeviceImplementation& physical_device) noexcept - -> std::vector> { + -> dyn_array> { const auto& handle = physical_device.native_handle(); return transform(cm::enumerate(), [&handle](const auto val) noexcept { return std::make_pair(val, diff --git a/src/gpu/execution/command_buffer.cpp b/src/gpu/execution/command_buffer.cpp index fa1204037..36a515210 100644 --- a/src/gpu/execution/command_buffer.cpp +++ b/src/gpu/execution/command_buffer.cpp @@ -96,7 +96,7 @@ namespace stormkit::gpu { const auto& device = Base::owner(); const auto& device_table = device.device_table(); - auto rendering_color_attachments = std::vector {}; + auto rendering_color_attachments = dyn_array {}; auto vk_rendering_inheritance_info = init_by([](auto& info) noexcept { info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO; info.pNext = nullptr; @@ -121,7 +121,7 @@ namespace stormkit::gpu { rendering_color_attachments = inheritance_info.color_attachments | stdv::transform(gpu::vk::monadic::to_vk()) - | stdr::to(); + | stdr::to>(); vk_rendering_inheritance_info.viewMask = inheritance_info.view_mask; vk_rendering_inheritance_info.colorAttachmentCount = as(stdr::size(inheritance_info.color_attachments)); vk_rendering_inheritance_info.pColorAttachmentFormats = stdr::data(rendering_color_attachments); @@ -184,7 +184,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto CommandBufferInterface::begin_debug_region(std::string_view name, const fcolor_rgb& color) const noexcept + auto CommandBufferInterface::begin_debug_region(string_view name, const fcolor_rgb& color) const noexcept -> const CommandBufferInterface& { const auto state = this->state(); EXPECTS(state == CommandBuffer::State::RECORDING); @@ -206,7 +206,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto CommandBufferInterface::insert_debug_label(std::string_view name, const fcolor_rgb& color) const noexcept + auto CommandBufferInterface::insert_debug_label(string_view name, const fcolor_rgb& color) const noexcept -> const CommandBufferInterface& { const auto state = this->state(); EXPECTS(state == CommandBuffer::State::RECORDING); @@ -319,10 +319,10 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto CommandBufferInterface::begin_render_pass(view::RenderPass render_pass, - view::FrameBuffer framebuffer, - std::span clear_values, - bool secondary_commandbuffers) const noexcept + auto CommandBufferInterface::begin_render_pass(view::RenderPass render_pass, + view::FrameBuffer framebuffer, + array_view clear_values, + bool secondary_commandbuffers) const noexcept -> const CommandBufferInterface& { const auto state = this->state(); EXPECTS(state == CommandBuffer::State::RECORDING); @@ -428,7 +428,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto CommandBufferInterface::set_viewport(u32 first_viewport, std::span viewports) const noexcept + auto CommandBufferInterface::set_viewport(u32 first_viewport, array_view viewports) const noexcept -> const CommandBufferInterface& { const auto state = this->state(); EXPECTS(state == CommandBuffer::State::RECORDING); @@ -445,7 +445,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto CommandBufferInterface::set_scissor(u32 first_scissor, std::span scissors) const noexcept + auto CommandBufferInterface::set_scissor(u32 first_scissor, array_view scissors) const noexcept -> const CommandBufferInterface& { const auto state = this->state(); EXPECTS(state == CommandBuffer::State::RECORDING); @@ -491,7 +491,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto CommandBufferInterface::set_blend_constants(std::span constants) const noexcept + auto CommandBufferInterface::set_blend_constants(array_view constants) const noexcept -> const CommandBufferInterface& { const auto state = this->state(); EXPECTS(state == CommandBuffer::State::RECORDING); @@ -651,7 +651,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto CommandBufferInterface::bind_vertex_buffers(std::span buffers, std::span offsets) + auto CommandBufferInterface::bind_vertex_buffers(array_view buffers, array_view offsets) const noexcept -> const CommandBufferInterface& { EXPECTS(not std::empty(buffers)); EXPECTS(std::size(buffers) == std::size(offsets)); @@ -695,10 +695,10 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto CommandBufferInterface::bind_descriptor_sets(view::Pipeline pipeline, - view::PipelineLayout layout, - std::span descriptor_sets, - std::span dynamic_offsets) const noexcept + auto CommandBufferInterface::bind_descriptor_sets(view::Pipeline pipeline, + view::PipelineLayout layout, + array_view descriptor_sets, + array_view dynamic_offsets) const noexcept -> const CommandBufferInterface& { const auto state = this->state(); EXPECTS(state == CommandBuffer::State::RECORDING); @@ -735,7 +735,7 @@ namespace stormkit::gpu { const auto& device = Base::owner(); const auto& device_table = device.device_table(); - const auto vk_copy_buffers = std::array { + const auto vk_copy_buffers = array { VkBufferCopy { .srcOffset = src_offset, .dstOffset = dst_offset, .size = size } }; @@ -746,9 +746,9 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto CommandBufferInterface::copy_buffer_to_image(view::Buffer src, - view::Image dst, - std::span buffer_image_copies) const noexcept + auto CommandBufferInterface::copy_buffer_to_image(view::Buffer src, + view::Image dst, + array_view buffer_image_copies) const noexcept -> const CommandBufferInterface& { const auto state = this->state(); EXPECTS(state == CommandBuffer::State::RECORDING); @@ -756,7 +756,7 @@ namespace stormkit::gpu { const auto& device = Base::owner(); const auto& device_table = device.device_table(); - const auto DEFAULT_COPY = std::array { + const auto DEFAULT_COPY = array { BufferImageCopy { 0, 0, 0, {}, { 0, 0, 0 }, dst.extent() } }; @@ -793,9 +793,9 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto CommandBufferInterface::copy_image_to_buffer(view::Image src, - view::Buffer dst, - std::span buffer_image_copies) const noexcept + auto CommandBufferInterface::copy_image_to_buffer(view::Image src, + view::Buffer dst, + array_view buffer_image_copies) const noexcept -> const CommandBufferInterface& { const auto state = this->state(); EXPECTS(state == CommandBuffer::State::RECORDING); @@ -940,11 +940,11 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto CommandBufferInterface::blit_image(view::Image src, - view::Image dst, - ImageLayout src_layout, - ImageLayout dst_layout, - std::span regions, + auto CommandBufferInterface::blit_image(view::Image src, + view::Image dst, + ImageLayout src_layout, + ImageLayout dst_layout, + array_view regions, Filter filter) const noexcept -> const CommandBufferInterface& { const auto state = this->state(); EXPECTS(state == CommandBuffer::State::RECORDING); @@ -1053,12 +1053,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto CommandBufferInterface::pipeline_barrier(PipelineStageFlag src_mask, - PipelineStageFlag dst_mask, - DependencyFlag dependency, - std::span memory_barriers, - std::span buffer_memory_barriers, - std::span image_memory_barriers) const noexcept + auto CommandBufferInterface::pipeline_barrier(PipelineStageFlag src_mask, + PipelineStageFlag dst_mask, + DependencyFlag dependency, + array_view memory_barriers, + array_view buffer_memory_barriers, + array_view image_memory_barriers) const noexcept -> const CommandBufferInterface& { const auto state = this->state(); EXPECTS(state == CommandBuffer::State::RECORDING); @@ -1129,9 +1129,9 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto CommandBufferInterface::push_constants(view::PipelineLayout pipeline_layout, - ShaderStageFlag stage, - std::span data, + auto CommandBufferInterface::push_constants(view::PipelineLayout pipeline_layout, + ShaderStageFlag stage, + byte_view<> data, u32 offset) const noexcept -> const CommandBufferInterface& { EXPECTS(not std::empty(data)); @@ -1154,7 +1154,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto CommandBufferInterface::execute_sub_command_buffers(std::span commandbuffers) + auto CommandBufferInterface::execute_sub_command_buffers(array_view commandbuffers) const noexcept -> const CommandBufferInterface& { const auto state = this->state(); EXPECTS(state == CommandBuffer::State::RECORDING); diff --git a/src/gpu/execution/command_pool.cpp b/src/gpu/execution/command_pool.cpp index 6fa7df000..c08a3fc98 100644 --- a/src/gpu/execution/command_pool.cpp +++ b/src/gpu/execution/command_pool.cpp @@ -26,7 +26,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template auto CommandPoolInterface::create_vk_command_buffers(usize count, CommandBufferLevel level) const noexcept - -> Expected> { + -> Expected> { const auto& device = Base::owner(); const auto& device_table = device.device_table(); diff --git a/src/gpu/execution/descriptor_pool.cpp b/src/gpu/execution/descriptor_pool.cpp index 80cc901b2..8d349053d 100644 --- a/src/gpu/execution/descriptor_pool.cpp +++ b/src/gpu/execution/descriptor_pool.cpp @@ -27,7 +27,7 @@ namespace stormkit::gpu { ///////////////////////////////////// template auto DescriptorPoolInterface::create_vk_descriptor_sets(usize count, view::DescriptorSetLayout&& layout) const noexcept - -> Expected> { + -> Expected> { const auto vk_layout = vk::to_vk(layout); const auto allocate_info = VkDescriptorSetAllocateInfo { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, @@ -58,7 +58,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto DescriptorPoolImplementation::do_init(PrivateTag, std::span&& sizes, u32 max_sets) noexcept + auto DescriptorPoolImplementation::do_init(PrivateTag, array_view&& sizes, u32 max_sets) noexcept -> Expected { const auto pool_sizes = transform(sizes, [](const Size& size) static noexcept { return VkDescriptorPoolSize { diff --git a/src/gpu/execution/descriptor_set.cpp b/src/gpu/execution/descriptor_set.cpp index da32fbc47..a4125bd92 100644 --- a/src/gpu/execution/descriptor_set.cpp +++ b/src/gpu/execution/descriptor_set.cpp @@ -25,14 +25,14 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto DescriptorSetInterface::update(std::span descriptors) const noexcept -> void { + auto DescriptorSetInterface::update(array_view descriptors) const noexcept -> void { const auto& device = Base::owner(); const auto& device_table = device.device_table(); auto&& [_, _, _writes] = [this, descriptors = std::move(descriptors)] noexcept -> decltype(auto) { - auto buffers = std::vector {}; - auto images = std::vector {}; - auto writes = std::vector {}; + auto buffers = dyn_array {}; + auto images = dyn_array {}; + auto writes = dyn_array {}; buffers.reserve(std::size(descriptors)); images.reserve(std::size(descriptors)); writes.reserve(std::size(descriptors)); diff --git a/src/gpu/execution/descriptor_set_layout.cpp b/src/gpu/execution/descriptor_set_layout.cpp index 63cfab177..099e430ca 100644 --- a/src/gpu/execution/descriptor_set_layout.cpp +++ b/src/gpu/execution/descriptor_set_layout.cpp @@ -27,7 +27,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto DescriptorSetLayoutImplementation::do_init(PrivateTag, std::vector&& bindings) noexcept + auto DescriptorSetLayoutImplementation::do_init(PrivateTag, dyn_array&& bindings) noexcept -> Expected { m_bindings = std::move(bindings); const auto vk_bindings = transform(m_bindings, [](const DescriptorSetLayoutBinding& binding) static noexcept { diff --git a/src/gpu/execution/frame_buffer.cpp b/src/gpu/execution/frame_buffer.cpp index c5c2d07a6..7c232d146 100644 --- a/src/gpu/execution/frame_buffer.cpp +++ b/src/gpu/execution/frame_buffer.cpp @@ -28,9 +28,9 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// auto FrameBufferImplementation::do_init(PrivateTag, - view::RenderPass&& render_pass, - const math::uextent2& extent, - std::vector&& attachments) noexcept -> Expected { + view::RenderPass&& render_pass, + const math::uextent2& extent, + dyn_array&& attachments) noexcept -> Expected { m_extent = extent; m_attachments = std::move(attachments); const auto vk_attachments = transform(m_attachments, vk::monadic::to_vk()); diff --git a/src/gpu/execution/pipeline.cpp b/src/gpu/execution/pipeline.cpp index 5f6e684eb..b57515ac5 100644 --- a/src/gpu/execution/pipeline.cpp +++ b/src/gpu/execution/pipeline.cpp @@ -26,21 +26,21 @@ using namespace std::literals; namespace stormkit::gpu { namespace { struct PipelineData { - std::vector binding_descriptions; - std::vector input_attribute_descriptions; - VkPipelineVertexInputStateCreateInfo vertex_input_info; - VkPipelineInputAssemblyStateCreateInfo input_assembly; - std::vector viewports; - std::vector scissors; - VkPipelineViewportStateCreateInfo viewport_state; - VkPipelineRasterizationStateCreateInfo rasterizer; - VkPipelineMultisampleStateCreateInfo multisample; - std::vector blend_attachments; - VkPipelineColorBlendStateCreateInfo color_blending; - std::vector states; - VkPipelineDynamicStateCreateInfo dynamic_state; - std::vector shaders; - VkPipelineDepthStencilStateCreateInfo depth_stencil; + dyn_array binding_descriptions; + dyn_array input_attribute_descriptions; + VkPipelineVertexInputStateCreateInfo vertex_input_info; + VkPipelineInputAssemblyStateCreateInfo input_assembly; + dyn_array viewports; + dyn_array scissors; + VkPipelineViewportStateCreateInfo viewport_state; + VkPipelineRasterizationStateCreateInfo rasterizer; + VkPipelineMultisampleStateCreateInfo multisample; + dyn_array blend_attachments; + VkPipelineColorBlendStateCreateInfo color_blending; + dyn_array states; + VkPipelineDynamicStateCreateInfo dynamic_state; + dyn_array shaders; + VkPipelineDepthStencilStateCreateInfo depth_stencil; }; auto do_init(const RasterPipelineState& state) noexcept -> PipelineData { diff --git a/src/gpu/execution/pipeline_cache.cpp b/src/gpu/execution/pipeline_cache.cpp index 1e7801611..dad7e4707 100644 --- a/src/gpu/execution/pipeline_cache.cpp +++ b/src/gpu/execution/pipeline_cache.cpp @@ -100,7 +100,7 @@ namespace stormkit::gpu { if (not stdr::equal(m_serialized.uuid.value, physical_device_infos.pipeline_cache_uuid)) Return create_new_pipeline_cache(); - auto data = std::vector {}; + auto data = byte_dyn_array {}; data.resize(m_serialized.guard.data_size); TryTransformError(io::read_to(m_path, data), sys_to_load_error); @@ -129,7 +129,7 @@ namespace stormkit::gpu { auto size = 0_usize; TryTransformError(vk::call_checked(device_table.vkGetPipelineCacheData, device, m_vk_handle, &size, nullptr), result_to_load_error); - auto data = std::vector {}; + auto data = byte_dyn_array {}; data.resize(size, 0_b); TryTransformError(vk::call_checked(device_table.vkGetPipelineCacheData, device, m_vk_handle, &size, stdr::data(data)), result_to_load_error); diff --git a/src/gpu/execution/queue.cpp b/src/gpu/execution/queue.cpp index 2e03e32d0..14637ec95 100644 --- a/src/gpu/execution/queue.cpp +++ b/src/gpu/execution/queue.cpp @@ -37,13 +37,13 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto QueueInterface::submit(std::span submit_infos, std::optional fence) const noexcept + auto QueueInterface::submit(array_view submit_infos, std::optional fence) const noexcept -> Expected { struct SubmitInfoRange { - std::span wait_semaphores; - std::span wait_dst_stages; - std::span command_buffers; - std::span signal_semaphores; + array_view wait_semaphores; + array_view wait_dst_stages; + array_view command_buffers; + array_view signal_semaphores; }; const auto bytes_count = [&submit_infos] noexcept { @@ -67,17 +67,17 @@ namespace stormkit::gpu { auto memory_resource = stdp::monotonic_buffer_resource { bytes_count }; - auto wait_semaphores_buf = stdp::vector> { &memory_resource }; + auto wait_semaphores_buf = pmr::dyn_array> { &memory_resource }; wait_semaphores_buf.reserve(stdr::size(submit_infos)); - auto wait_dst_stages_buf = stdp::vector> { &memory_resource }; + auto wait_dst_stages_buf = pmr::dyn_array> { &memory_resource }; wait_dst_stages_buf.reserve(stdr::size(submit_infos)); - auto command_buffers_buf = stdp::vector> { &memory_resource }; + auto command_buffers_buf = pmr::dyn_array> { &memory_resource }; command_buffers_buf.reserve(stdr::size(submit_infos)); - auto signal_semaphores_buf = stdp::vector> { &memory_resource }; + auto signal_semaphores_buf = pmr::dyn_array> { &memory_resource }; signal_semaphores_buf.reserve(stdr::size(submit_infos)); const auto submit_ranges = [&] noexcept { - auto vec = stdp::vector { &memory_resource }; + auto vec = pmr::dyn_array { &memory_resource }; vec.reserve(stdr::size(submit_infos)); for (auto&& submit_info : submit_infos) { auto& wait_semaphores = wait_semaphores_buf.emplace_back(std::from_range, @@ -124,7 +124,7 @@ namespace stormkit::gpu { .pSignalSemaphores = stdr::data(submit_range.signal_semaphores), }; }) - | stdr::to(); + | stdr::to>(); const auto vk_fence = either(fence, vk::monadic::to_vk(), core::monadic::init(VK_NULL_HANDLE)); @@ -140,9 +140,9 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto QueueInterface::present(std::span swapchains, - std::span wait_semaphores, - std::span image_indices) const noexcept -> Expected { + auto QueueInterface::present(array_view swapchains, + array_view wait_semaphores, + array_view image_indices) const noexcept -> Expected { EXPECTS(stdr::size(wait_semaphores) >= 1); EXPECTS(stdr::size(image_indices) >= 1); @@ -152,12 +152,12 @@ namespace stormkit::gpu { const auto bytes_count = swapchains_count * sizeof(VkSwapchainKHR) + wait_semaphores_count * sizeof(VkSemaphore); auto memory_resource = stdp::monotonic_buffer_resource { bytes_count }; - const auto vk_swapchains = stdp::vector { + const auto vk_swapchains = pmr::dyn_array { std::from_range, swapchains | stdv::transform(vk::monadic::to_vk()), &memory_resource }; - const auto vk_semaphores = stdp::vector { + const auto vk_semaphores = pmr::dyn_array { std::from_range, wait_semaphores | stdv::transform(vk::monadic::to_vk()), &memory_resource diff --git a/src/gpu/execution/render_pass.cpp b/src/gpu/execution/render_pass.cpp index c1e87c01a..9f22e7f5e 100644 --- a/src/gpu/execution/render_pass.cpp +++ b/src/gpu/execution/render_pass.cpp @@ -53,11 +53,11 @@ namespace stormkit::gpu { }; }); - auto color_attachment_refs = std::vector> {}; + auto color_attachment_refs = dyn_array> {}; auto depth_attachment_ref = std::optional {}; - auto resolve_attachment_refs = std::vector> {}; - auto subpasses = std::vector {}; - auto subpasses_deps = std::vector {}; + auto resolve_attachment_refs = dyn_array> {}; + auto subpasses = dyn_array {}; + auto subpasses_deps = dyn_array {}; color_attachment_refs.reserve(stdr::size(m_description->subpasses)); resolve_attachment_refs.reserve(stdr::size(m_description->subpasses)); diff --git a/src/gpu/execution/swapchain.cpp b/src/gpu/execution/swapchain.cpp index e567b5834..356ee7026 100644 --- a/src/gpu/execution/swapchain.cpp +++ b/src/gpu/execution/swapchain.cpp @@ -18,7 +18,7 @@ namespace stormkit::gpu { namespace { ///////////////////////////////////// ///////////////////////////////////// - auto choose_swap_surface_format(std::span formats) noexcept -> VkSurfaceFormatKHR { + auto choose_swap_surface_format(array_view formats) noexcept -> VkSurfaceFormatKHR { for (const auto& format : formats) { if (format.format == VK_FORMAT_B8G8R8A8_UNORM && format.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) return format; @@ -29,7 +29,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto choose_swap_present_mode(std::span present_modes) noexcept -> VkPresentModeKHR { + auto choose_swap_present_mode(array_view present_modes) noexcept -> VkPresentModeKHR { auto present_mode_ = VK_PRESENT_MODE_FIFO_KHR; for (const auto& present_mode : present_modes) { diff --git a/src/gpu/resource/buffer.cpp b/src/gpu/resource/buffer.cpp index b16485af2..68ef3d312 100644 --- a/src/gpu/resource/buffer.cpp +++ b/src/gpu/resource/buffer.cpp @@ -74,7 +74,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// template - auto BufferInterface::upload(std::span data, ioffset offset) noexcept -> Expected { + auto BufferInterface::upload(byte_view<> data, ioffset offset) noexcept -> Expected { EXPECTS(stdr::size(data) <= this->size()); if (is_persistently_mapped()) { diff --git a/src/gpu/resource/shader.cpp b/src/gpu/resource/shader.cpp index 9781680a7..7d4488b03 100644 --- a/src/gpu/resource/shader.cpp +++ b/src/gpu/resource/shader.cpp @@ -23,7 +23,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto ShaderImplementation::do_init(PrivateTag, std::vector&& data, ShaderStageFlag type) -> Expected { + auto ShaderImplementation::do_init(PrivateTag, dyn_array&& data, ShaderStageFlag type) -> Expected { m_source = std::move(data); m_type = type; diff --git a/src/image/hdr.cppm b/src/image/hdr.cppm index 2069b8393..798a18891 100644 --- a/src/image/hdr.cppm +++ b/src/image/hdr.cppm @@ -11,14 +11,14 @@ import stormkit.image; export namespace stormkit::image::details { [[nodiscard]] - auto load_hdr(std::span data) noexcept -> std::expected; + auto load_hdr(byte_view<> data) noexcept -> std::expected; [[nodiscard]] auto save_hdr(const image::Image& image, const std::filesystem::path& filepath) noexcept -> std::expected; [[nodiscard]] - auto save_hdr(const image::Image& image) noexcept -> std::expected, image::Image::Error>; + auto save_hdr(const image::Image& image) noexcept -> std::expected; } // namespace stormkit::image::details namespace stormkit::image::details { @@ -29,7 +29,7 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto load_hdr(std::span) noexcept -> std::expected { + auto load_hdr(byte_view<>) noexcept -> std::expected { assert(false, "Not implemented yet !"); return {}; } @@ -43,7 +43,7 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto save_hdr(const image::Image&) noexcept -> std::expected, image::Image::Error> { + auto save_hdr(const image::Image&) noexcept -> std::expected { assert(false, "Not implemented yet !"); return {}; } diff --git a/src/image/image.cpp b/src/image/image.cpp index f32dbc8c7..52108a07b 100644 --- a/src/image/image.cpp +++ b/src/image/image.cpp @@ -56,7 +56,7 @@ namespace stormkit::image { return Image::Codec::UNKNOWN; } - auto header_to_codec(std::span data) noexcept -> Image::Codec { + auto header_to_codec(byte_view<> data) noexcept -> Image::Codec { EXPECTS(std::size(data) >= 12); if (std::memcmp(std::data(data), std::data(KTX_HEADER), std::size(KTX_HEADER)) == 0) return Image::Codec::KTX; @@ -70,7 +70,7 @@ namespace stormkit::image { return Image::Codec::UNKNOWN; } - auto map(std::span bytes, u32 source_count, u32 destination_count) noexcept -> std::vector { + auto map(byte_view<> bytes, u32 source_count, u32 destination_count) noexcept -> byte_dyn_array { EXPECTS(source_count <= 4u and source_count > 0u and destination_count <= 4u and destination_count > 0u); static constexpr auto BYTE_1_MIN = std::numeric_limits::min(); @@ -80,7 +80,7 @@ namespace stormkit::image { static constexpr auto BYTE_4_MIN = std::numeric_limits::min(); static constexpr auto BYTE_4_MAX = std::numeric_limits::max(); - auto data = std::vector {}; + auto data = byte_dyn_array {}; data.resize(std::size(bytes) * destination_count); if (source_count == 1u and destination_count == 2u) { @@ -150,7 +150,7 @@ namespace stormkit::image { ///////////////////////////////////// ///////////////////////////////////// - Image::Image(std::span data, Image::Codec codec) noexcept : Image {} { + Image::Image(byte_view<> data, Image::Codec codec) noexcept : Image {} { const auto _ = load_from_memory(data, codec); } @@ -249,7 +249,7 @@ namespace stormkit::image { ///////////////////////////////////// ///////////////////////////////////// - auto Image::load_from_memory(std::span data, Image::Codec codec) noexcept -> std::expected { + auto Image::load_from_memory(byte_view<> data, Image::Codec codec) noexcept -> std::expected { EXPECTS(codec != Image::Codec::UNKNOWN); EXPECTS(!std::empty(data)); @@ -350,7 +350,7 @@ namespace stormkit::image { std::format("Failed to load " _Name " image from data\n > {}", result.error().str_error) \ }; \ } \ - return std::expected, Error> { std::in_place, std::move(*result) }; \ + return std::expected { std::in_place, std::move(*result) }; \ } #define CASE_ARGS_DO(_E, _Func, _Name) \ case Image::Codec::_E: { \ @@ -362,17 +362,17 @@ namespace stormkit::image { std::format("Failed to load " _Name " image from data\n > {}", result.error().str_error) \ }; \ } \ - return std::expected, Error> { std::in_place, std::move(*result) }; \ + return std::expected { std::in_place, std::move(*result) }; \ } ///////////////////////////////////// ///////////////////////////////////// - auto Image::save_to_memory(Codec codec, CodecArgs args) const noexcept -> std::expected, Error> { + auto Image::save_to_memory(Codec codec, CodecArgs args) const noexcept -> std::expected { EXPECTS(codec != Image::Codec::UNKNOWN); EXPECTS(codec != Image::Codec::AUTODETECT); EXPECTS(!std::empty(m_data.data)); - auto output = std::vector {}; + auto output = byte_dyn_array {}; switch (codec) { CASE_DO (JPEG, save_jpg, "JPEG") @@ -448,7 +448,7 @@ namespace stormkit::image { static_cast(m_data.channel_count)));*/ const auto pixel_count = m_data.extent.width * m_data.extent.height * m_data.extent.depth; - image_data.data.resize(pixel_count * image_data.channel_count * image_data.bytes_per_channel, Byte { 255u }); + image_data.data.resize(pixel_count * image_data.channel_count * image_data.bytes_per_channel, byte { 255u }); auto image = Image { std::move(image_data) }; diff --git a/src/image/jpg.cppm b/src/image/jpg.cppm index 882969839..6ca657fe4 100644 --- a/src/image/jpg.cppm +++ b/src/image/jpg.cppm @@ -27,14 +27,14 @@ namespace stdr = std::ranges; export namespace stormkit::image::details { [[nodiscard]] - auto load_jpg(std::span data) noexcept -> std::expected; + auto load_jpg(byte_view<> data) noexcept -> std::expected; [[nodiscard]] auto save_jpg(const image::Image& image, const std::filesystem::path& filepath) noexcept -> std::expected; [[nodiscard]] - auto save_jpg(const image::Image& image) noexcept -> std::expected, image::Image::Error>; + auto save_jpg(const image::Image& image) noexcept -> std::expected; } // namespace stormkit::image::details namespace stormkit::image::details { @@ -47,7 +47,7 @@ namespace stormkit::image::details { namespace jpg { struct ErrorData { std::jmp_buf setjmp_buffer; - std::string msg; + string msg; }; ///////////////////////////////////// @@ -57,7 +57,7 @@ namespace stormkit::image::details { auto error_data = reinterpret_cast(st->client_data); - auto message = std::string {}; + auto message = string {}; message.resize(JMSG_STR_PARM_MAX); (*st->err->format_message)(st, stdr::data(message)); @@ -69,8 +69,8 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto load_jpg(std::span data) noexcept -> std::expected { - auto image_memory = std::vector {}; + auto load_jpg(byte_view<> data) noexcept -> std::expected { + auto image_memory = byte_dyn_array {}; volatile auto format = Format {}; // NOTE volatile for error: variable ‘format’ might be // clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered] auto extent = math::uextent3 {}; @@ -101,7 +101,7 @@ namespace stormkit::image::details { image_memory.resize(as(extent.width * extent.height * extent.depth * as(info.out_color_components))); - auto row_ptr = std::array { nullptr }; + auto row_ptr = array { nullptr }; while (info.output_scanline < info.output_height) { const auto index = as(extent.width * as(info.output_components) * info.output_scanline); row_ptr[0] = stdr::data(image_memory) + index; @@ -176,7 +176,7 @@ namespace stormkit::image::details { jpeg_start_compress(&info, TRUE); - auto row_ptr = std::array { nullptr }; + auto row_ptr = array { nullptr }; while (info.next_scanline < info.image_height) { const auto index = info.next_scanline * 3u * info.image_width; row_ptr[0] = stdr::data(data) + index; @@ -200,7 +200,7 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto save_jpg(const image::Image& image) noexcept -> std::expected, image::Image::Error> { + auto save_jpg(const image::Image& image) noexcept -> std::expected { using uchar_ptr = unsigned char*; auto output_ptr = uchar_ptr { nullptr }; @@ -234,7 +234,7 @@ namespace stormkit::image::details { jpeg_start_compress(&info, TRUE); - auto row_ptr = std::array { nullptr }; + auto row_ptr = array { nullptr }; while (info.next_scanline < info.image_height) { const auto index = info.next_scanline * 3u * info.image_width; row_ptr[0] = stdr::data(data) + index; @@ -250,7 +250,7 @@ namespace stormkit::image::details { return std::unexpected(Error { .reason = Reason::FAILED_TO_SAVE, .str_error = error_data.msg }); } - auto output = std::vector {}; + auto output = byte_dyn_array {}; output.reserve((out_size)); std::ranges::copy(as_bytes(output_ptr, out_size), std::back_inserter(output)); diff --git a/src/image/ktx.cppm b/src/image/ktx.cppm index 64f3125b9..63d5eae16 100644 --- a/src/image/ktx.cppm +++ b/src/image/ktx.cppm @@ -14,14 +14,14 @@ import stormkit.image; export namespace stormkit::image::details { [[nodiscard]] - auto load_ktx(std::span data) noexcept -> std::expected; + auto load_ktx(byte_view<> data) noexcept -> std::expected; [[nodiscard]] auto save_ktx(const image::Image& image, const std::filesystem::path& filepath) noexcept -> std::expected; [[nodiscard]] - auto save_ktx(const image::Image& image) noexcept -> std::expected, image::Image::Error>; + auto save_ktx(const image::Image& image) noexcept -> std::expected; } // namespace stormkit::image::details namespace stormkit::image::details { @@ -100,7 +100,7 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto load_ktx([[maybe_unused]] std::span data) noexcept -> std::expected { + auto load_ktx([[maybe_unused]] byte_view<> data) noexcept -> std::expected { /*auto image = gli::load_ktx(reinterpret_cast(std::data(data)), * std::size(data));*/ /**/ @@ -113,7 +113,7 @@ namespace stormkit::image::details { /* return std::unexpected(Error { .reason = Reason::FAILED_TO_PARSE,*/ /* .str_error = "Unsupported pixel format" });*/ /**/ - /*auto image_memory = std::vector {};*/ + /*auto image_memory = byte_dyn_array {};*/ /*image_memory.resize(image.size());*/ /**/ /*std::ranges::copy(as_bytes(image.data(), image.size()), std::begin(image_memory));*/ @@ -144,7 +144,7 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto save_ktx(const image::Image&) noexcept -> std::expected, image::Image::Error> { + auto save_ktx(const image::Image&) noexcept -> std::expected { assert(false, "Not implemented yet !"); return {}; } diff --git a/src/image/png.cppm b/src/image/png.cppm index f78a82443..b0b8043d7 100644 --- a/src/image/png.cppm +++ b/src/image/png.cppm @@ -18,14 +18,14 @@ import stormkit.image; export namespace stormkit::image::details { [[nodiscard]] - auto load_png(std::span data) noexcept -> std::expected; + auto load_png(byte_view<> data) noexcept -> std::expected; [[nodiscard]] auto save_png(const image::Image& image, const std::filesystem::path& filepath) noexcept -> std::expected; [[nodiscard]] - auto save_png(const image::Image& image) noexcept -> std::expected, image::Image::Error>; + auto save_png(const image::Image& image) noexcept -> std::expected; } // namespace stormkit::image::details namespace stdr = std::ranges; @@ -39,12 +39,12 @@ namespace stormkit::image::details { namespace png { struct ReadParam { - usize readed; - std::span& data; + usize readed; + byte_view<>& data; }; struct WriteParam { - std::vector& data; + byte_dyn_array& data; }; ///////////////////////////////////// @@ -74,8 +74,8 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto load_png(std::span data) noexcept -> std::expected { - auto image_memory = std::vector {}; + auto load_png(byte_view<> data) noexcept -> std::expected { + auto image_memory = byte_dyn_array {}; auto format = Format {}; auto extent = math::uextent3 {}; @@ -162,7 +162,7 @@ namespace stormkit::image::details { const auto row_bytes = png_get_rowbytes(png_ptr, info_ptr); image_memory.resize(extent.height * row_bytes); - auto row_pointers = std::vector { extent.height, nullptr }; + auto row_pointers = dyn_array { extent.height, nullptr }; auto buff_pos = std::data(image_memory); @@ -197,8 +197,8 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto save_png(const image::Image& image) noexcept -> std::expected, image::Image::Error> { - auto output = std::vector {}; + auto save_png(const image::Image& image) noexcept -> std::expected { + auto output = byte_dyn_array {}; auto write_param = png::WriteParam { output }; @@ -236,10 +236,10 @@ namespace stormkit::image::details { PNG_FILTER_TYPE_DEFAULT); png_write_info(png_ptr, info_ptr); - auto rows = std::vector { data.extent.height, nullptr }; + auto rows = dyn_array { data.extent.height, nullptr }; for (auto i : range(data.extent.height)) rows[i] = const_cast< - Byte*>(&data.data[i * data.extent.width * data.channel_count * data.bytes_per_channel]); // TODO Fix + byte*>(&data.data[i * data.extent.width * data.channel_count * data.bytes_per_channel]); // TODO Fix // this shit png_set_rows(png_ptr, info_ptr, std::bit_cast(std::data(rows))); diff --git a/src/image/ppm.cppm b/src/image/ppm.cppm index c7b92ecc1..d0372e64c 100644 --- a/src/image/ppm.cppm +++ b/src/image/ppm.cppm @@ -15,7 +15,7 @@ import stormkit.image; export namespace stormkit::image::details { [[nodiscard]] - auto load_ppm(std::span data) noexcept -> std::expected; + auto load_ppm(byte_view<> data) noexcept -> std::expected; [[nodiscard]] auto save_ppm(const image::Image& image, image::Image::CodecArgs args, const std::filesystem::path& filepath) noexcept @@ -23,7 +23,7 @@ export namespace stormkit::image::details { [[nodiscard]] auto save_ppm(const image::Image& image, image::Image::CodecArgs args) noexcept - -> std::expected, image::Image::Error>; + -> std::expected; } // namespace stormkit::image::details using namespace std::literals; @@ -37,7 +37,7 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto load_ppm(std::span) noexcept -> std::expected { + auto load_ppm(byte_view<>) noexcept -> std::expected { assert(false, "Not implemented yet !"); return {}; } @@ -58,11 +58,11 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// auto save_ppm(const image::Image& image, image::Image::CodecArgs args) noexcept - -> std::expected, image::Image::Error> { + -> std::expected { const auto output_image = image.convert_to(Format::RGB8_UNORM); const auto& data = output_image.image_data(); - auto output = std::vector {}; + auto output = byte_dyn_array {}; if (args == image::Image::CodecArgs::ASCII) { auto result = std::format("P3\n{}\n{}\n255\n"sv, data.extent.width, data.extent.height); diff --git a/src/image/qoi.cppm b/src/image/qoi.cppm index 693cf1bc6..8508dce25 100644 --- a/src/image/qoi.cppm +++ b/src/image/qoi.cppm @@ -17,14 +17,14 @@ import stormkit.image; export namespace stormkit::image::details { [[nodiscard]] - auto load_qoi(std::span data) noexcept -> std::expected; + auto load_qoi(byte_view<> data) noexcept -> std::expected; [[nodiscard]] auto save_qoi(const image::Image& image, const std::filesystem::path& filepath) noexcept -> std::expected; [[nodiscard]] - auto save_qoi(const image::Image& image) noexcept -> std::expected, image::Image::Error>; + auto save_qoi(const image::Image& image) noexcept -> std::expected; } // namespace stormkit::image::details using namespace std::literals; @@ -38,19 +38,19 @@ namespace stormkit::image::details { using Reason = image::Image::Error::Reason; struct QOIHeader { - std::array magic; - u32 width; - u32 height; - u8 channels; - u8 colorspace; + array magic; + u32 width; + u32 height; + u8 channels; + u8 colorspace; }; namespace { constexpr auto SIZE_OF_HEADER = 14; - constexpr auto CHANNELS_TO_FORMAT = frozen::make_unordered_map>({ - { 3, std::array { image::Image::Format::SRGB8, image::Image::Format::RGB8_UNORM } }, - { 4, std::array { image::Image::Format::SRGBA8, image::Image::Format::RGBA8_UNORM } } + constexpr auto CHANNELS_TO_FORMAT = frozen::make_unordered_map>({ + { 3, array { image::Image::Format::SRGB8, image::Image::Format::RGB8_UNORM } }, + { 4, array { image::Image::Format::SRGBA8, image::Image::Format::RGBA8_UNORM } } }); constexpr auto END_OF_FILE = into_bytes({ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }); @@ -75,7 +75,7 @@ namespace stormkit::image::details { u8 a = 0; } rgba; - std::array data; + array data; }; ///////////////////////////////////// @@ -86,7 +86,7 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto load_qoi(std::span data) noexcept -> std::expected { + auto load_qoi(byte_view<> data) noexcept -> std::expected { const auto raw_header = data.subspan(SIZE_OF_HEADER); const auto* header = std::bit_cast(stdr::data(raw_header)); @@ -94,14 +94,14 @@ namespace stormkit::image::details { const auto channels = header->channels; const auto format = CHANNELS_TO_FORMAT.at(header->channels)[header->colorspace]; - auto pixel_cache = std::array {}; + auto pixel_cache = array {}; - const auto chunks = std::span { std::bit_cast(stdr::data(data)) + SIZE_OF_HEADER, - stdr::size(data) - SIZE_OF_HEADER }; + const auto chunks = array_view { std::bit_cast(stdr::data(data)) + SIZE_OF_HEADER, + stdr::size(data) - SIZE_OF_HEADER }; const auto output_size = extent.width * extent.height * channels; - auto output = std::vector {}; + auto output = byte_dyn_array {}; output.reserve(output_size); auto previous_pixel = Pixel { .rgba = { .a = 255 } }; @@ -174,7 +174,7 @@ namespace stormkit::image::details { stdr::transform(stdr::begin(previous_pixel.data), stdr::end(previous_pixel.data) - diff, std::back_inserter(output), - monadic::as()); + monadic::as()); } auto image_data = image::Image::ImageData { @@ -202,7 +202,7 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// [[nodiscard]] - auto save_qoi(const image::Image&) noexcept -> std::expected, image::Image::Error> { + auto save_qoi(const image::Image&) noexcept -> std::expected { assert(false, "Not implemented yet !"); return {}; } diff --git a/src/image/tga.cppm b/src/image/tga.cppm index d0e6cd2a3..3835a23b0 100644 --- a/src/image/tga.cppm +++ b/src/image/tga.cppm @@ -16,14 +16,14 @@ import stormkit.image; export namespace stormkit::image::details { [[nodiscard]] - auto load_tga(std::span data) noexcept -> std::expected; + auto load_tga(byte_view<> data) noexcept -> std::expected; [[nodiscard]] auto save_tga(const image::Image& image, const std::filesystem::path& filepath) noexcept -> std::expected; [[nodiscard]] - auto save_tga(const image::Image& image) noexcept -> std::expected, image::Image::Error>; + auto save_tga(const image::Image& image) noexcept -> std::expected; } // namespace stormkit::image::details namespace stormkit::image::details { @@ -34,7 +34,7 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto load_tga(std::span) noexcept -> std::expected { + auto load_tga(byte_view<>) noexcept -> std::expected { assert(false, "Not implemented yet !"); return {}; } @@ -48,7 +48,7 @@ namespace stormkit::image::details { ///////////////////////////////////// ///////////////////////////////////// - auto save_tga(const image::Image&) noexcept -> std::expected, image::Image::Error> { + auto save_tga(const image::Image&) noexcept -> std::expected { assert(false, "Not implemented yet !"); return {}; } diff --git a/src/log/console_logger.cpp b/src/log/console_logger.cpp index bf61d6435..5bb8df99e 100644 --- a/src/log/console_logger.cpp +++ b/src/log/console_logger.cpp @@ -41,7 +41,7 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// - auto ConsoleLogger::write(Severity severity, const Module& module, CZString string) noexcept -> void { + auto ConsoleLogger::write(Severity severity, const Module& module, czstring str) noexcept -> void { const auto now = LogClock::now(); const auto time = std::chrono::duration_cast(now - m_start_time); const auto is_error = severity == Severity::ERROR or severity == Severity::FATAL; @@ -54,13 +54,13 @@ namespace stormkit::log { return std::format("[{}, {:%S}, {}]", severity_str, time, module.name); }(); - const auto prefixed_string = [&header, string] noexcept { + const auto prefixed_string = [&header, str] noexcept { const auto header_length = stdr::size(header) + 1; - auto prefix = std::string {}; + auto prefix = string {}; prefix.resize(header_length + 1, ' '); prefix.front() = '\n'; - return replace(string, "\n", prefix); + return replace(str, "\n", prefix); }(); const auto styled_header = std::format("{} ", StyleMap.at(severity) | header); diff --git a/src/log/file_logger.cpp b/src/log/file_logger.cpp index a87d3ed64..818b1ee1e 100644 --- a/src/log/file_logger.cpp +++ b/src/log/file_logger.cpp @@ -47,7 +47,7 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// - auto FileLogger::write(Severity severity, const Module& m, CZString string) noexcept -> void { + auto FileLogger::write(Severity severity, const Module& m, czstring str) noexcept -> void { const auto now = LogClock::now(); const auto time = std::chrono::duration_cast(now - m_start_time).count(); @@ -63,11 +63,11 @@ namespace stormkit::log { static constexpr auto LOG_LINE = "[{}, {}] {}\n"sv; static constexpr auto LOG_LINE_MODULE = "[{}, {}, {}] {}\n"sv; - auto final_string = std::string {}; + auto final_string = string {}; const auto severity_str = replace(as_string(severity), "Severity::", ""); - if (std::empty(m.name)) final_string = std::format(LOG_LINE, severity_str, time, string); + if (std::empty(m.name)) final_string = std::format(LOG_LINE, severity_str, time, str); else - final_string = std::format(LOG_LINE_MODULE, severity_str, time, m.name, string); + final_string = std::format(LOG_LINE_MODULE, severity_str, time, m.name, str); m_streams.at(filepath.string()) << final_string << std::flush; } diff --git a/src/log/logger.cpp b/src/log/logger.cpp index eb9297479..0becbe889 100644 --- a/src/log/logger.cpp +++ b/src/log/logger.cpp @@ -31,7 +31,7 @@ namespace stormkit::log { ///////////////////////////////////// ///////////////////////////////////// - auto parse_args(std::span args) noexcept -> void { + auto parse_args(array_view args) noexcept -> void { debug_enabled = stdr::find_if(args, [](auto&& v) { return v == "--debug" or v == "-d"; }) != stdr::cend(args); } diff --git a/src/lua/core/color.cpp b/src/lua/core/color.cpp index 674355a4e..c6bf69ecb 100644 --- a/src/lua/core/color.cpp +++ b/src/lua/core/color.cpp @@ -17,7 +17,7 @@ namespace stormkit::lua::core { //////////////////////////////////////// //////////////////////////////////////// template - auto _bind_color(std::string_view name, auto& parent, auto... values) { + auto _bind_color(string_view name, auto& parent, auto... values) { auto metatable = parent.template new_usertype(name, sol::constructors {}); metatable[sol::meta_function::to_string] = &stormkit::to_string; metatable[sol::meta_function::equal_to] = &T::operator==; diff --git a/src/lua/core/math.cpp b/src/lua/core/math.cpp index dd60943fa..691be3f88 100644 --- a/src/lua/core/math.cpp +++ b/src/lua/core/math.cpp @@ -24,7 +24,7 @@ namespace stormkit::lua::core { using Rect = math::rect; parent.template new_usertype( - std::string { Rects.name }, + string { Rects.name }, sol::constructors {}, "position", &Rect::position, @@ -46,7 +46,7 @@ namespace stormkit::lua::core { using Rect = math::bounding_rect; parent.template new_usertype( - std::string { Rects.name }, + string { Rects.name }, sol::constructors {}, "topleft", &Rect::topleft, @@ -61,7 +61,7 @@ namespace stormkit::lua::core { //////////////////////////////////////// //////////////////////////////////////// template typename T, typename U> - auto _bind_angle(std::string_view name, auto& parent) { + auto _bind_angle(string_view name, auto& parent) { auto metatable = parent.template new_usertype>(name, sol::constructors(U)> {}); metatable["value"] = sol::property( +[](T* angle) static noexcept { return angle->get(); }, @@ -77,7 +77,7 @@ namespace stormkit::lua::core { //////////////////////////////////////// //////////////////////////////////////// template - auto _bind_extent(std::string_view name, auto& parent, auto... values) { + auto _bind_extent(string_view name, auto& parent, auto... values) { auto metatable = parent.template new_usertype(name, sol::constructors {}); metatable[sol::meta_function::to_string] = &math::to_string; @@ -98,7 +98,7 @@ namespace stormkit::lua::core { //////////////////////////////////////// //////////////////////////////////////// template - auto _bind_vector(std::string_view name, auto& parent, auto... values) { + auto _bind_vector(string_view name, auto& parent, auto... values) { auto metatable = parent.template new_usertype(name, sol::constructors {}); metatable[sol::meta_function::to_string] = +[](const T& value) static noexcept { return to_string(value); }; @@ -117,11 +117,11 @@ namespace stormkit::lua::core { //////////////////////////////////////// //////////////////////////////////////// template - auto _bind_matrix(std::string_view name, auto& parent) { + auto _bind_matrix(string_view name, auto& parent) { auto metatable = parent.template new_usertype(name, sol::constructors {}); metatable[sol::meta_function::index] = +[](T* value, usize index) static noexcept { - return std::span { &((*value)[index, 0u]), T::EXTENTS[1] }; + return array_view { &((*value)[index, 0u]), T::EXTENTS[1] }; }; metatable[sol::meta_function::to_string] = +[](const T& value) static noexcept { return math::to_string(value); }; diff --git a/src/lua/entities.cpp b/src/lua/entities.cpp index d1a8e6337..d6231e053 100644 --- a/src/lua/entities.cpp +++ b/src/lua/entities.cpp @@ -47,23 +47,23 @@ namespace stormkit::lua::entities { const auto result = luacall(type, component); const auto value = sol::object { result }; - ensures(value.is(), "Component type() must return a string or a component type"); - const auto _type = hash(value.as()); + ensures(value.is(), "Component type() must return a string or a component type"); + const auto _type = hash(value.as()); manager->add_component(entity, LuaComponent { .data = std::move(component), ._type = _type }); }; - manager["get_component"] = +[](EntityManager* manager, Entity entity, std::string_view name) static noexcept { + manager["get_component"] = +[](EntityManager* manager, Entity entity, string_view name) static noexcept { return manager->get_component(entity, name).data; }; - manager["has_component"] = +[](EntityManager* manager, Entity entity, std::string_view name) static noexcept { + manager["has_component"] = +[](EntityManager* manager, Entity entity, string_view name) static noexcept { return manager->has_component(entity, name); }; manager["entities"] = &EntityManager::entities; manager["entity_count"] = &EntityManager::entity_count; manager["components_types_of"] = &EntityManager::components_types_of; - manager["add_system"] = +[](EntityManager* manager, - std::string name, - std::vector types, - sol::table opt) static noexcept { + manager["add_system"] = +[](EntityManager* manager, + string name, + dyn_array types, + sol::table opt) static noexcept { auto update = opt.get>("update"); expects(update.has_value(), std::format("No update closure supplied for system {}", name)); @@ -88,7 +88,7 @@ namespace stormkit::lua::entities { manager->add_system(std::move(name), types | stdv::transform([](const auto& type) static noexcept { return hash(type); - }) | stdr::to(), + }) | stdr::to>(), std::move(_closures)); }; manager["has_system"] = &EntityManager::has_system; diff --git a/src/lua/log.cpp b/src/lua/log.cpp index 986ba74af..eb72c4351 100644 --- a/src/lua/log.cpp +++ b/src/lua/log.cpp @@ -20,34 +20,34 @@ LOGGER("lua") namespace stormkit::lua::log { auto init_lua(sol::state& global_state) noexcept -> void { auto log_table = global_state["log"].get_or_create(); - log_table["info"] = [&global_state](std::string_view str, sol::variadic_args args) noexcept { + log_table["info"] = [&global_state](string_view str, sol::variadic_args args) noexcept { const auto format = sol::protected_function { global_state["format"] }; const auto result = luacall(format, str, std::move(args)); - const auto out = sol::object { result }.as(); + const auto out = sol::object { result }.as(); ilog("{}", out); }; - log_table["debug"] = [&global_state](std::string_view str, sol::variadic_args args) noexcept { + log_table["debug"] = [&global_state](string_view str, sol::variadic_args args) noexcept { const auto format = sol::protected_function { global_state["format"] }; const auto result = luacall(format, str, std::move(args)); - const auto out = sol::object { result }.as(); + const auto out = sol::object { result }.as(); dlog("{}", out); }; - log_table["error"] = [&global_state](std::string_view str, sol::variadic_args args) noexcept { + log_table["error"] = [&global_state](string_view str, sol::variadic_args args) noexcept { const auto format = sol::protected_function { global_state["format"] }; const auto result = luacall(format, str, std::move(args)); - const auto out = sol::object { result }.as(); + const auto out = sol::object { result }.as(); elog("{}", out); }; - log_table["fatal"] = [&global_state](std::string_view str, sol::variadic_args args) noexcept { + log_table["fatal"] = [&global_state](string_view str, sol::variadic_args args) noexcept { const auto format = sol::protected_function { global_state["format"] }; const auto result = luacall(format, str, std::move(args)); - const auto out = sol::object { result }.as(); + const auto out = sol::object { result }.as(); flog("{}", out); }; - log_table["warning"] = [&global_state](std::string_view str, sol::variadic_args args) noexcept { + log_table["warning"] = [&global_state](string_view str, sol::variadic_args args) noexcept { const auto format = sol::protected_function { global_state["format"] }; const auto result = luacall(format, str, std::move(args)); - const auto out = sol::object { result }.as(); + const auto out = sol::object { result }.as(); wlog("{}", out); }; } diff --git a/src/lua/lua.cpp b/src/lua/lua.cpp index 142b11628..dbb1cf66d 100644 --- a/src/lua/lua.cpp +++ b/src/lua/lua.cpp @@ -66,7 +66,7 @@ namespace stormkit::lua { init_libraries(state); m_init_user_libraries(state); - auto result = state.do_string(std::string_view { stdr::data(m_script), stdr::size(m_script) }); + auto result = state.do_string(string_view { stdr::data(m_script), stdr::size(m_script) }); if (not result.valid()) elog("lua error!\n{}", sol::error { result }.what()); return state; @@ -88,12 +88,12 @@ namespace stormkit::lua { auto tostring = sol::protected_function { global_state["tostring"] }; global_state["tostring"] = [format = std::move(tostring)](sol::object v) noexcept { - if (not v.valid()) return std::string {}; + if (not v.valid()) return string {}; if (v.is()) { - auto out = std::string { "[lua_table " }; + auto out = string { "[lua_table " }; for (auto&& [key, value] : v.as()) { - auto key_as_string = sol::object { luacall(format, key) }.as(); - auto value_as_string = sol::object { luacall(format, value) }.as(); + auto key_as_string = sol::object { luacall(format, key) }.as(); + auto value_as_string = sol::object { luacall(format, value) }.as(); out += key_as_string; out += ": "; out += value_as_string; @@ -103,23 +103,23 @@ namespace stormkit::lua { out += "]"; return out; } - return sol::object { luacall(format, v) }.as(); + return sol::object { luacall(format, v) }.as(); }; - global_state["print"] = [&global_state](std::string_view str, sol::variadic_args args) noexcept { + global_state["print"] = [&global_state](string_view str, sol::variadic_args args) noexcept { const auto format = sol::protected_function { global_state["format"] }; const auto result = luacall(format, str, std::move(args)); - const auto out = sol::object { result }.as(); + const auto out = sol::object { result }.as(); std::println("{}", out); }; - global_state["format"] = [&global_state](std::string_view str, sol::variadic_args args) noexcept { + global_state["format"] = [&global_state](string_view str, sol::variadic_args args) noexcept { auto slices = split(str, "{}"); if (stdr::size(slices) == 1) { return std::format("{}", str); } expects(args.size() == stdr::size(slices) - 1, std::format("Invalid count of args! should be {}, got {}", stdr::size(slices) - 1, args.size())); - auto out = std::string {}; + auto out = string {}; out.reserve(stdr::size(str)); auto it = stdr::begin(slices); out += *it; @@ -127,7 +127,7 @@ namespace stormkit::lua { for (auto v : args) { auto format = sol::protected_function { global_state["tostring"] }; const auto result = luacall(global_state["tostring"], v); - out += sol::object { result }.as(); + out += sol::object { result }.as(); out += *it; ++it; diff --git a/src/lua/wsi/window.cpp b/src/lua/wsi/window.cpp index 9908c5f68..108021bcc 100644 --- a/src/lua/wsi/window.cpp +++ b/src/lua/wsi/window.cpp @@ -42,7 +42,7 @@ namespace stormkit::lua::wsi { //////////////////////////////////////// //////////////////////////////////////// - auto open_window(std::string name, u32 width, u32 height, wsi::WindowFlag flags) noexcept -> wsi::Window { + auto open_window(string name, u32 width, u32 height, wsi::WindowFlag flags) noexcept -> wsi::Window { return wsi::Window::open(std::move(name), { width, height }, flags); } diff --git a/src/main/linux/main_linux.cpp b/src/main/linux/main_linux.cpp index 03f381736..4037eb59c 100644 --- a/src/main/linux/main_linux.cpp +++ b/src/main/linux/main_linux.cpp @@ -7,15 +7,17 @@ import stormkit.core; #include -extern auto user_main(std::span) -> int; +using namespace stormkit; -auto main(int argc, char** argv) -> int { - stormkit::setup_signal_handler(); - stormkit::set_current_thread_name("stormkit:main_thread"); +extern auto user_main(array_view) -> i32; - auto args = std::vector {}; +auto main(i32 argc, char** argv) -> i32 { + setup_signal_handler(); + set_current_thread_name("stormkit:main_thread"); - for (auto i : stormkit::range(argc)) args.emplace_back(argv[i]); + auto args = dyn_array {}; + + for (auto i : range(argc)) args.emplace_back(argv[i]); return user_main(args); } diff --git a/src/main/macos/stormkit_core.cpp b/src/main/macos/stormkit_core.cpp index f025ad881..b36b4f1a4 100644 --- a/src/main/macos/stormkit_core.cpp +++ b/src/main/macos/stormkit_core.cpp @@ -6,6 +6,6 @@ auto setup_signal_handler() -> void { stormkit::setup_signal_handler(); } -auto set_current_thread_name(std::string_view name) -> void { +auto set_current_thread_name(string_view name) -> void { stormkit::set_current_thread_name(name); } diff --git a/src/main/macos/stormkit_core.hpp b/src/main/macos/stormkit_core.hpp index c4e83c1f6..7a56a9a4c 100644 --- a/src/main/macos/stormkit_core.hpp +++ b/src/main/macos/stormkit_core.hpp @@ -4,6 +4,6 @@ #include auto setup_signal_handler() -> void; -auto set_current_thread_name(std::string_view name) -> void; +auto set_current_thread_name(string_view name) -> void; #endif diff --git a/src/main/win32/main_win.cpp b/src/main/win32/main_win.cpp index a851f492c..0e9a8dfb5 100644 --- a/src/main/win32/main_win.cpp +++ b/src/main/win32/main_win.cpp @@ -75,10 +75,10 @@ namespace { } } // namespace -extern auto user_main(std::span) -> int; +extern auto user_main(array_view) -> int; auto __stdcall main(int argc, char** argv) -> int { - auto args = std::vector {}; + auto args = dyn_array {}; args.reserve(as(argc)); for (auto&& i : stormkit::range(argc)) args.emplace_back(argv[i]); @@ -95,7 +95,7 @@ auto __stdcall WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) -> int { const auto argc = __argc; const auto argv = __argv; - auto args = std::vector {}; + auto args = dyn_array {}; args.reserve(as(argc)); for (auto&& i : stormkit::range(argc)) args.emplace_back(argv[i]); diff --git a/src/test/main.cpp b/src/test/main.cpp index 01097bf6f..875aa3880 100644 --- a/src/test/main.cpp +++ b/src/test/main.cpp @@ -9,7 +9,9 @@ import std; #include -auto main(std::span args) noexcept -> int { +using namespace stormkit; + +auto main(array_view args) noexcept -> i32 { test::parse_args(args); return test::runTests(); diff --git a/src/wsi/common/input_base.cppm b/src/wsi/common/input_base.cppm index bcb826c34..814e76bc4 100644 --- a/src/wsi/common/input_base.cppm +++ b/src/wsi/common/input_base.cppm @@ -30,7 +30,7 @@ export namespace stormkit::wsi::common { u8 id; bool key_repeat = false; - std::array keys = filled_with<102>(KeyState::UP); + array keys = filled_with<102>(KeyState::UP); }; enum class ButtonState : u8 { @@ -48,7 +48,7 @@ export namespace stormkit::wsi::common { math::uvec2 locked_at = {}; math::uvec2 last_position = {}; - std::array buttons = filled_with<15>(ButtonState::UP); + array buttons = filled_with<15>(ButtonState::UP); }; } // namespace stormkit::wsi::common diff --git a/src/wsi/common/window_base.cppm b/src/wsi/common/window_base.cppm index 29f745ca8..451aa5722 100644 --- a/src/wsi/common/window_base.cppm +++ b/src/wsi/common/window_base.cppm @@ -47,9 +47,9 @@ export namespace stormkit::wsi::common { auto current_monitor() const noexcept -> const Monitor&; auto set_current_monitor(const Monitor& extent) noexcept -> void; - auto set_title(std::string title) noexcept -> bool; + auto set_title(string title) noexcept -> bool; [[nodiscard]] - auto title() const noexcept -> const std::string&; + auto title() const noexcept -> const string&; auto set_extent(const math::uextent2& extent) noexcept -> bool; [[nodiscard]] @@ -100,15 +100,15 @@ export namespace stormkit::wsi::common { bool visible = false; math::uextent2 extent; optref current_monitor; - std::string title; + string title; f32 dpi = 1.f; math::ivec2 position = { 0, 0 }; } m_state; - std::vector m_mouse_states; - std::vector m_keyboard_states; + dyn_array m_mouse_states; + dyn_array m_keyboard_states; }; } // namespace stormkit::wsi::common @@ -155,7 +155,7 @@ namespace stormkit::wsi::common { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto WindowBase::set_title(std::string title) noexcept -> bool { + inline auto WindowBase::set_title(string title) noexcept -> bool { if (not m_state.open) return false; m_state.title = std::move(title); @@ -165,7 +165,7 @@ namespace stormkit::wsi::common { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto WindowBase::title() const noexcept -> const std::string& { + inline auto WindowBase::title() const noexcept -> const string& { return m_state.title; } diff --git a/src/wsi/core.cpp b/src/wsi/core.cpp index 87b15def0..bdafa40ae 100644 --- a/src/wsi/core.cpp +++ b/src/wsi/core.cpp @@ -21,7 +21,7 @@ namespace stormkit::wsi { ///////////////////////////////////// ///////////////////////////////////// - auto parse_args(std::span args) noexcept -> void { + auto parse_args(array_view args) noexcept -> void { auto hint = std::ranges::find_if(args, [](auto&& v) { return v == "--x11" or v == "--wayland"; }); if (hint != std::ranges::cend(args)) { diff --git a/src/wsi/ios/window_impl.hpp b/src/wsi/ios/window_impl.hpp index 3a25a3cf6..0dba9bc8c 100644 --- a/src/wsi/ios/window_impl.hpp +++ b/src/wsi/ios/window_impl.hpp @@ -28,12 +28,12 @@ namespace storm::window { class STORMKIT_PRIVATE Window: public storm::window::AbstractWindow { public: Window() noexcept; - Window(const std::string& title, + Window(const string& title, const storm::window::VideoSettings& settings, storm::window::WindowStyle style) noexcept; ~Window() override; - void create(const std::string& title, + void create(const string& title, const storm::window::VideoSettings& settings, storm::window::WindowStyle style) noexcept override; void close() noexcept override; @@ -41,7 +41,7 @@ namespace storm::window { bool poll_event(storm::window::Event& event, void* native_event) noexcept override; bool wait_event(storm::window::Event& event, void* native_event) noexcept override; - void set_title(const std::string& title) noexcept override; + void set_title(const string& title) noexcept override; void setVideoSettings(const storm::window::VideoSettings& settings) noexcept override; storm::core::extentu size() const noexcept override; diff --git a/src/wsi/linux/common/xkb.cppm b/src/wsi/linux/common/xkb.cppm index d1c340568..ea8091a57 100644 --- a/src/wsi/linux/common/xkb.cppm +++ b/src/wsi/linux/common/xkb.cppm @@ -176,7 +176,7 @@ namespace stormkit::wsi::linux::common { }); constexpr auto KEY_AS_SCANCODE = [] static noexcept -> decltype(auto) { - auto out = std::array, 111> {}; + auto out = array, 111> {}; auto i = 0_usize; for (const auto& [key, value] : SCANCODE_AS_KEY) out[i++] = std::make_pair(value, key); diff --git a/src/wsi/linux/monitor.cppm b/src/wsi/linux/monitor.cppm index 41a59e196..954813fdb 100644 --- a/src/wsi/linux/monitor.cppm +++ b/src/wsi/linux/monitor.cppm @@ -15,7 +15,7 @@ import :linux.x11.monitor; namespace stormkit::wsi::linux { ///////////////////////////////////// ///////////////////////////////////// - auto get_monitors(WM wm, bool update = false) noexcept -> std::span { + auto get_monitors(WM wm, bool update = false) noexcept -> array_view { switch (wm) { case WM::X11: return x11::get_monitors(wm, update); case WM::WAYLAND: return wayland::get_monitors(wm, update); diff --git a/src/wsi/linux/wayland/context.cpp b/src/wsi/linux/wayland/context.cpp index fc3b52cde..fcb14876a 100644 --- a/src/wsi/linux/wayland/context.cpp +++ b/src/wsi/linux/wayland/context.cpp @@ -225,7 +225,7 @@ namespace stormkit::wsi::linux::wayland::wl { auto& _globals = *std::bit_cast(data); - const auto interface_name = std::string_view { interface, std::char_traits::length(interface) }; + const auto interface_name = string_view { interface, std::char_traits::length(interface) }; const auto it = INTERFACE_MAP.find(interface_name); if (it == stdr::cend(INTERFACE_MAP)) return; diff --git a/src/wsi/linux/wayland/context.cppm b/src/wsi/linux/wayland/context.cppm index 5981d99f5..427a232d1 100644 --- a/src/wsi/linux/wayland/context.cppm +++ b/src/wsi/linux/wayland/context.cppm @@ -39,7 +39,7 @@ export namespace stormkit::wsi::linux::wayland { wl::Display display = wl::Display::empty(); wl::Registry registry = wl::Registry::empty(); wl::Compositor compositor = wl::Compositor::empty(); - std::vector outputs; + dyn_array outputs; wl::XDGWmBase xdg_wm_base = wl::XDGWmBase::empty(); wl::Shm shm = wl::Shm::empty(); wl::XDGDecorationManager decoration_manager = wl::XDGDecorationManager::empty(); @@ -55,15 +55,15 @@ export namespace stormkit::wsi::linux::wayland { wl::CursorTheme cursor_theme = wl::CursorTheme::empty(); wl::CursorTheme cursor_theme_high_dpi = wl::CursorTheme::empty(); - std::vector> keyboards; - std::vector> pointers; - std::vector> touchs; + dyn_array> keyboards; + dyn_array> pointers; + dyn_array> touchs; wl::RelativePointerManager relative_pointer_manager = wl::RelativePointerManager::empty(); - std::vector monitors; + dyn_array monitors; - std::vector> windows; + dyn_array> windows; common::xkb::Context xkb_context = common::xkb::Context::empty(); }; diff --git a/src/wsi/linux/wayland/inputs.cpp b/src/wsi/linux/wayland/inputs.cpp index 577fcc931..d9ffeb8ce 100644 --- a/src/wsi/linux/wayland/inputs.cpp +++ b/src/wsi/linux/wayland/inputs.cpp @@ -36,7 +36,7 @@ namespace stormkit::wsi::linux::wayland::wl { auto keyboard_key_handler(void*, wl_keyboard*, u32, u32, u32, u32) noexcept -> void; auto keyboard_modifiers_handler(void*, wl_keyboard*, u32, u32, u32, u32, u32) noexcept -> void; auto keyboard_repeat_info_handler(void*, wl_keyboard*, i32, i32) noexcept -> void; - auto update_keymap(KeyboardState&, std::string_view) noexcept -> void; + auto update_keymap(KeyboardState&, string_view) noexcept -> void; auto pointer_enter_handler(void*, wl_pointer*, u32, wl_surface*, wl_fixed_t, wl_fixed_t) noexcept -> void; auto pointer_leave_handler(void*, wl_pointer*, u32, wl_surface*) noexcept -> void; @@ -140,7 +140,7 @@ namespace stormkit::wsi::linux::wayland::wl { if (format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { auto map_shm = std::bit_cast(mmap(nullptr, size, PROT_READ, MAP_PRIVATE, fd, 0)); - update_keymap(state, std::string_view { map_shm, size }); + update_keymap(state, string_view { map_shm, size }); munmap(map_shm, size); ::close(fd); @@ -154,7 +154,7 @@ namespace stormkit::wsi::linux::wayland::wl { auto& state = *std::bit_cast(data); if (not state.focused_window or not state.xkb_state) return; - auto characters = std::array {}; + auto characters = array {}; // stdr const auto keycode = key + 8; @@ -218,7 +218,7 @@ namespace stormkit::wsi::linux::wayland::wl { ///////////////////////////////////// ///////////////////////////////////// - auto update_keymap(KeyboardState& state, std::string_view keymap) noexcept -> void { + auto update_keymap(KeyboardState& state, string_view keymap) noexcept -> void { auto& globals = get_globals(); state.xkb_keymap = common::xkb::Keymap::create(globals.xkb_context, std::data(keymap), diff --git a/src/wsi/linux/wayland/inputs.cppm b/src/wsi/linux/wayland/inputs.cppm index 7879b4b95..2a1e5fe24 100644 --- a/src/wsi/linux/wayland/inputs.cppm +++ b/src/wsi/linux/wayland/inputs.cppm @@ -41,14 +41,14 @@ export namespace stormkit::wsi::linux::wayland { std::optional serial = std::nullopt; - std::array button_state; + array button_state; wl::ConfinedPointer confined_pointer = wl::ConfinedPointer::empty(); wl::LockedPointer locked_pointer = wl::LockedPointer::empty(); wl::RelativePointer relative_pointer = wl::RelativePointer::empty(); struct Cursor { - std::string name; + string name; wl::Surface surface = wl::Surface::empty(); wl::CursorShapeDevice shape_device = wl::CursorShapeDevice::empty(); @@ -85,7 +85,7 @@ export namespace stormkit::wsi::linux::wayland { Window* focused_window = nullptr; - std::array keyboard_state = { + array keyboard_state = { KeyState { XKB_KEY_a, false }, KeyState { XKB_KEY_b, false }, KeyState { XKB_KEY_c, false }, diff --git a/src/wsi/linux/wayland/monitor.cppm b/src/wsi/linux/wayland/monitor.cppm index 3e8cc03e1..3aad60239 100644 --- a/src/wsi/linux/wayland/monitor.cppm +++ b/src/wsi/linux/wayland/monitor.cppm @@ -17,13 +17,13 @@ namespace stdv = std::views; namespace stormkit::wsi::linux::wayland { ///////////////////////////////////// ///////////////////////////////////// - auto get_monitors(WM, bool update) noexcept -> std::span { - thread_local auto monitors = std::vector {}; + auto get_monitors(WM, bool update) noexcept -> array_view { + thread_local auto monitors = dyn_array {}; if (update or stdr::empty(monitors)) { auto& globals = wl::get_globals(); monitors = globals.monitors | stdv::transform([](const wl::WaylandMonitor& pair) static noexcept { return pair.monitor; }) - | stdr::to(); + | stdr::to>(); } return monitors; diff --git a/src/wsi/linux/wayland/window.cpp b/src/wsi/linux/wayland/window.cpp index 478db36c0..891abc253 100644 --- a/src/wsi/linux/wayland/window.cpp +++ b/src/wsi/linux/wayland/window.cpp @@ -114,7 +114,7 @@ namespace stormkit::wsi::linux::wayland { ///////////////////////////////////// ///////////////////////////////////// - auto Window::open(std::string title, const math::uextent2& extent, WindowFlag flags) noexcept -> void { + auto Window::open(string title, const math::uextent2& extent, WindowFlag flags) noexcept -> void { auto& globals = wl::get_globals(); m_surface = wl::Surface::create(globals.compositor); @@ -197,7 +197,7 @@ namespace stormkit::wsi::linux::wayland { auto Window::clear(const ucolor_rgb& color) noexcept -> void { const auto value = (255 << 24) + (color.r << 16) + (color.g << 8) + (color.b); - auto view = std::span { std::bit_cast(m_shm_buffer.value().begin()), m_shm_buffer->size() / sizeof(i32) }; + auto view = array_view { std::bit_cast(m_shm_buffer.value().begin()), m_shm_buffer->size() / sizeof(i32) }; stdr::fill(view, value); const auto [width, height] = extent().to(); @@ -207,8 +207,8 @@ namespace stormkit::wsi::linux::wayland { ///////////////////////////////////// ///////////////////////////////////// - auto Window::fill_framebuffer(std::span colors) noexcept -> void { - auto view = std::span { std::bit_cast(m_shm_buffer.value().begin()), m_shm_buffer->size() / sizeof(i32) }; + auto Window::fill_framebuffer(array_view colors) noexcept -> void { + auto view = array_view { std::bit_cast(m_shm_buffer.value().begin()), m_shm_buffer->size() / sizeof(i32) }; stdr::copy(colors | stdv::transform([](const auto& color) static noexcept { return (255 << 24) + (color.r << 16) + (color.g << 8) + (color.b); }), @@ -221,7 +221,7 @@ namespace stormkit::wsi::linux::wayland { ///////////////////////////////////// ///////////////////////////////////// - auto Window::set_title(std::string title) noexcept -> void { + auto Window::set_title(string title) noexcept -> void { if (!m_state.open) return; m_title = std::move(title); @@ -499,7 +499,7 @@ namespace stormkit::wsi::linux::wayland { ///////////////////////////////////// ///////////////////////////////////// - auto Window::handle_xdg_top_level_configure(u32 width, u32 height, std::span states) noexcept + auto Window::handle_xdg_top_level_configure(u32 width, u32 height, array_view states) noexcept -> void { m_state.open = true; @@ -660,7 +660,7 @@ namespace stormkit::wsi::linux::wayland { ///////////////////////////////////// ///////////////////////////////////// - auto Window::set_cursor(std::string_view name, wl_pointer* pointer, wl::PointerState& state) noexcept -> void { + auto Window::set_cursor(string_view name, wl_pointer* pointer, wl::PointerState& state) noexcept -> void { auto& globals = wl::get_globals(); auto cursor_theme = globals.cursor_theme.handle(); diff --git a/src/wsi/linux/wayland/window.cppm b/src/wsi/linux/wayland/window.cppm index c08c6511d..c0b780455 100644 --- a/src/wsi/linux/wayland/window.cppm +++ b/src/wsi/linux/wayland/window.cppm @@ -43,15 +43,15 @@ export { Window(Window&&) noexcept; auto operator=(Window&&) noexcept -> Window&; - auto open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> void; + auto open(string title, const math::uextent2& size, WindowFlag flags) noexcept -> void; auto close() noexcept -> void; auto handle_events() noexcept -> void; auto clear(const ucolor_rgb& color) noexcept -> void; - auto fill_framebuffer(std::span colors) noexcept -> void; + auto fill_framebuffer(array_view colors) noexcept -> void; - auto set_title(std::string title) noexcept -> void; + auto set_title(string title) noexcept -> void; auto set_extent(const math::uextent2& extent) noexcept -> void; auto set_fullscreen(bool fullscreen) noexcept -> void; @@ -87,7 +87,7 @@ export { auto handle_xdg_surface_configure(u32) noexcept -> void; auto handle_xdg_surface_close() noexcept -> void; - auto handle_xdg_top_level_configure(u32, u32, std::span) noexcept -> void; + auto handle_xdg_top_level_configure(u32, u32, array_view) noexcept -> void; auto handle_surface_enter(wl_surface*, wl_output*) noexcept -> void; auto handle_keyboard_key(Key, char, bool) noexcept -> void; @@ -101,7 +101,7 @@ export { auto reallocate_pixel_buffer() noexcept -> void; auto hide_mouse(bool hidden, wl_pointer*, wl::PointerState&) noexcept -> void; - auto set_cursor(std::string_view, wl_pointer*, wl::PointerState&) noexcept -> void; + auto set_cursor(string_view, wl_pointer*, wl::PointerState&) noexcept -> void; auto handle_key_repeat() noexcept -> void; @@ -112,7 +112,7 @@ export { WindowFlag m_flags; wl_output* m_current_output = nullptr; - std::string m_title; + string m_title; Handles m_handles; diff --git a/src/wsi/linux/window.cppm b/src/wsi/linux/window.cppm index 76b819fbc..35da13714 100644 --- a/src/wsi/linux/window.cppm +++ b/src/wsi/linux/window.cppm @@ -35,7 +35,7 @@ export namespace stormkit::wsi::linux { Window(Window&&) noexcept; auto operator=(Window&&) noexcept -> Window&; - auto open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> void; + auto open(string title, const math::uextent2& size, WindowFlag flags) noexcept -> void; auto close() noexcept -> void; [[nodiscard]] @@ -50,11 +50,11 @@ export namespace stormkit::wsi::linux { auto handle_events() noexcept -> void; auto clear(const ucolor_rgb& color) noexcept -> void; - auto fill_framebuffer(std::span colors) noexcept -> void; + auto fill_framebuffer(array_view colors) noexcept -> void; - auto set_title(std::string title) noexcept -> void; + auto set_title(string title) noexcept -> void; [[nodiscard]] - auto title() const noexcept -> const std::string&; + auto title() const noexcept -> const string&; auto set_extent(const math::uextent2& extent) noexcept -> void; [[nodiscard]] @@ -141,7 +141,7 @@ namespace stormkit::wsi::linux { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Window::open(std::string title, const math::uextent2& extent, WindowFlag flags) noexcept -> void { + inline auto Window::open(string title, const math::uextent2& extent, WindowFlag flags) noexcept -> void { switch (m_wm) { case WM::X11: as(m_impl).open(std::move(title), extent, flags); break; case WM::WAYLAND: as(m_impl).open(std::move(title), extent, flags); break; @@ -231,7 +231,7 @@ namespace stormkit::wsi::linux { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Window::fill_framebuffer(std::span colors) noexcept -> void { + inline auto Window::fill_framebuffer(array_view colors) noexcept -> void { switch (m_wm) { case WM::X11: as(m_impl).fill_framebuffer(colors); break; case WM::WAYLAND: as(m_impl).fill_framebuffer(colors); break; @@ -243,7 +243,7 @@ namespace stormkit::wsi::linux { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - inline auto Window::set_title(std::string title) noexcept -> void { + inline auto Window::set_title(string title) noexcept -> void { switch (m_wm) { case WM::X11: as(m_impl).set_title(std::move(title)); break; case WM::WAYLAND: as(m_impl).set_title(std::move(title)); break; @@ -255,7 +255,7 @@ namespace stormkit::wsi::linux { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE STORMKIT_PURE - inline auto Window::title() const noexcept -> const std::string& { + inline auto Window::title() const noexcept -> const string& { switch (m_wm) { case WM::X11: return as(m_impl).title(); case WM::WAYLAND: return as(m_impl).title(); diff --git a/src/wsi/linux/x11/context.cpp b/src/wsi/linux/x11/context.cpp index bd7ea2592..81ffccd9d 100644 --- a/src/wsi/linux/x11/context.cpp +++ b/src/wsi/linux/x11/context.cpp @@ -30,7 +30,7 @@ namespace stormkit::wsi::linux::x11::xcb { namespace { thread_local constinit auto initialized = false; thread_local constinit auto globals = Globals {}; - thread_local auto atoms = stormkit::StringHashMap {}; + thread_local auto atoms = stormkit::string_hash_map {}; } // namespace ///////////////////////////////////// @@ -66,7 +66,7 @@ namespace stormkit::wsi::linux::x11::xcb { ///////////////////////////////////// ///////////////////////////////////// - auto get_atom(std::string_view name, bool only_if_exists) noexcept -> std::expected { + auto get_atom(string_view name, bool only_if_exists) noexcept -> std::expected { auto out = std::expected {}; auto it = atoms.find(name); @@ -89,8 +89,8 @@ namespace stormkit::wsi::linux::x11::xcb { return out; } - auto get_atom_name(xcb_atom_t atom) -> std::expected { - auto out = std::expected {}; + auto get_atom_name(xcb_atom_t atom) -> std::expected { + auto out = std::expected {}; const auto cookie = xcb_get_atom_name(globals.connection, atom); @@ -98,20 +98,20 @@ namespace stormkit::wsi::linux::x11::xcb { const auto reply = xcb::AtomNameReply::create(globals.connection, cookie, &error.handle()); if (error) out = std::unexpected { std::in_place, get_error(as_ref_mut(*error)) }; else - out = std::string { xcb_get_atom_name_name(reply), as(xcb_get_atom_name_name_length(reply)) }; + out = string { xcb_get_atom_name_name(reply), as(xcb_get_atom_name_name_length(reply)) }; return out; } ///////////////////////////////////// ///////////////////////////////////// - auto get_error(ref error) -> std::string { + auto get_error(ref error) -> string { auto guard = xcb::GenericError::take(error); const auto major = xcb_errors_get_name_for_major_code(globals.error_context, error->major_code); const auto minor = xcb_errors_get_name_for_minor_code(globals.error_context, error->major_code, error->minor_code); - const auto* extension = CZString { nullptr }; + const auto* extension = czstring { nullptr }; const auto str_error = xcb_errors_get_name_for_error(globals.error_context, error->major_code, &extension); return std::format("{} extension: {} major: {} minor: {}\n", diff --git a/src/wsi/linux/x11/context.cppm b/src/wsi/linux/x11/context.cppm index 48a727c3c..7a4b06478 100644 --- a/src/wsi/linux/x11/context.cppm +++ b/src/wsi/linux/x11/context.cppm @@ -31,15 +31,15 @@ export namespace stormkit::wsi::linux::x11::xcb { auto init() noexcept -> bool; auto get_globals() noexcept -> Globals&; - auto get_atom(std::string_view name, bool only_if_exists) noexcept -> std::expected; - auto get_atom_name(xcb_atom_t atom) -> std::expected; + auto get_atom(string_view name, bool only_if_exists) noexcept -> std::expected; + auto get_atom_name(xcb_atom_t atom) -> std::expected; - auto get_error(ref error) -> std::string; + auto get_error(ref error) -> string; auto get_xi_device_info(xcb_input_device_id_t device_id) -> std::expected, Error>; // template - // auto get_xft_value(std::string_view name) -> std::optional; + // auto get_xft_value(string_view name) -> std::optional; } // namespace stormkit::wsi::linux::x11::xcb //////////////////////////////////////////////////////////////////// @@ -52,7 +52,7 @@ export namespace stormkit::wsi::linux::x11::xcb { // ///////////////////////////////////// // ///////////////////////////////////// // template - // auto get_xft_value(std::string_view name) -> std::optional { + // auto get_xft_value(string_view name) -> std::optional { // using XcbXrmDatabase = RAIICapsule std::span { - thread_local auto monitors = std::vector {}; + auto get_monitors(WM, bool update) noexcept -> array_view { + thread_local auto monitors = dyn_array {}; if (stdr::empty(monitors) or update) { auto& globals = xcb::get_globals(); diff --git a/src/wsi/linux/x11/window.cpp b/src/wsi/linux/x11/window.cpp index 770cb2271..89724012d 100644 --- a/src/wsi/linux/x11/window.cpp +++ b/src/wsi/linux/x11/window.cpp @@ -45,13 +45,13 @@ namespace stdv = std::views; namespace stormkit::wsi::linux::x11 { namespace { [[maybe_unused]] - constexpr auto WM_CLASS = std::string_view("WM_CLASS"); - constexpr auto WM_HINTS_STR = std::string_view("_MOTIF_WM_HINTS"); - constexpr auto WM_PROTOCOLS = std::string_view("WM_PROTOCOLS"); - constexpr auto WM_DELETE_WINDOW = std::string_view("WM_DELETE_WINDOW"); - constexpr auto WM_STATE_STR = std::string_view("_NET_WM_STATE"); - constexpr auto WM_STATE_FULLSCREEN_STR = std::string_view("_NET_WM_STATE_FULLSCREEN"); - constexpr auto WM_STATE_HIDDEN_STR = std::string_view("_NET_WM_STATE_HIDDEN"); + constexpr auto WM_CLASS = string_view("WM_CLASS"); + constexpr auto WM_HINTS_STR = string_view("_MOTIF_WM_HINTS"); + constexpr auto WM_PROTOCOLS = string_view("WM_PROTOCOLS"); + constexpr auto WM_DELETE_WINDOW = string_view("WM_DELETE_WINDOW"); + constexpr auto WM_STATE_STR = string_view("_NET_WM_STATE"); + constexpr auto WM_STATE_FULLSCREEN_STR = string_view("_NET_WM_STATE_FULLSCREEN"); + constexpr auto WM_STATE_HIDDEN_STR = string_view("_NET_WM_STATE_HIDDEN"); constexpr auto MWM_HINTS_FUNCTIONS = 1 << 0; constexpr auto MWM_HINTS_DECORATIONS = 1 << 1; @@ -136,7 +136,7 @@ namespace stormkit::wsi::linux::x11 { ///////////////////////////////////// ///////////////////////////////////// - auto Window::open(std::string title, const math::uextent2& extent, WindowFlag flags) noexcept -> void { + auto Window::open(string title, const math::uextent2& extent, WindowFlag flags) noexcept -> void { const auto& connection = xcb::get_globals().connection; const auto screen = xcb_setup_roots_iterator(xcb_get_setup(connection)).data; @@ -148,7 +148,7 @@ namespace stormkit::wsi::linux::x11 { { m_color_map = xcb::ColorMap::create(connection); xcb_create_colormap(connection, XCB_COLORMAP_ALLOC_NONE, m_color_map, screen->root, screen->root_visual); - const auto value_list = std::array { screen->white_pixel, EVENTS, m_color_map }; + const auto value_list = array { screen->white_pixel, EVENTS, m_color_map }; const auto cookie = xcb_create_window_checked(connection, screen->root_depth, @@ -350,7 +350,7 @@ namespace stormkit::wsi::linux::x11 { if (not check_flag_bit(flags, WindowFlag::EXTERNAL_CONTEXT)) { m_graphics_context = xcb::GraphicsContext::create(connection); - const auto values = std::array { screen->white_pixel, screen->black_pixel, 0_u32 }; + const auto values = array { screen->white_pixel, screen->black_pixel, 0_u32 }; xcb_create_gc(connection, m_graphics_context, m_window, @@ -428,7 +428,7 @@ namespace stormkit::wsi::linux::x11 { ///////////////////////////////////// ///////////////////////////////////// - auto Window::fill_framebuffer(std::span pixels) noexcept -> void { + auto Window::fill_framebuffer(array_view pixels) noexcept -> void { expects(m_graphics_context, "fill_framebuffer called on a window opened with EXTERNAL_CONTEXT flag"); const auto count = std::min(stdr::size(pixels), stdr::size(m_framebuffer)); stdr::copy(pixels | stdv::take(count) | stdv::transform([](const auto& col) static noexcept { @@ -445,7 +445,7 @@ namespace stormkit::wsi::linux::x11 { ///////////////////////////////////// ///////////////////////////////////// - auto Window::set_title(std::string title) noexcept -> void { + auto Window::set_title(string title) noexcept -> void { const auto& globals = xcb::get_globals(); xcb_change_property(globals.connection, @@ -470,7 +470,7 @@ namespace stormkit::wsi::linux::x11 { const auto mask = XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT; const auto width = as(extent.width); const auto height = as(extent.height); - const auto values = std::array { as(width), as(height) }; + const auto values = array { as(width), as(height) }; xcb_configure_window(globals.connection, m_window, mask, stdr::data(values)); diff --git a/src/wsi/linux/x11/window.cppm b/src/wsi/linux/x11/window.cppm index 3f1a4c911..a2b414a4e 100644 --- a/src/wsi/linux/x11/window.cppm +++ b/src/wsi/linux/x11/window.cppm @@ -72,15 +72,15 @@ export namespace stormkit::wsi::linux::x11 { Window(Window&&) noexcept; auto operator=(Window&&) noexcept -> Window&; - auto open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> void; + auto open(string title, const math::uextent2& size, WindowFlag flags) noexcept -> void; auto close() noexcept -> void; auto handle_events() noexcept -> void; auto clear(const ucolor_rgb& color) noexcept -> void; - auto fill_framebuffer(std::span colors) noexcept -> void; + auto fill_framebuffer(array_view colors) noexcept -> void; - auto set_title(std::string title) noexcept -> void; + auto set_title(string title) noexcept -> void; auto set_extent(const math::uextent2& extent) noexcept -> void; auto set_fullscreen(bool fullscreen) noexcept -> void; @@ -129,7 +129,7 @@ export namespace stormkit::wsi::linux::x11 { xcb::ColorMap m_color_map = xcb::ColorMap::empty(); xcb::GraphicsContext m_graphics_context = xcb::GraphicsContext::empty(); xcb::Image m_image = xcb::Image::empty(); - std::span m_framebuffer; + array_view m_framebuffer; xcb::Pixmap m_pixmap = xcb::Pixmap::empty(); xcb::KeySymbols m_key_symbols = xcb::KeySymbols::empty(); common::xkb::Keymap m_keymap = common::xkb::Keymap::empty(); diff --git a/src/wsi/linux/x11/xcb.cppm b/src/wsi/linux/x11/xcb.cppm index 22a977843..b0c9613ba 100644 --- a/src/wsi/linux/x11/xcb.cppm +++ b/src/wsi/linux/x11/xcb.cppm @@ -22,7 +22,7 @@ import :linux.x11.log; export namespace stormkit::wsi::linux::x11 { struct Error { - std::string message; + string message; }; namespace xcb { @@ -49,13 +49,13 @@ export namespace stormkit::wsi::linux::x11 { using KeySymbols = RAIICapsule; - constexpr auto atom_error(std::string_view msg, std::string_view atom_name) -> decltype(auto); + constexpr auto atom_error(string_view msg, string_view atom_name) -> decltype(auto); } // namespace xcb } // namespace stormkit::wsi::linux::x11 export namespace stormkit::wsi::linux::x11::xcb { STORMKIT_FORCE_INLINE STORMKIT_PURE - constexpr auto atom_error(std::string_view atom_name) -> decltype(auto) { + constexpr auto atom_error(string_view atom_name) -> decltype(auto) { return [atom_name](Error&& error) noexcept -> Error { elog("Failed to get atom " "{}\n > reason: {}", diff --git a/src/wsi/macos/monitor.cppm b/src/wsi/macos/monitor.cppm index b2037221c..803d3c06c 100644 --- a/src/wsi/macos/monitor.cppm +++ b/src/wsi/macos/monitor.cppm @@ -17,7 +17,7 @@ namespace stormkit::wsi::macos { ///////////////////////////////////// ///////////////////////////////////// auto get_monitors(WM, [[maybe_unused]] bool update = false) noexcept - -> std::span { + -> array_view { return {}; } diff --git a/src/wsi/macos/swift/CppBridge.cpp b/src/wsi/macos/swift/CppBridge.cpp index c933c01b1..44fd46d9e 100644 --- a/src/wsi/macos/swift/CppBridge.cpp +++ b/src/wsi/macos/swift/CppBridge.cpp @@ -29,7 +29,7 @@ namespace stormkit::wsi::macos { } consteval auto generate_key_array() -> decltype(auto) { - auto out = std::array {}; + auto out = array {}; stdr::fill(out, Key::UNKNOWN); out[0x00] = Key::A; @@ -159,8 +159,8 @@ namespace stormkit::wsi::macos { return out; } - consteval auto generate_scancode_array(std::span keys) -> decltype(auto) { - auto out = std::array {}; + consteval auto generate_scancode_array(array_view keys) -> decltype(auto) { + auto out = array {}; stdr::fill(out, 0); for (auto i : range(256_u8)) { diff --git a/src/wsi/macos/window.cppm b/src/wsi/macos/window.cppm index 55a7a796c..a8ef407aa 100644 --- a/src/wsi/macos/window.cppm +++ b/src/wsi/macos/window.cppm @@ -56,7 +56,7 @@ export namespace stormkit::wsi::macos { return *this; } - auto open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept + auto open(string title, const math::uextent2& size, WindowFlag flags) noexcept -> void { const auto resizeable = check_flag_bit(flags, WindowFlag::RESIZEABLE); const auto borderless = check_flag_bit(flags, WindowFlag::BORDERLESS); @@ -88,7 +88,7 @@ export namespace stormkit::wsi::macos { m_window->drawBitmap(std::bit_cast(stdr::data(m_pixels))); } - auto fill_framebuffer(std::span pixels) noexcept -> void { + auto fill_framebuffer(array_view pixels) noexcept -> void { const auto [width, height] = extent(); const auto count = std::min(as(stdr::size(pixels)), height * width); if (stdr::size(pixels) > stdr::size(m_pixels)) m_pixels.resize(stdr::size(pixels)); @@ -102,7 +102,7 @@ export namespace stormkit::wsi::macos { m_window->drawBitmap(std::bit_cast(stdr::data(m_pixels))); } - auto set_title(std::string title) noexcept -> void { + auto set_title(string title) noexcept -> void { if (WindowBase::set_title(std::move(title))) { m_window->setTitle(swift::String { m_state.title }); } @@ -205,6 +205,6 @@ export namespace stormkit::wsi::macos { private: DeferInit m_window; - std::vector m_pixels; + dyn_array m_pixels; }; } // namespace stormkit::wsi::macos diff --git a/src/wsi/monitor.cpp b/src/wsi/monitor.cpp index a924de108..35ccb4e98 100644 --- a/src/wsi/monitor.cpp +++ b/src/wsi/monitor.cpp @@ -38,7 +38,7 @@ using namespace std::literals; namespace stormkit::wsi { ///////////////////////////////////// ///////////////////////////////////// - auto get_monitors(bool update) noexcept -> std::span { + auto get_monitors(bool update) noexcept -> array_view { return impl::get_monitors(wm(), update); } diff --git a/src/wsi/win32/keyboard.cppm b/src/wsi/win32/keyboard.cppm index f91b46699..e110b2528 100644 --- a/src/wsi/win32/keyboard.cppm +++ b/src/wsi/win32/keyboard.cppm @@ -154,7 +154,7 @@ namespace stormkit::wsi::win32 { }); constexpr auto KEY_AS_SCANCODE = [] static noexcept -> decltype(auto) { - auto out = std::array, 111> {}; + auto out = array, 111> {}; auto i = 0_usize; for (const auto& [key, value] : SCANCODE_AS_KEY) out[i++] = std::make_pair(value.first, key); diff --git a/src/wsi/win32/monitor.cppm b/src/wsi/win32/monitor.cppm index bb0e0bae0..58c23433e 100644 --- a/src/wsi/win32/monitor.cppm +++ b/src/wsi/win32/monitor.cppm @@ -29,7 +29,7 @@ namespace stormkit::wsi::win32 { if ((monitor_info.dwFlags & MONITORINFOF_PRIMARY) == MONITORINFOF_PRIMARY) monitor.flags = Monitor::Flags::PRIMARY; - monitor.name = std::string { monitor_info.szDevice }; + monitor.name = string { monitor_info.szDevice }; auto dm = zeroed(); @@ -49,7 +49,7 @@ namespace stormkit::wsi::win32 { auto load_monitors(HMONITOR native, HDC, LPRECT, LPARAM data) noexcept -> BOOL { if (native == nullptr) return TRUE; - auto& monitors = *std::bit_cast*>(data); + auto& monitors = *std::bit_cast*>(data); monitors.emplace_back(load_monitor(native)); return TRUE; @@ -57,8 +57,8 @@ namespace stormkit::wsi::win32 { ///////////////////////////////////// ///////////////////////////////////// - auto get_monitors(WM, bool update = false) noexcept -> std::span { - thread_local auto monitors = std::vector {}; + auto get_monitors(WM, bool update = false) noexcept -> array_view { + thread_local auto monitors = dyn_array {}; if (update or stdr::empty(monitors)) EnumDisplayMonitors(nullptr, nullptr, load_monitors, std::bit_cast(&monitors)); diff --git a/src/wsi/win32/window.cpp b/src/wsi/win32/window.cpp index 5171e5376..b6639086a 100644 --- a/src/wsi/win32/window.cpp +++ b/src/wsi/win32/window.cpp @@ -105,7 +105,7 @@ namespace stormkit::wsi::win32 { ///////////////////////////////////// ///////////////////////////////////// - auto Window::open(std::string title, const math::uextent2& extent, WindowFlag flags) noexcept -> void { + auto Window::open(string title, const math::uextent2& extent, WindowFlag flags) noexcept -> void { auto style = DWORD { WS_SYSMENU | WS_BORDER }; auto style_ex = DWORD { 0 }; auto h_instance = GetModuleHandleA(nullptr); @@ -187,7 +187,7 @@ namespace stormkit::wsi::win32 { ///////////////////////////////////// ///////////////////////////////////// - auto Window::fill_framebuffer(std::span pixels) noexcept -> void { + auto Window::fill_framebuffer(array_view pixels) noexcept -> void { if (m_win32_state.external_context) return; const auto [width, height] = extent(); @@ -215,7 +215,7 @@ namespace stormkit::wsi::win32 { ///////////////////////////////////// ///////////////////////////////////// - auto Window::set_title(std::string title) noexcept -> void { + auto Window::set_title(string title) noexcept -> void { SetWindowTextA(m_window_handle, std::data(title)); WindowBase::set_title(std::move(title)); diff --git a/src/wsi/win32/window.cppm b/src/wsi/win32/window.cppm index b8e5329a9..49b0d62fc 100644 --- a/src/wsi/win32/window.cppm +++ b/src/wsi/win32/window.cppm @@ -34,16 +34,16 @@ export namespace stormkit::wsi::win32 { Window(Window&&) noexcept; auto operator=(Window&&) noexcept -> Window&; - auto open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept + auto open(string title, const math::uextent2& size, WindowFlag flags) noexcept -> void; auto close() noexcept -> void; auto handle_events() noexcept -> void; auto clear(const ucolor_rgb& color) noexcept -> void; - auto fill_framebuffer(std::span colors) noexcept -> void; + auto fill_framebuffer(array_view colors) noexcept -> void; - auto set_title(std::string title) noexcept -> void; + auto set_title(string title) noexcept -> void; auto set_extent(const math::uextent2& extent) noexcept -> void; auto set_fullscreen(bool fullscreen) noexcept -> void; diff --git a/src/wsi/window.cpp b/src/wsi/window.cpp index 22ced5a93..97815ee07 100644 --- a/src/wsi/window.cpp +++ b/src/wsi/window.cpp @@ -63,7 +63,7 @@ namespace stormkit::wsi { ///////////////////////////////////// ///////////////////////////////////// - auto Window::open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> Window { + auto Window::open(string title, const math::uextent2& size, WindowFlag flags) noexcept -> Window { auto window = Window {}; window.m_impl->open(std::move(title), size, flags); return window; @@ -71,7 +71,7 @@ namespace stormkit::wsi { ///////////////////////////////////// ///////////////////////////////////// - auto Window::allocate_and_open(std::string title, const math::uextent2& size, WindowFlag flags) noexcept -> Heap { + auto Window::allocate_and_open(string title, const math::uextent2& size, WindowFlag flags) noexcept -> Heap { auto window = allocate_unsafe(Window {}); window->m_impl->open(std::move(title), size, flags); return window; @@ -91,7 +91,7 @@ namespace stormkit::wsi { ///////////////////////////////////// ///////////////////////////////////// - auto Window::fill_framebuffer(std::span colors) noexcept -> void { + auto Window::fill_framebuffer(array_view colors) noexcept -> void { m_impl->fill_framebuffer(colors); } @@ -121,13 +121,13 @@ namespace stormkit::wsi { ///////////////////////////////////// ///////////////////////////////////// - auto Window::set_title(std::string title) noexcept -> void { + auto Window::set_title(string title) noexcept -> void { m_impl->set_title(std::move(title)); } ///////////////////////////////////// ///////////////////////////////////// - auto Window::title() const noexcept -> const std::string& { + auto Window::title() const noexcept -> const string& { return m_impl->title(); } diff --git a/tests/core/containers/dag.cpp b/tests/core/containers/dag.cpp index 88a57bd06..53119cca5 100644 --- a/tests/core/containers/dag.cpp +++ b/tests/core/containers/dag.cpp @@ -20,18 +20,19 @@ namespace { { { "topological_sort", [] { - using Edge = std::pair; - constexpr auto edges = into_array(Edge { 0, 5 }, - Edge { 0, 2 }, - Edge { 0, 1 }, - Edge { 3, 6 }, - Edge { 3, 5 }, - Edge { 3, 4 }, - Edge { 5, 4 }, - Edge { 6, 4 }, - Edge { 6, 0 }, - Edge { 3, 2 }, - Edge { 1, 4 }); + using Edge = std::pair; + constexpr auto + edges = into_array(Edge { 0, 5 }, + Edge { 0, 2 }, + Edge { 0, 1 }, + Edge { 3, 6 }, + Edge { 3, 5 }, + Edge { 3, 4 }, + Edge { 5, 4 }, + Edge { 6, 4 }, + Edge { 6, 0 }, + Edge { 3, 2 }, + Edge { 1, 4 }); auto dag = DAG {}; for (auto i : range(7)) dag.add_vertex(i); @@ -46,7 +47,7 @@ namespace { auto ordered = std::move(*result); - auto orders = HashMap {}; + auto orders = hash_map {}; { auto i = 0; for (auto id : ordered) orders.emplace(id, i++); @@ -56,7 +57,7 @@ namespace { } }, { "remove_edge_and_vertex", [] { - auto dag = DAG {}; + auto dag = DAG {}; dag.emplace_vertex("a"); dag.emplace_vertex("b"); dag.emplace_vertex("c"); @@ -132,7 +133,7 @@ namespace { } }, { "reverse_view", [] { - auto dag = DAG {}; + auto dag = DAG {}; dag.emplace_vertex("a"); dag.emplace_vertex("b"); dag.emplace_vertex("c"); @@ -156,7 +157,7 @@ namespace { } }, { "reverse_clone", [] { - auto dag = DAG {}; + auto dag = DAG {}; dag.emplace_vertex("a"); dag.emplace_vertex("b"); dag.emplace_vertex("c"); @@ -180,7 +181,7 @@ namespace { } }, { "dump", [] { - auto dag = DAG {}; + auto dag = DAG {}; dag.emplace_vertex("a"); dag.emplace_vertex("b"); dag.emplace_vertex("c"); diff --git a/tests/core/containers/tree.cpp b/tests/core/containers/tree.cpp index c7654ea48..573ba77dc 100644 --- a/tests/core/containers/tree.cpp +++ b/tests/core/containers/tree.cpp @@ -18,7 +18,7 @@ namespace { auto node = TreeNode {}; EXPECTS(node.name() == ""s); - node.set_name(std::string { name }); + node.set_name(string { name }); EXPECTS(node.name() == name); } } } }; } // namespace diff --git a/tests/core/parallelism/threadpool.cpp b/tests/core/parallelism/threadpool.cpp index 48669b4e1..6f958effc 100644 --- a/tests/core/parallelism/threadpool.cpp +++ b/tests/core/parallelism/threadpool.cpp @@ -105,7 +105,7 @@ namespace { [] static noexcept { auto thread_pool = ThreadPool {}; - auto values = std::vector { std::from_range, range(0, 1000000) }; + auto values = dyn_array { std::from_range, range(0, 1000000) }; parallel_for(thread_pool, values, [](auto& value) { value += value; }); auto k = 0; diff --git a/tests/core/typesafe/ref.cpp b/tests/core/typesafe/ref.cpp index 24c80ff42..d163b4667 100644 --- a/tests/core/typesafe/ref.cpp +++ b/tests/core/typesafe/ref.cpp @@ -24,7 +24,7 @@ namespace { auto e = 4; auto f = 5; - auto refs = to_refs(a, b, c, d, e, f); + auto refs = to_refs(a, b, c, d, e, f); auto i = 0; for (auto&& ref : refs) EXPECTS(*ref == i++); @@ -38,7 +38,7 @@ namespace { auto e = 4; auto f = 5; - auto refs = as_refs(a, b, c, d, e, f); + auto refs = as_refs(a, b, c, d, e, f); auto i = 0; for (auto&& ref : refs) EXPECTS(*ref == i++); @@ -66,7 +66,7 @@ namespace { auto e = new int { 4 }; auto f = 5; - auto refs = to_refs(a, b, c, d, e, &f); + auto refs = to_refs(a, b, c, d, e, &f); auto i = 0; for (auto&& ref : refs) EXPECTS(*ref == i++); @@ -83,7 +83,7 @@ namespace { auto e = new int { 4 }; auto f = 5; - auto refs = as_refs(a, b, c, d, e, &f); + auto refs = as_refs(a, b, c, d, e, &f); auto i = 0; for (auto&& ref : refs) EXPECTS(*ref == i++); @@ -110,7 +110,7 @@ namespace { } }, { "ref.to_refs.std_set", [] static noexcept { - auto vec = std::vector { 1, 3, 5, 6, 9 }; + auto vec = dyn_array { 1, 3, 5, 6, 9 }; auto refs = to_refs(vec); auto i = 0u; @@ -118,7 +118,7 @@ namespace { } }, { "ref.to_refs.default", [] static noexcept { - constexpr auto vec = std::array { 1, 3, 5, 6, 9 }; + constexpr auto vec = array { 1, 3, 5, 6, 9 }; auto refs = to_refs(vec); auto i = 0u; diff --git a/tests/core/typesafe/safecasts.integer.cpp b/tests/core/typesafe/safecasts.integer.cpp index 6091d63e1..144d7167b 100644 --- a/tests/core/typesafe/safecasts.integer.cpp +++ b/tests/core/typesafe/safecasts.integer.cpp @@ -33,74 +33,54 @@ namespace bar { namespace { [[maybe_unused]] - const auto i8_1 - = i8 { 1 }; + const auto i8_1 = i8 { 1 }; [[maybe_unused]] - const auto i8_2 - = i8 { 2 }; + const auto i8_2 = i8 { 2 }; [[maybe_unused]] - const auto u8_1 - = u8 { 1 }; + const auto u8_1 = u8 { 1 }; [[maybe_unused]] - const auto u8_2 - = u8 { 2 }; + const auto u8_2 = u8 { 2 }; [[maybe_unused]] - const auto i16_1 - = i16 { 1 }; + const auto i16_1 = i16 { 1 }; [[maybe_unused]] - const auto i16_2 - = i16 { 2 }; + const auto i16_2 = i16 { 2 }; [[maybe_unused]] - const auto u16_1 - = u16 { 1 }; + const auto u16_1 = u16 { 1 }; [[maybe_unused]] - const auto u16_2 - = u16 { 2 }; + const auto u16_2 = u16 { 2 }; [[maybe_unused]] - const auto i32_1 - = i32 { 1 }; + const auto i32_1 = i32 { 1 }; [[maybe_unused]] - const auto i32_2 - = i32 { 2 }; + const auto i32_2 = i32 { 2 }; [[maybe_unused]] - const auto u32_1 - = u32 { 1 }; + const auto u32_1 = u32 { 1 }; [[maybe_unused]] - const auto u32_2 - = u32 { 2 }; + const auto u32_2 = u32 { 2 }; [[maybe_unused]] - const auto i64_1 - = i64 { 1 }; + const auto i64_1 = i64 { 1 }; [[maybe_unused]] - const auto i64_2 - = i64 { 2 }; + const auto i64_2 = i64 { 2 }; [[maybe_unused]] - const auto u64_1 - = u64 { 1 }; + const auto u64_1 = u64 { 1 }; [[maybe_unused]] - const auto u64_2 - = u64 { 2 }; + const auto u64_2 = u64 { 2 }; [[maybe_unused]] - const auto i128_1 - = i128 { 1 }; + const auto i128_1 = i128 { 1 }; [[maybe_unused]] - const auto i128_2 - = i128 { 2 }; + const auto i128_2 = i128 { 2 }; [[maybe_unused]] - const auto u128_1 - = u128 { 1 }; + const auto u128_1 = u128 { 1 }; [[maybe_unused]] - const auto u128_2 - = u128 { 2 }; + const auto u128_2 = u128 { 2 }; auto _ = test::TestSuite { "Core.typesafe.safecasts", diff --git a/tools/terra/src/main.cpp b/tools/terra/src/main.cpp index b6097621c..627c665d6 100644 --- a/tools/terra/src/main.cpp +++ b/tools/terra/src/main.cpp @@ -13,7 +13,7 @@ using namespace std::literals; using namespace stormkit; -auto main(const std::span args) noexcept -> int { +auto main(const array_view args) noexcept -> int { if (stdr::size(args) < 2) { std::println(get_stderr(), "No template filename provided"); return -1; @@ -35,11 +35,11 @@ auto main(const std::span args) noexcept -> int { const auto template_data = TryAssert(io::read_text(template_path), std::format("Failed to read file {}, reason: ", template_path.string())); - auto out = std::string {}; + auto out = string {}; out.reserve(stdr::size(template_data)); // TODO replace with std::hive when supported - auto buff = std::vector {}; + auto buff = dyn_array {}; buff.reserve(50); out += std::format(R"( From 8332b32bee0932a16daa09584012023cbec4c006 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 27 Mar 2026 17:04:12 +0100 Subject: [PATCH 192/194] (core) use nontype_function module instead of headers --- modules/stormkit/core/utils/function_ref.cppm | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/modules/stormkit/core/utils/function_ref.cppm b/modules/stormkit/core/utils/function_ref.cppm index 4b92ccb1a..3410b409e 100644 --- a/modules/stormkit/core/utils/function_ref.cppm +++ b/modules/stormkit/core/utils/function_ref.cppm @@ -1,10 +1,7 @@ -module; - -#include -#include - export module stormkit.core:utils.std23_functional; +export import nontype_functional; + export namespace std23 { using std23::function_ref; using std23::move_only_function; From e2a45784a8c6292d9e6c707788489ed80baf4af7 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 27 Mar 2026 17:04:20 +0100 Subject: [PATCH 193/194] (core) fix linear matrix rotate --- examples/gpu/textured_cube/src/main.cpp | 6 ++-- modules/stormkit/core/math/linear-matrix.cppm | 31 ++++++++++++++++++- modules/stormkit/core/math/linear.cppm | 15 +++------ 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/examples/gpu/textured_cube/src/main.cpp b/examples/gpu/textured_cube/src/main.cpp index c12a22ccd..45c94ad18 100644 --- a/examples/gpu/textured_cube/src/main.cpp +++ b/examples/gpu/textured_cube/src/main.cpp @@ -462,9 +462,9 @@ class Application: public base::Application { // update viewer data and upload const auto time = stdc::duration_cast(current_time - m_start_time).count(); - viewer_data.model = math::rotate(math::fmat4::identity(), - time * math::angle::radians(90.f), - math::fvec3 { 0.f, 1.f, 0.f }); + viewer_data.model = math::transpose(math::rotate(math::fmat4::identity(), + time * math::angle::radians(90.f), + math::fvec3 { 0.f, 1.f, 0.f })); auto& viewer_buffer = submission_resource.viewer_buffer; TryAssert(viewer_buffer.upload(viewer_data), "Failed to upload texture to gpu!"); diff --git a/modules/stormkit/core/math/linear-matrix.cppm b/modules/stormkit/core/math/linear-matrix.cppm index ea1299556..dc1fb462a 100644 --- a/modules/stormkit/core/math/linear-matrix.cppm +++ b/modules/stormkit/core/math/linear-matrix.cppm @@ -504,7 +504,36 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m constexpr auto rotate(const mat4x4& mat, angle::radian angle, const vec3& axis) noexcept -> mat4x4 { auto out = auto(mat); - math::rotate(as_mdspan(mat), angle, as_mdspan(axis), as_mdspan_mut(out)); + const auto cos = narrow(std::cos(angle.get())); + const auto sin = narrow(std::sin(angle.get())); + + const auto axis_norm = normalize(axis); + const auto temp = mul(axis_norm, T { 1 } - cos); + + auto rotation_matrix = mat4x4 {}; + rotation_matrix[0, 0] = cos + temp[0] * axis_norm[0]; + rotation_matrix[1, 0] = temp[0] * axis_norm[1] + sin * axis_norm[2]; + rotation_matrix[2, 0] = temp[0] * axis_norm[2] - sin * axis_norm[1]; + + rotation_matrix[0, 1] = temp[1] * axis_norm[0] - sin * axis_norm[2]; + rotation_matrix[1, 1] = cos + temp[1] * axis_norm[1]; + rotation_matrix[2, 1] = temp[1] * axis_norm[2] + sin * axis_norm[0]; + + rotation_matrix[0, 2] = temp[2] * axis_norm[0] + sin * axis_norm[1]; + rotation_matrix[1, 2] = temp[2] * axis_norm[1] - sin * axis_norm[0]; + rotation_matrix[2, 2] = cos + temp[2] * axis_norm[2]; + + out[0, 0] = mat[0, 0] * rotation_matrix[0, 0] + mat[1, 0] * rotation_matrix[1, 0] + mat[2, 0] * rotation_matrix[2, 0]; + out[0, 1] = mat[0, 1] * rotation_matrix[0, 0] + mat[1, 1] * rotation_matrix[1, 0] + mat[2, 1] * rotation_matrix[2, 0]; + out[0, 2] = mat[0, 2] * rotation_matrix[0, 0] + mat[1, 2] * rotation_matrix[1, 0] + mat[2, 2] * rotation_matrix[2, 0]; + + out[1, 0] = mat[0, 0] * rotation_matrix[0, 1] + mat[1, 0] * rotation_matrix[1, 1] + mat[2, 0] * rotation_matrix[2, 1]; + out[1, 1] = mat[0, 1] * rotation_matrix[0, 1] + mat[1, 1] * rotation_matrix[1, 1] + mat[2, 1] * rotation_matrix[2, 1]; + out[1, 2] = mat[0, 2] * rotation_matrix[0, 1] + mat[1, 2] * rotation_matrix[1, 1] + mat[2, 2] * rotation_matrix[2, 1]; + + out[2, 0] = mat[0, 0] * rotation_matrix[0, 2] + mat[1, 0] * rotation_matrix[1, 2] + mat[2, 0] * rotation_matrix[2, 2]; + out[2, 1] = mat[0, 1] * rotation_matrix[0, 2] + mat[1, 1] * rotation_matrix[1, 2] + mat[2, 1] * rotation_matrix[2, 2]; + out[2, 2] = mat[0, 2] * rotation_matrix[0, 2] + mat[1, 2] * rotation_matrix[1, 2] + mat[2, 2] * rotation_matrix[2, 2]; return out; } diff --git a/modules/stormkit/core/math/linear.cppm b/modules/stormkit/core/math/linear.cppm index b8e75c7ce..9fb9fe63a 100644 --- a/modules/stormkit/core/math/linear.cppm +++ b/modules/stormkit/core/math/linear.cppm @@ -526,10 +526,9 @@ namespace stormkit { inline namespace core { namespace math { STORMKIT_FORCE_INLINE constexpr auto mul(const MatrixSpan& a, const MatrixSpan& b, MatrixSpan out) noexcept -> void { - stdr::fill(as_span_mut(out), T { 0 }); for (auto i = 0u; i < M; ++i) for (auto j = 0u; j < K; ++j) - for (auto k = 0u; k < N; ++k) out[i, j] += a[i, k] * b[k, j]; + for (auto k = 0u; k < N; ++k) out[i, j] += a[i, k] * b[j, k]; } //////////////////////////////////////// @@ -626,8 +625,7 @@ namespace stormkit { inline namespace core { namespace math { (); - auto rotation_matrix = SMatData {}; - stdr::fill(rotation_matrix, 0); + auto rotation_matrix = SMatData {}; auto rotation_matrix_ = as_mdspan_mut<4, 4>(rotation_matrix); rotation_matrix_[0, 0] = cos + temp[0] * axis_norm[0]; @@ -642,15 +640,10 @@ namespace stormkit { inline namespace core { namespace math { rotation_matrix_[1, 2] = temp[2] * axis_norm[1] - sin * axis_norm[0]; rotation_matrix_[2, 2] = cos + temp[2] * axis_norm[2]; - // TODO replace by mul when submdspan is available + // // TODO replace by mul when submdspan is available for (auto i = 0u; i < 3; ++i) for (auto j = 0u; j < 3; ++j) - for (auto k = 0u; k < 3; ++k) out[i, j] += a[i, k] * rotation_matrix_[k, j]; - - out[0, 3] = a[0, 3]; - out[1, 3] = a[1, 3]; - out[2, 3] = a[2, 3]; - out[3, 3] = a[3, 3]; + for (auto k = 0u; k < 3; ++k) out[j, i] += a[k, i] * rotation_matrix_[j, k]; } //////////////////////////////////////// From 3be75126700fd333e2a7b7f65f5125aef5af8666 Mon Sep 17 00:00:00 2001 From: Arthur LAURENT Date: Fri, 3 Apr 2026 19:06:04 +0200 Subject: [PATCH 194/194] (all) improve named constructors --- examples/gpu/common/app.cppm | 20 +- examples/gpu/imgui/src/main.cpp | 2 +- examples/gpu/textured_cube/src/main.cpp | 34 +- examples/gpu/triangle/src/main.cpp | 7 +- include/stormkit/core/platform_macro.hpp | 48 ++- include/stormkit/core/try_expected.hpp | 2 + include/stormkit/log/log_macro.hpp | 60 ++- modules/stormkit/core/console/style.cppm | 136 +++--- .../stormkit/core/containers/shmbuffer.cppm | 35 +- modules/stormkit/core/hash/string.cppm | 2 +- modules/stormkit/core/math/geometry.cppm | 4 +- modules/stormkit/core/math/linear-matrix.cppm | 2 +- modules/stormkit/core/meta/concepts.cppm | 47 +-- modules/stormkit/core/named_constructors.cppm | 347 ++++++++-------- modules/stormkit/core/parallelism/locked.cppm | 254 +++++++----- modules/stormkit/core/typesafe/integer.cppm | 4 +- modules/stormkit/core/typesafe/ref.cppm | 2 +- modules/stormkit/core/utils/filesystem.cppm | 20 +- modules/stormkit/gpu/core/base.cppm | 161 ++++---- modules/stormkit/gpu/core/debug_callback.cppm | 33 +- modules/stormkit/gpu/core/device.cppm | 20 +- modules/stormkit/gpu/core/instance.cppm | 23 +- modules/stormkit/gpu/core/surface.cppm | 53 ++- modules/stormkit/gpu/core/sync.cppm | 34 +- modules/stormkit/gpu/core/vulkan/utils.cppm | 4 +- .../gpu/execution/command_buffer.cppm | 85 ++-- .../stormkit/gpu/execution/descriptors.cppm | 28 +- modules/stormkit/gpu/execution/pipeline.cppm | 149 ++++--- .../stormkit/gpu/execution/render_pass.cppm | 17 +- modules/stormkit/gpu/execution/swapchain.cppm | 18 +- modules/stormkit/gpu/resource/buffer.cppm | 26 +- modules/stormkit/gpu/resource/image.cppm | 162 ++++---- modules/stormkit/gpu/resource/shader.cppm | 24 +- modules/stormkit/log.cppm | 388 +++++++++++++++--- modules/stormkit/test.cppm | 2 +- src/gpu/core/debug_callback.cpp | 10 +- src/gpu/core/fence.cpp | 8 +- src/gpu/core/instance.cpp | 33 +- src/gpu/core/surface.cpp | 6 +- src/gpu/execution/command_buffer.cpp | 6 +- src/gpu/execution/command_pool.cpp | 13 +- src/gpu/execution/descriptor_set.cpp | 6 +- src/gpu/execution/pipeline.cpp | 51 +-- src/gpu/execution/swapchain.cpp | 25 +- src/gpu/resource/image_view.cpp | 18 +- src/log/console_logger.cpp | 28 +- src/log/file_logger.cpp | 2 +- 47 files changed, 1551 insertions(+), 908 deletions(-) diff --git a/examples/gpu/common/app.cppm b/examples/gpu/common/app.cppm index 4f227a21f..9fe4d8c3c 100644 --- a/examples/gpu/common/app.cppm +++ b/examples/gpu/common/app.cppm @@ -43,6 +43,8 @@ extern "C" auto debug_callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, return 0; } +static constexpr auto ENABLE_VALIDATION_LAYERS = false; + export namespace base { class Application { public: @@ -93,10 +95,14 @@ export namespace base { TryDiscardAssert(gpu::initialize_backend(), "Failed to initialize gpu backend"); // create gpu instance and attach surface to window - m_instance = TryAssert(gpu::Instance::create(string { example_name }, true), "Failed to initialize gpu instance"); + m_instance = TryAssert(gpu::Instance::create({ .application_name = string { example_name }, + .enable_validation_layers = ENABLE_VALIDATION_LAYERS }), + "Failed to initialize gpu instance"); - m_debug_callback = TryAssert(gpu::DebugCallback::create(m_instance, debug_callback), - "Failed to initialize gpu instance"); + if (ENABLE_VALIDATION_LAYERS) { + m_debug_callback = TryAssert(gpu::DebugCallback::create(m_instance, { .messenger_closure = debug_callback }), + "Failed to initialize gpu instance"); + } m_surface = TryAssert(gpu::Surface::create_from_window(m_instance, m_window), "Failed to initialize window gpu surface"); @@ -123,11 +129,11 @@ export namespace base { ilog("Picked gpu: {}", *m_physical_device); // create gpu device - m_device = TryAssert(gpu::Device::create(m_physical_device), "Failed to initialize gpu device"); + m_device = TryAssert(gpu::Device::create(m_physical_device, {}), "Failed to initialize gpu device"); // create swapchain const auto window_extent = m_window->extent(); - m_swapchain = TryAssert(gpu::SwapChain::create(m_device, gpu::as_view(m_surface), window_extent), + m_swapchain = TryAssert(gpu::SwapChain::create(m_device, { gpu::as_view(m_surface), window_extent }), "Failed to create swapchain"); const auto queue_entries = m_device->queue_entries(); @@ -136,8 +142,8 @@ export namespace base { m_raster_queue = gpu::Queue::create(m_device, *it); - m_command_pool = TryAssert(gpu::CommandPool::create(m_device), - "Failed to create raster queue " + m_command_pool = TryAssert(gpu::CommandPool::create(m_device, { .queue = m_raster_queue }), + "Failed to create command pool " "command pool"); } }; diff --git a/examples/gpu/imgui/src/main.cpp b/examples/gpu/imgui/src/main.cpp index cef2eeace..018321dc2 100644 --- a/examples/gpu/imgui/src/main.cpp +++ b/examples/gpu/imgui/src/main.cpp @@ -82,7 +82,7 @@ class Application: public base::Application { auto image_index = 0u; for (const auto& swap_image : images) { - auto view = TryAssert(gpu::ImageView::create(m_device, swap_image), "Failed to create swapchain image view!"); + auto view = TryAssert(gpu::ImageView::create(m_device, { swap_image }), "Failed to create swapchain image view!"); m_image_resources.push_back({ .image = swap_image, .view = std::move(view), diff --git a/examples/gpu/textured_cube/src/main.cpp b/examples/gpu/textured_cube/src/main.cpp index 45c94ad18..1f868809e 100644 --- a/examples/gpu/textured_cube/src/main.cpp +++ b/examples/gpu/textured_cube/src/main.cpp @@ -240,7 +240,10 @@ class Application: public base::Application { .depth_attachment_format = depth_format, }; - m_pipeline = TryAssert(gpu::Pipeline::create(m_device, state, m_pipeline_layout, rendering_info), + m_pipeline = TryAssert(gpu::Pipeline::create(m_device, + gpu::Pipeline::RasterizationCreateInfo { .state = as_ref(state), + .layout = m_pipeline_layout, + .rendering_info = rendering_info }), "Failed to create raster pipeline!"); // load texture @@ -248,8 +251,7 @@ class Application: public base::Application { TryAssert(image.load_from_file(TEXTURE), std::format("Failed to load texture file {}!", TEXTURE.string())); m_texture = TryAssert(gpu::Image::create(m_device, - gpu::Image::CreateInfo { - .extent = image.extent(), + { .extent = image.extent(), .format = gpu::PixelFormat::RGBA8_UNORM, .usages = gpu::ImageUsageFlag::SAMPLED | gpu::ImageUsageFlag::TRANSFER_DST, .properties = gpu::MemoryPropertyFlag::DEVICE_LOCAL }), @@ -258,8 +260,7 @@ class Application: public base::Application { { auto cpy_fence = TryAssert(gpu::Fence::create(m_device), "Failed to create copy texture buffer fence!"); auto staging_buffer = TryAssert(gpu::Buffer::create(m_device, - gpu::Buffer::CreateInfo { - .usages = gpu::BufferUsageFlag::TRANSFER_SRC, + { .usages = gpu::BufferUsageFlag::TRANSFER_SRC, .size = image.size() }), "Failed to allocate gpu texture staging buffer!"); TryAssert(staging_buffer.upload(image.data()), "Failed to upload texture data to staging buffer!"); @@ -296,8 +297,8 @@ class Application: public base::Application { TryDiscardAssert(cpy_fence.wait(), "Failed to create texture view!"); } - m_texture_view = TryAssert(gpu::ImageView::create(m_device, m_texture), "Failed to create texture view!"); - m_sampler = TryAssert(gpu::Sampler::create(m_device, gpu::Sampler::Settings {}), "Failed to create sampler!"); + m_texture_view = TryAssert(gpu::ImageView::create(m_device, { m_texture }), "Failed to create texture view!"); + m_sampler = TryAssert(gpu::Sampler::create(m_device, {}), "Failed to create sampler!"); m_submission_resources = dyn_array {}; m_submission_resources.reserve(BUFFERING_COUNT); @@ -307,7 +308,7 @@ class Application: public base::Application { .image_available = TryAssert(gpu::Semaphore::create(m_device), "Failed to create present image!"), .render_cmb = TryAssert(m_command_pool->create_command_buffer(), "Failed to create buffers!"), .viewer_buffer = TryAssert(gpu::Buffer::create(m_device, - gpu::Buffer::CreateInfo { + { .usages = gpu::BufferUsageFlag::UNIFORM, .size = sizeof(ViewerData), .persistently_mapped = true, @@ -344,19 +345,18 @@ class Application: public base::Application { auto image_index = 0u; for (const auto& swap_image : images) { - auto view = TryAssert(gpu::ImageView::create(m_device, swap_image), "Failed to create swapchain image view!"); + auto view = TryAssert(gpu::ImageView::create(m_device, { swap_image }), "Failed to create swapchain image view!"); auto depth_image = TryAssert(gpu::Image::create(m_device, - gpu::Image::CreateInfo { - .extent = swap_image.extent(), + { .extent = swap_image.extent(), .format = depth_format, .usages = gpu::ImageUsageFlag::DEPTH_STENCIL_ATTACHMENT, .properties = gpu::MemoryPropertyFlag::DEVICE_LOCAL }), "Failed to create depth image!"); auto depth_view = TryAssert(gpu::ImageView::create(m_device, - depth_image, - gpu::ImageViewType::T2D, - gpu::ImageSubresourceRange { .aspect_mask = depth_aspect_flag }), + { .image = depth_image, + .subresource_range = gpu:: + ImageSubresourceRange { .aspect_mask = depth_aspect_flag } }), "Failed to create depth image view!"); m_image_resources.push_back({ .image = swap_image, @@ -395,8 +395,7 @@ class Application: public base::Application { // setup vertex buffer m_vertex_buffer = TryAssert(gpu::Buffer::create(m_device, - gpu::Buffer::CreateInfo { - .usages = gpu::BufferUsageFlag::VERTEX + { .usages = gpu::BufferUsageFlag::VERTEX | gpu::BufferUsageFlag::TRANSFER_DST, .size = VERTICES_SIZE, .properties = gpu::MemoryPropertyFlag::DEVICE_LOCAL }), @@ -404,8 +403,7 @@ class Application: public base::Application { { auto staging_buffer = TryAssert(gpu::Buffer::create(m_device, - gpu::Buffer::CreateInfo { - .usages = gpu::BufferUsageFlag::TRANSFER_SRC, + { .usages = gpu::BufferUsageFlag::TRANSFER_SRC, .size = VERTICES_SIZE }), "Failed to allocate gpu vertex staging buffer!"); diff --git a/examples/gpu/triangle/src/main.cpp b/examples/gpu/triangle/src/main.cpp index 7f7f0bba6..a1716f214 100644 --- a/examples/gpu/triangle/src/main.cpp +++ b/examples/gpu/triangle/src/main.cpp @@ -83,7 +83,10 @@ class Application: public base::Application { .color_attachment_formats = { m_swapchain->pixel_format() } }; - m_pipeline = TryAssert(gpu::Pipeline::create(m_device, state, m_pipeline_layout, rendering_info), + m_pipeline = TryAssert(gpu::Pipeline::create(m_device, + gpu::Pipeline::RasterizationCreateInfo { .state = as_ref(state), + .layout = m_pipeline_layout, + .rendering_info = rendering_info }), "Failed to create raster pipeline!"); // create present engine resources @@ -114,7 +117,7 @@ class Application: public base::Application { auto image_index = 0u; for (const auto& swap_image : images) { - auto view = TryAssert(gpu::ImageView::create(m_device, swap_image), "Failed to create swapchain image view!"); + auto view = TryAssert(gpu::ImageView::create(m_device, { swap_image }), "Failed to create swapchain image view!"); m_image_resources.push_back({ .image = swap_image, .view = std::move(view), diff --git a/include/stormkit/core/platform_macro.hpp b/include/stormkit/core/platform_macro.hpp index 51a6c6f2e..068042f00 100644 --- a/include/stormkit/core/platform_macro.hpp +++ b/include/stormkit/core/platform_macro.hpp @@ -17,8 +17,9 @@ #error "Stormkit need a c++ compiler" #endif -#define STORMKIT_STRINGIFY_DETAILS(x) #x -#define STORMKIT_STRINGIFY(x) STORMKIT_STRINGIFY_DETAILS(x) +#define STORMKIT_STRINGIFY_DETAILS(x) #x +#define STORMKIT_STRINGIFY(x) STORMKIT_STRINGIFY_DETAILS(x) +#define STORMKIT_PRAGMA_FROM_STRING(x) _Pragma(STORMKIT_STRINGIFY(x)) #if defined(_MSC_VER) and not defined(__clang__) #pragma warning(disable: 4251) @@ -30,12 +31,16 @@ #define STORMKIT_IMPORT __declspec(dllimport) #define STORMKIT_RESTRICT __restrict #define STORMKIT_PRIVATE - #define STORMKIT_FORCE_INLINE_IMPL [[msvc::forceinline]] - #define STORMKIT_INTRINSIC [[msvc::intrinsic]] - #define STORMKIT_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]] - #define STORMKIT_PUSH_WARNINGS _Pragma("warning(push)") - #define STORMKIT_POP_WARNINGS _Pragma("warning(pop)") - #define STORMKIT_ARRAY_IF_MSVC array + #define STORMKIT_FORCE_INLINE_IMPL [[msvc::forceinline]] + #define STORMKIT_INTRINSIC [[msvc::intrinsic]] + #define STORMKIT_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]] + #define STORMKIT_PUSH_WARNINGS _Pragma("warning(push)") + #define STORMKIT_WARNING_IGNORE_MSVC_IMPL(warning_) _Pragma(#warning_) + //clang-format off + #define STORMKIT_WARNING_IGNORE_MSVC(value) STORMKIT_WARNING_IGNORE_MSVC_IMPL(warning(disable : value)) + //clang-format on + #define STORMKIT_POP_WARNINGS _Pragma("warning(pop)") + #define STORMKIT_ARRAY_IF_MSVC array #elif defined(_MSC_VER) and defined(__clang__) #if defined(_LIBCPP_VERSION) #define STORMKIT_COMPILER_LIBCPP "libc++" @@ -46,11 +51,14 @@ #define STORMKIT_COMPILER_CXXLIB STORMKIT_COMPILER_MSSTL #define STORMKIT_ARRAY_IF_MSVC array #endif - #define STORMKIT_EXPORT __declspec(dllexport) - #define STORMKIT_IMPORT __declspec(dllimport) - #define STORMKIT_PRIVATE [[gnu::visibility("hidden")]] - #define STORMKIT_RESTRICT __restrict - #define STORMKIT_FORCE_INLINE_IMPL [[gnu::always_inline]] + #define STORMKIT_EXPORT __declspec(dllexport) + #define STORMKIT_IMPORT __declspec(dllimport) + #define STORMKIT_PRIVATE [[gnu::visibility("hidden")]] + #define STORMKIT_RESTRICT __restrict + //clang-format off + #define STORMKIT_WARNING_IGNORE_MSVC(value) STORMKIT_PRAGMA_FROM_STRING(warning(disable : value)) + //clang-format on + #define STORMKIT_FORCE_INLINE_IMPL [[gnu::always_inline]] #define STORMKIT_INTRINSIC #define STORMKIT_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]] #elif defined(__MINGW32__) @@ -146,15 +154,25 @@ #define STORMKIT_COMPILER_CLANG string { "Clang " } + __clang_version__ #define STORMKIT_COMPILER STORMKIT_COMPILER_CLANG #define STORMKIT_PUSH_WARNINGS _Pragma("clang diagnostic push") - #define STORMKIT_POP_WARNINGS _Pragma("clang diagnostic pop") + #define STORMKIT_WARNING_IGNORE_GCC(_) + #define STORMKIT_WARNING_IGNORE_MSVC(_) + #define STORMKIT_WARNING_IGNORE_CLANG(warning) STORMKIT_PRAGMA_FROM_STRING(clang diagnostic ignore warning) + #define STORMKIT_POP_WARNINGS _Pragma("clang diagnostic pop") #elif defined(__GNUC__) or defined(__GNUG__) #define STORMKIT_COMPILER_GCC \ "GCC " + std::to_string(__GNUC__) + "." + std::to_string(__GNUC_MINOR__) + "." + "." + std::to_string(__GNUC_PATCHLEVEL__) #define STORMKIT_COMPILER STORMKIT_COMPILER_GCC #define STORMKIT_PUSH_WARNINGS _Pragma("GCC diagnostic push") - #define STORMKIT_POP_WARNINGS _Pragma("GCC diagnostic pop") + #define STORMKIT_WARNING_IGNORE_CLANG(_) + #define STORMKIT_WARNING_IGNORE_MSVC(_) + #define STORMKIT_WARNING_IGNORE_GCC(warning) STORMKIT_PRAGMA_FROM_STRING(GCC diagnostic ignored warning) + #define STORMKIT_POP_WARNINGS _Pragma("GCC diagnostic pop") #endif +#define STORMKIT_WARNING_IGNORE_GCC_CLANG(warning) \ + STORMKIT_WARNING_IGNORE_GCC(warning) \ + STORMKIT_WARNING_IGNORE_CLANG(warning) + #if defined(__SWITCH__) #define STORMKIT_OS_NX "Nintendo Switch" #define STORMKIT_BITS_64 diff --git a/include/stormkit/core/try_expected.hpp b/include/stormkit/core/try_expected.hpp index 2d75b9f23..e2b83a4b2 100644 --- a/include/stormkit/core/try_expected.hpp +++ b/include/stormkit/core/try_expected.hpp @@ -5,6 +5,8 @@ #ifndef STORMKIT_TRY_EXPECTED_HPP #define STORMKIT_TRY_EXPECTED_HPP +#include + #if (defined(__clang__) or defined(__GNUC__)) #define Try(m) \ ({ \ diff --git a/include/stormkit/log/log_macro.hpp b/include/stormkit/log/log_macro.hpp index 52b68cec9..83edcd346 100644 --- a/include/stormkit/log/log_macro.hpp +++ b/include/stormkit/log/log_macro.hpp @@ -13,26 +13,46 @@ constexpr auto NAME = stormkit::log::Module { module_chars }; \ } -#define LOGGER_FUNC(LOG_MODULE) \ - template \ - STORMKIT_FORCE_INLINE inline auto dlog(Args&&... args) noexcept -> void { \ - LOG_MODULE.dlog(std::forward(args)...); \ - } \ - template \ - STORMKIT_FORCE_INLINE inline auto ilog(Args&&... args) noexcept -> void { \ - LOG_MODULE.ilog(std::forward(args)...); \ - } \ - template \ - STORMKIT_FORCE_INLINE inline auto wlog(Args&&... args) noexcept -> void { \ - LOG_MODULE.wlog(std::forward(args)...); \ - } \ - template \ - STORMKIT_FORCE_INLINE inline auto elog(Args&&... args) noexcept -> void { \ - LOG_MODULE.elog(std::forward(args)...); \ - } \ - template \ - STORMKIT_FORCE_INLINE inline auto flog(Args&&... args) noexcept -> void { \ - LOG_MODULE.flog(std::forward(args)...); \ +#define LOGGER_FUNC(LOG_MODULE) \ + template \ + STORMKIT_FORCE_INLINE inline auto dlog(std::format_string format_string, Args&&... args) noexcept -> void { \ + LOG_MODULE.dlog(std::move(format_string), std::forward(args)...); \ + } \ + template \ + STORMKIT_FORCE_INLINE inline auto ilog(std::format_string format_string, Args&&... args) noexcept -> void { \ + LOG_MODULE.ilog(std::move(format_string), std::forward(args)...); \ + } \ + template \ + STORMKIT_FORCE_INLINE inline auto wlog(std::format_string format_string, Args&&... args) noexcept -> void { \ + LOG_MODULE.wlog(std::move(format_string), std::forward(args)...); \ + } \ + template \ + STORMKIT_FORCE_INLINE inline auto elog(std::format_string format_string, Args&&... args) noexcept -> void { \ + LOG_MODULE.elog(std::move(format_string), std::forward(args)...); \ + } \ + template \ + STORMKIT_FORCE_INLINE inline auto flog(std::format_string format_string, Args&&... args) noexcept -> void { \ + LOG_MODULE.flog(std::move(format_string), std::forward(args)...); \ + } \ + template \ + STORMKIT_FORCE_INLINE inline auto dlog_runtime(std::string_view format_string, Args&&... args) noexcept -> void { \ + LOG_MODULE.dlog_runtime(std::move(format_string), std::forward(args)...); \ + } \ + template \ + STORMKIT_FORCE_INLINE inline auto ilog_runtime(std::string_view format_string, Args&&... args) noexcept -> void { \ + LOG_MODULE.ilog_runtime(std::move(format_string), std::forward(args)...); \ + } \ + template \ + STORMKIT_FORCE_INLINE inline auto wlog_runtime(std::string_view format_string, Args&&... args) noexcept -> void { \ + LOG_MODULE.wlog_runtime(std::move(format_string), std::forward(args)...); \ + } \ + template \ + STORMKIT_FORCE_INLINE inline auto elog_runtime(std::string_view format_string, Args&&... args) noexcept -> void { \ + LOG_MODULE.elog_runtime(std::move(format_string), std::forward(args)...); \ + } \ + template \ + STORMKIT_FORCE_INLINE inline auto flog_runtime(std::string_view format_string, Args&&... args) noexcept -> void { \ + LOG_MODULE.flog_runtime(std::move(format_string), std::forward(args)...); \ } #define LOGGER(module) \ diff --git a/modules/stormkit/core/console/style.cppm b/modules/stormkit/core/console/style.cppm index 35a826385..4160b96cb 100644 --- a/modules/stormkit/core/console/style.cppm +++ b/modules/stormkit/core/console/style.cppm @@ -78,6 +78,56 @@ export { inline constexpr auto CYAN_TEXT_STYLE = ConsoleStyle { .fg = ConsoleColor::CYAN }; inline constexpr auto WHITE_TEXT_STYLE = ConsoleStyle { .fg = ConsoleColor::WHITE }; inline constexpr auto BLACK_TEXT_STYLE = ConsoleStyle { .fg = ConsoleColor::BLACK }; + + namespace ecma48 { + inline constexpr auto FOREGROUND = frozen::make_unordered_map({ + { ConsoleColor::BLACK, "\x1B[30m" }, + { ConsoleColor::RED, "\x1B[31m" }, + { ConsoleColor::GREEN, "\x1B[32m" }, + { ConsoleColor::YELLOW, "\x1B[33m" }, + { ConsoleColor::BLUE, "\x1B[34m" }, + { ConsoleColor::MAGENTA, "\x1B[35m" }, + { ConsoleColor::CYAN, "\x1B[36m" }, + { ConsoleColor::WHITE, "\x1B[37m" }, + { ConsoleColor::BRIGHT_BLACK, "\x1B[90m" }, + { ConsoleColor::BRIGHT_RED, "\x1B[91m" }, + { ConsoleColor::BRIGHT_GREEN, "\x1B[92m" }, + { ConsoleColor::BRIGHT_YELLOW, "\x1B[93m" }, + { ConsoleColor::BRIGHT_BLUE, "\x1B[94m" }, + { ConsoleColor::BRIGHT_MAGENTA, "\x1B[95m" }, + { ConsoleColor::BRIGHT_CYAN, "\x1B[96m" }, + { ConsoleColor::BRIGHT_WHITE, "\x1B[97m" }, + }); + + inline constexpr auto BACKGROUND = frozen::make_unordered_map({ + { ConsoleColor::BLACK, "\x1B[40m" }, + { ConsoleColor::RED, "\x1B[41m" }, + { ConsoleColor::GREEN, "\x1B[42m" }, + { ConsoleColor::YELLOW, "\x1B[43m" }, + { ConsoleColor::BLUE, "\x1B[44m" }, + { ConsoleColor::MAGENTA, "\x1B[45m" }, + { ConsoleColor::CYAN, "\x1B[46m" }, + { ConsoleColor::WHITE, "\x1B[47m" }, + { ConsoleColor::BRIGHT_BLACK, "\x1B[100m" }, + { ConsoleColor::BRIGHT_RED, "\x1B[101m" }, + { ConsoleColor::BRIGHT_GREEN, "\x1B[102m" }, + { ConsoleColor::BRIGHT_YELLOW, "\x1B[103m" }, + { ConsoleColor::BRIGHT_BLUE, "\x1B[104m" }, + { ConsoleColor::BRIGHT_MAGENTA, "\x1B[105m" }, + { ConsoleColor::BRIGHT_CYAN, "\x1B[106m" }, + { ConsoleColor::BRIGHT_WHITE, "\x1B[107m" }, + }); + + inline constexpr auto RESET = "\x1B[0m"sv; + inline constexpr auto BOLD = "\x1B[1m"sv; + inline constexpr auto FAINT = "\x1B[2m"sv; + inline constexpr auto ITALIC = "\x1B[3m"sv; + inline constexpr auto UNDERLINE = "\x1B[4m"sv; + inline constexpr auto INVERSE = "\x1B[7m"sv; + } // namespace ecma48 + + template + auto format_as(const ConsoleStyle& style, FormatContext& ctx) noexcept -> decltype(ctx.out()); }} // namespace stormkit::core FLAG_ENUM(stormkit::core::StyleModifier) @@ -98,53 +148,6 @@ export { using namespace std::literals; namespace stormkit { inline namespace core { - namespace ecma48 { - inline constexpr auto FOREGROUND = frozen::make_unordered_map({ - { ConsoleColor::BLACK, "\x1B[30m" }, - { ConsoleColor::RED, "\x1B[31m" }, - { ConsoleColor::GREEN, "\x1B[32m" }, - { ConsoleColor::YELLOW, "\x1B[33m" }, - { ConsoleColor::BLUE, "\x1B[34m" }, - { ConsoleColor::MAGENTA, "\x1B[35m" }, - { ConsoleColor::CYAN, "\x1B[36m" }, - { ConsoleColor::WHITE, "\x1B[37m" }, - { ConsoleColor::BRIGHT_BLACK, "\x1B[90m" }, - { ConsoleColor::BRIGHT_RED, "\x1B[91m" }, - { ConsoleColor::BRIGHT_GREEN, "\x1B[92m" }, - { ConsoleColor::BRIGHT_YELLOW, "\x1B[93m" }, - { ConsoleColor::BRIGHT_BLUE, "\x1B[94m" }, - { ConsoleColor::BRIGHT_MAGENTA, "\x1B[95m" }, - { ConsoleColor::BRIGHT_CYAN, "\x1B[96m" }, - { ConsoleColor::BRIGHT_WHITE, "\x1B[97m" }, - }); - - inline constexpr auto BACKGROUND = frozen::make_unordered_map({ - { ConsoleColor::BLACK, "\x1B[40m" }, - { ConsoleColor::RED, "\x1B[41m" }, - { ConsoleColor::GREEN, "\x1B[42m" }, - { ConsoleColor::YELLOW, "\x1B[43m" }, - { ConsoleColor::BLUE, "\x1B[44m" }, - { ConsoleColor::MAGENTA, "\x1B[45m" }, - { ConsoleColor::CYAN, "\x1B[46m" }, - { ConsoleColor::WHITE, "\x1B[47m" }, - { ConsoleColor::BRIGHT_BLACK, "\x1B[100m" }, - { ConsoleColor::BRIGHT_RED, "\x1B[101m" }, - { ConsoleColor::BRIGHT_GREEN, "\x1B[102m" }, - { ConsoleColor::BRIGHT_YELLOW, "\x1B[103m" }, - { ConsoleColor::BRIGHT_BLUE, "\x1B[104m" }, - { ConsoleColor::BRIGHT_MAGENTA, "\x1B[105m" }, - { ConsoleColor::BRIGHT_CYAN, "\x1B[106m" }, - { ConsoleColor::BRIGHT_WHITE, "\x1B[107m" }, - }); - - inline constexpr auto RESET = "\x1B[0m"sv; - inline constexpr auto BOLD = "\x1B[1m"sv; - inline constexpr auto FAINT = "\x1B[2m"sv; - inline constexpr auto ITALIC = "\x1B[3m"sv; - inline constexpr auto UNDERLINE = "\x1B[4m"sv; - inline constexpr auto INVERSE = "\x1B[7m"sv; - } // namespace ecma48 - ///////////////////////////////////// ///////////////////////////////////// template @@ -189,6 +192,45 @@ namespace stormkit { inline namespace core { out.append(ecma48::RESET); } + + ///////////////////////////////////// + ///////////////////////////////////// + template + auto format_as(const ConsoleStyle& style, FormatContext& ctx) noexcept -> decltype(ctx.out()) { + thread_local auto buf = array {}; + auto end = stdr::begin(buf); + + if (style.fg) { + auto [_, end_] = stdr::copy(ecma48::FOREGROUND.at(*style.fg), end); + end = end_; + } + if (style.bg) { + auto [_, end_] = stdr::copy(ecma48::BACKGROUND.at(*style.bg), end); + end = end_; + } + if (check_flag_bit(style.modifiers, StyleModifier::BOLD)) { + auto [_, end_] = stdr::copy(ecma48::BOLD, end); + end = end_; + } + if (check_flag_bit(style.modifiers, StyleModifier::FAINT)) { + auto [_, end_] = stdr::copy(ecma48::FAINT, end); + end = end_; + } + if (check_flag_bit(style.modifiers, StyleModifier::ITALIC)) { + auto [_, end_] = stdr::copy(ecma48::ITALIC, end); + end = end_; + } + if (check_flag_bit(style.modifiers, StyleModifier::INVERSE)) { + auto [_, end_] = stdr::copy(ecma48::INVERSE, end); + end = end_; + } + if (check_flag_bit(style.modifiers, StyleModifier::UNDERLINE)) { + auto [_, end_] = stdr::copy(ecma48::UNDERLINE, end); + end = end_; + } + + return std::format_to(ctx.out(), "{}", string_view { stdr::begin(buf), end }); + } }} // namespace stormkit::core using namespace stormkit; diff --git a/modules/stormkit/core/containers/shmbuffer.cppm b/modules/stormkit/core/containers/shmbuffer.cppm index c36a4e783..932bf2cc1 100644 --- a/modules/stormkit/core/containers/shmbuffer.cppm +++ b/modules/stormkit/core/containers/shmbuffer.cppm @@ -22,12 +22,22 @@ import :named_constructors; import :utils.filesystem; export namespace stormkit { inline namespace core { - class STORMKIT_CORE_API SHMBuffer: public UseNamedConstructors> { + class STORMKIT_CORE_API SHMBuffer final: public NamedConstructor> { + using Base = NamedConstructor>; + public: using ValueType = byte; + template + using ExpectedType = std::expected; using value_type = ValueType; + static auto create(usize size, string name, io::Access access = io::Access::READ | io::Access::WRITE) noexcept + -> ExpectedType; + static auto allocate(usize size, string name, io::Access access = io::Access::READ | io::Access::WRITE) noexcept + -> ExpectedType>; + + explicit SHMBuffer(PrivateTag) noexcept; ~SHMBuffer(); SHMBuffer(const SHMBuffer&) = delete; @@ -57,11 +67,12 @@ export namespace stormkit { inline namespace core { auto name() const noexcept -> string_view; auto access() const noexcept -> io::Access; - constexpr SHMBuffer(PrivateTag) noexcept; - auto do_init(PrivateTag, usize, string, io::Access = io::Access::READ | io::Access::WRITE) noexcept - -> std::expected; + auto do_init(PrivateTag, usize, string, io::Access) noexcept -> ExpectedType; private: + using Base::allocate; + using Base::create; + io::Access m_access; void* m_handle = nullptr; usize m_size; @@ -74,7 +85,21 @@ namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE - constexpr SHMBuffer::SHMBuffer(PrivateTag) noexcept { + inline auto SHMBuffer::create(usize size, string name, io::Access access) noexcept -> ExpectedType { + return Base::create(size, std::move(name), access); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto SHMBuffer::allocate(usize size, string name, io::Access access) noexcept -> ExpectedType> { + return Base::allocate(size, std::move(name), access); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline SHMBuffer::SHMBuffer(PrivateTag) noexcept { } ///////////////////////////////////// diff --git a/modules/stormkit/core/hash/string.cppm b/modules/stormkit/core/hash/string.cppm index bfae7caad..86799383e 100644 --- a/modules/stormkit/core/hash/string.cppm +++ b/modules/stormkit/core/hash/string.cppm @@ -191,7 +191,7 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// - template + template STORMKIT_FORCE_INLINE constexpr auto hasher(string_view value) noexcept -> Ret { return StringHash::operator()(value); diff --git a/modules/stormkit/core/math/geometry.cppm b/modules/stormkit/core/math/geometry.cppm index a014e0c04..244600a4f 100644 --- a/modules/stormkit/core/math/geometry.cppm +++ b/modules/stormkit/core/math/geometry.cppm @@ -168,7 +168,7 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// //////////////////////////////////////// - template + template STORMKIT_FORCE_INLINE constexpr auto hasher(const rect& value) noexcept -> Ret { return hash(value.x, value.y, value.width, value.height); @@ -176,7 +176,7 @@ namespace stormkit { inline namespace core { namespace math { //////////////////////////////////////// //////////////////////////////////////// - template + template STORMKIT_FORCE_INLINE constexpr auto hasher(const bounding_rect& value) noexcept -> Ret { return hash(value.left, value.top, value.right, value.bottom); diff --git a/modules/stormkit/core/math/linear-matrix.cppm b/modules/stormkit/core/math/linear-matrix.cppm index dc1fb462a..5870d3387 100644 --- a/modules/stormkit/core/math/linear-matrix.cppm +++ b/modules/stormkit/core/math/linear-matrix.cppm @@ -634,7 +634,7 @@ namespace stormkit { inline namespace core { namespace math { inline namespace m //////////////////////////////////////// //////////////////////////////////////// - template + template STORMKIT_PURE STORMKIT_FORCE_INLINE constexpr auto hasher(const T& value) noexcept -> Ret { return hash(as_view(value)); diff --git a/modules/stormkit/core/meta/concepts.cppm b/modules/stormkit/core/meta/concepts.cppm index 1fd77193b..667b3c38b 100644 --- a/modules/stormkit/core/meta/concepts.cppm +++ b/modules/stormkit/core/meta/concepts.cppm @@ -2,10 +2,22 @@ // This file is subject to the license terms in the LICENSE file // found in the top-level of this distribution +module; + +#include + export module stormkit.core:meta.concepts; import std; +#if defined(STORMKIT_COMPILER_MSVC) +using int128 = std::__Signed128; +using uint128 = std::__Unsigned128; +#else +__extension__ using int128 = __int128; +__extension__ using uint128 = unsigned __int128; +#endif + namespace stormkit { inline namespace core { namespace meta::details { template concept IsBooleanTestable = std::convertible_to; @@ -49,14 +61,14 @@ export namespace stormkit { inline namespace core { namespace meta { template concept IsNot = not Is; - template concept C> - concept Not = not C; + // template concept C> + // concept Not = not C; - template concept... C> - concept AllOf = (C and ...); + // template concept... C> + // concept AllOf = (C and ...); - template concept... C> - concept AnyOf = (C or ...); + // template concept... C> + // concept AnyOf = (C or ...); template concept IsBooleanTestable = details::IsBooleanTestable && requires(T&& t) { @@ -272,13 +284,8 @@ export namespace stormkit { inline namespace core { namespace meta { concept IsIntegral = (std::integral and not SameAs and not Isbyte) or Is>> or Is>> -#if defined(STORMKIT_COMPILER_MSVC) - or Is - or Is; -#else - or Is - or Is; -#endif + or Is + or Is; template concept IsIntegralOrEnumeration = IsIntegral or IsEnumeration; @@ -354,20 +361,10 @@ export namespace stormkit { inline namespace core { namespace meta { }; template - concept IsUnsigned = std::is_unsigned_v -#if defined(STORMKIT_COMPILER_MSVC) - or Is; -#else - or Is; -#endif + concept IsUnsigned = std::is_unsigned_v or Is; template - concept IsSigned = std::is_signed_v -#if defined(STORMKIT_COMPILER_MSVC) - or Is; -#else - or Is; -#endif + concept IsSigned = std::is_signed_v or Is; template concept IsSameSigneness = (IsSigned and IsSigned) or (IsUnsigned and IsUnsigned); diff --git a/modules/stormkit/core/named_constructors.cppm b/modules/stormkit/core/named_constructors.cppm index eb0e4f542..f4efb627f 100644 --- a/modules/stormkit/core/named_constructors.cppm +++ b/modules/stormkit/core/named_constructors.cppm @@ -17,105 +17,99 @@ import :utils.allocation; namespace stormkit { inline namespace core { export { namespace meta { - template - concept HasCreateAllocateProtected = requires() { - { T::CREATE_ALLOCATE_PROTECTED } -> IsBooleanTestable; - } and T::CREATE_ALLOCATE_PROTECTED; - - template - concept DoInitHasExpectedType = IsStdExpected>; - - template - using DoInitExpectedType = ReturnType; - template using TransformExpectedValueTo = std::expected; } // namespace meta } - export { - struct PrivateTagBase { - struct Tag { - private: - Tag() = default; - friend struct PrivateTagBase; - }; - + struct PrivateTagBase { + struct Tag { private: - static constexpr auto PRIVATE = Tag {}; - - template - friend class UseNamedConstructors; + Tag() = default; + friend struct PrivateTagBase; }; - using PrivateTag = PrivateTagBase::Tag; + private: + static constexpr auto PRIVATE = Tag {}; - template, meta::DoInitExpectedType, void>, - typename... ConstructorArgs> - class UseNamedConstructors { - using ValueType = T; - using RetType = DoInitRetType; + template + friend class NamedConstructor; + }; - public: - constexpr ~UseNamedConstructors() noexcept; + export { + using PrivateTag = PrivateTagBase::Tag; - constexpr UseNamedConstructors(const UseNamedConstructors&) noexcept; - constexpr auto operator=(const UseNamedConstructors&) noexcept -> UseNamedConstructors&; + template + struct ConstructorArgs {}; - constexpr UseNamedConstructors(UseNamedConstructors&&) noexcept; - constexpr auto operator=(UseNamedConstructors&&) noexcept -> UseNamedConstructors&; + template + struct DoInitArgs {}; - // template - // requires(sizeof...(ConstructorArgs_) == sizeof...(ConstructorArgs) - // and (std::constructible_from and ...) - // and meta::IsStdExpected) - // [[nodiscard]] - // static constexpr auto create(ConstructorArgs_&&... c_args, Args&&... args) noexcept - // -> meta::TransformExpectedValueTo; + template + class NamedConstructor { + protected: + constexpr ~NamedConstructor() noexcept; - template - [[nodiscard]] - static constexpr auto create(ConstructorArgs... c_args, Args&&... args) noexcept -> ValueType; + constexpr NamedConstructor(const NamedConstructor&) noexcept; + constexpr auto operator=(const NamedConstructor&) noexcept -> NamedConstructor&; - template - [[nodiscard]] - static constexpr auto allocate(ConstructorArgs... c_args, Args&&... args) noexcept -> Heap; + constexpr NamedConstructor(NamedConstructor&&) noexcept; + constexpr auto operator=(NamedConstructor&&) noexcept -> NamedConstructor&; - protected: static constexpr auto PRIVATE = PrivateTagBase::PRIVATE; - constexpr UseNamedConstructors() noexcept; + constexpr NamedConstructor() noexcept; }; - template - class UseNamedConstructors { + template + class NamedConstructor>: public NamedConstructor<> { using ValueType = T; - using RetType = DoInitRetType; public: - constexpr ~UseNamedConstructors() noexcept; + using NamedConstructor<>::NamedConstructor; + using NamedConstructor<>::operator=; + + [[nodiscard]] + static constexpr auto create(TConstructorArgs... c_args) noexcept -> ValueType; + + [[nodiscard]] + static constexpr auto allocate(TConstructorArgs... c_args) noexcept -> Heap; + }; + + template + class NamedConstructor: NamedConstructor> { + public: + using NamedConstructor>::NamedConstructor; + using NamedConstructor>::operator=; + }; - constexpr UseNamedConstructors(const UseNamedConstructors&) noexcept; - constexpr auto operator=(const UseNamedConstructors&) noexcept -> UseNamedConstructors&; + template + class NamedConstructor, DoInitArgs>: public NamedConstructor<> { + using ValueType = T; - constexpr UseNamedConstructors(UseNamedConstructors&&) noexcept; - constexpr auto operator=(UseNamedConstructors&&) noexcept -> UseNamedConstructors&; + public: + using NamedConstructor<>::NamedConstructor; + using NamedConstructor<>::operator=; - template [[nodiscard]] - static constexpr auto create(ConstructorArgs... c_args, Args&&... args) noexcept -> decltype(auto); - // -> meta::TransformExpectedValueTo; + static constexpr auto create(TConstructorArgs... c_args, TDoInitArgs... d_args) noexcept -> decltype(auto); - template [[nodiscard]] - static constexpr auto allocate(ConstructorArgs... c_args, Args&&... args) noexcept -> decltype(auto); - // -> meta::TransformExpectedValueTo, RetType>; + static constexpr auto allocate(TConstructorArgs... c_args, TDoInitArgs... d_args) noexcept -> decltype(auto); + }; - protected: - static constexpr auto PRIVATE = PrivateTagBase::PRIVATE; + template + class NamedConstructor>: public NamedConstructor<> { + using ValueType = T; - constexpr UseNamedConstructors() noexcept; + public: + using NamedConstructor<>::NamedConstructor; + using NamedConstructor<>::operator=; + [[nodiscard]] + static constexpr auto create(TDoInitArgs... args) noexcept -> decltype(auto); + + [[nodiscard]] + static constexpr auto allocate(TDoInitArgs... args) noexcept -> decltype(auto); }; } }} // namespace stormkit::core @@ -127,143 +121,176 @@ namespace stormkit { inline namespace core { namespace stormkit { inline namespace core { ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr UseNamedConstructors::UseNamedConstructors() noexcept = default; + constexpr NamedConstructor::NamedConstructor() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr UseNamedConstructors::~UseNamedConstructors() noexcept = default; + constexpr NamedConstructor::~NamedConstructor() noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr auto UseNamedConstructors::operator=(const UseNamedConstructors&) noexcept - -> UseNamedConstructors& = default; + constexpr auto NamedConstructor::operator=(const NamedConstructor&) noexcept -> NamedConstructor& = default; ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr UseNamedConstructors:: - UseNamedConstructors(const UseNamedConstructors&) noexcept = default; + constexpr NamedConstructor::NamedConstructor(const NamedConstructor&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr auto UseNamedConstructors::operator=(UseNamedConstructors&&) noexcept - -> UseNamedConstructors& = default; + constexpr auto NamedConstructor::operator=(NamedConstructor&&) noexcept -> NamedConstructor& = default; ///////////////////////////////////// ///////////////////////////////////// - template + template STORMKIT_FORCE_INLINE - constexpr UseNamedConstructors:: - UseNamedConstructors(UseNamedConstructors&&) noexcept = default; + constexpr NamedConstructor::NamedConstructor(NamedConstructor&&) noexcept = default; ///////////////////////////////////// ///////////////////////////////////// - template - template + template STORMKIT_FORCE_INLINE - constexpr auto UseNamedConstructors::create(ConstructorArgs... c_args, - Args&&... args) noexcept -> ValueType { - auto out = ValueType { PrivateTagBase::PRIVATE, std::forward(c_args)... }; - out.do_init(PrivateTagBase::PRIVATE, std::forward(args)...); - return out; + constexpr auto NamedConstructor>::create(TConstructorArgs... args) noexcept + -> ValueType { + return ValueType { PrivateTagBase::PRIVATE, std::forward(args)... }; } ///////////////////////////////////// ///////////////////////////////////// - template - template + template STORMKIT_FORCE_INLINE - constexpr auto UseNamedConstructors::allocate(ConstructorArgs... c_args, - Args&&... args) noexcept + constexpr auto NamedConstructor>::allocate(TConstructorArgs... args) noexcept -> Heap { - auto out = core::allocate_unsafe(PrivateTagBase::PRIVATE, std::forward(c_args)...); - out->do_init(PrivateTagBase::PRIVATE, std::forward(args)...); - return out; + return core::allocate_unsafe(PrivateTagBase::PRIVATE, std::forward(args)...); } ///////////////////////////////////// ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr UseNamedConstructors::UseNamedConstructors() noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr UseNamedConstructors::~UseNamedConstructors() noexcept = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto UseNamedConstructors::operator=(const UseNamedConstructors&) noexcept - -> UseNamedConstructors& = default; - - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr UseNamedConstructors:: - UseNamedConstructors(const UseNamedConstructors&) noexcept = default; + template + constexpr auto NamedConstructor, DoInitArgs>:: + create(TConstructorArgs... c_args, TDoInitArgs... d_args) noexcept -> decltype(auto) { + using DoInitReturnType = decltype(std::declval().do_init(PRIVATE, std::declval()...)); + if constexpr (not meta::IsStdExpected) { + auto out = ValueType { PrivateTagBase::PRIVATE, std::forward(c_args)... }; + out.do_init(PrivateTagBase::PRIVATE, std::forward(d_args)...); + return out; + } else { + using ReturnType = meta::TransformExpectedValueTo; + +#ifdef STORMKIT_COMPILER_CLANG + auto out = ValueType { PrivateTagBase::PRIVATE, std::forward(c_args)... }; + if (auto result = out.do_init(PrivateTagBase::PRIVATE, std::forward(d_args)...); not result) + return ReturnType { std::unexpect, std::move(result).error() }; + + return ReturnType { std::in_place, std::move(out) }; +#else + auto out_expected = ReturnType { std::in_place, PrivateTagBase::PRIVATE, std::forward(c_args)... }; + if (auto result = out_expected.value().do_init(PrivateTagBase::PRIVATE, std::forward(d_args)...); + not result) + out_expected = std::unexpected { std::move(result).error() }; + + return out_expected; +#endif + } + } ///////////////////////////////////// ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr auto UseNamedConstructors::operator=(UseNamedConstructors&&) noexcept - -> UseNamedConstructors& = default; + template + constexpr auto NamedConstructor, DoInitArgs>:: + allocate(TConstructorArgs... c_args, TDoInitArgs... d_args) noexcept -> decltype(auto) { + using DoInitReturnType = decltype(std::declval().do_init(PRIVATE, std::declval()...)); + if constexpr (not meta::IsStdExpected) { + auto out = core::allocate_unsafe(PrivateTagBase::PRIVATE, std::forward(c_args)...); + out->do_init(PrivateTagBase::PRIVATE, std::forward(d_args)...); + return out; + } else { + using ReturnType = meta::TransformExpectedValueTo, DoInitReturnType>; + +#ifdef STORMKIT_COMPILER_CLANG + auto out = core::allocate_unsafe(PrivateTagBase::PRIVATE, std::forward(c_args)...); + if (auto result = out->do_init(PrivateTagBase::PRIVATE, std::forward(d_args)...); not result) + return ReturnType { std::unexpect, std::move(result).error() }; + + return ReturnType { std::in_place, std::move(out) }; +#else + auto out_expected = ReturnType { + std::in_place, + core::allocate_unsafe(PrivateTagBase::PRIVATE, std::forward(c_args)...) + }; + if (auto result = out_expected.value()->do_init(PrivateTagBase::PRIVATE, std::forward(d_args)...); + not result) + out_expected = std::unexpected { std::move(result).error() }; - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - constexpr UseNamedConstructors:: - UseNamedConstructors(UseNamedConstructors&&) noexcept = default; + return out_expected; +#endif + } + } ///////////////////////////////////// ///////////////////////////////////// - template - template - STORMKIT_FORCE_INLINE - constexpr auto UseNamedConstructors::create(ConstructorArgs... c_args, - Args&&... args) noexcept -> decltype(auto) { - using ReturnValue = meta::TransformExpectedValueTo; - - auto out_expected = ReturnValue { std::in_place, PrivateTagBase::PRIVATE, std::forward(c_args)... }; - if (auto result = out_expected.value().do_init(PrivateTagBase::PRIVATE, std::forward(args)...); not result) - out_expected = std::unexpected { std::move(result).error() }; - - return out_expected; + template + constexpr auto NamedConstructor>::create(TDoInitArgs... args) noexcept -> decltype(auto) { + using DoInitReturnType = decltype(std::declval().do_init(PRIVATE, std::declval()...)); + if constexpr (not meta::IsStdExpected) { + auto out = ValueType { PrivateTagBase::PRIVATE }; + out.do_init(PrivateTagBase::PRIVATE, std::forward(args)...); + return out; + } else { + using ReturnType = meta::TransformExpectedValueTo; + +#ifdef STORMKIT_COMPILER_CLANG + auto out = ValueType { PrivateTagBase::PRIVATE }; + if (auto result = out.do_init(PrivateTagBase::PRIVATE, std::forward(args)...); not result) + return ReturnType { std::unexpect, std::move(result).error() }; + + return ReturnType { std::in_place, std::move(out) }; +#else + auto out_expected = ReturnType { std::in_place, PrivateTagBase::PRIVATE }; + if (auto result = out_expected.value().do_init(PrivateTagBase::PRIVATE, std::forward(args)...); + not result) + out_expected = std::unexpected { std::move(result).error() }; + + return out_expected; +#endif + } } ///////////////////////////////////// ///////////////////////////////////// - template - template - STORMKIT_FORCE_INLINE - constexpr auto UseNamedConstructors::allocate(ConstructorArgs... c_args, - Args&&... args) noexcept - -> decltype(auto) { - using ReturnValue = meta::TransformExpectedValueTo, RetType>; - - auto out_expected = ReturnValue { - std::in_place, - core::allocate_unsafe(PrivateTagBase::PRIVATE, std::forward(c_args)...) - }; - if (auto result = out_expected.value()->do_init(PrivateTagBase::PRIVATE, std::forward(args)...); not result) - out_expected = std::unexpected { std::move(result).error() }; - - return out_expected; + template + constexpr auto NamedConstructor>::allocate(TDoInitArgs... args) noexcept -> decltype(auto) { + using DoInitReturnType = decltype(std::declval().do_init(PRIVATE, std::declval()...)); + if constexpr (not meta::IsStdExpected) { + auto out = core::allocate_unsafe(PrivateTagBase::PRIVATE); + out->do_init(PrivateTagBase::PRIVATE, std::forward(args)...); + return out; + } else { + using ReturnType = meta::TransformExpectedValueTo, DoInitReturnType>; + +#ifdef STORMKIT_COMPILER_CLANG + auto out = core::allocate_unsafe(PrivateTagBase::PRIVATE); + if (auto result = out->do_init(PrivateTagBase::PRIVATE, std::forward(args)...); not result) + return ReturnType { std::unexpect, std::move(result).error() }; + + return ReturnType { std::in_place, std::move(out) }; +#else + auto out_expected = ReturnType { std::in_place, core::allocate_unsafe(PrivateTagBase::PRIVATE...) }; + if (auto result = out_expected.value()->do_init(PrivateTagBase::PRIVATE, std::forward(args)...); + not result) + out_expected = std::unexpected { std::move(result).error() }; + + return out_expected; +#endif + } } - }} // namespace stormkit::core diff --git a/modules/stormkit/core/parallelism/locked.cppm b/modules/stormkit/core/parallelism/locked.cppm index 88a3304c9..640e7dd53 100644 --- a/modules/stormkit/core/parallelism/locked.cppm +++ b/modules/stormkit/core/parallelism/locked.cppm @@ -16,6 +16,13 @@ import :typesafe.integer; import :typesafe.ref; namespace stormkit { inline namespace core { + export { + enum class LockAccessMode : core::u8 { + READ_ONLY, + READ_WRITE, + }; + } + namespace meta { namespace details { template struct LockedValueType { @@ -26,6 +33,9 @@ namespace stormkit { inline namespace core { struct LockedValueType { using Type = meta::ContainedOrPointedType; }; + + template + using AccessClosureInvokeParameter = meta::If; }} // namespace meta::details namespace details { @@ -35,139 +45,146 @@ namespace stormkit { inline namespace core { template using DefaultReadWriteLock = std::unique_lock; } // namespace details -}} // namespace stormkit::core -export namespace stormkit { inline namespace core { - enum class LockAccessMode : core::u8 { - READ_ONLY, - READ_WRITE, - }; + export { + template + class STORMKIT_CORE_API Locked { + public: + using ValueType = meta::details::LockedValueType::Type; + using ReferenceType = ValueType&; + using ConstReferenceType = const ValueType&; + using PointerType = ValueType*; + + /* stl compatible */ + using value_type = ValueType; + using reference_type = ReferenceType; + using pointer_type = PointerType; - template - class STORMKIT_CORE_API Locked { - public: - using ValueType = meta::details::LockedValueType::Type; - using ReferenceType = ValueType&; - using ConstReferenceType = const ValueType&; - using PointerType = ValueType*; + using MutexType = Mutex; - /* stl compatible */ - using value_type = ValueType; - using reference_type = ReferenceType; - using pointer_type = PointerType; + private: + template class Lock, LockAccessMode Mode> + class Access; - using MutexType = Mutex; + public: + template class Lock> + using ReadAccess = Access; + template class Lock> + using WriteAccess = Access; - private: - template - using AccessClosureInvokeParameter = meta::If; + Locked() noexcept(noexcept(std::is_nothrow_default_constructible_v)); - template class Lock, LockAccessMode Mode> - class Access; + template + explicit(sizeof...(Args) == 1) + Locked(Args&&... args) noexcept(noexcept(std::is_nothrow_constructible_v)); - public: - template class Lock> - using ReadAccess = Access; - template class Lock> - using WriteAccess = Access; + Locked(const Locked&) = delete; + auto operator=(const Locked&) -> Locked& = delete; - Locked() noexcept(noexcept(std::is_nothrow_default_constructible_v)); + Locked(Locked&&) noexcept; + auto operator=(Locked&&) noexcept -> Locked&; - template - explicit(sizeof...(Args) == 1) - Locked(Args&&... args) noexcept(noexcept(std::is_nothrow_constructible_v)); + ~Locked() noexcept; - Locked(const Locked&) = delete; - auto operator=(const Locked&) -> Locked& = delete; + template class Lock, typename... LockArgs, class Self> + auto access(this Self& self, LockArgs&&... lock_args) noexcept -> Access; - Locked(Locked&&) noexcept; - auto operator=(Locked&&) noexcept -> Locked&; + template< + LockAccessMode Mode, + std::invocable::Type&, Mode>> + Closure, + template class Lock, + typename... LockArgs, + class Self> + auto access(this Self& self, Closure&& closure, LockArgs&&... lock_args) noexcept + -> std::invoke_result_t>; - ~Locked() noexcept; + template class Lock = details::DefaultReadOnlyLock, typename... LockArgs> + auto read(LockArgs&&... lock_args) const noexcept -> ReadAccess; - template class Lock, typename... LockArgs, class Self> - auto access(this Self& self, LockArgs&&... lock_args) noexcept -> Access; + template Closure, + template class Lock = details::DefaultReadOnlyLock, + typename... LockArgs> + auto read(Closure&& closure, LockArgs&&... lock_args) const noexcept + -> std::invoke_result_t; - template> Closure, - template class Lock, - typename... LockArgs, - class Self> - auto access(this Self& self, Closure&& closure, LockArgs&&... lock_args) noexcept - -> std::invoke_result_t>; + template class Lock = details::DefaultReadWriteLock, typename... LockArgs> + auto write(LockArgs&&... lock_args) noexcept -> WriteAccess; - template class Lock = details::DefaultReadOnlyLock, typename... LockArgs> - auto read(LockArgs&&... lock_args) const noexcept -> ReadAccess; + template Closure, + template class Lock = details::DefaultReadWriteLock, + typename... LockArgs> + auto write(Closure&& closure, LockArgs&&... lock_args) noexcept -> std::invoke_result_t; - template Closure, - template class Lock = details::DefaultReadOnlyLock, - typename... LockArgs> - auto read(Closure&& closure, LockArgs&&... lock_args) const noexcept -> std::invoke_result_t; + template class Lock = details::DefaultReadOnlyLock, typename... LockArgs> + auto copy(LockArgs&&... lock_args) const noexcept -> ValueType; - template class Lock = details::DefaultReadWriteLock, typename... LockArgs> - auto write(LockArgs&&... lock_args) noexcept -> WriteAccess; + template class Lock = details::DefaultReadWriteLock, typename... LockArgs> + auto assign(ConstReferenceType value, + LockArgs&&... lock_args) noexcept(noexcept(std::is_nothrow_assignable_v)) + -> void; - template Closure, - template class Lock = details::DefaultReadWriteLock, - typename... LockArgs> - auto write(Closure&& closure, LockArgs&&... lock_args) noexcept -> std::invoke_result_t; + template class Lock = details::DefaultReadWriteLock, typename... LockArgs> + auto assign(ValueType&& value, + LockArgs&&... lock_args) noexcept(noexcept(std::is_nothrow_assignable_v)) -> void; - template class Lock = details::DefaultReadOnlyLock, typename... LockArgs> - auto copy(LockArgs&&... lock_args) const noexcept -> ValueType; + template + auto unsafe(this Self& self) noexcept -> meta::ForwardConst&; - template class Lock = details::DefaultReadWriteLock, typename... LockArgs> - auto assign(ConstReferenceType value, - LockArgs&&... lock_args) noexcept(noexcept(std::is_nothrow_assignable_v)) - -> void; + auto mutex() const noexcept -> const MutexType&; - template class Lock = details::DefaultReadWriteLock, typename... LockArgs> - auto assign(ValueType&& value, - LockArgs&&... lock_args) noexcept(noexcept(std::is_nothrow_assignable_v)) -> void; + private: + template class Lock, LockAccessMode Mode> + class Access { + public: + using AccessValueType = std::conditional_t; + using RefContainerType = std:: + conditional_t, ref>; - template - auto unsafe(this Self& self) noexcept -> meta::ForwardConst&; + template + Access(ReferenceType value, MutexType& mutex, LockArgs&&... args) noexcept; - auto mutex() const noexcept -> const MutexType&; + template + Access(ConstReferenceType value, MutexType& mutex, LockArgs&&... args) noexcept; - private: - template class Lock, LockAccessMode Mode> - class Access { - public: - using AccessValueType = std::conditional_t; - using RefContainerType = std::conditional_t, ref>; + template + requires(not meta::IsContainerOrPointer) + explicit(sizeof...(LockArgs) == 0) Access(const Locked& locked, LockArgs&&... args) noexcept + requires(Mode == LockAccessMode::READ_ONLY); - template - Access(ReferenceType value, MutexType& mutex, LockArgs&&... args) noexcept; + template + requires(not meta::IsContainerOrPointer) + explicit(sizeof...(LockArgs) == 0) Access(Locked& locked, LockArgs&&... args) noexcept; - template - Access(ConstReferenceType value, MutexType& mutex, LockArgs&&... args) noexcept; + template + requires(meta::IsContainerOrPointer) + explicit(sizeof...(LockArgs) == 0) Access(const Locked& locked, LockArgs&&... args) noexcept + requires(Mode == LockAccessMode::READ_ONLY); - template - explicit(sizeof...(LockArgs) == 0) Access(const Locked& locked, LockArgs&&... args) noexcept - requires(Mode == LockAccessMode::READ_ONLY); + template + requires(meta::IsContainerOrPointer) + explicit(sizeof...(LockArgs) == 0) Access(Locked& locked, LockArgs&&... args) noexcept; - template - explicit(sizeof...(LockArgs) == 0) Access(Locked& locked, LockArgs&&... args) noexcept; + auto operator->() const noexcept -> AccessValueType*; + auto operator*() const noexcept -> AccessValueType&; - auto operator->() const noexcept -> AccessValueType*; - auto operator*() const noexcept -> AccessValueType&; + mutable Lock lock; - mutable Lock lock; + private: + RefContainerType m_value; + }; - private: - RefContainerType m_value; + mutable Mutex m_mutex; + T m_value STORMKIT_GUARDED_BY(m_mutex); }; - mutable Mutex m_mutex; - T m_value STORMKIT_GUARDED_BY(m_mutex); - }; - - template - Locked(T) -> Locked; + template + Locked(T) -> Locked; - template class Locked; - template class Locked>; - template class Locked>; + template class Locked; + template class Locked>; + template class Locked>; + } }} // namespace stormkit::core //////////////////////////////////////////////////////////////////// @@ -194,9 +211,9 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// template Locked::Locked(Locked&& other) noexcept { - auto from = other.write(); + auto _ = other.write(); - m_value = std::move(*from); + m_value = std::move(other.m_value); } //////////////////////////////////////// @@ -234,14 +251,14 @@ namespace stormkit { inline namespace core { //////////////////////////////////////// //////////////////////////////////////// template - template::template AccessClosureInvokeParameter> Closure, + template::Type&, Mode>> + Closure, template class Lock, typename... LockArgs, - class Self> - STORMKIT_FORCE_INLINE + class Self> STORMKIT_FORCE_INLINE auto Locked::access(this Self& self, Closure&& closure, LockArgs&&... lock_args) noexcept - -> std::invoke_result_t> { + -> std::invoke_result_t> { static_assert(not(Mode == LockAccessMode::READ_ONLY and not std::is_const_v>), "can't get read access on const Locked"); using AccessType = Access; @@ -365,6 +382,7 @@ namespace stormkit { inline namespace core { template template class Lock, LockAccessMode Mode> template + requires(not meta::IsContainerOrPointer) STORMKIT_FORCE_INLINE Locked::Access::Access(const Locked& locked, LockArgs&&... lock_args) noexcept requires(Mode == LockAccessMode::READ_ONLY) @@ -376,11 +394,35 @@ namespace stormkit { inline namespace core { template template class Lock, LockAccessMode Mode> template + requires(not meta::IsContainerOrPointer) STORMKIT_FORCE_INLINE Locked::Access::Access(Locked& locked, LockArgs&&... lock_args) noexcept : Access { locked.m_value, locked.m_mutex, std::forward(lock_args)... } { } + //////////////////////////////////////// + //////////////////////////////////////// + template + template class Lock, LockAccessMode Mode> + template + requires(meta::IsContainerOrPointer) + STORMKIT_FORCE_INLINE + Locked::Access::Access(const Locked& locked, LockArgs&&... lock_args) noexcept + requires(Mode == LockAccessMode::READ_ONLY) + : Access { *locked.m_value, locked.m_mutex, std::forward(lock_args)... } { + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + template class Lock, LockAccessMode Mode> + template + requires(meta::IsContainerOrPointer) + STORMKIT_FORCE_INLINE + Locked::Access::Access(Locked& locked, LockArgs&&... lock_args) noexcept + : Access { *locked.m_value, locked.m_mutex, std::forward(lock_args)... } { + } + //////////////////////////////////////// //////////////////////////////////////// template diff --git a/modules/stormkit/core/typesafe/integer.cppm b/modules/stormkit/core/typesafe/integer.cppm index 8cf803372..fcc04e74a 100644 --- a/modules/stormkit/core/typesafe/integer.cppm +++ b/modules/stormkit/core/typesafe/integer.cppm @@ -41,7 +41,7 @@ export { using u32 = std::uint32_t; using u64 = std::uint64_t; #ifdef __SIZEOF_INT128__ - using u128 = unsigned __int128; + __extension__ using u128 = unsigned __int128; #elif defined(STORMKIT_COMPILER_MSVC) using u128 = std::_Unsigned128; #endif @@ -51,7 +51,7 @@ export { using i32 = std::int32_t; using i64 = std::int64_t; #ifdef __SIZEOF_INT128__ - using i128 = __int128; + __extension__ using i128 = __int128; #elif defined(STORMKIT_COMPILER_MSVC) using i128 = std::_Signed128; #else diff --git a/modules/stormkit/core/typesafe/ref.cppm b/modules/stormkit/core/typesafe/ref.cppm index 69968c30e..7a3bd59d9 100644 --- a/modules/stormkit/core/typesafe/ref.cppm +++ b/modules/stormkit/core/typesafe/ref.cppm @@ -31,7 +31,7 @@ export { template using owned_ptr = T*; - template + template class ref; template diff --git a/modules/stormkit/core/utils/filesystem.cppm b/modules/stormkit/core/utils/filesystem.cppm index 4bbed7bf2..57196d042 100644 --- a/modules/stormkit/core/utils/filesystem.cppm +++ b/modules/stormkit/core/utils/filesystem.cppm @@ -76,11 +76,11 @@ export { namespace io { template - class Descriptor final: protected UseNamedConstructors, Expected> { - public: - static auto open(const stdfs::path& path, Access access) noexcept -> Expected; - static auto allocate_and_open(const stdfs::path& path, Access access) noexcept -> Expected; + class Descriptor final: public NamedConstructor, DoInitArgs> { + using Base = NamedConstructor, DoInitArgs>; + public: + explicit Descriptor(PrivateTag) noexcept; ~Descriptor() noexcept; Descriptor(Descriptor&) = delete; @@ -89,6 +89,9 @@ export { Descriptor(Descriptor&&) noexcept; auto operator=(Descriptor&&) noexcept -> Descriptor&; + static auto open(const stdfs::path& path, Access access) noexcept -> Expected; + static auto allocate_and_open(const stdfs::path& path, Access access) noexcept -> Expected; + auto close() noexcept; auto read_to(byte_mut_view<> out) noexcept -> Expected; @@ -110,10 +113,12 @@ export { auto native_descriptor() const noexcept -> int; - Descriptor(PrivateTag) noexcept; auto do_init(PrivateTag, const stdfs::path&, Access) noexcept -> Expected; private: + using Base::allocate; + using Base::create; + int m_descriptor = 0; mutable std::atomic m_size = 0; @@ -194,8 +199,7 @@ namespace stormkit { inline namespace core { namespace io { template STORMKIT_FORCE_INLINE inline auto Descriptor::open(const stdfs::path& path, Access access) noexcept -> Expected> { - auto descriptor = Try(Descriptor::create(path, access)); - Return descriptor; + return Descriptor::create(path, access); } //////////////////////////////////////// @@ -204,7 +208,7 @@ namespace stormkit { inline namespace core { namespace io { STORMKIT_FORCE_INLINE inline auto Descriptor::allocate_and_open(const stdfs::path& path, Access access) noexcept -> Expected> { - Return Try(Descriptor::allocate(path, access)); + return Descriptor::allocate(path, access); } //////////////////////////////////////// diff --git a/modules/stormkit/gpu/core/base.cppm b/modules/stormkit/gpu/core/base.cppm index 56868c696..a8ab5c1e6 100644 --- a/modules/stormkit/gpu/core/base.cppm +++ b/modules/stormkit/gpu/core/base.cppm @@ -101,7 +101,7 @@ export namespace stormkit::gpu { friend class GpuObjectViewImplementation; }; - template + template class GpuObjectImplementation; template @@ -115,7 +115,7 @@ export namespace stormkit::gpu { using ObjectType = Base::ObjectType; using ViewType = Base::ViewType; - GpuObjectViewImplementation(const GpuObjectImplementation&) noexcept; + GpuObjectViewImplementation(const cmeta::IsSpecializationOf auto&) noexcept; template GpuObjectViewImplementation(const TContainerOrPointer&) noexcept; ~GpuObjectViewImplementation() noexcept; @@ -141,7 +141,7 @@ export namespace stormkit::gpu { using OwnerType = Base::OwnerType; using OwnerViewType = Base::OwnerViewType; - GpuObjectViewImplementation(const GpuObjectImplementation&) noexcept; + GpuObjectViewImplementation(const cmeta::IsSpecializationOf auto&) noexcept; template GpuObjectViewImplementation(const TContainerOrPointer&) noexcept; ~GpuObjectViewImplementation() noexcept; @@ -153,12 +153,17 @@ export namespace stormkit::gpu { auto operator=(GpuObjectViewImplementation&&) noexcept -> GpuObjectViewImplementation&; }; - template - class GpuObjectImplementation + template + requires(meta::GpuObjectHasTraitDefined) + class GpuObjectImplementation : public GpuObjectBase, - public UseNamedConstructors::ObjectType, meta::GpuObjectDoInitReturnType> { + public core::NamedConstructor::ObjectType, DoInitArgs> { using Base = GpuObjectBase; + protected: + using NamedConstructorBase = core::NamedConstructor::ObjectType, + DoInitArgs>; + public: using TagType = Base::TagType; using TraitType = Base::TraitType; @@ -176,19 +181,27 @@ export namespace stormkit::gpu { GpuObjectImplementation(GpuObjectImplementation&&) noexcept; auto operator=(GpuObjectImplementation&&) noexcept -> GpuObjectImplementation&; + using NamedConstructorBase::allocate; + using NamedConstructorBase::create; + protected: DeleterType m_deleter_ptr; }; - template - requires(meta::HasOwnerType) - class GpuObjectImplementation + template + requires(meta::GpuObjectHasTraitDefined and meta::HasOwnerType) + class GpuObjectImplementation : public GpuObjectBase, - public UseNamedConstructors::ObjectType, - meta::GpuObjectDoInitReturnType, - typename trait::GpuObject::OwnerType::ViewType> { + public core::NamedConstructor::ObjectType, + ConstructorArgs::OwnerType::ViewType>, + DoInitArgs> { using Base = GpuObjectBase; + protected: + using NamedConstructorBase = core::NamedConstructor::ObjectType, + ConstructorArgs::OwnerType::ViewType>, + DoInitArgs>; + public: using TagType = Base::TagType; using TraitType = Base::TraitType; @@ -208,6 +221,9 @@ export namespace stormkit::gpu { GpuObjectImplementation(GpuObjectImplementation&&) noexcept; auto operator=(GpuObjectImplementation&&) noexcept -> GpuObjectImplementation&; + using NamedConstructorBase::allocate; + using NamedConstructorBase::create; + protected: DeleterType m_deleter_ptr; }; @@ -397,7 +413,8 @@ namespace stormkit::gpu { ///////////////////////////////////// template STORMKIT_FORCE_INLINE - inline GpuObjectViewImplementation::GpuObjectViewImplementation(const GpuObjectImplementation& object) noexcept + inline GpuObjectViewImplementation< + Tag>::GpuObjectViewImplementation(const cmeta::IsSpecializationOf auto& object) noexcept : GpuObjectBase {} { GpuObjectBase::m_vk_handle = object.m_vk_handle; } @@ -412,6 +429,12 @@ namespace stormkit::gpu { GpuObjectBase::m_vk_handle = (*object).m_vk_handle; } + ///////////////////////////////////// + ///////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline GpuObjectViewImplementation::~GpuObjectViewImplementation() noexcept = default; + ///////////////////////////////////// ///////////////////////////////////// template @@ -448,18 +471,13 @@ namespace stormkit::gpu { return *this; } - ///////////////////////////////////// - ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline GpuObjectViewImplementation::~GpuObjectViewImplementation() noexcept = default; - ///////////////////////////////////// ///////////////////////////////////// template requires(meta::HasOwnerType) STORMKIT_FORCE_INLINE - inline GpuObjectViewImplementation::GpuObjectViewImplementation(const GpuObjectImplementation& object) noexcept + inline GpuObjectViewImplementation< + Tag>::GpuObjectViewImplementation(const cmeta::IsSpecializationOf auto& object) noexcept : GpuObjectBase { object.owner() } { GpuObjectBase::m_vk_handle = object.m_vk_handle; } @@ -475,6 +493,13 @@ namespace stormkit::gpu { GpuObjectBase::m_vk_handle = (*object).m_vk_handle; } + ///////////////////////////////////// + ///////////////////////////////////// + template + requires(meta::HasOwnerType) + STORMKIT_FORCE_INLINE + inline GpuObjectViewImplementation::~GpuObjectViewImplementation() noexcept = default; + ///////////////////////////////////// ///////////////////////////////////// template @@ -519,32 +544,40 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - template - requires(meta::HasOwnerType) + template + requires(meta::GpuObjectHasTraitDefined) STORMKIT_FORCE_INLINE - inline GpuObjectViewImplementation::~GpuObjectViewImplementation() noexcept = default; + inline GpuObjectImplementation::GpuObjectImplementation(DeleterType&& deleter_ptr) noexcept + : GpuObjectBase {}, m_deleter_ptr { std::move(deleter_ptr) } { + } ///////////////////////////////////// ///////////////////////////////////// - template - STORMKIT_FORCE_INLINE - inline GpuObjectImplementation::GpuObjectImplementation(DeleterType&& deleter_ptr) noexcept - : GpuObjectBase {}, m_deleter_ptr { std::move(deleter_ptr) } { + template + requires(meta::GpuObjectHasTraitDefined) + STORMKIT_FORCE_INLINE inline GpuObjectImplementation::~GpuObjectImplementation() noexcept { + if constexpr (cmeta::SameAs) { + if (m_deleter_ptr != nullptr and Base::m_vk_handle != VK_NULL_HANDLE) + vk::call(m_deleter_ptr, Base::m_vk_handle, nullptr); + } } ///////////////////////////////////// ///////////////////////////////////// - template + template + requires(meta::GpuObjectHasTraitDefined) STORMKIT_FORCE_INLINE - inline GpuObjectImplementation::GpuObjectImplementation(GpuObjectImplementation&& other) noexcept + inline GpuObjectImplementation::GpuObjectImplementation(GpuObjectImplementation&& other) noexcept : GpuObjectBase { std::move(other) }, m_deleter_ptr { std::exchange(other.m_deleter_ptr, {}) } { } ///////////////////////////////////// ///////////////////////////////////// - template + template + requires(meta::GpuObjectHasTraitDefined) STORMKIT_FORCE_INLINE - inline auto GpuObjectImplementation::operator=(GpuObjectImplementation&& other) noexcept -> GpuObjectImplementation& { + inline auto GpuObjectImplementation::operator=(GpuObjectImplementation&& other) noexcept + -> GpuObjectImplementation& { if (&other == this) [[unlikely]] return *this; @@ -557,39 +590,50 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - template + template + requires(meta::GpuObjectHasTraitDefined and meta::HasOwnerType) STORMKIT_FORCE_INLINE - inline GpuObjectImplementation::~GpuObjectImplementation() noexcept { - if constexpr (cmeta::SameAs) { - if (m_deleter_ptr != nullptr and Base::m_vk_handle != VK_NULL_HANDLE) - vk::call(m_deleter_ptr, Base::m_vk_handle, nullptr); - } + inline GpuObjectImplementation::GpuObjectImplementation(OwnerViewType&& owner, + DeleterType&& deleter_ptr) noexcept + : GpuObjectBase { std::move(owner) }, m_deleter_ptr { std::move(deleter_ptr) } { } ///////////////////////////////////// ///////////////////////////////////// - template - requires(meta::HasOwnerType) - STORMKIT_FORCE_INLINE - inline GpuObjectImplementation::GpuObjectImplementation(OwnerViewType&& owner, DeleterType&& deleter_ptr) noexcept - : GpuObjectBase { std::move(owner) }, m_deleter_ptr { std::move(deleter_ptr) } { + template + requires(meta::GpuObjectHasTraitDefined and meta::HasOwnerType) + STORMKIT_FORCE_INLINE inline GpuObjectImplementation::~GpuObjectImplementation() noexcept { + using OwnerValueType = OwnerType::ValueType; + + if constexpr (cmeta::SameAs) { + if constexpr (cmeta::SameAs) { + if (m_deleter_ptr != nullptr and Base::m_vk_handle != VK_NULL_HANDLE) + vk::call(m_deleter_ptr, Base::m_owner, Base::m_vk_handle, nullptr); + } else { + const auto& device = this->device(); + const auto& device_table = device.device_table(); + if (m_deleter_ptr != nullptr and Base::m_vk_handle != VK_NULL_HANDLE) + vk::call(device_table.*m_deleter_ptr, device, Base::m_vk_handle, nullptr); + } + } } ///////////////////////////////////// ///////////////////////////////////// - template - requires(meta::HasOwnerType) + template + requires(meta::GpuObjectHasTraitDefined and meta::HasOwnerType) STORMKIT_FORCE_INLINE - inline GpuObjectImplementation::GpuObjectImplementation(GpuObjectImplementation&& other) noexcept + inline GpuObjectImplementation::GpuObjectImplementation(GpuObjectImplementation&& other) noexcept : GpuObjectBase { std::move(other) }, m_deleter_ptr { std::exchange(other.m_deleter_ptr, {}) } { } ///////////////////////////////////// ///////////////////////////////////// - template - requires(meta::HasOwnerType) + template + requires(meta::GpuObjectHasTraitDefined and meta::HasOwnerType) STORMKIT_FORCE_INLINE - inline auto GpuObjectImplementation::operator=(GpuObjectImplementation&& other) noexcept -> GpuObjectImplementation& { + inline auto GpuObjectImplementation::operator=(GpuObjectImplementation&& other) noexcept + -> GpuObjectImplementation& { if (&other == this) [[unlikely]] return *this; @@ -600,27 +644,6 @@ namespace stormkit::gpu { return *this; } - ///////////////////////////////////// - ///////////////////////////////////// - template - requires(meta::HasOwnerType) - STORMKIT_FORCE_INLINE - inline GpuObjectImplementation::~GpuObjectImplementation() noexcept { - using OwnerValueType = OwnerType::ValueType; - - if constexpr (cmeta::SameAs) { - if constexpr (cmeta::SameAs) { - if (m_deleter_ptr != nullptr and Base::m_vk_handle != VK_NULL_HANDLE) - vk::call(m_deleter_ptr, Base::m_owner, Base::m_vk_handle, nullptr); - } else { - const auto& device = this->device(); - const auto& device_table = device.device_table(); - if (m_deleter_ptr != nullptr and Base::m_vk_handle != VK_NULL_HANDLE) - vk::call(device_table.*m_deleter_ptr, device, Base::m_vk_handle, nullptr); - } - } - } - ///////////////////////////////////// ///////////////////////////////////// template diff --git a/modules/stormkit/gpu/core/debug_callback.cppm b/modules/stormkit/gpu/core/debug_callback.cppm index dfaa0b466..0a17d6035 100644 --- a/modules/stormkit/gpu/core/debug_callback.cppm +++ b/modules/stormkit/gpu/core/debug_callback.cppm @@ -22,20 +22,31 @@ import :objects; import :instance; namespace stormkit::gpu { - export template - class DebugCallbackInterface final: public InstanceObject { - public: - using InstanceObject::InstanceObject; - using InstanceObject::operator=; - using TagType = DebugCallbackTag; - }; + export { + struct DebugCallbackInterfaceBase { + struct CreateInfo { + using Closure = PFN_vkDebugUtilsMessengerCallbackEXT; + + Closure messenger_closure; + ptr user_data = nullptr; + }; + }; + + template + class DebugCallbackInterface final: public InstanceObject, public DebugCallbackInterfaceBase { + public: + using InstanceObject::InstanceObject; + using InstanceObject::operator=; + using TagType = DebugCallbackTag; + }; + } - class STORMKIT_GPU_API DebugCallbackImplementation: public GpuObjectImplementation { + class STORMKIT_GPU_API DebugCallbackImplementation + : public GpuObjectImplementation { public: - using Closure = PFN_vkDebugUtilsMessengerCallbackEXT; + using CreateInfo = DebugCallbackInterfaceBase::CreateInfo; DebugCallbackImplementation(PrivateTag, view::Instance&&) noexcept; - auto do_init(PrivateTag, Closure messenger_closure, void* user_data = nullptr) noexcept -> Expected; ~DebugCallbackImplementation() noexcept; DebugCallbackImplementation(const DebugCallbackImplementation&) noexcept = delete; @@ -43,6 +54,8 @@ namespace stormkit::gpu { DebugCallbackImplementation(DebugCallbackImplementation&&) noexcept; auto operator=(DebugCallbackImplementation&&) noexcept -> DebugCallbackImplementation&; + + auto do_init(PrivateTag, const CreateInfo&) noexcept -> Expected; }; namespace view { diff --git a/modules/stormkit/gpu/core/device.cppm b/modules/stormkit/gpu/core/device.cppm index 7cb4ef1d1..0caeeae26 100644 --- a/modules/stormkit/gpu/core/device.cppm +++ b/modules/stormkit/gpu/core/device.cppm @@ -37,8 +37,15 @@ namespace stormkit::gpu { QueueFlag flags = QueueFlag {}; }; + struct DeviceInterfaceBase { + struct CreateInfo { + bool enable_swapchain = true; + bool enable_raytracing = false; + }; + }; + template - class STORMKIT_GPU_API DeviceInterface final: public PhysicalDeviceObject { + class STORMKIT_GPU_API DeviceInterface final: public PhysicalDeviceObject, public DeviceInterfaceBase { public: using PhysicalDeviceObject::PhysicalDeviceObject; using PhysicalDeviceObject::operator=; @@ -82,15 +89,12 @@ namespace stormkit::gpu { } // namespace monadic } - class STORMKIT_GPU_API DeviceImplementation: public GpuObjectImplementation { + class STORMKIT_GPU_API + DeviceImplementation: public GpuObjectImplementation { public: - struct CreateInfo { - bool enable_swapchain = true; - bool enable_raytracing = false; - }; + using CreateInfo = DeviceInterfaceBase::CreateInfo; DeviceImplementation(PrivateTag, view::PhysicalDevice&&) noexcept; - auto do_init(PrivateTag, const CreateInfo& create_info = { true, false }) noexcept -> Expected; ~DeviceImplementation() noexcept; DeviceImplementation(const DeviceImplementation&) noexcept = delete; @@ -99,6 +103,8 @@ namespace stormkit::gpu { DeviceImplementation(DeviceImplementation&&) noexcept; auto operator=(DeviceImplementation&&) noexcept -> DeviceImplementation&; + auto do_init(PrivateTag, const CreateInfo&) noexcept -> Expected; + protected: dyn_array m_queue_entries; diff --git a/modules/stormkit/gpu/core/instance.cppm b/modules/stormkit/gpu/core/instance.cppm index 8602ba589..38b5c59a2 100644 --- a/modules/stormkit/gpu/core/instance.cppm +++ b/modules/stormkit/gpu/core/instance.cppm @@ -58,8 +58,16 @@ namespace stormkit::gpu { auto formats_properties() const noexcept -> array_view>; }; + struct InstanceInterfaceBase { + struct CreateInfo { + string_view application_name; + u32 application_version = vk::make_version(0, 0, 0); + bool enable_validation_layers = (STORMKIT_BUILD_TYPE == "DEBUG"); + }; + }; + template - class InstanceInterface final: public Base { + class InstanceInterface final: public Base, public InstanceInterfaceBase { public: using Base::Base; using Base::operator=; @@ -73,10 +81,12 @@ namespace stormkit::gpu { }; } - class STORMKIT_GPU_API InstanceImplementation: public GpuObjectImplementation { + class STORMKIT_GPU_API + InstanceImplementation: public GpuObjectImplementation { public: + using CreateInfo = InstanceInterfaceBase::CreateInfo; + explicit InstanceImplementation(PrivateTag) noexcept; - auto do_init(PrivateTag, string = "", bool = (STORMKIT_BUILD_TYPE == "DEBUG")) noexcept -> Expected; ~InstanceImplementation() noexcept; InstanceImplementation(const InstanceImplementation&) noexcept = delete; @@ -85,6 +95,8 @@ namespace stormkit::gpu { InstanceImplementation(InstanceImplementation&&) noexcept; auto operator=(InstanceImplementation&&) noexcept -> InstanceImplementation&; + auto do_init(PrivateTag, const CreateInfo&) noexcept -> Expected; + protected: dyn_array m_extensions; dyn_array m_physical_devices; @@ -117,7 +129,7 @@ namespace stormkit::gpu { }; } // namespace view - class STORMKIT_GPU_API PhysicalDeviceImplementation: public GpuObjectImplementation { + class STORMKIT_GPU_API PhysicalDeviceImplementation: public GpuObjectImplementation { public: struct Data { PhysicalDeviceInfo device_info; @@ -125,7 +137,6 @@ namespace stormkit::gpu { }; PhysicalDeviceImplementation(PrivateTag, view::Instance&&) noexcept; - auto do_init(PrivateTag, VkPhysicalDevice&&) noexcept -> void; ~PhysicalDeviceImplementation() noexcept; PhysicalDeviceImplementation(const PhysicalDeviceImplementation&) noexcept = delete; @@ -134,6 +145,8 @@ namespace stormkit::gpu { PhysicalDeviceImplementation(PhysicalDeviceImplementation&&) noexcept; auto operator=(PhysicalDeviceImplementation&&) noexcept -> PhysicalDeviceImplementation&; + auto do_init(PrivateTag, VkPhysicalDevice&&) noexcept -> void; + protected: Heap m_data; dyn_array m_memory_types; diff --git a/modules/stormkit/gpu/core/surface.cppm b/modules/stormkit/gpu/core/surface.cppm index a26038b96..bad263622 100644 --- a/modules/stormkit/gpu/core/surface.cppm +++ b/modules/stormkit/gpu/core/surface.cppm @@ -27,19 +27,39 @@ import :objects; import :instance; namespace stormkit::gpu { - export template - class SurfaceInterface final: public InstanceObject { - public: - using InstanceObject::InstanceObject; - using InstanceObject::operator=; - using TagType = SurfaceTag; - }; + export { + struct SurfaceInterfaceBase { + struct OffscreenCreateInfo {}; + + struct CreateInfo { + ref window; + }; + }; + + template + class SurfaceInterface final: public InstanceObject { + public: + using InstanceObject::InstanceObject; + using InstanceObject::operator=; + using TagType = SurfaceTag; + }; + } - class STORMKIT_GPU_API SurfaceImplementation: public GpuObjectImplementation { + class STORMKIT_GPU_API SurfaceImplementation + : public GpuObjectImplementation, + public core::NamedConstructor, + DoInitArgs> { public: + using CreateInfo = SurfaceInterfaceBase::CreateInfo; + using OffscreenCreateInfo = SurfaceInterfaceBase::OffscreenCreateInfo; + using OffscreenNamedConstructor = core:: + NamedConstructor, DoInitArgs>; + + using OffscreenNamedConstructor::allocate; + using OffscreenNamedConstructor::create; + SurfaceImplementation(PrivateTag, view::Instance&&) noexcept; - auto do_init(PrivateTag) noexcept -> Expected; - auto do_init(PrivateTag, const wsi::Window&) noexcept -> Expected; ~SurfaceImplementation() noexcept; SurfaceImplementation(const SurfaceImplementation&) noexcept = delete; @@ -62,9 +82,8 @@ namespace stormkit::gpu { [[nodiscard]] static auto allocate_from_window(view::Instance instance, const wsi::Window& window) noexcept -> Expected>; - private: - using UseNamedConstructors::allocate; - using UseNamedConstructors::create; + auto do_init(PrivateTag, const CreateInfo&) noexcept -> Expected; + auto do_init(PrivateTag, const OffscreenCreateInfo&) noexcept -> Expected; }; namespace view { @@ -108,14 +127,14 @@ namespace stormkit::gpu { ///////////////////////////////////// STORMKIT_FORCE_INLINE inline auto SurfaceImplementation::create_offscreen(view::Instance instance) noexcept -> Expected { - return UseNamedConstructors::create(std::move(instance)); + return OffScreenNamedConstructor::create(std::move(instance), OffscreenCreateInfo{}); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE inline auto SurfaceImplementation::allocate_offscreen(view::Instance instance) noexcept -> Expected> { - return UseNamedConstructors::allocate(std::move(instance)); + return OffScreenNamedConstructor::allocate(std::move(instance), OffscreenCreateInfo{}); } #endif @@ -124,7 +143,7 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto SurfaceImplementation::create_from_window(view::Instance instance, const wsi::Window& window) noexcept -> Expected { - return UseNamedConstructors::create(std::move(instance), window); + return GpuObjectImplementation::create(std::move(instance), CreateInfo { as_ref(window) }); } ///////////////////////////////////// @@ -132,6 +151,6 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto SurfaceImplementation::allocate_from_window(view::Instance instance, const wsi::Window& window) noexcept -> Expected> { - return UseNamedConstructors::allocate(std::move(instance), window); + return GpuObjectImplementation::allocate(std::move(instance), CreateInfo { as_ref(window) }); } } // namespace stormkit::gpu diff --git a/modules/stormkit/gpu/core/sync.cppm b/modules/stormkit/gpu/core/sync.cppm index 4407832c9..812f8e37b 100644 --- a/modules/stormkit/gpu/core/sync.cppm +++ b/modules/stormkit/gpu/core/sync.cppm @@ -29,6 +29,10 @@ import :device; namespace stormkit::gpu { export { struct FenceInterfaceBase { + struct CreateInfo { + bool signaled = false; + }; + enum class Status { SIGNALED, UNSIGNALED, @@ -59,13 +63,18 @@ namespace stormkit::gpu { }; } - class STORMKIT_GPU_API FenceImplementation: public GpuObjectImplementation { + class STORMKIT_GPU_API FenceImplementation: public GpuObjectImplementation { public: - FenceImplementation(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, bool = false) noexcept -> Expected; + using CreateInfo = FenceInterfaceBase::CreateInfo; + static auto create(view::Device device) noexcept -> Expected; + static auto allocate(view::Device device) noexcept -> Expected>; static auto create_signaled(view::Device device) noexcept -> Expected; static auto allocate_signaled(view::Device device) noexcept -> Expected>; + + FenceImplementation(PrivateTag, view::Device&&) noexcept; + + auto do_init(PrivateTag, const CreateInfo&) noexcept -> Expected; }; namespace view { @@ -79,6 +88,7 @@ namespace stormkit::gpu { class STORMKIT_GPU_API SemaphoreImplementation: public GpuObjectImplementation { public: SemaphoreImplementation(PrivateTag, view::Device&&) noexcept; + auto do_init(PrivateTag) noexcept -> Expected; }; @@ -120,18 +130,32 @@ namespace stormkit::gpu { : GpuObjectImplementation { std::move(device), &VolkDeviceTable::vkDestroyFence } { } + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto FenceImplementation::create(view::Device device) noexcept -> Expected { + return NamedConstructor::create(std::move(device), {}); + } + + ///////////////////////////////////// + ///////////////////////////////////// + STORMKIT_FORCE_INLINE + inline auto FenceImplementation::allocate(view::Device device) noexcept -> Expected> { + return NamedConstructor::allocate(std::move(device), {}); + } + ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE inline auto FenceImplementation::create_signaled(view::Device device) noexcept -> Expected { - return UseNamedConstructors::create(std::move(device), true); + return NamedConstructor::create(std::move(device), { true }); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE inline auto FenceImplementation::allocate_signaled(view::Device device) noexcept -> Expected> { - return UseNamedConstructors::allocate(std::move(device), true); + return NamedConstructor::allocate(std::move(device), { true }); } ///////////////////////////////////// diff --git a/modules/stormkit/gpu/core/vulkan/utils.cppm b/modules/stormkit/gpu/core/vulkan/utils.cppm index e5b75359e..10c60211f 100644 --- a/modules/stormkit/gpu/core/vulkan/utils.cppm +++ b/modules/stormkit/gpu/core/vulkan/utils.cppm @@ -343,13 +343,11 @@ namespace stormkit::gpu::vk { using OutExpected = Expected>; auto out_expected = OutExpected { std::in_place }; - auto out = dyn_array {}; + auto& out = out_expected.value(); out.resize(count, VK_NULL_HANDLE); const auto result = std::invoke(func, std::forward(args)..., stdr::data(out)); if (not stdr::any_of(SUCCESS_RESULTS, cmonadic::is_equal(result))) [[likely]] out_expected = std::unexpected { vk::from_vk(result) }; - else - out_expected = std::move(out); return out_expected; } diff --git a/modules/stormkit/gpu/execution/command_buffer.cppm b/modules/stormkit/gpu/execution/command_buffer.cppm index 4bedc295a..beec66520 100644 --- a/modules/stormkit/gpu/execution/command_buffer.cppm +++ b/modules/stormkit/gpu/execution/command_buffer.cppm @@ -260,37 +260,13 @@ namespace stormkit::gpu { array_view signal_semaphores = {}, std::optional fence = std::nullopt) noexcept -> Expected; }; - - template - class CommandPoolInterface final: public DeviceObject { - public: - using DeviceObject::DeviceObject; - using DeviceObject::operator=; - using TagType = CommandPoolTag; - - auto create_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected; - auto create_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>; - - auto allocate_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>; - auto allocate_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept - -> Expected>>; - - protected: - auto create_vk_command_buffers(usize, CommandBufferLevel) const noexcept -> Expected>; - - static auto delete_vk_command_buffers(view::Device, view::CommandPool, VkCommandBuffer) noexcept -> void; - }; } - class STORMKIT_GPU_API QueueImplementation: public GpuObjectImplementation { + class STORMKIT_GPU_API QueueImplementation: public GpuObjectImplementation { public: using SubmitInfo = QueueInterfaceBase::SubmitInfo; QueueImplementation(PrivateTag, view::Device&& device) noexcept; - auto do_init(PrivateTag, const QueueEntry&) -> void; ~QueueImplementation() noexcept; QueueImplementation(const QueueImplementation&) = delete; @@ -299,6 +275,8 @@ namespace stormkit::gpu { QueueImplementation(QueueImplementation&&) noexcept; auto operator=(QueueImplementation&&) noexcept -> QueueImplementation&; + auto do_init(PrivateTag, const QueueEntry&) -> void; + protected: QueueEntry m_entry; @@ -326,15 +304,15 @@ namespace stormkit::gpu { }; } // namespace view - class STORMKIT_GPU_API CommandBufferImplementation: public GpuObjectImplementation { + using CommandBufferDeleter = std::function; + + class STORMKIT_GPU_API CommandBufferImplementation + : public GpuObjectImplementation { public: using RecordClosure = CommandBufferInterfaceBase::RecordClosure; using State = CommandBufferInterfaceBase::State; - using Deleter = std::function; - CommandBufferImplementation(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, CommandBufferLevel, VkCommandBuffer&&, Deleter&&) noexcept -> void; ~CommandBufferImplementation() noexcept; CommandBufferImplementation(const CommandBufferImplementation&) = delete; @@ -343,14 +321,16 @@ namespace stormkit::gpu { CommandBufferImplementation(CommandBufferImplementation&&) noexcept; auto operator=(CommandBufferImplementation&&) noexcept -> CommandBufferImplementation&; + auto do_init(PrivateTag, CommandBufferLevel, VkCommandBuffer&&, CommandBufferDeleter&&) noexcept -> void; + protected: - using UseNamedConstructors::allocate; - using UseNamedConstructors::create; + using NamedConstructor::allocate; + using NamedConstructor::create; Heap m_state; CommandBufferLevel m_level = CommandBufferLevel::PRIMARY; - Deleter m_deleter; + CommandBufferDeleter m_deleter; friend class CommandPoolInterface; friend class CommandPoolInterface; @@ -380,10 +360,45 @@ namespace stormkit::gpu { }; } // namespace view - class STORMKIT_GPU_API CommandPoolImplementation: public GpuObjectImplementation { + export { + struct CommandPoolInterfaceBase { + struct CreateInfo { + view::Queue queue; + bool reset = true; + bool transient = false; + }; + }; + + template + class CommandPoolInterface final: public DeviceObject, public CommandPoolInterfaceBase { + public: + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = CommandPoolTag; + + auto create_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected; + auto create_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected>; + + auto allocate_command_buffer(CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected>; + auto allocate_command_buffers(usize count, CommandBufferLevel level = CommandBufferLevel::PRIMARY) const noexcept + -> Expected>>; + + protected: + auto create_vk_command_buffers(usize, CommandBufferLevel) const noexcept -> Expected>; + + static auto delete_vk_command_buffers(view::Device, view::CommandPool, VkCommandBuffer) noexcept -> void; + }; + } + + class STORMKIT_GPU_API + CommandPoolImplementation: public GpuObjectImplementation { public: + using CreateInfo = CommandPoolInterfaceBase::CreateInfo; + CommandPoolImplementation(PrivateTag, view::Device&& device) noexcept; - auto do_init(PrivateTag) noexcept -> Expected; ~CommandPoolImplementation() noexcept; CommandPoolImplementation(const CommandPoolImplementation&) = delete; @@ -391,6 +406,8 @@ namespace stormkit::gpu { CommandPoolImplementation(CommandPoolImplementation&&) noexcept; auto operator=(CommandPoolImplementation&&) noexcept -> CommandPoolImplementation&; + + auto do_init(PrivateTag, const CreateInfo&) noexcept -> Expected; }; namespace view { diff --git a/modules/stormkit/gpu/execution/descriptors.cppm b/modules/stormkit/gpu/execution/descriptors.cppm index c9cfca3f4..5721d85ae 100644 --- a/modules/stormkit/gpu/execution/descriptors.cppm +++ b/modules/stormkit/gpu/execution/descriptors.cppm @@ -65,6 +65,8 @@ namespace stormkit::gpu { }; } + using DescriptorSetDeleter = std::function; + struct DescriptorSetLayoutInterfaceBase { struct Size { DescriptorType type; @@ -110,12 +112,10 @@ namespace stormkit::gpu { }; } - class STORMKIT_GPU_API DescriptorSetImplementation: public GpuObjectImplementation { + class STORMKIT_GPU_API + DescriptorSetImplementation: public GpuObjectImplementation { public: - using Deleter = std::function; - DescriptorSetImplementation(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, VkDescriptorSet&&, Deleter&&) noexcept -> void; ~DescriptorSetImplementation() noexcept; DescriptorSetImplementation(const DescriptorSetImplementation&) = delete; @@ -124,11 +124,13 @@ namespace stormkit::gpu { DescriptorSetImplementation(DescriptorSetImplementation&&) noexcept; auto operator=(DescriptorSetImplementation&&) noexcept -> DescriptorSetImplementation&; + auto do_init(PrivateTag, VkDescriptorSet&&, DescriptorSetDeleter&&) noexcept -> Expected; + protected: - using UseNamedConstructors::allocate; - using UseNamedConstructors::create; + using NamedConstructor::allocate; + using NamedConstructor::create; - Deleter m_deleter; + DescriptorSetDeleter m_deleter; friend class DescriptorPoolInterface; friend class DescriptorPoolInterface; @@ -142,10 +144,10 @@ namespace stormkit::gpu { }; } // namespace view - class STORMKIT_GPU_API DescriptorSetLayoutImplementation: public GpuObjectImplementation { + class STORMKIT_GPU_API DescriptorSetLayoutImplementation + : public GpuObjectImplementation> { public: DescriptorSetLayoutImplementation(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, dyn_array&&) noexcept -> Expected; ~DescriptorSetLayoutImplementation() noexcept; DescriptorSetLayoutImplementation(const DescriptorSetLayoutImplementation&) = delete; @@ -154,6 +156,8 @@ namespace stormkit::gpu { DescriptorSetLayoutImplementation(DescriptorSetLayoutImplementation&&) noexcept; auto operator=(DescriptorSetLayoutImplementation&&) noexcept -> DescriptorSetLayoutImplementation&; + auto do_init(PrivateTag, dyn_array&&) noexcept -> Expected; + protected: dyn_array m_bindings; }; @@ -177,12 +181,12 @@ namespace stormkit::gpu { }; } // namespace view - class STORMKIT_GPU_API DescriptorPoolImplementation: public GpuObjectImplementation { + class STORMKIT_GPU_API DescriptorPoolImplementation + : public GpuObjectImplementation, u32> { public: using Size = DescriptorSetLayoutInterfaceBase::Size; DescriptorPoolImplementation(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, array_view&&, u32) noexcept -> Expected; ~DescriptorPoolImplementation() noexcept; DescriptorPoolImplementation(const DescriptorPoolImplementation&) = delete; @@ -190,6 +194,8 @@ namespace stormkit::gpu { DescriptorPoolImplementation(DescriptorPoolImplementation&&) noexcept; auto operator=(DescriptorPoolImplementation&&) noexcept -> DescriptorPoolImplementation&; + + auto do_init(PrivateTag, array_view&&, u32) noexcept -> Expected; }; namespace view { diff --git a/modules/stormkit/gpu/execution/pipeline.cppm b/modules/stormkit/gpu/execution/pipeline.cppm index b7938e702..4fbe4fe66 100644 --- a/modules/stormkit/gpu/execution/pipeline.cppm +++ b/modules/stormkit/gpu/execution/pipeline.cppm @@ -28,54 +28,30 @@ namespace stdfs = std::filesystem; namespace cmeta = stormkit::core::meta; namespace stormkit::gpu { - export template - class PipelineCacheInterface final: public DeviceObject { - public: - using DeviceObject::DeviceObject; - using DeviceObject::operator=; - using TagType = PipelineCacheTag; - }; - - export template - class PipelineLayoutInterface final: public DeviceObject { - public: - using DeviceObject::DeviceObject; - using DeviceObject::operator=; - using TagType = PipelineLayoutTag; - - [[nodiscard]] - auto raster_layout() const noexcept -> const RasterPipelineLayout&; - }; - - struct PipelineInterfaceBase { - using StateVariant = std::variant; - - enum class Type { - RASTER, - COMPUTE, - RAYTRACING, + export { + template + class PipelineCacheInterface final: public DeviceObject { + public: + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = PipelineCacheTag; }; - }; - - export template - class PipelineInterface final: public DeviceObject, protected PipelineInterfaceBase { - public: - using DeviceObject::DeviceObject; - using DeviceObject::operator=; - using TagType = PipelineTag; - using PipelineInterfaceBase::Type; + template + class PipelineLayoutInterface final: public DeviceObject { + public: + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = PipelineLayoutTag; - [[nodiscard]] - auto type() const noexcept -> Type; - [[nodiscard]] - auto raster_state() const noexcept -> const RasterPipelineState&; - }; + [[nodiscard]] + auto raster_layout() const noexcept -> const RasterPipelineLayout&; + }; + } - class STORMKIT_GPU_API PipelineCacheImplementation: public GpuObjectImplementation { + class STORMKIT_GPU_API PipelineCacheImplementation: public GpuObjectImplementation { public: PipelineCacheImplementation(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, stdfs::path&&) noexcept -> LoadSaveExpected; ~PipelineCacheImplementation() noexcept; PipelineCacheImplementation(const PipelineCacheImplementation&) = delete; @@ -88,9 +64,11 @@ namespace stormkit::gpu { static auto allocate_load_from_file(view::Device device, stdfs::path cache_path) noexcept -> LoadSaveExpected>; + auto do_init(PrivateTag, stdfs::path&&) noexcept -> LoadSaveExpected; + protected: - using UseNamedConstructors::allocate; - using UseNamedConstructors::create; + using NamedConstructor::allocate; + using NamedConstructor::create; auto create_new_pipeline_cache() noexcept -> LoadSaveExpected; auto read_pipeline_cache() noexcept -> LoadSaveExpected; @@ -128,10 +106,10 @@ namespace stormkit::gpu { }; } // namespace view - class STORMKIT_GPU_API PipelineLayoutImplementation: public GpuObjectImplementation { + class STORMKIT_GPU_API + PipelineLayoutImplementation: public GpuObjectImplementation { public: PipelineLayoutImplementation(PrivateTag, view::Device&& device) noexcept; - auto do_init(PrivateTag, const RasterPipelineLayout&) noexcept -> Expected; ~PipelineLayoutImplementation() noexcept; PipelineLayoutImplementation(const PipelineLayoutImplementation&) = delete; @@ -140,6 +118,8 @@ namespace stormkit::gpu { PipelineLayoutImplementation(PipelineLayoutImplementation&&) noexcept; auto operator=(PipelineLayoutImplementation&&) noexcept -> PipelineLayoutImplementation&; + auto do_init(PrivateTag, const RasterPipelineLayout&) noexcept -> Expected; + protected: Heap m_layout; @@ -165,23 +145,64 @@ namespace stormkit::gpu { }; } // namespace view - class STORMKIT_GPU_API PipelineImplementation: public GpuObjectImplementation { + export { + struct PipelineInterfaceBase { + using StateVariant = std::variant; + + enum class Type { + RASTER, + COMPUTE, + RAYTRACING, + }; + + struct RasterizationCreateInfo { + ref state; + view::PipelineLayout layout; + RasterPipelineRenderingInfo rendering_info; + std::optional cache = std::nullopt; + }; + + struct LegacyRasterizationCreateInfo { + ref state; + view::PipelineLayout layout; + view::RenderPass render_pass; + std::optional cache = std::nullopt; + }; + }; + + template + class PipelineInterface final: public DeviceObject, protected PipelineInterfaceBase { + public: + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = PipelineTag; + + using PipelineInterfaceBase::Type; + + [[nodiscard]] + auto type() const noexcept -> Type; + [[nodiscard]] + auto raster_state() const noexcept -> const RasterPipelineState&; + }; + } + + class STORMKIT_GPU_API PipelineImplementation + : public GpuObjectImplementation, + public core::NamedConstructor, + DoInitArgs> { using StateVariant = PipelineInterfaceBase::StateVariant; + using LegacyNamedConstructor = NamedConstructor, + DoInitArgs>; + public: - using Type = PipelineInterfaceBase::Type; + using Type = PipelineInterfaceBase::Type; + using RasterizationCreateInfo = PipelineInterfaceBase::RasterizationCreateInfo; + using LegacyRasterizationCreateInfo = PipelineInterfaceBase::LegacyRasterizationCreateInfo; PipelineImplementation(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, - const RasterPipelineState&, - view::PipelineLayout, - const RasterPipelineRenderingInfo&, - std::optional&& = std::nullopt) noexcept -> Expected; - auto do_init(PrivateTag, - const RasterPipelineState&, - view::PipelineLayout, - view::RenderPass, - std::optional&& = std::nullopt) noexcept -> Expected; ~PipelineImplementation() noexcept; PipelineImplementation(const PipelineImplementation&) = delete; @@ -190,6 +211,14 @@ namespace stormkit::gpu { PipelineImplementation(PipelineImplementation&&) noexcept; auto operator=(PipelineImplementation&&) noexcept -> PipelineImplementation&; + using GpuObjectImplementation::allocate; + using GpuObjectImplementation::create; + using LegacyNamedConstructor::allocate; + using LegacyNamedConstructor::create; + + auto do_init(PrivateTag, const RasterizationCreateInfo&) noexcept -> Expected; + auto do_init(PrivateTag, const LegacyRasterizationCreateInfo&) noexcept -> Expected; + protected: Type m_type; Heap m_state; @@ -278,7 +307,7 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto PipelineCacheImplementation::load_from_file(view::Device device, stdfs::path cache_path) noexcept -> LoadSaveExpected { - Return UseNamedConstructors::create(std::move(device), std::move(cache_path)); + Return NamedConstructor::create(std::move(device), std::move(cache_path)); } ///////////////////////////////////// @@ -286,7 +315,7 @@ namespace stormkit::gpu { STORMKIT_FORCE_INLINE inline auto PipelineCacheImplementation::allocate_load_from_file(view::Device device, stdfs::path cache_path) noexcept -> LoadSaveExpected> { - Return UseNamedConstructors::allocate(std::move(device), std::move(cache_path)); + Return NamedConstructor::allocate(std::move(device), std::move(cache_path)); } ///////////////////////////////////// diff --git a/modules/stormkit/gpu/execution/render_pass.cppm b/modules/stormkit/gpu/execution/render_pass.cppm index 32f0e598f..522b5f5b1 100644 --- a/modules/stormkit/gpu/execution/render_pass.cppm +++ b/modules/stormkit/gpu/execution/render_pass.cppm @@ -104,11 +104,10 @@ namespace stormkit::gpu { }; } - class STORMKIT_GPU_API FrameBufferImplementation: public GpuObjectImplementation { + class STORMKIT_GPU_API FrameBufferImplementation + : public GpuObjectImplementation> { public: FrameBufferImplementation(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, view::RenderPass&&, const math::uextent2&, dyn_array&&) noexcept - -> Expected; ~FrameBufferImplementation() noexcept; FrameBufferImplementation(const FrameBufferImplementation&) = delete; @@ -117,9 +116,12 @@ namespace stormkit::gpu { FrameBufferImplementation(FrameBufferImplementation&&) noexcept; auto operator=(FrameBufferImplementation&&) noexcept -> FrameBufferImplementation&; + auto do_init(PrivateTag, view::RenderPass&&, const math::uextent2&, dyn_array&&) noexcept + -> Expected; + protected: - using UseNamedConstructors::allocate; - using UseNamedConstructors::create; + using NamedConstructor::allocate; + using NamedConstructor::create; math::uextent2 m_extent = { 0, 0 }; dyn_array m_attachments; @@ -148,10 +150,9 @@ namespace stormkit::gpu { }; } // namespace view - class STORMKIT_GPU_API RenderPassImplementation: public GpuObjectImplementation { + class STORMKIT_GPU_API RenderPassImplementation: public GpuObjectImplementation { public: RenderPassImplementation(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, const RenderPassDescription&) noexcept -> Expected; ~RenderPassImplementation() noexcept; RenderPassImplementation(const RenderPassImplementation&) = delete; @@ -160,6 +161,8 @@ namespace stormkit::gpu { RenderPassImplementation(RenderPassImplementation&&) noexcept; auto operator=(RenderPassImplementation&&) noexcept -> RenderPassImplementation&; + auto do_init(PrivateTag, const RenderPassDescription&) noexcept -> Expected; + protected: Heap m_description = {}; }; diff --git a/modules/stormkit/gpu/execution/swapchain.cppm b/modules/stormkit/gpu/execution/swapchain.cppm index 5092d85f5..1d7873d8a 100644 --- a/modules/stormkit/gpu/execution/swapchain.cppm +++ b/modules/stormkit/gpu/execution/swapchain.cppm @@ -29,6 +29,12 @@ namespace stormkit::gpu { Result result; ImageID id; }; + + struct CreateInfo { + view::Surface surface; + math::uextent2 extent; + VkSwapchainKHR old = VK_NULL_HANDLE; + }; }; export template @@ -49,14 +55,14 @@ namespace stormkit::gpu { -> Expected; }; - class STORMKIT_GPU_API SwapChainImplementation: public GpuObjectImplementation { + class STORMKIT_GPU_API + SwapChainImplementation: public GpuObjectImplementation { public: - using ImageID = SwapChainInterfaceBase::ImageID; - using NextImage = SwapChainInterfaceBase::NextImage; + using ImageID = SwapChainInterfaceBase::ImageID; + using NextImage = SwapChainInterfaceBase::NextImage; + using CreateInfo = SwapChainInterfaceBase::CreateInfo; SwapChainImplementation(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, view::Surface, const math::uextent2&, VkSwapchainKHR = VK_NULL_HANDLE) noexcept - -> Expected; ~SwapChainImplementation() noexcept; SwapChainImplementation(const SwapChainImplementation&) = delete; @@ -65,6 +71,8 @@ namespace stormkit::gpu { SwapChainImplementation(SwapChainImplementation&&) noexcept; auto operator=(SwapChainImplementation&&) noexcept -> SwapChainImplementation&; + auto do_init(PrivateTag, const CreateInfo&) noexcept -> Expected; + protected: math::uextent2 m_extent; PixelFormat m_pixel_format; diff --git a/modules/stormkit/gpu/resource/buffer.cppm b/modules/stormkit/gpu/resource/buffer.cppm index e8c5d5f78..4c729c6d4 100644 --- a/modules/stormkit/gpu/resource/buffer.cppm +++ b/modules/stormkit/gpu/resource/buffer.cppm @@ -26,8 +26,18 @@ namespace cmeta = stormkit::core::meta; namespace cmonadic = stormkit::core::monadic; namespace stormkit::gpu { + struct BufferInterfaceBase { + struct CreateInfo { + BufferUsageFlag usages; + usize size; + MemoryPropertyFlag properties = MemoryPropertyFlag::HOST_VISIBLE | MemoryPropertyFlag::HOST_COHERENT; + + bool persistently_mapped = false; + }; + }; + export template - class STORMKIT_GPU_API BufferInterface final: public DeviceObject { + class STORMKIT_GPU_API BufferInterface final: public DeviceObject, public BufferInterfaceBase { public: using DeviceObject::DeviceObject; using DeviceObject::operator=; @@ -83,18 +93,12 @@ namespace stormkit::gpu { auto allocation() const noexcept -> vk::Observer; }; - class STORMKIT_GPU_API BufferImplementation: public GpuObjectImplementation { + class STORMKIT_GPU_API + BufferImplementation: public GpuObjectImplementation { public: - struct CreateInfo { - BufferUsageFlag usages; - usize size; - MemoryPropertyFlag properties = MemoryPropertyFlag::HOST_VISIBLE | MemoryPropertyFlag::HOST_COHERENT; - - bool persistently_mapped = false; - }; + using CreateInfo = BufferInterfaceBase::CreateInfo; BufferImplementation(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, const CreateInfo&) noexcept -> Expected; ~BufferImplementation() noexcept; BufferImplementation(const BufferImplementation&) noexcept = delete; @@ -103,6 +107,8 @@ namespace stormkit::gpu { BufferImplementation(BufferImplementation&&) noexcept; auto operator=(BufferImplementation&&) noexcept -> BufferImplementation&; + auto do_init(PrivateTag, const CreateInfo&) noexcept -> Expected; + protected: BufferUsageFlag m_usages = {}; usize m_size = 0; diff --git a/modules/stormkit/gpu/resource/image.cppm b/modules/stormkit/gpu/resource/image.cppm index db40b2f6a..d8fc2d5cb 100644 --- a/modules/stormkit/gpu/resource/image.cppm +++ b/modules/stormkit/gpu/resource/image.cppm @@ -51,6 +51,21 @@ namespace stormkit::gpu { }; }; + struct ImageInterfaceBase { + struct CreateInfo { + math::uextent3 extent; + PixelFormat format = PixelFormat::RGBA8_UNORM; + u32 layers = 1u; + u32 mip_levels = 1u; + ImageType type = ImageType::T2D; + ImageCreateFlag flags = ImageCreateFlag::NONE; + SampleCountFlag samples = SampleCountFlag::C1; + ImageUsageFlag usages = ImageUsageFlag::SAMPLED | ImageUsageFlag::TRANSFER_DST | ImageUsageFlag::TRANSFER_SRC; + ImageTiling tiling = ImageTiling::OPTIMAL; + MemoryPropertyFlag properties = MemoryPropertyFlag::DEVICE_LOCAL; + }; + }; + export { template class SamplerInterface: public DeviceObject, public SamplerInterfaceBase { @@ -64,7 +79,7 @@ namespace stormkit::gpu { }; template - class ImageInterface: public DeviceObject { + class ImageInterface: public DeviceObject, public ImageInterfaceBase { public: using DeviceObject::DeviceObject; using DeviceObject::operator=; @@ -89,77 +104,13 @@ namespace stormkit::gpu { [[nodiscard]] auto allocation() const noexcept -> vk::Observer; }; - - template - class ImageViewInterface: public DeviceObject { - public: - using DeviceObject::DeviceObject; - using DeviceObject::operator=; - using TagType = ImageViewTag; - - [[nodiscard]] - auto type() const noexcept -> ImageViewType; - [[nodiscard]] - auto subresource_range() const noexcept -> const ImageSubresourceRange&; - }; } - class STORMKIT_GPU_API SamplerImplementation: public GpuObjectImplementation { - public: - using Settings = SamplerInterfaceBase::Settings; - - SamplerImplementation(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, const Settings&) noexcept -> Expected; - ~SamplerImplementation() noexcept; - - SamplerImplementation(const SamplerImplementation&) noexcept = delete; - auto operator=(const SamplerImplementation&) noexcept -> SamplerImplementation& = delete; - - SamplerImplementation(SamplerImplementation&&) noexcept; - auto operator=(SamplerImplementation&&) noexcept -> SamplerImplementation&; - - protected: - Settings m_settings = {}; - }; - - namespace view { - class SamplerImplementation: public GpuObjectViewImplementation { - public: - using Settings = SamplerInterfaceBase::Settings; - - SamplerImplementation(const gpu::Sampler&) noexcept; - template TContainerOrPointer> - SamplerImplementation(const TContainerOrPointer&) noexcept; - ~SamplerImplementation() noexcept; - - SamplerImplementation(const SamplerImplementation&) noexcept; - auto operator=(const SamplerImplementation&) noexcept -> SamplerImplementation&; - - SamplerImplementation(SamplerImplementation&&) noexcept; - auto operator=(SamplerImplementation&&) noexcept -> SamplerImplementation&; - - protected: - Settings m_settings; - }; - } // namespace view - - class STORMKIT_GPU_API ImageImplementation: public GpuObjectImplementation { + class STORMKIT_GPU_API ImageImplementation: public GpuObjectImplementation { public: - struct CreateInfo { - math::uextent3 extent; - PixelFormat format = PixelFormat::RGBA8_UNORM; - u32 layers = 1u; - u32 mip_levels = 1u; - ImageType type = ImageType::T2D; - ImageCreateFlag flags = ImageCreateFlag::NONE; - SampleCountFlag samples = SampleCountFlag::C1; - ImageUsageFlag usages = ImageUsageFlag::SAMPLED | ImageUsageFlag::TRANSFER_DST | ImageUsageFlag::TRANSFER_SRC; - ImageTiling tiling = ImageTiling::OPTIMAL; - MemoryPropertyFlag properties = MemoryPropertyFlag::DEVICE_LOCAL; - }; + using CreateInfo = ImageInterfaceBase::CreateInfo; ImageImplementation(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, const CreateInfo&) noexcept -> Expected; ~ImageImplementation() noexcept; ImageImplementation(const ImageImplementation&) noexcept = delete; @@ -170,6 +121,8 @@ namespace stormkit::gpu { static auto from_existing(view::Device device, const CreateInfo& create_info, VkImage image) noexcept -> Image; + auto do_init(PrivateTag, const CreateInfo&) noexcept -> Expected; + protected: bool m_no_delete = false; @@ -220,11 +173,76 @@ namespace stormkit::gpu { }; } // namespace view - class STORMKIT_GPU_API ImageViewImplementation: public GpuObjectImplementation { + struct ImageViewInterfaceBase { + struct CreateInfo { + view::Image image; + ImageViewType type = ImageViewType::T2D; + ImageSubresourceRange subresource_range = {}; + }; + }; + + export template + class ImageViewInterface: public DeviceObject, public ImageViewInterfaceBase { + public: + using CreateInfo = ImageViewInterfaceBase::CreateInfo; + + using DeviceObject::DeviceObject; + using DeviceObject::operator=; + using TagType = ImageViewTag; + + [[nodiscard]] + auto type() const noexcept -> ImageViewType; + [[nodiscard]] + auto subresource_range() const noexcept -> const ImageSubresourceRange&; + }; + + class STORMKIT_GPU_API + SamplerImplementation: public GpuObjectImplementation { + public: + using Settings = SamplerInterfaceBase::Settings; + + SamplerImplementation(PrivateTag, view::Device&&) noexcept; + ~SamplerImplementation() noexcept; + + SamplerImplementation(const SamplerImplementation&) noexcept = delete; + auto operator=(const SamplerImplementation&) noexcept -> SamplerImplementation& = delete; + + SamplerImplementation(SamplerImplementation&&) noexcept; + auto operator=(SamplerImplementation&&) noexcept -> SamplerImplementation&; + + auto do_init(PrivateTag, const Settings&) noexcept -> Expected; + + protected: + Settings m_settings = {}; + }; + + namespace view { + class SamplerImplementation: public GpuObjectViewImplementation { + public: + using Settings = SamplerInterfaceBase::Settings; + + SamplerImplementation(const gpu::Sampler&) noexcept; + template TContainerOrPointer> + SamplerImplementation(const TContainerOrPointer&) noexcept; + ~SamplerImplementation() noexcept; + + SamplerImplementation(const SamplerImplementation&) noexcept; + auto operator=(const SamplerImplementation&) noexcept -> SamplerImplementation&; + + SamplerImplementation(SamplerImplementation&&) noexcept; + auto operator=(SamplerImplementation&&) noexcept -> SamplerImplementation&; + + protected: + Settings m_settings; + }; + } // namespace view + + class STORMKIT_GPU_API + ImageViewImplementation: public GpuObjectImplementation { public: + using CreateInfo = ImageViewInterfaceBase::CreateInfo; + ImageViewImplementation(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, view::Image, ImageViewType = ImageViewType::T2D, const ImageSubresourceRange& = {}) noexcept - -> Expected; ~ImageViewImplementation() noexcept; ImageViewImplementation(const ImageViewImplementation&) noexcept = delete; @@ -233,6 +251,8 @@ namespace stormkit::gpu { ImageViewImplementation(ImageViewImplementation&&) noexcept; auto operator=(ImageViewImplementation&&) noexcept -> ImageViewImplementation&; + auto do_init(PrivateTag, const CreateInfo&) noexcept -> Expected; + protected: ImageViewType m_type = {}; ImageSubresourceRange m_subresource_range = {}; @@ -473,7 +493,7 @@ namespace stormkit::gpu { ///////////////////////////////////// inline auto ImageImplementation::from_existing(view::Device device, const CreateInfo& create_info, VkImage vk_image) noexcept -> Image { - auto image = Image { UseNamedConstructors::PRIVATE, std::move(device) }; + auto image = Image { NamedConstructor::PRIVATE, std::move(device) }; image.m_extent = create_info.extent; image.m_format = create_info.format; image.m_layers = create_info.layers; diff --git a/modules/stormkit/gpu/resource/shader.cppm b/modules/stormkit/gpu/resource/shader.cppm index 9a41076eb..045ec3e4d 100644 --- a/modules/stormkit/gpu/resource/shader.cppm +++ b/modules/stormkit/gpu/resource/shader.cppm @@ -41,7 +41,8 @@ namespace stormkit::gpu { auto source_as_bytes() const noexcept -> byte_view<>; }; - class STORMKIT_GPU_API ShaderImplementation: public GpuObjectImplementation { + class STORMKIT_GPU_API + ShaderImplementation: public GpuObjectImplementation&&, ShaderStageFlag> { public: enum class Error { INVALID_SPIRV, @@ -52,7 +53,6 @@ namespace stormkit::gpu { using LoadExpected = std::expected; ShaderImplementation(PrivateTag, view::Device&&) noexcept; - auto do_init(PrivateTag, dyn_array&&, ShaderStageFlag) -> Expected; ~ShaderImplementation() noexcept; ShaderImplementation(const ShaderImplementation&) noexcept = delete; @@ -76,9 +76,11 @@ namespace stormkit::gpu { array_view data, ShaderStageFlag type) noexcept -> Expected>; + auto do_init(PrivateTag, dyn_array&&, ShaderStageFlag) -> Expected; + protected: - using UseNamedConstructors::allocate; - using UseNamedConstructors::create; + using NamedConstructor::allocate; + using NamedConstructor::create; ShaderStageFlag m_type = ShaderStageFlag::NONE; dyn_array m_source = {}; @@ -180,7 +182,7 @@ namespace stormkit::gpu { const auto data = TryTransformError(io::read(filepath), sys_to_load_error); auto spirv = dyn_array { std::from_range, bytes_as_span(data) }; - Return TryTransformError(UseNamedConstructors::create(std::move(device), std::move(spirv), type), result_to_load_error); + Return TryTransformError(NamedConstructor::create(std::move(device), std::move(spirv), type), result_to_load_error); } ///////////////////////////////////// @@ -189,7 +191,7 @@ namespace stormkit::gpu { inline auto ShaderImplementation::load_from_bytes(view::Device device, byte_view<> data, ShaderStageFlag type) noexcept -> Expected { auto spirv = dyn_array { std::from_range, bytes_as_span(data) }; - return UseNamedConstructors::create(std::move(device), std::move(spirv), type); + return NamedConstructor::create(std::move(device), std::move(spirv), type); } ///////////////////////////////////// @@ -199,7 +201,7 @@ namespace stormkit::gpu { array_view data, ShaderStageFlag type) noexcept -> Expected { auto spirv = dyn_array { std::from_range, data }; - return UseNamedConstructors::create(std::move(device), std::move(spirv), type); + return NamedConstructor::create(std::move(device), std::move(spirv), type); } ///////////////////////////////////// @@ -212,17 +214,17 @@ namespace stormkit::gpu { const auto data = TryTransformError(io::read(filepath), sys_to_load_error); auto spirv = dyn_array { std::from_range, bytes_as_span(data) }; - Return TryTransformError(UseNamedConstructors::allocate(std::move(device), std::move(spirv), type), result_to_load_error); + Return TryTransformError(NamedConstructor::allocate(std::move(device), std::move(spirv), type), result_to_load_error); } ///////////////////////////////////// ///////////////////////////////////// STORMKIT_FORCE_INLINE inline auto ShaderImplementation::allocate_and_load_from_bytes(view::Device device, - byte_view<> data, + byte_view<> data, ShaderStageFlag type) noexcept -> Expected> { auto spirv = dyn_array { std::from_range, bytes_as_span(data) }; - return UseNamedConstructors::allocate(std::move(device), std::move(spirv), type); + return NamedConstructor::allocate(std::move(device), std::move(spirv), type); } ///////////////////////////////////// @@ -232,7 +234,7 @@ namespace stormkit::gpu { array_view data, ShaderStageFlag type) noexcept -> Expected> { auto spirv = dyn_array { std::from_range, data }; - return UseNamedConstructors::allocate(std::move(device), std::move(spirv), type); + return NamedConstructor::allocate(std::move(device), std::move(spirv), type); } namespace view { diff --git a/modules/stormkit/log.cppm b/modules/stormkit/log.cppm index 2de7f54cf..2038e9b9a 100644 --- a/modules/stormkit/log.cppm +++ b/modules/stormkit/log.cppm @@ -17,6 +17,8 @@ import frozen; import stormkit.core; +namespace stdr = std::ranges; + export { namespace stormkit::log { struct Module; @@ -44,8 +46,8 @@ export { Logger(LogClock::time_point start, Severity log_level) noexcept; virtual ~Logger() noexcept; - virtual auto write(Severity severity, const Module& module, czstring string) noexcept -> void = 0; - virtual auto flush() noexcept -> void = 0; + virtual auto write(Severity severity, const Module& module, std::string_view string) noexcept -> void = 0; + virtual auto flush() noexcept -> void = 0; auto set_log_level(Severity log_level) noexcept -> void; @@ -66,26 +68,64 @@ export { static auto allocate_logger_instance(Args&&... param_args) noexcept -> Heap; template - static auto log(Severity severity, const Module& module, string_view format_string, Args&&... param_args) noexcept - -> void; + static auto log(Severity severity, + const Module& module, + std::format_string format_string, + Args&&... args) noexcept -> void; template - static auto log(Severity severity, string_view format_string, Args&&... param_args) noexcept -> void; + static auto log(Severity severity, std::format_string format_string, Args&&... args) noexcept -> void; template - static auto dlog(Args&&... param_args) noexcept -> void; + static auto log_runtime(Severity severity, const Module& module, string_view format_string, Args&&... args) noexcept + -> void; template - static auto ilog(Args&&... param_args) noexcept -> void; + static auto log_runtime(Severity severity, string_view format_string, Args&&... args) noexcept -> void; template - static auto wlog(Args&&... param_args) noexcept -> void; + static auto dlog(std::format_string format_string, Args&&... args) noexcept -> void; + template + static auto ilog(std::format_string format_string, Args&&... args) noexcept -> void; + template + static auto wlog(std::format_string format_string, Args&&... args) noexcept -> void; + template + static auto elog(std::format_string format_string, Args&&... args) noexcept -> void; + template + static auto flog(std::format_string format_string, Args&&... args) noexcept -> void; + + template + static auto dlog(const Module& module, std::format_string format_string, Args&&... args) noexcept -> void; + template + static auto ilog(const Module& module, std::format_string format_string, Args&&... args) noexcept -> void; + template + static auto wlog(const Module& module, std::format_string format_string, Args&&... args) noexcept -> void; + template + static auto elog(const Module& module, std::format_string format_string, Args&&... args) noexcept -> void; + template + static auto flog(const Module& module, std::format_string format_string, Args&&... args) noexcept -> void; template - static auto elog(Args&&... param_args) noexcept -> void; + static auto dlog_runtime(std::string_view format_string, Args&&... args) noexcept -> void; + template + static auto ilog_runtime(std::string_view format_string, Args&&... args) noexcept -> void; + template + static auto wlog_runtime(std::string_view format_string, Args&&... args) noexcept -> void; + template + static auto elog_runtime(std::string_view format_string, Args&&... args) noexcept -> void; + template + static auto flog_runtime(std::string_view format_string, Args&&... args) noexcept -> void; template - static auto flog(Args&&... param_args) noexcept -> void; + static auto dlog_runtime(const Module& module, std::string_view format_string, Args&&... args) noexcept -> void; + template + static auto ilog_runtime(const Module& module, std::string_view format_string, Args&&... args) noexcept -> void; + template + static auto wlog_runtime(const Module& module, std::string_view format_string, Args&&... args) noexcept -> void; + template + static auto elog_runtime(const Module& module, std::string_view format_string, Args&&... args) noexcept -> void; + template + static auto flog_runtime(const Module& module, std::string_view format_string, Args&&... args) noexcept -> void; [[nodiscard]] static auto has_logger() noexcept -> bool; @@ -101,19 +141,26 @@ export { struct Module { template - auto dlog(Args&&... args) const noexcept -> void; - + auto dlog(std::format_string format_string, Args&&... args) const noexcept -> void; template - auto ilog(Args&&... args) const noexcept -> void; - + auto ilog(std::format_string format_string, Args&&... args) const noexcept -> void; template - auto wlog(Args&&... args) const noexcept -> void; - + auto wlog(std::format_string format_string, Args&&... args) const noexcept -> void; + template + auto elog(std::format_string format_string, Args&&... args) const noexcept -> void; template - auto elog(Args&&... args) const noexcept -> void; + auto flog(std::format_string format_string, Args&&... args) const noexcept -> void; template - auto flog(Args&&... args) const noexcept -> void; + auto dlog_runtime(std::string_view format_string, Args&&... args) const noexcept -> void; + template + auto ilog_runtime(std::string_view format_string, Args&&... args) const noexcept -> void; + template + auto wlog_runtime(std::string_view format_string, Args&&... args) const noexcept -> void; + template + auto elog_runtime(std::string_view format_string, Args&&... args) const noexcept -> void; + template + auto flog_runtime(std::string_view format_string, Args&&... args) const noexcept -> void; auto flush() const noexcept -> void; @@ -136,7 +183,7 @@ export { FileLogger(FileLogger&&) noexcept = delete; auto operator=(FileLogger&&) noexcept -> FileLogger& = delete; - auto write(Severity severity, const Module& module, czstring string) noexcept -> void override; + auto write(Severity severity, const Module& module, std::string_view string) noexcept -> void override; auto flush() noexcept -> void override; private: @@ -158,7 +205,7 @@ export { ~ConsoleLogger() noexcept override; - auto write(Severity severity, const Module& module, czstring string) noexcept -> void override; + auto write(Severity severity, const Module& module, std::string_view string) noexcept -> void override; auto flush() noexcept -> void override; }; } // namespace stormkit::log @@ -177,11 +224,11 @@ namespace stormkit::log { STORMKIT_FORCE_INLINE STORMKIT_CONST constexpr auto as_string(Severity severity) noexcept -> string_view { switch (severity) { - case Severity::INFO: return "Severity::INFO"; - case Severity::WARNING: return "Severity::WARNING"; - case Severity::ERROR: return "Severity::ERROR"; - case Severity::FATAL: return "Severity::FATAL"; - case Severity::DEBUG: return "Severity::DEBUG"; + case Severity::INFO: return "INFO"; + case Severity::WARNING: return "WARNING"; + case Severity::ERROR: return "ERROR"; + case Severity::FATAL: return "FATAL"; + case Severity::DEBUG: return "DEBUG"; default: break; } @@ -249,19 +296,100 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// template - inline auto Logger::log(Severity severity, const Module& m, string_view format_string, Args&&... param_args) noexcept - -> void { + inline auto Logger::log(Severity severity, + const Module& m, + std::format_string format_string, + Args&&... param_args) noexcept -> void { + EXPECTS(has_logger()); + + const auto log_level = instance().log_level(); + if (not check_flag_bit(log_level, severity)) return; + + auto size = std::formatted_size(format_string, std::forward(param_args)...); + + if (size <= 64) { + thread_local auto memory_buffer = array {}; + const auto end_it = std::format_to(stdr::begin(memory_buffer), + std::move(format_string), + std::forward(param_args)...); + + const auto _ = std::unique_lock(instance().mutex()); + instance().write(severity, m, string_view { stdr::begin(memory_buffer), end_it }); + } else { + auto memory_buffer = dyn_array {}; + memory_buffer.resize(size); + const auto end_it = std::format_to(stdr::begin(memory_buffer), + std::move(format_string), + std::forward(param_args)...); + + const auto _ = std::unique_lock(instance().mutex()); + instance().write(severity, m, string_view { stdr::begin(memory_buffer), end_it }); + } + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::log(Severity severity, std::format_string format_string, Args&&... param_args) noexcept -> void { + log(severity, Module {}, std::move(format_string), std::forward(param_args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + inline auto Logger::log_runtime(Severity severity, + const Module& m, + std::string_view format_string, + Args&&... param_args) noexcept -> void { EXPECTS(has_logger()); + struct counter { + usize n { 0 }; + using difference_type = long; + + auto operator*() const noexcept { return std::ignore; } + + auto operator++() noexcept -> counter& { + ++n; + return *this; + } + + auto operator++(int) noexcept -> counter { return counter { n++ }; } + }; + const auto log_level = instance().log_level(); if (not check_flag_bit(log_level, severity)) return; - auto memory_buffer = string {}; - memory_buffer.reserve(std::size(format_string)); - std::vformat_to(std::back_inserter(memory_buffer), format_string, std::make_format_args(param_args...)); + auto args = std::format_args { std::forward(param_args)... }; + + auto c = counter {}; + c = std::vformat_to(c, format_string, args); + + if (c.n <= 64) { + thread_local auto memory_buffer = array {}; + const auto end_it = std::format_to(stdr::begin(memory_buffer), + std::move(format_string), + std::forward(param_args)...); + + const auto _ = std::unique_lock(instance().mutex()); + instance().write(severity, m, string_view { stdr::begin(memory_buffer), end_it }); + } else { + auto memory_buffer = dyn_array {}; + memory_buffer.resize(c.n); + const auto end_it = std::vformat_to(stdr::begin(memory_buffer), std::move(format_string), args); + + const auto _ = std::unique_lock(instance().mutex()); + instance().write(severity, m, string_view { stdr::begin(memory_buffer), end_it }); + } + } - auto _ = std::unique_lock(instance().mutex()); - instance().write(severity, m, std::data(memory_buffer)); + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::log_runtime(Severity severity, string_view format_string, Args&&... param_args) noexcept -> void { + log(severity, Module {}, std::move(format_string), std::forward(param_args)...); } //////////////////////////////////////// @@ -278,88 +406,240 @@ namespace stormkit::log { //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Logger::log(Severity severity, string_view format_string, Args&&... param_args) noexcept -> void { - log(severity, Module {}, format_string, std::forward(param_args)...); + inline auto Logger::dlog(std::format_string format_string, Args&&... args) noexcept -> void { + log(Severity::DEBUG, std::move(format_string), std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::ilog(std::format_string format_string, Args&&... args) noexcept -> void { + log(Severity::INFO, std::move(format_string), std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::wlog(std::format_string format_string, Args&&... args) noexcept -> void { + log(Severity::WARNING, std::move(format_string), std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::elog(std::format_string format_string, Args&&... args) noexcept -> void { + log(Severity::ERROR, std::move(format_string), std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::flog(std::format_string format_string, Args&&... args) noexcept -> void { + log(Severity::FATAL, std::move(format_string), std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::dlog(const Module& module, std::format_string format_string, Args&&... args) noexcept -> void { + log(Severity::DEBUG, module, std::move(format_string), std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::ilog(const Module& module, std::format_string format_string, Args&&... args) noexcept -> void { + log(Severity::INFO, module, std::move(format_string), std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::wlog(const Module& module, std::format_string format_string, Args&&... args) noexcept -> void { + log(Severity::WARNING, module, std::move(format_string), std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::elog(const Module& module, std::format_string format_string, Args&&... args) noexcept -> void { + log(Severity::ERROR, module, std::move(format_string), std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::flog(const Module& module, std::format_string format_string, Args&&... args) noexcept -> void { + log(Severity::FATAL, module, std::move(format_string), std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::dlog_runtime(std::string_view format_string, Args&&... args) noexcept -> void { + log_runtime(Severity::DEBUG, std::move(format_string), std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::ilog_runtime(std::string_view format_string, Args&&... args) noexcept -> void { + log_runtime(Severity::INFO, std::move(format_string), std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::wlog_runtime(std::string_view format_string, Args&&... args) noexcept -> void { + log_runtime(Severity::WARNING, std::move(format_string), std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::elog_runtime(std::string_view format_string, Args&&... args) noexcept -> void { + log_runtime(Severity::ERROR, std::move(format_string), std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::flog_runtime(std::string_view format_string, Args&&... args) noexcept -> void { + log_runtime(Severity::FATAL, std::move(format_string), std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::dlog_runtime(const Module& module, std::string_view format_string, Args&&... args) noexcept -> void { + log_runtime(Severity::DEBUG, module, std::move(format_string), std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::ilog_runtime(const Module& module, std::string_view format_string, Args&&... args) noexcept -> void { + log_runtime(Severity::INFO, module, std::move(format_string), std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::wlog_runtime(const Module& module, std::string_view format_string, Args&&... args) noexcept -> void { + log_runtime(Severity::WARNING, module, std::move(format_string), std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::elog_runtime(const Module& module, std::string_view format_string, Args&&... args) noexcept -> void { + log_runtime(Severity::ERROR, module, std::move(format_string), std::forward(args)...); + } + + //////////////////////////////////////// + //////////////////////////////////////// + template + STORMKIT_FORCE_INLINE + inline auto Logger::flog_runtime(const Module& module, std::string_view format_string, Args&&... args) noexcept -> void { + log_runtime(Severity::FATAL, module, std::move(format_string), std::forward(args)...); } //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Logger::dlog(Args&&... param_args) noexcept -> void { - log(Severity::DEBUG, std::forward(param_args)...); + inline auto Module::dlog(std::format_string format_string, Args&&... args) const noexcept -> void { + Logger::dlog(*this, std::move(format_string), std::forward(args)...); } //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Logger::ilog(Args&&... param_args) noexcept -> void { - log(Severity::INFO, std::forward(param_args)...); + inline auto Module::ilog(std::format_string format_string, Args&&... args) const noexcept -> void { + Logger::ilog(*this, std::move(format_string), std::forward(args)...); } //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Logger::wlog(Args&&... param_args) noexcept -> void { - log(Severity::WARNING, std::forward(param_args)...); + inline auto Module::wlog(std::format_string format_string, Args&&... args) const noexcept -> void { + Logger::wlog(*this, std::move(format_string), std::forward(args)...); } //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Logger::elog(Args&&... param_args) noexcept -> void { - log(Severity::ERROR, std::forward(param_args)...); + inline auto Module::elog(std::format_string format_string, Args&&... args) const noexcept -> void { + Logger::elog(*this, std::move(format_string), std::forward(args)...); } //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Logger::flog(Args&&... param_args) noexcept -> void { - log(Severity::FATAL, std::forward(param_args)...); + inline auto Module::flog(std::format_string format_string, Args&&... args) const noexcept -> void { + Logger::flog(*this, std::move(format_string), std::forward(args)...); } //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Module::dlog(Args&&... args) const noexcept -> void { - Logger::dlog(*this, std::forward(args)...); + inline auto Module::dlog_runtime(std::string_view format_string, Args&&... args) const noexcept -> void { + Logger::dlog_runtime(*this, std::move(format_string), std::forward(args)...); } //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Module::ilog(Args&&... args) const noexcept -> void { - Logger::ilog(*this, std::forward(args)...); + inline auto Module::ilog_runtime(std::string_view format_string, Args&&... args) const noexcept -> void { + Logger::ilog_runtime(*this, std::move(format_string), std::forward(args)...); } //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Module::wlog(Args&&... args) const noexcept -> void { - Logger::wlog(*this, std::forward(args)...); + inline auto Module::wlog_runtime(std::string_view format_string, Args&&... args) const noexcept -> void { + Logger::wlog_runtime(*this, std::move(format_string), std::forward(args)...); } //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Module::elog(Args&&... args) const noexcept -> void { - Logger::elog(*this, std::forward(args)...); + inline auto Module::elog_runtime(std::string_view format_string, Args&&... args) const noexcept -> void { + Logger::elog_runtime(*this, std::move(format_string), std::forward(args)...); } //////////////////////////////////////// //////////////////////////////////////// template STORMKIT_FORCE_INLINE - inline auto Module::flog(Args&&... args) const noexcept -> void { - Logger::flog(*this, std::forward(args)...); + inline auto Module::flog_runtime(std::string_view format_string, Args&&... args) const noexcept -> void { + Logger::flog_runtime(*this, std::move(format_string), std::forward(args)...); } //////////////////////////////////////// diff --git a/modules/stormkit/test.cppm b/modules/stormkit/test.cppm index 355130440..0efc2e4bc 100644 --- a/modules/stormkit/test.cppm +++ b/modules/stormkit/test.cppm @@ -45,7 +45,7 @@ export namespace test { auto runTests() noexcept -> int; } // namespace test -module :private; +// module :private; using namespace std::literals; diff --git a/src/gpu/core/debug_callback.cpp b/src/gpu/core/debug_callback.cpp index c7dfdb760..54c35b841 100644 --- a/src/gpu/core/debug_callback.cpp +++ b/src/gpu/core/debug_callback.cpp @@ -25,7 +25,7 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto DebugCallbackImplementation::do_init(PrivateTag, Closure closure, void* user_data) noexcept -> Expected { + auto DebugCallbackImplementation::do_init(PrivateTag, const CreateInfo& create_info) noexcept -> Expected { constexpr auto severity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT; @@ -34,18 +34,18 @@ namespace stormkit::gpu { | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT; - const auto create_info = VkDebugUtilsMessengerCreateInfoEXT { + const auto vk_create_info = VkDebugUtilsMessengerCreateInfoEXT { .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, .pNext = nullptr, .flags = 0, .messageSeverity = severity, .messageType = type, - .pfnUserCallback = closure, - .pUserData = user_data, + .pfnUserCallback = create_info.messenger_closure, + .pUserData = create_info.user_data, }; m_vk_handle = Try(vk::call_checked< - VkDebugUtilsMessengerEXT>(vkCreateDebugUtilsMessengerEXT, owner(), &create_info, nullptr)); + VkDebugUtilsMessengerEXT>(vkCreateDebugUtilsMessengerEXT, owner(), &vk_create_info, nullptr)); Return {}; } } // namespace stormkit::gpu diff --git a/src/gpu/core/fence.cpp b/src/gpu/core/fence.cpp index 1ebb0b3c2..32cdff7d8 100644 --- a/src/gpu/core/fence.cpp +++ b/src/gpu/core/fence.cpp @@ -70,10 +70,10 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto FenceImplementation::do_init(PrivateTag, bool signaled) noexcept -> Expected { - const auto flags = (signaled) ? VkFenceCreateFlags { VK_FENCE_CREATE_SIGNALED_BIT } : VkFenceCreateFlags {}; + auto FenceImplementation::do_init(PrivateTag, const CreateInfo& create_info) noexcept -> Expected { + const auto flags = (create_info.signaled) ? VkFenceCreateFlags { VK_FENCE_CREATE_SIGNALED_BIT } : VkFenceCreateFlags {}; - const auto create_info = VkFenceCreateInfo { + const auto vk_create_info = VkFenceCreateInfo { .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, .pNext = nullptr, .flags = flags @@ -82,7 +82,7 @@ namespace stormkit::gpu { const auto& device = owner(); const auto& device_table = device.device_table(); - m_vk_handle = Try(vk::call_checked(device_table.vkCreateFence, device, &create_info, nullptr)); + m_vk_handle = Try(vk::call_checked(device_table.vkCreateFence, device, &vk_create_info, nullptr)); Return {}; } diff --git a/src/gpu/core/instance.cpp b/src/gpu/core/instance.cpp index d978aa50b..5cb269cbf 100644 --- a/src/gpu/core/instance.cpp +++ b/src/gpu/core/instance.cpp @@ -29,9 +29,8 @@ namespace stormkit::gpu { namespace { constexpr auto VALIDATION_LAYERS = into_array_of("VK_LAYER_KHRONOS_validation", // "VK_LAYER_LUNARG_api_dump", - "VK_LAYER_LUNARG_monitor" - // "VK_LAYER_MESA_overlay", - ); + "VK_LAYER_LUNARG_monitor", + "VK_LAYER_MESA_overlay"); // [[maybe_unused]] // constexpr auto VALIDATION_FEATURES = into_array_of(VK_VALIDATION_FEATURE_ENABLE_BEST_PRACTICES_EXT, @@ -92,21 +91,25 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto InstanceImplementation::do_init(PrivateTag, string app_name, bool validation_layers_enabled) noexcept -> Expected { + auto InstanceImplementation::do_init(PrivateTag, const CreateInfo& create_info) noexcept -> Expected { const auto exts = Try(vk::enumerate_checked(vkEnumerateInstanceExtensionProperties, nullptr)); m_extensions = transform(exts, [](const auto& ext) static noexcept { return string { ext.extensionName }; }); - const auto validation_layers = validation_layers_enabled - ? dyn_array() - : transform_if( - Try(vk::enumerate_checked(vkEnumerateInstanceLayerProperties)), + const auto available_layers = Try(vk::enumerate_checked(vkEnumerateInstanceLayerProperties)); + // std::println("{}", available_layers | stdv::transform([](const auto& layer) static noexcept { + // return std::string_view { layer.layerName }; + // })); + const auto validation_layers = create_info.enable_validation_layers + ? transform_if( + available_layers, [](const auto& layer) static noexcept { return stdr::contains(VALIDATION_LAYERS, string_view { layer.layerName }); }, - [](const auto& layer) static noexcept { return layer.layerName; }); + [](const auto& layer) static noexcept { return layer.layerName; }) + : dyn_array(); - const auto instance_extensions = [validation_layers_enabled] noexcept { + const auto instance_extensions = [enable_validation_layers = create_info.enable_validation_layers] noexcept { auto e = concat(BASE_EXTENSIONS, SURFACE_EXTENSIONS, WSI_SURFACE_EXTENSIONS); - if (validation_layers_enabled) e.emplace_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); + if (enable_validation_layers) e.emplace_back(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); return e; }(); const auto result = check_extension_support(m_extensions, instance_extensions); @@ -117,14 +120,14 @@ namespace stormkit::gpu { const auto app_info = VkApplicationInfo { .sType = VK_STRUCTURE_TYPE_APPLICATION_INFO, .pNext = nullptr, - .pApplicationName = std::data(app_name), - .applicationVersion = vk::make_version(0, 0, 0), + .pApplicationName = std::data(create_info.application_name), + .applicationVersion = create_info.application_version, .pEngineName = ENGINE_NAME, .engineVersion = STORMKIT_VK_VERSION, .apiVersion = VK_API_VERSION_1_3, }; - const auto create_info = VkInstanceCreateInfo { + const auto vk_create_info = VkInstanceCreateInfo { .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, .pNext = nullptr, #ifdef STORMKIT_OS_APPLE @@ -139,7 +142,7 @@ namespace stormkit::gpu { .ppEnabledExtensionNames = stdr::data(instance_extensions), }; - m_vk_handle = Try(vk::call_checked(vkCreateInstance, &create_info, nullptr)); + m_vk_handle = Try(vk::call_checked(vkCreateInstance, &vk_create_info, nullptr)); Try(do_load_instance()); Try(do_retrieve_physical_devices()); diff --git a/src/gpu/core/surface.cpp b/src/gpu/core/surface.cpp index e7b6df2f5..cd92ae8b0 100644 --- a/src/gpu/core/surface.cpp +++ b/src/gpu/core/surface.cpp @@ -32,14 +32,16 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto SurfaceImplementation::do_init(PrivateTag) noexcept -> Expected { + auto SurfaceImplementation::do_init(PrivateTag, const OffscreenCreateInfo&) noexcept -> Expected { assert(false, "not implemented yet"); return {}; } ///////////////////////////////////// ///////////////////////////////////// - auto SurfaceImplementation::do_init(PrivateTag, const wsi::Window& window) noexcept -> Expected { + auto SurfaceImplementation::do_init(PrivateTag, const CreateInfo& create_info) noexcept -> Expected { + const auto& window = *create_info.window; + EXPECTS(window.is_open()); const auto instance = owner(); diff --git a/src/gpu/execution/command_buffer.cpp b/src/gpu/execution/command_buffer.cpp index 36a515210..3327d049c 100644 --- a/src/gpu/execution/command_buffer.cpp +++ b/src/gpu/execution/command_buffer.cpp @@ -1178,9 +1178,9 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// auto CommandBufferImplementation::do_init(PrivateTag, - CommandBufferLevel level, - VkCommandBuffer&& handle, - Deleter&& deleter) noexcept -> void { + CommandBufferLevel level, + VkCommandBuffer&& handle, + CommandBufferDeleter&& deleter) noexcept -> void { m_state = core::allocate_unsafe(State::INITIAL); m_level = level; diff --git a/src/gpu/execution/command_pool.cpp b/src/gpu/execution/command_pool.cpp index c08a3fc98..67e512485 100644 --- a/src/gpu/execution/command_pool.cpp +++ b/src/gpu/execution/command_pool.cpp @@ -56,15 +56,22 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto CommandPoolImplementation::do_init(PrivateTag) noexcept -> Expected { + auto CommandPoolImplementation::do_init(PrivateTag, const CreateInfo& create_info_) noexcept -> Expected { const auto& device = owner(); const auto& device_table = device.device_table(); + const auto flags = [&create_info_] noexcept { + auto out = VkCommandPoolCreateFlags {}; + if (create_info_.reset) out |= VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + if (create_info_.transient) out |= VK_COMMAND_POOL_CREATE_TRANSIENT_BIT; + return out; + }(); + const auto create_info = VkCommandPoolCreateInfo { .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, .pNext = nullptr, - .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT | VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, - .queueFamilyIndex = 0, + .flags = flags, + .queueFamilyIndex = create_info_.queue.entry().id, }; m_vk_handle = Try(vk::call_checked(device_table.vkCreateCommandPool, device, &create_info, nullptr)); diff --git a/src/gpu/execution/descriptor_set.cpp b/src/gpu/execution/descriptor_set.cpp index a4125bd92..cc53bb881 100644 --- a/src/gpu/execution/descriptor_set.cpp +++ b/src/gpu/execution/descriptor_set.cpp @@ -93,8 +93,12 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto DescriptorSetImplementation::do_init(PrivateTag, VkDescriptorSet&& descriptor_set, Deleter&& deleter) noexcept -> void { + auto DescriptorSetImplementation::do_init(PrivateTag, + VkDescriptorSet&& descriptor_set, + DescriptorSetDeleter&& deleter) noexcept -> Expected { m_vk_handle = std::move(descriptor_set); m_deleter = std::move(deleter); + + return {}; } } // namespace stormkit::gpu diff --git a/src/gpu/execution/pipeline.cpp b/src/gpu/execution/pipeline.cpp index b57515ac5..c1f6056f1 100644 --- a/src/gpu/execution/pipeline.cpp +++ b/src/gpu/execution/pipeline.cpp @@ -206,13 +206,9 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto PipelineImplementation::do_init(PrivateTag, - const RasterPipelineState& _state, - view::PipelineLayout layout, - const RasterPipelineRenderingInfo& rendering_info, - std::optional&& pipeline_cache) noexcept -> Expected { + auto PipelineImplementation::do_init(PrivateTag, const RasterizationCreateInfo& create_info) noexcept -> Expected { m_type = Type::RASTER; - m_state = core::allocate_unsafe(_state); + m_state = core::allocate_unsafe(create_info.state); const auto& state = as(*m_state); @@ -232,31 +228,31 @@ namespace stormkit::gpu { shaders, depth_stencil] = gpu::do_init(state); - const auto formats = transform(rendering_info.color_attachment_formats, vk::monadic::to_vk()); + const auto formats = transform(create_info.rendering_info.color_attachment_formats, vk::monadic::to_vk()); - const auto _rendering_info = [&] noexcept { + const auto rendering_info = [&] noexcept { auto info = VkPipelineRenderingCreateInfo { .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, .pNext = nullptr, - .viewMask = rendering_info.view_mask, + .viewMask = create_info.rendering_info.view_mask, .colorAttachmentCount = as(stdr::size(formats)), .pColorAttachmentFormats = stdr::data(formats), .depthAttachmentFormat = {}, .stencilAttachmentFormat = {} }; - if (rendering_info.depth_attachment_format) - info.depthAttachmentFormat = vk::to_vk(*rendering_info.depth_attachment_format); + if (create_info.rendering_info.depth_attachment_format) + info.depthAttachmentFormat = vk::to_vk(*create_info.rendering_info.depth_attachment_format); - if (rendering_info.stencil_attachment_format) - info.stencilAttachmentFormat = vk::to_vk(*rendering_info.stencil_attachment_format); + if (create_info.rendering_info.stencil_attachment_format) + info.stencilAttachmentFormat = vk::to_vk(*create_info.rendering_info.stencil_attachment_format); return info; }(); - const auto create_info = VkGraphicsPipelineCreateInfo { + const auto vk_create_info = VkGraphicsPipelineCreateInfo { .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, - .pNext = &_rendering_info, + .pNext = &rendering_info, .flags = 0, .stageCount = as(stdr::size(shaders)), .pStages = stdr::data(shaders), @@ -269,14 +265,14 @@ namespace stormkit::gpu { .pDepthStencilState = &depth_stencil, .pColorBlendState = &color_blending, .pDynamicState = &dynamic_state, - .layout = vk::to_vk(layout), + .layout = vk::to_vk(create_info.layout), .renderPass = VK_NULL_HANDLE, .subpass = 0, .basePipelineHandle = nullptr, .basePipelineIndex = -1, }; - const auto vk_pipeline_cache = either(pipeline_cache, vk::monadic::to_vk(), cmonadic::init(nullptr)); + const auto vk_pipeline_cache = either(create_info.cache, vk::monadic::to_vk(), cmonadic::init(nullptr)); const auto& device = owner(); const auto& device_table = device.device_table(); @@ -285,20 +281,17 @@ namespace stormkit::gpu { device, vk_pipeline_cache, 1, - &create_info, + &vk_create_info, nullptr)); Return {}; } ///////////////////////////////////// ///////////////////////////////////// - auto PipelineImplementation::do_init(PrivateTag, - const RasterPipelineState& _state, - view::PipelineLayout layout, - view::RenderPass render_pass, - std::optional&& pipeline_cache) noexcept -> Expected { + auto PipelineImplementation::do_init(PrivateTag, const LegacyRasterizationCreateInfo& create_info) noexcept + -> Expected { m_type = Type::RASTER; - m_state = core::allocate_unsafe(_state); + m_state = core::allocate_unsafe(create_info.state); const auto& state = as(*m_state); @@ -318,7 +311,7 @@ namespace stormkit::gpu { shaders, depth_stencil] = gpu::do_init(state); - const auto create_info = VkGraphicsPipelineCreateInfo { + const auto vk_create_info = VkGraphicsPipelineCreateInfo { .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, .pNext = nullptr, .flags = 0, @@ -333,14 +326,14 @@ namespace stormkit::gpu { .pDepthStencilState = &depth_stencil, .pColorBlendState = &color_blending, .pDynamicState = &dynamic_state, - .layout = vk::to_vk(layout), - .renderPass = render_pass, + .layout = vk::to_vk(create_info.layout), + .renderPass = create_info.render_pass, .subpass = 0, .basePipelineHandle = nullptr, .basePipelineIndex = -1, }; - const auto vk_pipeline_cache = either(pipeline_cache, vk::monadic::to_vk(), cmonadic::init(nullptr)); + const auto vk_pipeline_cache = either(create_info.cache, vk::monadic::to_vk(), cmonadic::init(nullptr)); const auto& device = owner(); const auto& device_table = device.device_table(); @@ -349,7 +342,7 @@ namespace stormkit::gpu { device, vk_pipeline_cache, 1, - &create_info, + &vk_create_info, nullptr)); Return {}; } diff --git a/src/gpu/execution/swapchain.cpp b/src/gpu/execution/swapchain.cpp index 356ee7026..34f941f8f 100644 --- a/src/gpu/execution/swapchain.cpp +++ b/src/gpu/execution/swapchain.cpp @@ -96,39 +96,36 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto SwapChainImplementation::do_init(PrivateTag, - view::Surface surface, - const math::uextent2& extent, - VkSwapchainKHR old_swapchain) noexcept -> Expected { + auto SwapChainImplementation::do_init(PrivateTag, const CreateInfo& create_info) noexcept -> Expected { const auto& device = owner(); const auto& device_table = device.device_table(); const auto& physical_device = device.physical_device(); const auto capabilities = Try(vk::call_checked(vkGetPhysicalDeviceSurfaceCapabilitiesKHR, physical_device, - surface)); + create_info.surface)); const auto formats = Try(vk::enumerate_checked(vkGetPhysicalDeviceSurfaceFormatsKHR, physical_device, - surface)); + create_info.surface)); const auto present_modes = Try(vk::enumerate_checked(vkGetPhysicalDeviceSurfacePresentModesKHR, physical_device, - surface)); + create_info.surface)); const auto format = choose_swap_surface_format(formats); const auto present_mode = choose_swap_present_mode(present_modes); - const auto swapchain_extent = choose_swap_extent(capabilities, extent.to<2uz>()); + const auto swapchain_extent = choose_swap_extent(capabilities, create_info.extent.to<2>()); const auto image_count = choose_image_count(capabilities); const auto image_sharing_mode = VK_SHARING_MODE_EXCLUSIVE; const auto image_usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; - m_extent = extent; + m_extent = create_info.extent; m_pixel_format = vk::from_vk(format.format); - const auto create_info = VkSwapchainCreateInfoKHR { + const auto vk_create_info = VkSwapchainCreateInfoKHR { .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, - .pNext = nullptr, + .pNext = VK_NULL_HANDLE, .flags = 0, - .surface = surface, + .surface = create_info.surface, .minImageCount = image_count, .imageFormat = format.format, .imageColorSpace = format.colorSpace, @@ -142,13 +139,13 @@ namespace stormkit::gpu { .compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR, .presentMode = present_mode, .clipped = true, - .oldSwapchain = old_swapchain, + .oldSwapchain = create_info.old, }; ENSURES(device_table.vkCreateSwapchainKHR != nullptr); ENSURES(device_table.vkGetSwapchainImagesKHR != nullptr); - m_vk_handle = Try(vk::call_checked(device_table.vkCreateSwapchainKHR, device, &create_info, nullptr)); + m_vk_handle = Try(vk::call_checked(device_table.vkCreateSwapchainKHR, device, &vk_create_info, nullptr)); const auto vk_images = Try(vk::enumerate_checked(device_table.vkGetSwapchainImagesKHR, device, m_vk_handle)); m_image_count = as(stdr::size(vk_images)); diff --git a/src/gpu/resource/image_view.cpp b/src/gpu/resource/image_view.cpp index 187236712..5e4dee04d 100644 --- a/src/gpu/resource/image_view.cpp +++ b/src/gpu/resource/image_view.cpp @@ -23,12 +23,9 @@ namespace stormkit::gpu { ///////////////////////////////////// ///////////////////////////////////// - auto ImageViewImplementation::do_init(PrivateTag, - view::Image image, - ImageViewType type, - const ImageSubresourceRange& subresource_range) noexcept -> Expected { - m_type = type; - m_subresource_range = subresource_range; + auto ImageViewImplementation::do_init(PrivateTag, const CreateInfo& create_info) noexcept -> Expected { + m_type = create_info.type; + m_subresource_range = create_info.subresource_range; const auto vk_subresource_range = VkImageSubresourceRange { .aspectMask = vk::to_vk(m_subresource_range.aspect_mask), @@ -38,13 +35,13 @@ namespace stormkit::gpu { .layerCount = m_subresource_range.layer_count, }; - const auto create_info = VkImageViewCreateInfo { + const auto vk_create_info = VkImageViewCreateInfo { .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, .pNext = nullptr, .flags = 0, - .image = image, + .image = create_info.image, .viewType = vk::to_vk(m_type), - .format = vk::to_vk(image.format()), + .format = vk::to_vk(create_info.image.format()), .components = { .r = VK_COMPONENT_SWIZZLE_R, .g = VK_COMPONENT_SWIZZLE_G, .b = VK_COMPONENT_SWIZZLE_B, @@ -54,7 +51,8 @@ namespace stormkit::gpu { const auto device = owner(); - m_vk_handle = Try(vk::call_checked(device.device_table().vkCreateImageView, device, &create_info, nullptr)); + m_vk_handle = Try(vk::call_checked< + VkImageView>(device.device_table().vkCreateImageView, device, &vk_create_info, nullptr)); Return {}; } } // namespace stormkit::gpu diff --git a/src/log/console_logger.cpp b/src/log/console_logger.cpp index 5bb8df99e..8ee24b74b 100644 --- a/src/log/console_logger.cpp +++ b/src/log/console_logger.cpp @@ -26,7 +26,10 @@ namespace stormkit::log { { Severity::FATAL, ConsoleStyle { .fg = ConsoleColor::RED, .modifiers = StyleModifier::INVERSE } }, { Severity::DEBUG, ConsoleStyle { .fg = ConsoleColor::CYAN, .modifiers = StyleModifier::INVERSE } }, }); - } + + constexpr auto format_string_with_module = "{}[{}, {:%S}, {}]{} {}"sv; + constexpr auto format_string = "{}[{}, {:%S}]{} {}"sv; + } // namespace //////////////////////////////////////// //////////////////////////////////////// @@ -41,30 +44,15 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// - auto ConsoleLogger::write(Severity severity, const Module& module, czstring str) noexcept -> void { + auto ConsoleLogger::write(Severity severity, const Module& module, std::string_view str) noexcept -> void { const auto now = LogClock::now(); const auto time = std::chrono::duration_cast(now - m_start_time); const auto is_error = severity == Severity::ERROR or severity == Severity::FATAL; const auto out = (is_error) ? get_stderr() : get_stdout(); - const auto header = [&severity, &module, &time] noexcept { - const auto severity_str = replace(as_string(severity), "Severity::", ""); - if (std::empty(module.name)) return std::format("[{}, {:%S}]", severity_str, time); - else - return std::format("[{}, {:%S}, {}]", severity_str, time, module.name); - }(); - - const auto prefixed_string = [&header, str] noexcept { - const auto header_length = stdr::size(header) + 1; - - auto prefix = string {}; - prefix.resize(header_length + 1, ' '); - prefix.front() = '\n'; - return replace(str, "\n", prefix); - }(); - - const auto styled_header = std::format("{} ", StyleMap.at(severity) | header); - std::println(out, "{}{}", styled_header, prefixed_string); + if (stdr::empty(module.name)) std::println(out, format_string, StyleMap.at(severity), severity, time, ecma48::RESET, str); + else + std::println(out, format_string_with_module, StyleMap.at(severity), severity, time, module.name, ecma48::RESET, str); } //////////////////////////////////////// diff --git a/src/log/file_logger.cpp b/src/log/file_logger.cpp index 818b1ee1e..a6eae0864 100644 --- a/src/log/file_logger.cpp +++ b/src/log/file_logger.cpp @@ -47,7 +47,7 @@ namespace stormkit::log { //////////////////////////////////////// //////////////////////////////////////// - auto FileLogger::write(Severity severity, const Module& m, czstring str) noexcept -> void { + auto FileLogger::write(Severity severity, const Module& m, std::string_view str) noexcept -> void { const auto now = LogClock::now(); const auto time = std::chrono::duration_cast(now - m_start_time).count();