153 lines
3.5 KiB
C++
153 lines
3.5 KiB
C++
// =============================================
|
|
// Aster: global.h
|
|
// Copyright (c) 2020-2024 Anish Bhobe
|
|
// =============================================
|
|
|
|
#pragma once
|
|
|
|
#include "config.h"
|
|
#include "constants.h"
|
|
#include "logger.h"
|
|
|
|
#include <GLFW/glfw3.h>
|
|
#include <glm/glm.hpp>
|
|
|
|
#include <fmt/format.h>
|
|
|
|
// Macros that can collide with functions.
|
|
#if defined(max)
|
|
#undef max
|
|
#endif
|
|
|
|
#if defined(min)
|
|
#undef min
|
|
#endif
|
|
|
|
#define VULKAN_HPP_ASSERT(expr) DEBUG_IF(!(expr), "Vulkan assert failed")
|
|
#include <EASTL/fixed_string.h>
|
|
#include <EASTL/string.h>
|
|
#include <vk_mem_alloc.h>
|
|
|
|
#include <vulkan/vulkan.hpp>
|
|
|
|
constexpr u32 ASTER_API_VERSION = vk::ApiVersion13;
|
|
|
|
#define CODE_LOC " @ " __FILE__ ":" VULKAN_HPP_STRINGIFY(__LINE__)
|
|
|
|
[[nodiscard]] inline bool
|
|
failed(const vk::Result result)
|
|
{
|
|
return result != vk::Result::eSuccess;
|
|
}
|
|
|
|
template <typename T>
|
|
concept IsVkEnum = requires(T t) {
|
|
{
|
|
std::is_enum_v<T>
|
|
};
|
|
{
|
|
vk::to_string(t)
|
|
} -> std::same_as<std::string>;
|
|
};
|
|
|
|
template <typename T>
|
|
requires IsVkEnum<T>
|
|
[[nodiscard]] const char *
|
|
toCstr(const T &val)
|
|
{
|
|
static std::string buffer;
|
|
buffer = vk::to_string(val);
|
|
return buffer.c_str();
|
|
}
|
|
|
|
using NameString = eastl::fixed_string<char, 32, false>;
|
|
|
|
// TODO: Check why inline namespaces aren't working in MSVC 19.27.29110
|
|
using namespace std::literals::string_literals;
|
|
using namespace std::literals::string_view_literals;
|
|
|
|
template <typename T>
|
|
requires vk::isVulkanHandleType<T>::value
|
|
[[nodiscard]] constexpr u64
|
|
getVkHandle(const T &vkHandle) noexcept
|
|
{
|
|
return reinterpret_cast<u64>(cast<T::CType>(vkHandle));
|
|
}
|
|
|
|
template <typename F>
|
|
struct std::hash<vk::Flags<F>>
|
|
{
|
|
[[nodiscard]] usize
|
|
operator()(const vk::Flags<F> &val)
|
|
{
|
|
return std::hash<u32>()(cast<u32>(val));
|
|
}
|
|
};
|
|
|
|
template <typename T>
|
|
[[nodiscard]] usize
|
|
hashAny(const T &val)
|
|
{
|
|
return std::hash<std::remove_cvref_t<T>>()(val);
|
|
}
|
|
|
|
[[nodiscard]] inline usize
|
|
hashCombine(const usize hash0, const usize hash1)
|
|
{
|
|
constexpr usize saltValue = 0x9e3779b9;
|
|
return hash0 ^ (hash1 + saltValue + (hash0 << 6) + (hash0 >> 2));
|
|
}
|
|
|
|
struct Time
|
|
{
|
|
static constexpr f64 c_MaxDelta = 0.1;
|
|
|
|
inline static f64 m_Elapsed{Qnan<f64>};
|
|
inline static f64 m_Delta{Qnan<f64>};
|
|
|
|
static void
|
|
Init()
|
|
{
|
|
WARN_IF(!std::isnan(m_Elapsed), "Time already init.");
|
|
m_Elapsed = glfwGetTime();
|
|
m_Delta = 1.0 / 60.0;
|
|
}
|
|
|
|
static void
|
|
Update()
|
|
{
|
|
ERROR_IF(std::isnan(m_Elapsed), "Time not init.");
|
|
const auto newElapsed = glfwGetTime();
|
|
m_Delta = std::clamp(newElapsed - m_Elapsed, 0.0, c_MaxDelta);
|
|
m_Elapsed = newElapsed;
|
|
}
|
|
};
|
|
|
|
[[nodiscard]] inline usize
|
|
closestMultiple(const usize val, const usize of)
|
|
{
|
|
return of * ((val + of - 1) / of);
|
|
}
|
|
|
|
template <>
|
|
struct fmt::formatter<vk::Result> : nested_formatter<std::string>
|
|
{
|
|
auto
|
|
// ReSharper disable once CppInconsistentNaming
|
|
format(vk::Result result, format_context &ctx) const
|
|
{
|
|
return write_padded(ctx,
|
|
[this, result](auto out) { return v10::format_to(out, "{}", nested(to_string(result))); });
|
|
}
|
|
};
|
|
|
|
template <typename T, usize N, bool B>
|
|
struct fmt::formatter<eastl::fixed_string<T, N, B>> : nested_formatter<cstr>
|
|
{
|
|
auto
|
|
// ReSharper disable once CppInconsistentNaming
|
|
format(const eastl::fixed_string<T, N, B> &str, format_context &ctx) const
|
|
{
|
|
return write_padded(ctx, [this, str](auto out) { return v10::format_to(out, "{}", nested(str.c_str())); });
|
|
}
|
|
}; |