From e02f9fd89b059919baf3a8d8bf8b783470976a27 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic <steven.lerouzic@gmail.com> Date: Sat, 27 Apr 2024 01:16:21 +0200 Subject: Some work on Vulkan initialization --- deimos/core/allocator.h | 21 +++++++++++++++++++++ deimos/core/base.h | 19 ++++++++++++++++++- deimos/core/log.cpp | 8 +++++--- deimos/core/status.h | 14 ++++++++++++-- deimos/core/std.h | 1 + deimos/core/temp_allocator.cpp | 12 ++---------- deimos/vulkan/BUILD | 2 ++ deimos/vulkan/vulkan.h | 4 ++++ deimos/vulkan/vulkan_bootstrap_functions.inc | 3 +++ deimos/vulkan/vulkan_entry_functions.inc | 1 - deimos/vulkan/vulkan_instance_functions.inc | 6 ++++++ deimos/vulkan/vulkan_loader.cpp | 18 +++++++++++++++++- 12 files changed, 91 insertions(+), 18 deletions(-) create mode 100644 deimos/vulkan/vulkan_bootstrap_functions.inc create mode 100644 deimos/vulkan/vulkan_instance_functions.inc (limited to 'deimos') diff --git a/deimos/core/allocator.h b/deimos/core/allocator.h index 26374bd..5afb824 100644 --- a/deimos/core/allocator.h +++ b/deimos/core/allocator.h @@ -125,6 +125,27 @@ public: } Free(t, sizeof(T), source_location); } + + template<typename T> + gsl::owner<Span<T>> NewArray(int64_t count, const SourceLocation& source_location = {}) + requires std::is_default_constructible_v<T> + { + Expects(count > 0); + + auto* raw = Allocate((int64_t)sizeof(T) * count, source_location); + if constexpr (std::is_trivially_default_constructible_v<T>) + { + MemoryZero(raw, (int64_t)sizeof(T) * count); + } + else + { + for (int64_t i = 0; i < count; ++i) + { + new((T*)raw + i) T{}; + } + } + return Span<T>{ (T*)raw, count }; + } }; class AllocatorApi diff --git a/deimos/core/base.h b/deimos/core/base.h index 5cd3a40..70958a5 100644 --- a/deimos/core/base.h +++ b/deimos/core/base.h @@ -5,7 +5,13 @@ #define deimos_StaticAssert(...) static_assert(__VA_ARGS__, #__VA_ARGS__) -#define deimos_Panic(MSG) do { __builtin_trap(); } while (0) +[[noreturn]] +inline void deimos_Trap() +{ + __builtin_trap(); +} + +#define deimos_Panic(MSG) do { deimos_Trap(); } while (0) #define deimos_NO_COPY(TYPE) \ TYPE(const TYPE&) = delete; \ @@ -78,6 +84,11 @@ constexpr void MemoryCopy(void* dst, const void* src, int64_t size) __builtin_memcpy(dst, src, (size_t)size); } +inline void MemoryZero(void* dst, int64_t size) +{ + __builtin_memset(dst, 0, (size_t)size); +} + template<typename T, int64_t N> constexpr int64_t ArraySize(const T (&)[N]) { return N; } @@ -117,6 +128,12 @@ public: constexpr T* end() const { return m_begin + m_size; } // NOLINT constexpr int64_t size() const { return m_size; } constexpr bool empty() const { return m_size == 0; } + + constexpr T& operator[](int64_t i) const + { + Expects(i >= 0 && i < m_size); + return m_begin[i]; // NOLINT + } }; template<typename T> diff --git a/deimos/core/log.cpp b/deimos/core/log.cpp index e05c360..b8e7805 100644 --- a/deimos/core/log.cpp +++ b/deimos/core/log.cpp @@ -35,10 +35,12 @@ public: m_writer(os_console_api, OsConsoleType::kStdOut) {} - void Log(LogSeverity severity, const SourceLocation& location, StringView msg) override + void Log(LogSeverity severity, const SourceLocation& /* location */, StringView msg) override { - Format(&m_writer, "$[ $ ] $:$: $\033[0m\n", SeverityToColor(severity), - SeverityToStr(severity), location.file, location.line, msg); + // Format(&m_writer, "$[ $ ] $:$: $\033[0m\n", SeverityToColor(severity), + // SeverityToStr(severity), location.file, location.line, msg); + Format(&m_writer, "$[ $ ] $\033[0m\n", SeverityToColor(severity), + SeverityToStr(severity), msg); } }; diff --git a/deimos/core/status.h b/deimos/core/status.h index 912d4c8..8141dad 100644 --- a/deimos/core/status.h +++ b/deimos/core/status.h @@ -147,18 +147,18 @@ public: StatusOr(const Status& status) : m_status{status} // NOLINT { + Expects(!m_status.ok()); if (m_status.ok()) { - deimos_Panic("Cannot construct a StatusOr from OK"); m_status = InternalError("StatusOr constructed from OK"); } } StatusOr(Status&& status) : m_status{std::move(status)} // NOLINT { + Expects(!m_status.ok()); if (m_status.ok()) { - deimos_Panic("Cannot construct a StatusOr from OK"); m_status = InternalError("StatusOr constructed from OK"); } } @@ -229,6 +229,16 @@ public: } constexpr bool ok() const { return m_status.ok(); } + + constexpr StatusCode code() const { return m_status.code(); } + + constexpr const Status& status() const { return m_status; } + + constexpr const T& value() const & { Expects(m_status.ok()); return m_value; } + + constexpr T& value() & { Expects(m_status.ok()); return m_value; } + + constexpr T&& value() && { Expects(m_status.ok()); return std::move(m_value); } friend void DeimosFormat(IWriter* writer, const StatusOr<T>& status) { diff --git a/deimos/core/std.h b/deimos/core/std.h index 47f161a..27b5bc4 100644 --- a/deimos/core/std.h +++ b/deimos/core/std.h @@ -26,6 +26,7 @@ template<typename T> concept unsigned_integral = integral<T> && __is_unsigned(T) template<typename T> constexpr bool is_trivially_destructible_v = __is_trivially_destructible(T); template<typename T, typename... Args> constexpr bool is_constructible_v = __is_constructible(T, Args...); template<typename T> constexpr bool is_default_constructible_v = __is_constructible(T); +template<typename T> constexpr bool is_trivially_default_constructible_v = __is_trivially_constructible(T); template<typename T> constexpr bool is_copy_constructible_v = __is_constructible(T, const T&); template<typename T> constexpr bool is_move_constructible_v = __is_constructible(T, T&&); template<typename T> constexpr bool is_copy_assignable_v = __is_assignable(T, const T&); diff --git a/deimos/core/temp_allocator.cpp b/deimos/core/temp_allocator.cpp index d2b7900..99ee630 100644 --- a/deimos/core/temp_allocator.cpp +++ b/deimos/core/temp_allocator.cpp @@ -35,7 +35,6 @@ public: if (new_current > m_reserve_end) { deimos_Panic("Ran out of temporary memory"); - return nullptr; } if (new_current > m_commit_end) @@ -73,15 +72,8 @@ public: { void* rewind_base = std::bit_cast<void*>(tag.tag); Expects(rewind_base >= m_base && rewind_base <= m_commit_end); - - if (rewind_base < m_current) - { - m_current = rewind_base; - } - else - { - deimos_Panic("Invalid temporary allocator rewind"); - } + Expects(rewind_base <= m_current); + m_current = rewind_base; } }; diff --git a/deimos/vulkan/BUILD b/deimos/vulkan/BUILD index a773fa1..8f0a79e 100644 --- a/deimos/vulkan/BUILD +++ b/deimos/vulkan/BUILD @@ -5,7 +5,9 @@ cc_library( ], srcs = [ "vulkan_loader.cpp", + "vulkan_bootstrap_functions.inc", "vulkan_entry_functions.inc", + "vulkan_instance_functions.inc", ], deps = [ "//deimos/core", diff --git a/deimos/vulkan/vulkan.h b/deimos/vulkan/vulkan.h index 48d53b3..4315230 100644 --- a/deimos/vulkan/vulkan.h +++ b/deimos/vulkan/vulkan.h @@ -20,7 +20,9 @@ class ApiRegistry; struct VulkanApi { #define FN(NAME) PFN_vk##NAME NAME{}; +#include "deimos/vulkan/vulkan_bootstrap_functions.inc" #include "deimos/vulkan/vulkan_entry_functions.inc" +#include "deimos/vulkan/vulkan_instance_functions.inc" #undef FN }; @@ -34,6 +36,8 @@ public: static constexpr IdName kApiName{"deimos::VulkanLoaderApi"}; virtual VulkanApi* LoadEntry() = 0; + + virtual void LoadInstance(VulkanApi*, VkInstance) = 0; }; void RegisterVulkanLoaderApi(ApiRegistry*); diff --git a/deimos/vulkan/vulkan_bootstrap_functions.inc b/deimos/vulkan/vulkan_bootstrap_functions.inc new file mode 100644 index 0000000..a69c5a6 --- /dev/null +++ b/deimos/vulkan/vulkan_bootstrap_functions.inc @@ -0,0 +1,3 @@ +// NOLINTBEGIN +FN(GetInstanceProcAddr) +// NOLINTEND diff --git a/deimos/vulkan/vulkan_entry_functions.inc b/deimos/vulkan/vulkan_entry_functions.inc index fe5f9ea..761cb0f 100644 --- a/deimos/vulkan/vulkan_entry_functions.inc +++ b/deimos/vulkan/vulkan_entry_functions.inc @@ -1,4 +1,3 @@ // NOLINTBEGIN -FN(GetInstanceProcAddr) FN(CreateInstance) // NOLINTEND diff --git a/deimos/vulkan/vulkan_instance_functions.inc b/deimos/vulkan/vulkan_instance_functions.inc new file mode 100644 index 0000000..34535ad --- /dev/null +++ b/deimos/vulkan/vulkan_instance_functions.inc @@ -0,0 +1,6 @@ +// NOLINTBEGIN +FN(EnumeratePhysicalDevices) +FN(GetPhysicalDeviceProperties2) +FN(GetPhysicalDeviceQueueFamilyProperties) +FN(DestroyInstance) +// NOLINTEND diff --git a/deimos/vulkan/vulkan_loader.cpp b/deimos/vulkan/vulkan_loader.cpp index ddd5cf0..0760c67 100644 --- a/deimos/vulkan/vulkan_loader.cpp +++ b/deimos/vulkan/vulkan_loader.cpp @@ -31,16 +31,32 @@ public: else { deimos_Panic("Couldn't load Vulkan DLL"); - return nullptr; } } VulkanApi* api = m_allocator->New<VulkanApi>(); + #define FN(NAME) api->NAME = (PFN_vk##NAME)os_api->dll->GetSymbol(m_vulkan_dll, "vk" #NAME); +#include "deimos/vulkan/vulkan_bootstrap_functions.inc" +#undef FN + +#define FN(NAME) api->NAME = (PFN_vk##NAME)api->GetInstanceProcAddr(VK_NULL_HANDLE, "vk" #NAME); #include "deimos/vulkan/vulkan_entry_functions.inc" #undef FN + return api; } + + void LoadInstance(VulkanApi* api, VkInstance instance) override + { + Expects(api != nullptr); + Expects(instance != VK_NULL_HANDLE); + Expects(api->GetInstanceProcAddr != nullptr); + +#define FN(NAME) api->NAME = (PFN_vk##NAME)api->GetInstanceProcAddr(instance, "vk" #NAME); +#include "deimos/vulkan/vulkan_instance_functions.inc" +#undef FN + } }; void RegisterVulkanLoaderApi(ApiRegistry* registry) -- cgit