Compare commits

..

No commits in common. "84f38e18ed2f5f797b406075e5400d00dc59107c" and "38b697f2021ff784f9cbe9cea5c69b2799ce07b9" have entirely different histories.

63 changed files with 850 additions and 527 deletions

View File

@ -19,6 +19,7 @@ add_subdirectory("src")
target_compile_features(aster_core PUBLIC cxx_std_23)
target_include_directories(aster_core PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/include/aster")
target_include_directories(aster_core PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(aster_core PUBLIC glm::glm-header-only)

View File

@ -7,6 +7,6 @@ add_subdirectory("systems")
add_subdirectory("util")
target_sources(aster_core
PUBLIC "aster.h" "import_types.h")
PUBLIC "aster.h")
target_precompile_headers(aster_core PUBLIC "aster.h")

View File

@ -5,11 +5,4 @@
#pragma once
#include "aster/core/global.h"
#include "aster/core/window.h"
#include "aster/systems/commit_manager.h"
#include "aster/systems/context.h"
#include "aster/systems/rendering_device.h"
#include "aster/systems/resource.h"
#include "core/global.h"

View File

@ -7,8 +7,6 @@
#include "global.h"
namespace aster
{
struct Device;
/// A Vulkan buffer wrapper.
@ -117,5 +115,4 @@ concept AnyBufferRef = Deref<T> and AnyBuffer<DerefType<T>>;
template <typename T, typename TTo>
concept BufferRefTo = Deref<T> and BufferInto<DerefType<T>, TTo>;
} // namespace concepts
} // namespace aster
} // namespace concepts

View File

@ -15,8 +15,6 @@
#include <atomic>
namespace aster::types
{
using c8 = char;
using u8 = uint8_t;
using u16 = uint16_t;
@ -36,6 +34,19 @@ using isize = intptr_t;
using uptr = uintptr_t;
using cstr = char const *;
namespace ansi_color
{
constexpr auto Black = "\u001b[30m";
constexpr auto Red = "\u001b[31m";
constexpr auto Green = "\u001b[32m";
constexpr auto Yellow = "\u001b[33m";
constexpr auto Blue = "\u001b[34m";
constexpr auto Magenta = "\u001b[35m";
constexpr auto Cyan = "\u001b[36m";
constexpr auto White = "\u001b[37m";
constexpr auto Reset = "\u001b[0m";
} // namespace ansi_color
constexpr f32
operator""_deg(long double degrees)
{
@ -72,6 +83,57 @@ using glm::mat2;
using glm::mat3;
using glm::mat4;
constexpr auto *PROJECT_NAME = "Aster";
struct Version
{
u8 m_Major;
u8 m_Minor;
u8 m_Patch;
[[nodiscard]] u32
GetVkVersion() const
{
return VK_MAKE_API_VERSION(0, m_Major, m_Minor, m_Patch);
}
};
constexpr Version VERSION = {
.m_Major = 0,
.m_Minor = 1,
.m_Patch = 0,
};
constexpr u32
Kilobyte(u32 const in)
{
return in * 1024;
}
constexpr usize
Kilobyte(usize const in)
{
return in * 1024;
}
constexpr u32
Megabyte(u32 const in)
{
return in * 1024 * 1024;
}
constexpr usize
Megabyte(usize const in)
{
return in * 1024 * 1024;
}
constexpr usize
Gigabyte(usize const in)
{
return in * 1024 * 1024 * 1024;
}
template <typename T>
constexpr T MaxValue = std::numeric_limits<T>::max();
@ -94,23 +156,4 @@ template <typename T>
constexpr T Qnan = std::numeric_limits<T>::quiet_NaN();
template <typename T>
constexpr T Snan = std::numeric_limits<T>::signalling_NaN();
} // namespace aster::types
namespace aster
{
using namespace types;
namespace ansi_color
{
constexpr auto Black = "\u001b[30m";
constexpr auto Red = "\u001b[31m";
constexpr auto Green = "\u001b[32m";
constexpr auto Yellow = "\u001b[33m";
constexpr auto Blue = "\u001b[34m";
constexpr auto Magenta = "\u001b[35m";
constexpr auto Cyan = "\u001b[36m";
constexpr auto White = "\u001b[37m";
constexpr auto Reset = "\u001b[0m";
} // namespace ansi_color
} // namespace aster
constexpr T Snan = std::numeric_limits<T>::signalling_NaN();

View File

@ -10,8 +10,6 @@
#include <EASTL/span.h>
#include <EASTL/vector.h>
namespace aster
{
struct QueueAllocation;
struct Instance;
struct PhysicalDevice;
@ -83,5 +81,4 @@ Device::SetName(T const &object, cstr name) const
vk::Result result = m_Device.setDebugUtilsObjectNameEXT(&objectNameInfo);
WARN_IF(Failed(result), "Could not name {:x}: {} as {}. Cause: {}", handle, to_string(object.objectType), name,
result);
}
} // namespace aster
}

View File

@ -39,6 +39,8 @@
#include <vulkan/vulkan.hpp>
constexpr u32 ASTER_API_VERSION = VK_API_VERSION_1_3;
#define CODE_LOC " @ " __FILE__ ":" VULKAN_HPP_STRINGIFY(__LINE__)
#define DISALLOW_COPY_AND_ASSIGN(CLASS_NAME) \
@ -87,67 +89,24 @@ Failed(vk::Result const result)
return result != vk::Result::eSuccess;
}
namespace aster::concepts
namespace concepts
{
template <typename T>
concept VkHandle = vk::isVulkanHandleType<T>::value;
}
namespace aster
{
constexpr u32 ASTER_API_VERSION = VK_API_VERSION_1_3;
using NameString = eastl::fixed_string<char, 32, false>;
struct Version
template <typename TFlagBits>
struct eastl::hash<vk::Flags<TFlagBits>> // NOLINT(*-dcl58-cpp)
{
u8 m_Major;
u8 m_Minor;
u8 m_Patch;
[[nodiscard]] u32
GetVkVersion() const
[[nodiscard]] usize
operator()(vk::Flags<TFlagBits> const &val)
{
return VK_MAKE_API_VERSION(0, m_Major, m_Minor, m_Patch);
return std::hash<u32>()(static_cast<u32>(val));
}
};
constexpr Version VERSION = {
.m_Major = 0,
.m_Minor = 1,
.m_Patch = 0,
};
constexpr u32
Kilobyte(u32 const in)
{
return in * 1024;
}
constexpr usize
Kilobyte(usize const in)
{
return in * 1024;
}
constexpr u32
Megabyte(u32 const in)
{
return in * 1024 * 1024;
}
constexpr usize
Megabyte(usize const in)
{
return in * 1024 * 1024;
}
constexpr usize
Gigabyte(usize const in)
{
return in * 1024 * 1024 * 1024;
}
template <typename T>
[[nodiscard]] usize
HashAny(T const &val)
@ -272,14 +231,7 @@ concept VkToString = requires(T a) {
{ vk::to_string(a) } -> std::convertible_to<std::string>;
};
template <typename T>
using Ref = eastl::shared_ptr<T>;
template <typename T>
using WeakRef = eastl::weak_ptr<T>;
} // namespace aster
template <aster::VkToString T>
template <VkToString T>
struct fmt::formatter<T> : nested_formatter<std::string>
{
auto
@ -291,8 +243,8 @@ struct fmt::formatter<T> : nested_formatter<std::string>
}
};
template <typename TType, aster::usize TCount, bool TOverflow>
struct fmt::formatter<eastl::fixed_string<TType, TCount, TOverflow>> : nested_formatter<aster::cstr>
template <typename TType, usize TCount, bool TOverflow>
struct fmt::formatter<eastl::fixed_string<TType, TCount, TOverflow>> : nested_formatter<cstr>
{
auto
// ReSharper disable once CppInconsistentNaming
@ -302,12 +254,8 @@ struct fmt::formatter<eastl::fixed_string<TType, TCount, TOverflow>> : nested_fo
}
};
template <typename TFlagBits>
struct eastl::hash<vk::Flags<TFlagBits>> // NOLINT(*-dcl58-cpp)
{
[[nodiscard]] aster::usize
operator()(vk::Flags<TFlagBits> const &val)
{
return std::hash<aster::u32>()(static_cast<aster::u32>(val));
}
};
template <typename T>
using Ref = eastl::shared_ptr<T>;
template <typename T>
using WeakRef = eastl::weak_ptr<T>;

View File

@ -7,8 +7,6 @@
#include "global.h"
namespace aster
{
struct StorageTexture;
struct Device;
@ -131,5 +129,4 @@ concept AnyImageRef = Deref<T> and AnyImage<DerefType<T>>;
template <typename T, typename TTo>
concept ImageRefTo = Deref<T> and ImageInto<DerefType<T>, TTo>;
} // namespace concepts
} // namespace aster
} // namespace concepts

View File

@ -8,8 +8,6 @@
#include "global.h"
#include "image.h"
namespace aster
{
template <concepts::AnyImage TImage>
struct View
{
@ -107,5 +105,4 @@ concept ViewRef = Deref<T> and View<DerefType<T>>;
template <typename T, typename TTo>
concept ViewRefTo = ViewRef<T> and ImageInto<typename DerefType<T>::ImageType, TTo>;
} // namespace concepts
} // namespace aster
} // namespace concepts

View File

@ -7,8 +7,6 @@
#include "global.h"
namespace aster
{
/**
* @class Instance
*
@ -38,5 +36,4 @@ struct Instance final
#endif
DISALLOW_COPY_AND_ASSIGN(Instance);
};
} // namespace aster
};

View File

@ -12,8 +12,6 @@
#include <EASTL/fixed_vector.h>
namespace aster
{
struct Window;
struct Instance;
@ -91,5 +89,4 @@ class PhysicalDevices : public eastl::fixed_vector<PhysicalDevice, 4>
{
public:
PhysicalDevices(Surface const &surface, Instance const &context);
};
} // namespace aster
};

View File

@ -9,8 +9,6 @@
#include <EASTL/vector.h>
namespace aster
{
struct Device;
struct Pipeline
@ -56,5 +54,4 @@ struct Pipeline
swap(m_Kind, other.m_Kind);
return *this;
}
};
} // namespace aster
};

View File

@ -7,11 +7,8 @@
#include "global.h"
namespace aster
{
struct QueueAllocation
{
u32 m_Family;
u32 m_Count;
};
} // namespace aster
};

View File

@ -7,8 +7,6 @@
#include "global.h"
namespace aster
{
struct Device;
struct Sampler final
@ -31,5 +29,4 @@ struct Sampler final
Sampler &operator=(Sampler &&other) noexcept;
DISALLOW_COPY_AND_ASSIGN(Sampler);
};
} // namespace aster
};

View File

@ -7,8 +7,6 @@
#include "global.h"
namespace aster
{
struct Size2D
{
u32 m_Width = 0;
@ -42,5 +40,4 @@ struct Size2D
{
return {m_Width, m_Height};
}
};
} // namespace aster
};

View File

@ -7,8 +7,6 @@
#include "global.h"
namespace aster
{
struct Instance;
struct Window;
@ -28,5 +26,4 @@ struct Surface
Surface &operator=(Surface &&other) noexcept;
DISALLOW_COPY_AND_ASSIGN(Surface);
};
} // namespace aster
};

View File

@ -11,8 +11,6 @@
#include <EASTL/fixed_vector.h>
namespace aster
{
struct PhysicalDevice;
struct Surface;
struct Device;
@ -44,7 +42,6 @@ struct Swapchain final
DISALLOW_COPY_AND_ASSIGN(Swapchain);
private:
private:
void Cleanup();
};
} // namespace aster
};

View File

@ -7,8 +7,6 @@
#include "constants.h"
namespace aster
{
struct Device;
struct Image;
@ -27,5 +25,4 @@ concept DerefTo = requires(TRef a) {
template <Deref T>
using DerefType = std::remove_cvref_t<decltype(*std::declval<T>())>;
} // namespace concepts
} // namespace aster
} // namespace concepts

View File

@ -12,8 +12,6 @@
#include <EASTL/fixed_string.h>
#include <atomic>
namespace aster
{
struct Window final
{
// fields
@ -48,5 +46,4 @@ struct Window final
Window &operator=(Window &&other) noexcept;
DISALLOW_COPY_AND_ASSIGN(Window);
};
} // namespace aster
};

View File

@ -1,10 +0,0 @@
// =============================================
// Aster: import_types.h
// Copyright (c) 2020-2024 Anish Bhobe
// =============================================
#pragma once
#include "aster/aster.h"
using namespace aster::types;

View File

@ -18,7 +18,7 @@
#include "aster/core/sampler.h"
#include "resource.h"
namespace aster
namespace systems
{
class RenderingDevice;

View File

@ -23,7 +23,7 @@
#include <foonathan/memory/memory_pool.hpp>
#include <foonathan/memory/namespace_alias.hpp>
namespace aster
namespace systems
{
class RenderingDevice;

View File

@ -11,7 +11,7 @@
#include <slang.h>
#include <variant>
namespace aster
namespace systems
{
class RenderingDevice;
@ -29,10 +29,10 @@ struct PipelineCreationError
PipelineCreationError();
};
vk::ShaderStageFlagBits SlangToVulkanShaderStage(SlangStage stage);
namespace _internal
{
vk::ShaderStageFlagBits SlangToVulkanShaderStage(SlangStage const stage);
struct PipelineLayoutBuilder
{
RenderingDevice *m_Device;
@ -72,4 +72,4 @@ struct DescriptorLayoutBuilder
void Build();
};
} // namespace _internal
} // namespace aster
} // namespace systems

View File

@ -28,45 +28,42 @@
#include <slang-com-ptr.h>
#include <slang.h>
namespace aster
{
constexpr static u32 MAX_FRAMES_IN_FLIGHT = 3;
struct Window;
} // namespace aster
template <>
struct eastl::hash<vk::SamplerCreateInfo>
{
aster::usize
usize
operator()(vk::SamplerCreateInfo const &createInfo) const noexcept
{
aster::usize hash = aster::HashAny(createInfo.flags);
hash = aster::HashCombine(hash, aster::HashAny(createInfo.magFilter));
hash = aster::HashCombine(hash, aster::HashAny(createInfo.minFilter));
hash = aster::HashCombine(hash, aster::HashAny(createInfo.mipmapMode));
hash = aster::HashCombine(hash, aster::HashAny(createInfo.addressModeU));
hash = aster::HashCombine(hash, aster::HashAny(createInfo.addressModeV));
hash = aster::HashCombine(hash, aster::HashAny(createInfo.addressModeW));
hash = aster::HashCombine(hash, aster::HashAny(static_cast<aster::usize>(createInfo.mipLodBias * 1000))); // Resolution of 10^-3
hash = aster::HashCombine(hash, aster::HashAny(createInfo.anisotropyEnable));
hash = aster::HashCombine(
usize hash = HashAny(createInfo.flags);
hash = HashCombine(hash, HashAny(createInfo.magFilter));
hash = HashCombine(hash, HashAny(createInfo.minFilter));
hash = HashCombine(hash, HashAny(createInfo.mipmapMode));
hash = HashCombine(hash, HashAny(createInfo.addressModeU));
hash = HashCombine(hash, HashAny(createInfo.addressModeV));
hash = HashCombine(hash, HashAny(createInfo.addressModeW));
hash = HashCombine(hash, HashAny(static_cast<usize>(createInfo.mipLodBias * 1000))); // Resolution of 10^-3
hash = HashCombine(hash, HashAny(createInfo.anisotropyEnable));
hash = HashCombine(
hash,
aster::HashAny(static_cast<aster::usize>(createInfo.maxAnisotropy * 0x20))); // 32:1 Anisotropy is enough resolution
hash = aster::HashCombine(hash, aster::HashAny(createInfo.compareEnable));
hash = aster::HashCombine(hash, aster::HashAny(createInfo.compareOp));
hash = aster::HashCombine(hash, aster::HashAny(static_cast<aster::usize>(createInfo.minLod * 1000))); // 0.001 resolution is enough.
hash = aster::HashCombine(
HashAny(static_cast<usize>(createInfo.maxAnisotropy * 0x20))); // 32:1 Anisotropy is enough resolution
hash = HashCombine(hash, HashAny(createInfo.compareEnable));
hash = HashCombine(hash, HashAny(createInfo.compareOp));
hash = HashCombine(hash, HashAny(static_cast<usize>(createInfo.minLod * 1000))); // 0.001 resolution is enough.
hash = HashCombine(
hash,
aster::HashAny(static_cast<aster::usize>(createInfo.maxLod * 1000))); // 0.001 resolution is enough. (1 == NO Clamp)
hash = aster::HashCombine(hash, aster::HashAny(createInfo.borderColor));
hash = aster::HashCombine(hash, aster::HashAny(createInfo.unnormalizedCoordinates));
HashAny(static_cast<usize>(createInfo.maxLod * 1000))); // 0.001 resolution is enough. (1 == NO Clamp)
hash = HashCombine(hash, HashAny(createInfo.borderColor));
hash = HashCombine(hash, HashAny(createInfo.unnormalizedCoordinates));
return hash;
}
};
namespace aster
namespace systems
{
// ====================================================================================================

View File

@ -11,7 +11,7 @@
#include <EASTL/intrusive_ptr.h>
namespace aster
namespace systems
{
// ====================================================================================================

View File

@ -9,13 +9,13 @@
#include <EASTL/deque.h>
#include <EASTL/intrusive_list.h>
namespace aster
namespace systems
{
class Receipt;
class RenderingDevice;
} // namespace systems
namespace aster::_internal
namespace systems::_internal
{
struct TimelinePoint
{

View File

@ -10,9 +10,6 @@
#include <EASTL/span.h>
#include <EASTL/vector.h>
namespace aster
{
eastl::vector<u32> ReadFile(std::string_view fileName);
eastl::vector<u8> ReadFileBytes(std::string_view fileName, bool errorOnFail = true);
bool WriteFileBytes(std::string_view fileName, eastl::span<u8> data);
} // namespace aster
bool WriteFileBytes(std::string_view fileName, eastl::span<u8> data);

View File

@ -9,8 +9,6 @@
#include <debugbreak.h>
#include <fmt/core.h>
namespace aster
{
struct Logger
{
enum class LogType : u32
@ -96,61 +94,60 @@ struct Logger
#endif
}
};
}
extern aster::Logger g_Logger;
extern Logger g_Logger;
#define MIN_LOG_LEVEL(LOG_LVL) g_Logger.SetMinimumLoggingLevel(LOG_LVL)
#define ERROR(...) g_Logger.Log<aster::Logger::LogType::eError>(fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define WARN(...) g_Logger.Log<aster::Logger::LogType::eWarning>(fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define INFO(...) g_Logger.Log<aster::Logger::LogType::eInfo>(fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define ERROR(...) g_Logger.Log<Logger::LogType::eError>(fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define WARN(...) g_Logger.Log<Logger::LogType::eWarning>(fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define INFO(...) g_Logger.Log<Logger::LogType::eInfo>(fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define ERROR_IF(expr, ...) \
if (static_cast<bool>(expr)) [[unlikely]] \
g_Logger.LogCond<aster::Logger::LogType::eError>(#expr, fmt::format(__VA_ARGS__), __FILE__, __LINE__)
g_Logger.LogCond<Logger::LogType::eError>(#expr, fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define WARN_IF(expr, ...) \
if (static_cast<bool>(expr)) [[unlikely]] \
g_Logger.LogCond<aster::Logger::LogType::eWarning>(#expr, fmt::format(__VA_ARGS__), __FILE__, __LINE__)
g_Logger.LogCond<Logger::LogType::eWarning>(#expr, fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define INFO_IF(expr, ...) \
if (static_cast<bool>(expr)) \
g_Logger.LogCond<aster::Logger::LogType::eInfo>(#expr, fmt::format(__VA_ARGS__), __FILE__, __LINE__)
g_Logger.LogCond<Logger::LogType::eInfo>(#expr, fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define ELSE_IF_ERROR(expr, ...) \
; \
else if (static_cast<bool>(expr)) \
[[unlikely]] g_Logger.LogCond<aster::Logger::LogType::eError>(#expr, fmt::format(__VA_ARGS__), __FILE__, __LINE__)
[[unlikely]] g_Logger.LogCond<Logger::LogType::eError>(#expr, fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define ELSE_IF_WARN(expr, ...) \
; \
else if (static_cast<bool>(expr)) \
[[unlikely]] g_Logger.LogCond<aster::Logger::LogType::eWarning>(#expr, fmt::format(__VA_ARGS__), __FILE__, __LINE__)
[[unlikely]] g_Logger.LogCond<Logger::LogType::eWarning>(#expr, fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define ELSE_IF_INFO(expr, ...) \
; \
else if (static_cast<bool>(expr)) \
g_Logger.LogCond<aster::Logger::LogType::eInfo>(#expr, fmt::format(__VA_ARGS__), __FILE__, __LINE__)
g_Logger.LogCond<Logger::LogType::eInfo>(#expr, fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define ELSE_ERROR(...) \
; \
else [[unlikely]] g_Logger.Log<aster::Logger::LogType::eError>(fmt::format(__VA_ARGS__), __FILE__, __LINE__)
else [[unlikely]] g_Logger.Log<Logger::LogType::eError>(fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define ELSE_WARN(...) \
; \
else [[unlikely]] g_Logger.Log<aster::Logger::LogType::eWarning>(fmt::format(__VA_ARGS__), __FILE__, __LINE__)
else [[unlikely]] g_Logger.Log<Logger::LogType::eWarning>(fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define ELSE_INFO(...) \
; \
else g_Logger.Log<aster::Logger::LogType::eInfo>(fmt::format(__VA_ARGS__), __FILE__, __LINE__)
else g_Logger.Log<Logger::LogType::eInfo>(fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#if !defined(DEBUG_LOG_DISABLED) && !defined(ASTER_NDEBUG)
#define DEBUG(...) g_Logger.Log<aster::Logger::LogType::eDebug>(fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define DEBUG(...) g_Logger.Log<Logger::LogType::eDebug>(fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define DEBUG_IF(expr, ...) \
if (static_cast<bool>(expr)) \
g_Logger.LogCond<aster::Logger::LogType::eDebug>(#expr, fmt::format(__VA_ARGS__), __FILE__, __LINE__)
g_Logger.LogCond<Logger::LogType::eDebug>(#expr, fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define ELSE_IF_DEBUG(expr, ...) \
; \
else if (static_cast<bool>(expr)) \
g_Logger.LogCond<aster::Logger::LogType::eDebug>(#expr, fmt::format(__VA_ARGS__), __FILE__, __LINE__)
g_Logger.LogCond<Logger::LogType::eDebug>(#expr, fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define ELSE_DEBUG(...) \
; \
else g_Logger.Log<aster::Logger::LogType::eDebug>(fmt::format(__VA_ARGS__), __FILE__, __LINE__)
else g_Logger.Log<Logger::LogType::eDebug>(fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#else // !defined(DEBUG_LOG_DISABLED)
@ -175,17 +172,17 @@ extern aster::Logger g_Logger;
#if !defined(VERBOSE_LOG_DISABLED) && !defined(ASTER_NDEBUG)
#define VERBOSE(...) g_Logger.Log<aster::Logger::LogType::eVerbose>(fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define VERBOSE(...) g_Logger.Log<Logger::LogType::eVerbose>(fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define VERBOSE_IF(expr, ...) \
if (static_cast<bool>(expr)) \
g_Logger.LogCond<aster::Logger::LogType::eVerbose>(#expr, fmt::format(__VA_ARGS__), __FILE__, __LINE__)
g_Logger.LogCond<Logger::LogType::eVerbose>(#expr, fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define ELSE_IF_VERBOSE(expr, ...) \
; \
else if (static_cast<bool>(expr)) \
g_Logger.LogCond<aster::Logger::LogType::eVerbose>(#expr, fmt::format(__VA_ARGS__), __FILE__, __LINE__)
g_Logger.LogCond<Logger::LogType::eVerbose>(#expr, fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#define ELSE_VERBOSE(...) \
; \
else g_Logger.Log<aster::Logger::LogType::eVerbose>(fmt::format(__VA_ARGS__), __FILE__, __LINE__)
else g_Logger.Log<Logger::LogType::eVerbose>(fmt::format(__VA_ARGS__), __FILE__, __LINE__)
#else // !defined(DEBUG_LOG_DISABLED)
@ -210,5 +207,5 @@ extern aster::Logger g_Logger;
#endif // !defined(VERBOSE_LOG_DISABLED)
#define DO(code) , code
#define ABORT(code) exit(static_cast<int>(code))
#define ABORT(code) exit(static_cast<i32>(code))
#define THEN_ABORT(code) , ABORT(code)

View File

@ -3,11 +3,9 @@
// Copyright (c) 2020-2025 Anish Bhobe
// =============================================
#include "aster/core/buffer.h"
#include "core/buffer.h"
#include "aster/core/device.h"
using namespace aster;
#include "core/device.h"
Buffer::Buffer(Device const *device, usize const size, vk::BufferUsageFlags const bufferUsage,
VmaAllocationCreateFlags const allocationFlags, VmaMemoryUsage const memoryUsage, cstr const name)

View File

@ -3,17 +3,15 @@
// Copyright (c) 2020-2025 Anish Bhobe
// =============================================
#include "aster/core/device.h"
#include "core/device.h"
#include "aster/core/instance.h"
#include "aster/core/physical_device.h"
#include "aster/core/queue_allocation.h"
#include "core/instance.h"
#include "core/physical_device.h"
#include "core/queue_allocation.h"
#include <EASTL/array.h>
#include <EASTL/fixed_vector.h>
using namespace aster;
// TODO: This will need to be flexible for devices that don't support some of the extensions.
constexpr eastl::array DEVICE_EXTENSIONS = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME,

View File

@ -3,7 +3,7 @@
// Copyright (c) 2020-2025 Anish Bhobe
// =============================================
#include "aster/core/global.h"
#include "core/global.h"
#include <cstdarg>
#include <cstdio>
@ -14,8 +14,6 @@
// NOTE: Vulkan Dispatch Loader Storage - Should only appear once.
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
using namespace aster;
struct MemorySize
{
u16 m_Gigabytes;

View File

@ -3,11 +3,9 @@
// Copyright (c) 2020-2025 Anish Bhobe
// =============================================
#include "aster/core/image.h"
#include "core/image.h"
#include "aster/core/device.h"
using namespace aster;
#include "core/device.h"
Image &
Image::operator=(Image &&other) noexcept

View File

@ -3,15 +3,13 @@
// Copyright (c) 2020-2025 Anish Bhobe
// =============================================
#include "aster/core/instance.h"
#include "core/instance.h"
#include "aster/core/window.h"
#include "core/window.h"
#include <EASTL/array.h>
#include <EASTL/fixed_vector.h>
using namespace aster;
VKAPI_ATTR b32 VKAPI_CALL
DebugCallback(vk::DebugUtilsMessageSeverityFlagBitsEXT const messageSeverity,
vk::DebugUtilsMessageTypeFlagsEXT const messageType,
@ -45,7 +43,7 @@ Instance::Instance(cstr const appName, Version const version, bool enableValidat
vk::ApplicationInfo const appInfo = {
.pApplicationName = appName,
.applicationVersion = version.GetVkVersion(),
.pEngineName = "aster",
.pEngineName = PROJECT_NAME,
.engineVersion = version.GetVkVersion(),
.apiVersion = ASTER_API_VERSION,
};

View File

@ -3,15 +3,13 @@
// Copyright (c) 2020-2025 Anish Bhobe
// =============================================
#include "aster/core/physical_device.h"
#include "core/physical_device.h"
#include "aster/core/instance.h"
#include "aster/core/surface.h"
using namespace aster;
#include "core/instance.h"
#include "core/surface.h"
[[nodiscard]] vk::SurfaceCapabilitiesKHR
aster::GetSurfaceCapabilities(vk::PhysicalDevice const physicalDevice, vk::SurfaceKHR const surface)
GetSurfaceCapabilities(vk::PhysicalDevice const physicalDevice, vk::SurfaceKHR const surface)
{
vk::SurfaceCapabilitiesKHR surfaceCapabilities;
@ -23,7 +21,7 @@ aster::GetSurfaceCapabilities(vk::PhysicalDevice const physicalDevice, vk::Surfa
}
[[nodiscard]] eastl::vector<vk::SurfaceFormatKHR>
aster::GetSurfaceFormats(vk::PhysicalDevice const physicalDevice, vk::SurfaceKHR const surface)
GetSurfaceFormats(vk::PhysicalDevice const physicalDevice, vk::SurfaceKHR const surface)
{
// vk::Result::eIncomplete should not occur in this function. The rest are errors. Thus, abort is allowed.
u32 count = 0;
@ -40,7 +38,7 @@ aster::GetSurfaceFormats(vk::PhysicalDevice const physicalDevice, vk::SurfaceKHR
}
[[nodiscard]] eastl::vector<vk::PresentModeKHR>
aster::GetSurfacePresentModes(vk::PhysicalDevice const physicalDevice, vk::SurfaceKHR const surface)
GetSurfacePresentModes(vk::PhysicalDevice const physicalDevice, vk::SurfaceKHR const surface)
{
// vk::Result::eIncomplete should not occur in this function. The rest are errors. Thus, abort is allowed.
u32 count = 0;

View File

@ -3,11 +3,9 @@
// Copyright (c) 2020-2025 Anish Bhobe
// =============================================
#include "aster/core/pipeline.h"
#include "core/pipeline.h"
#include "aster/core/device.h"
using namespace aster;
#include "core/device.h"
Pipeline::Pipeline(Device const *device, vk::PipelineLayout const layout, vk::Pipeline const pipeline,
eastl::vector<vk::DescriptorSetLayout> &&setLayouts, Kind const kind)

View File

@ -3,11 +3,9 @@
// Copyright (c) 2020-2025 Anish Bhobe
// =============================================
#include "aster/core/sampler.h"
#include "core/sampler.h"
#include "aster/core/device.h"
using namespace aster;
#include "core/device.h"
Sampler::~Sampler()
{

View File

@ -3,12 +3,10 @@
// Copyright (c) 2020-2025 Anish Bhobe
// =============================================
#include "aster/core/surface.h"
#include "core/surface.h"
#include "aster/core/instance.h"
#include "aster/core/window.h"
using namespace aster;
#include "core/instance.h"
#include "core/window.h"
Surface::Surface(Instance &context, Window const &window)
: m_Context(&context)

View File

@ -3,13 +3,11 @@
// Copyright (c) 2020-2025 Anish Bhobe
// ==============================================
#include "aster/core/swapchain.h"
#include "core/swapchain.h"
#include "aster/core/device.h"
#include "aster/core/physical_device.h"
#include "aster/core/surface.h"
using namespace aster;
#include "core/device.h"
#include "core/physical_device.h"
#include "core/surface.h"
[[nodiscard]] vk::Extent2D GetExtent(Size2D size, vk::SurfaceCapabilitiesKHR *surfaceCapabilities);

View File

@ -3,12 +3,10 @@
// Copyright (c) 2020-2025 Anish Bhobe
// =============================================
#include "aster/core/window.h"
#include "core/window.h"
#include "aster/core/instance.h"
#include "aster/util/logger.h"
using namespace aster;
#include "core/instance.h"
#include "util/logger.h"
std::atomic_uint64_t Window::m_WindowCount = 0;
std::atomic_bool Window::m_IsGlfwInit = false;

View File

@ -3,14 +3,14 @@
// Copyright (c) 2020-2025 Anish Bhobe
// =============================================
#include "aster/systems/commit_manager.h"
#include "systems/commit_manager.h"
#include "EASTL/array.h"
#include "aster/core/device.h"
#include "aster/core/image_view.h"
#include "aster/systems/rendering_device.h"
#include "core/device.h"
#include "core/image_view.h"
#include "systems/rendering_device.h"
using namespace aster;
using namespace systems;
CommitManager *CommitManager::m_Instance = nullptr;

View File

@ -8,8 +8,6 @@
#include "aster/systems/commit_manager.h"
#include "aster/systems/rendering_device.h"
using namespace aster;
constexpr static u32
GetFormatSize(vk::Format const format)
{
@ -131,34 +129,34 @@ GetFormatSize(vk::Format const format)
}
void
Context::KeepAlive(Ref<Buffer> const &buffer)
systems::Context::KeepAlive(Ref<Buffer> const &buffer)
{
assert(m_Pool);
m_Pool->KeepAlive(buffer);
}
void
Context::KeepAlive(Ref<Image> const &image)
systems::Context::KeepAlive(Ref<Image> const &image)
{
assert(m_Pool);
m_Pool->KeepAlive(image);
}
void
Context::KeepAlive(Ref<ImageView> const &view)
systems::Context::KeepAlive(Ref<ImageView> const &view)
{
assert(m_Pool);
m_Pool->KeepAlive(view);
}
void
Context::Dependency(vk::DependencyInfo const &dependencyInfo)
systems::Context::Dependency(vk::DependencyInfo const &dependencyInfo)
{
m_Cmd.pipelineBarrier2(&dependencyInfo);
}
void
Context::Begin()
systems::Context::Begin()
{
vk::CommandBufferBeginInfo commandBufferBeginInfo = {
.flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit,
@ -171,7 +169,7 @@ Context::Begin()
// Release versions inline 'no-op'.
#if !defined(ASTER_NDEBUG)
void
Context::BeginDebugRegion(cstr const name, vec4 const color)
systems::Context::BeginDebugRegion(cstr const name, vec4 const color)
{
vk::DebugUtilsLabelEXT const label = {
.pLabelName = name,
@ -181,21 +179,21 @@ Context::BeginDebugRegion(cstr const name, vec4 const color)
}
void
Context::EndDebugRegion()
systems::Context::EndDebugRegion()
{
m_Cmd.endDebugUtilsLabelEXT();
}
#endif
void
Context::End()
systems::Context::End()
{
auto result = m_Cmd.end();
ERROR_IF(Failed(result), "Could not end context") THEN_ABORT(result);
}
void
ComputeContext::Dispatch(Pipeline const &pipeline, u32 x, u32 y, u32 z, usize size, void *data)
systems::ComputeContext::Dispatch(Pipeline const &pipeline, u32 x, u32 y, u32 z, usize size, void *data)
{
BindPipeline(pipeline);
PushConstantBlock(0, size, data);
@ -204,7 +202,7 @@ ComputeContext::Dispatch(Pipeline const &pipeline, u32 x, u32 y, u32 z, usize si
}
void
ComputeContext::BindPipeline(Pipeline const &pipeline)
systems::ComputeContext::BindPipeline(Pipeline const &pipeline)
{
auto bindPoint = vk::PipelineBindPoint::eGraphics;
switch (pipeline.m_Kind)
@ -231,57 +229,57 @@ ComputeContext::BindPipeline(Pipeline const &pipeline)
}
void
GraphicsContext::SetViewport(vk::Viewport const &viewport)
systems::GraphicsContext::SetViewport(vk::Viewport const &viewport)
{
m_Cmd.setViewport(0, 1, &viewport);
}
void
GraphicsContext::BindVertexBuffer(Ref<VertexBuffer> const &vertexBuffer)
systems::GraphicsContext::BindVertexBuffer(Ref<VertexBuffer> const &vertexBuffer)
{
constexpr vk::DeviceSize offset = 0;
m_Cmd.bindVertexBuffers(0, 1, &vertexBuffer->m_Buffer, &offset);
}
void
GraphicsContext::BindIndexBuffer(Ref<IndexBuffer> const &indexBuffer)
systems::GraphicsContext::BindIndexBuffer(Ref<IndexBuffer> const &indexBuffer)
{
m_Cmd.bindIndexBuffer(indexBuffer->m_Buffer, 0, vk::IndexType::eUint32);
}
void
GraphicsContext::Draw(usize const vertexCount)
systems::GraphicsContext::Draw(usize const vertexCount)
{
m_Cmd.draw(static_cast<u32>(vertexCount), 1, 0, 0);
}
void
GraphicsContext::DrawIndexed(usize indexCount)
systems::GraphicsContext::DrawIndexed(usize indexCount)
{
m_Cmd.drawIndexed(static_cast<u32>(indexCount), 1, 0, 0, 0);
}
void
GraphicsContext::DrawIndexed(usize const indexCount, usize const firstIndex, usize const firstVertex)
systems::GraphicsContext::DrawIndexed(usize const indexCount, usize const firstIndex, usize const firstVertex)
{
m_Cmd.drawIndexed(static_cast<u32>(indexCount), 1, static_cast<u32>(firstIndex), static_cast<i32>(firstVertex), 0);
}
void
GraphicsContext::BeginRendering(vk::RenderingInfo const &renderingInfo)
systems::GraphicsContext::BeginRendering(vk::RenderingInfo const &renderingInfo)
{
m_Cmd.beginRendering(&renderingInfo);
m_Cmd.setScissor(0, 1, &renderingInfo.renderArea);
}
void
GraphicsContext::EndRendering()
systems::GraphicsContext::EndRendering()
{
m_Cmd.endRendering();
}
void
TransferContext::UploadTexture(Ref<Image> const &image, eastl::span<u8> const &data)
systems::TransferContext::UploadTexture(Ref<Image> const &image, eastl::span<u8> const &data)
{
ERROR_IF(not(image and image->IsValid()), "Invalid image");
@ -316,7 +314,7 @@ TransferContext::UploadTexture(Ref<Image> const &image, eastl::span<u8> const &d
}
void
TransferContext::UploadBuffer(Ref<Buffer> const &buffer, usize size, void const *data)
systems::TransferContext::UploadBuffer(Ref<Buffer> const &buffer, usize size, void const *data)
{
ERROR_IF(not(buffer and buffer->IsValid()), "Invalid buffer");
@ -335,18 +333,18 @@ TransferContext::UploadBuffer(Ref<Buffer> const &buffer, usize size, void const
}
void
TransferContext::Blit(vk::BlitImageInfo2 const &mipBlitInfo)
systems::TransferContext::Blit(vk::BlitImageInfo2 const &mipBlitInfo)
{
m_Cmd.blitImage2(&mipBlitInfo);
}
TransferContext::TransferContext(TransferContext &&other) noexcept
systems::TransferContext::TransferContext(TransferContext &&other) noexcept
: Context{std::move(other)}
{
}
TransferContext &
TransferContext::operator=(TransferContext &&other) noexcept
systems::TransferContext &
systems::TransferContext::operator=(TransferContext &&other) noexcept
{
if (this == &other)
return *this;
@ -355,7 +353,7 @@ TransferContext::operator=(TransferContext &&other) noexcept
}
void
ComputeContext::PushConstantBlock(usize const offset, usize const size, void const *data)
systems::ComputeContext::PushConstantBlock(usize const offset, usize const size, void const *data)
{
assert(m_PipelineInUse);
@ -373,7 +371,7 @@ ComputeContext::PushConstantBlock(usize const offset, usize const size, void con
m_Cmd.pushConstants(m_PipelineInUse->m_Layout, stage, static_cast<u32>(offset), static_cast<u32>(size), data);
}
using namespace _internal;
using namespace systems::_internal;
ContextPool::ContextPool(RenderingDevice &device, u32 const queueFamilyIndex, ManagedBy const managedBy)
: m_Device{&device}
@ -470,7 +468,7 @@ ContextPool::AllocateCommandBuffer()
return cmd;
}
Context
systems::Context
ContextPool::CreateContext()
{
return Context{*this, AllocateCommandBuffer()};
@ -489,19 +487,19 @@ ContextPool::Reset()
m_OwnedImageViews.clear();
}
TransferContext
systems::TransferContext
TransferContextPool::CreateTransferContext()
{
return TransferContext{*this, AllocateCommandBuffer()};
}
ComputeContext
systems::ComputeContext
ComputeContextPool::CreateComputeContext()
{
return ComputeContext{*this, AllocateCommandBuffer()};
}
GraphicsContext
systems::GraphicsContext
GraphicsContextPool::CreateGraphicsContext()
{
return GraphicsContext{*this, AllocateCommandBuffer()};

View File

@ -3,12 +3,11 @@
// Copyright (c) 2020-2025 Anish Bhobe
// =============================================
#include "aster/systems/rendering_device.h"
#include "systems/rendering_device.h"
#include <aster/systems/pipeline_helpers.h>
using namespace aster;
using namespace aster::_internal;
using namespace systems::_internal;
struct WhatVisitor
{
@ -49,39 +48,39 @@ struct ValueVisitor
};
i32
PipelineCreationError::Value()
systems::PipelineCreationError::Value()
{
return std::visit(ValueVisitor{}, m_Data);
}
PipelineCreationError::PipelineCreationError(vk::Result res)
systems::PipelineCreationError::PipelineCreationError(vk::Result res)
: m_Data{res}
{
}
PipelineCreationError::PipelineCreationError(SlangResult res)
systems::PipelineCreationError::PipelineCreationError(SlangResult res)
: m_Data{res}
{
}
PipelineCreationError::PipelineCreationError()
systems::PipelineCreationError::PipelineCreationError()
: m_Data{std::monostate{}}
{
}
PipelineCreationError::operator bool() const
systems::PipelineCreationError::operator bool() const
{
return not std::holds_alternative<std::monostate>(m_Data);
}
std::string
PipelineCreationError::What()
systems::PipelineCreationError::What()
{
return std::visit(WhatVisitor{}, m_Data);
}
vk::ShaderStageFlagBits
_internal::SlangToVulkanShaderStage(SlangStage const stage)
systems::SlangToVulkanShaderStage(SlangStage const stage)
{
switch (stage)
{

View File

@ -3,16 +3,16 @@
// Copyright (c) 2020-2025 Anish Bhobe
// =============================================
#include "aster/systems/rendering_device.h"
#include "systems/rendering_device.h"
#include "aster/core/queue_allocation.h"
#include "aster/core/window.h"
#include "aster/systems/resource.h"
#include "core/queue_allocation.h"
#include "core/window.h"
#include "systems/resource.h"
#include "aster/systems/sync_server.h"
#include "aster/util/files.h"
#include "aster/systems/commit_manager.h"
#include "aster/systems/context.h"
#include "systems/commit_manager.h"
#include "systems/context.h"
#include <EASTL/vector_map.h>
#include <fmt/ranges.h>
@ -21,39 +21,37 @@
#undef DOMAIN
#endif
using namespace aster;
static constexpr QueueSupportFlags REQUIRED_QUEUE_SUPPORT =
QueueSupportFlags{} | QueueSupportFlagBits::eGraphics | QueueSupportFlagBits::eCompute |
QueueSupportFlagBits::ePresent | QueueSupportFlagBits::eTransfer;
vk::CompareOp
DepthOpToVulkan(GraphicsPipelineCreateInfo::CompareOp depthOp)
DepthOpToVulkan(systems::GraphicsPipelineCreateInfo::CompareOp depthOp)
{
switch (depthOp)
{
case GraphicsPipelineCreateInfo::CompareOp::eNever:
case systems::GraphicsPipelineCreateInfo::CompareOp::eNever:
return vk::CompareOp::eNever;
case GraphicsPipelineCreateInfo::CompareOp::eLessThan:
case systems::GraphicsPipelineCreateInfo::CompareOp::eLessThan:
return vk::CompareOp::eLess;
case GraphicsPipelineCreateInfo::CompareOp::eEqualTo:
case systems::GraphicsPipelineCreateInfo::CompareOp::eEqualTo:
return vk::CompareOp::eEqual;
case GraphicsPipelineCreateInfo::CompareOp::eGreaterThan:
case systems::GraphicsPipelineCreateInfo::CompareOp::eGreaterThan:
return vk::CompareOp::eGreater;
case GraphicsPipelineCreateInfo::CompareOp::eLessThanOrEqualTo:
case systems::GraphicsPipelineCreateInfo::CompareOp::eLessThanOrEqualTo:
return vk::CompareOp::eLessOrEqual;
case GraphicsPipelineCreateInfo::CompareOp::eGreaterThanOrEqualTo:
case systems::GraphicsPipelineCreateInfo::CompareOp::eGreaterThanOrEqualTo:
return vk::CompareOp::eGreaterOrEqual;
case GraphicsPipelineCreateInfo::CompareOp::eNotEqualTo:
case systems::GraphicsPipelineCreateInfo::CompareOp::eNotEqualTo:
return vk::CompareOp::eNotEqual;
case GraphicsPipelineCreateInfo::CompareOp::eAlways:
case systems::GraphicsPipelineCreateInfo::CompareOp::eAlways:
return vk::CompareOp::eAlways;
}
return vk::CompareOp::eAlways;
}
vk::PipelineDepthStencilStateCreateInfo
GraphicsPipelineCreateInfo::GetDepthStencilStateCreateInfo() const
systems::GraphicsPipelineCreateInfo::GetDepthStencilStateCreateInfo() const
{
bool depthEnabled = false;
bool depthWriteEnabled = false;
@ -79,7 +77,7 @@ GraphicsPipelineCreateInfo::GetDepthStencilStateCreateInfo() const
}
PhysicalDevice
aster::DefaultPhysicalDeviceSelector(PhysicalDevices const &physicalDevices)
systems::DefaultPhysicalDeviceSelector(PhysicalDevices const &physicalDevices)
{
for (auto &physicalDevice : physicalDevices)
{
@ -109,7 +107,7 @@ aster::DefaultPhysicalDeviceSelector(PhysicalDevices const &physicalDevices)
// ====================================================================================================
Ref<StorageBuffer>
RenderingDevice::CreateStorageBuffer(usize const size, cstr const name)
systems::RenderingDevice::CreateStorageBuffer(usize const size, cstr const name)
{
// TODO: Storage and Index buffer are set.
// This is hacky and should be improved.
@ -124,7 +122,7 @@ RenderingDevice::CreateStorageBuffer(usize const size, cstr const name)
}
Ref<IndexBuffer>
RenderingDevice::CreateIndexBuffer(usize size, cstr name)
systems::RenderingDevice::CreateIndexBuffer(usize size, cstr name)
{
// TODO: Storage and Index buffer are set.
// This is hacky and should be improved.
@ -139,7 +137,7 @@ RenderingDevice::CreateIndexBuffer(usize size, cstr name)
}
Ref<UniformBuffer>
RenderingDevice::CreateUniformBuffer(usize const size, cstr const name)
systems::RenderingDevice::CreateUniformBuffer(usize const size, cstr const name)
{
constexpr vk::BufferUsageFlags usage = vk::BufferUsageFlagBits::eUniformBuffer;
constexpr VmaAllocationCreateFlags createFlags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
@ -150,7 +148,7 @@ RenderingDevice::CreateUniformBuffer(usize const size, cstr const name)
}
Ref<StagingBuffer>
RenderingDevice::CreateStagingBuffer(usize const size, cstr const name)
systems::RenderingDevice::CreateStagingBuffer(usize const size, cstr const name)
{
constexpr vk::BufferUsageFlags usage = vk::BufferUsageFlagBits::eTransferSrc;
constexpr VmaAllocationCreateFlags createFlags =
@ -160,7 +158,7 @@ RenderingDevice::CreateStagingBuffer(usize const size, cstr const name)
}
Ref<VertexBuffer>
RenderingDevice::CreateVertexBuffer(usize const size, cstr const name)
systems::RenderingDevice::CreateVertexBuffer(usize const size, cstr const name)
{
constexpr vk::BufferUsageFlags usage = vk::BufferUsageFlagBits::eVertexBuffer;
constexpr VmaAllocationCreateFlags createFlags =
@ -174,10 +172,10 @@ RenderingDevice::CreateVertexBuffer(usize const size, cstr const name)
#pragma region Image Management
// ====================================================================================================
vk::ImageCreateInfo ToImageCreateInfo(Texture2DCreateInfo const &createInfo);
vk::ImageCreateInfo ToImageCreateInfo(TextureCubeCreateInfo const &createInfo);
vk::ImageCreateInfo ToImageCreateInfo(AttachmentCreateInfo const &createInfo);
vk::ImageCreateInfo ToImageCreateInfo(DepthStencilImageCreateInfo const &createInfo);
vk::ImageCreateInfo ToImageCreateInfo(systems::Texture2DCreateInfo const &createInfo);
vk::ImageCreateInfo ToImageCreateInfo(systems::TextureCubeCreateInfo const &createInfo);
vk::ImageCreateInfo ToImageCreateInfo(systems::AttachmentCreateInfo const &createInfo);
vk::ImageCreateInfo ToImageCreateInfo(systems::DepthStencilImageCreateInfo const &createInfo);
namespace usage_flags
{
@ -191,7 +189,7 @@ constexpr vk::ImageUsageFlags DEPTH_STENCIL_ATTACHMENT = vk::ImageUsageFlagBits:
} // namespace usage_flags
Ref<Image>
RenderingDevice::CreateTexture2D(Texture2DCreateInfo const &createInfo)
systems::RenderingDevice::CreateTexture2D(Texture2DCreateInfo const &createInfo)
{
constexpr VmaAllocationCreateInfo allocationCreateInfo = {
.flags = {},
@ -223,7 +221,7 @@ RenderingDevice::CreateTexture2D(Texture2DCreateInfo const &createInfo)
}
Ref<ImageCube>
RenderingDevice::CreateTextureCube(TextureCubeCreateInfo const &createInfo)
systems::RenderingDevice::CreateTextureCube(TextureCubeCreateInfo const &createInfo)
{
constexpr VmaAllocationCreateInfo allocationCreateInfo = {
.flags = {},
@ -255,7 +253,7 @@ RenderingDevice::CreateTextureCube(TextureCubeCreateInfo const &createInfo)
}
Ref<Image>
RenderingDevice::CreateAttachment(AttachmentCreateInfo const &createInfo)
systems::RenderingDevice::CreateAttachment(AttachmentCreateInfo const &createInfo)
{
constexpr VmaAllocationCreateInfo allocationCreateInfo = {
.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT,
@ -282,7 +280,7 @@ RenderingDevice::CreateAttachment(AttachmentCreateInfo const &createInfo)
}
Ref<Image>
RenderingDevice::CreateDepthStencilImage(DepthStencilImageCreateInfo const &createInfo)
systems::RenderingDevice::CreateDepthStencilImage(DepthStencilImageCreateInfo const &createInfo)
{
constexpr VmaAllocationCreateInfo allocationCreateInfo = {
.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT,
@ -309,7 +307,7 @@ RenderingDevice::CreateDepthStencilImage(DepthStencilImageCreateInfo const &crea
}
vk::ImageCreateInfo
ToImageCreateInfo(Texture2DCreateInfo const &createInfo)
ToImageCreateInfo(systems::Texture2DCreateInfo const &createInfo)
{
auto &[format, extent, name, isSampled, isMipMapped, isStorage] = createInfo;
@ -337,7 +335,7 @@ ToImageCreateInfo(Texture2DCreateInfo const &createInfo)
}
vk::ImageCreateInfo
ToImageCreateInfo(TextureCubeCreateInfo const &createInfo)
ToImageCreateInfo(systems::TextureCubeCreateInfo const &createInfo)
{
auto &[format, side, name, isSampled, isMipMapped, isStorage] = createInfo;
@ -365,7 +363,7 @@ ToImageCreateInfo(TextureCubeCreateInfo const &createInfo)
}
vk::ImageCreateInfo
ToImageCreateInfo(AttachmentCreateInfo const &createInfo)
ToImageCreateInfo(systems::AttachmentCreateInfo const &createInfo)
{
auto &[format, extent, name] = createInfo;
@ -382,7 +380,7 @@ ToImageCreateInfo(AttachmentCreateInfo const &createInfo)
}
vk::ImageCreateInfo
ToImageCreateInfo(DepthStencilImageCreateInfo const &createInfo)
ToImageCreateInfo(systems::DepthStencilImageCreateInfo const &createInfo)
{
auto &[extent, name] = createInfo;
@ -406,7 +404,7 @@ ToImageCreateInfo(DepthStencilImageCreateInfo const &createInfo)
// ====================================================================================================
Ref<ImageView>
RenderingDevice::CreateView(ViewCreateInfo<Image> const &createInfo)
systems::RenderingDevice::CreateView(ViewCreateInfo<Image> const &createInfo)
{
auto const layerCount = createInfo.GetLayerCount();
auto const mipCount = createInfo.GetMipLevelCount();
@ -434,7 +432,7 @@ RenderingDevice::CreateView(ViewCreateInfo<Image> const &createInfo)
// ====================================================================================================
Ref<TextureView>
RenderingDevice::CreateTexture2DWithView(Texture2DCreateInfo const &createInfo)
systems::RenderingDevice::CreateTexture2DWithView(Texture2DCreateInfo const &createInfo)
{
return CreateView<TextureView>({
.m_Image = CastImage<Texture>(CreateTexture2D(createInfo)),
@ -445,7 +443,7 @@ RenderingDevice::CreateTexture2DWithView(Texture2DCreateInfo const &createInfo)
}
Ref<ImageCubeView>
RenderingDevice::CreateTextureCubeWithView(TextureCubeCreateInfo const &createInfo)
systems::RenderingDevice::CreateTextureCubeWithView(TextureCubeCreateInfo const &createInfo)
{
return CreateView<ImageCubeView>({
.m_Image = CreateTextureCube(createInfo),
@ -456,7 +454,7 @@ RenderingDevice::CreateTextureCubeWithView(TextureCubeCreateInfo const &createIn
}
Ref<ImageView>
RenderingDevice::CreateAttachmentWithView(AttachmentCreateInfo const &createInfo)
systems::RenderingDevice::CreateAttachmentWithView(AttachmentCreateInfo const &createInfo)
{
return CreateView({
.m_Image = CreateAttachment(createInfo),
@ -467,7 +465,7 @@ RenderingDevice::CreateAttachmentWithView(AttachmentCreateInfo const &createInfo
}
Ref<ImageView>
RenderingDevice::CreateDepthStencilImageWithView(DepthStencilImageCreateInfo const &createInfo)
systems::RenderingDevice::CreateDepthStencilImageWithView(DepthStencilImageCreateInfo const &createInfo)
{
return CreateView({
.m_Image = CreateDepthStencilImage(createInfo),
@ -484,7 +482,7 @@ RenderingDevice::CreateDepthStencilImageWithView(DepthStencilImageCreateInfo con
// ====================================================================================================
Ref<Sampler>
RenderingDevice::CreateSampler(SamplerCreateInfo const &createInfo)
systems::RenderingDevice::CreateSampler(SamplerCreateInfo const &createInfo)
{
auto vkCreateInfo = static_cast<vk::SamplerCreateInfo>(createInfo);
@ -503,8 +501,8 @@ RenderingDevice::CreateSampler(SamplerCreateInfo const &createInfo)
// Pipelines
// ----------------------------------------------------------------------------------------------------
PipelineCreationError
RenderingDevice::CreateGraphicsPipeline(Pipeline &pipelineOut, GraphicsPipelineCreateInfo const &createInfo)
systems::PipelineCreationError
systems::RenderingDevice::CreateGraphicsPipeline(Pipeline &pipelineOut, GraphicsPipelineCreateInfo const &createInfo)
{
eastl::fixed_vector<vk::PipelineShaderStageCreateInfo, ShaderTypeCount, false> shaders;
Slang::ComPtr<slang::IComponentType> program;
@ -642,8 +640,8 @@ RenderingDevice::CreateGraphicsPipeline(Pipeline &pipelineOut, GraphicsPipelineC
return {};
}
PipelineCreationError
RenderingDevice::CreateComputePipeline(Pipeline &pipelineOut, ComputePipelineCreateInfo const &createInfo)
systems::PipelineCreationError
systems::RenderingDevice::CreateComputePipeline(Pipeline &pipelineOut, ComputePipelineCreateInfo const &createInfo)
{
eastl::fixed_vector<vk::PipelineShaderStageCreateInfo, ShaderTypeCount, false> shaders;
Slang::ComPtr<slang::IComponentType> program;
@ -700,8 +698,8 @@ RenderingDevice::CreateComputePipeline(Pipeline &pipelineOut, ComputePipelineCre
ERROR("Unimplemented Stage " #STAGE); \
return SLANG_FAIL
PipelineCreationError
RenderingDevice::CreateShaders(
systems::PipelineCreationError
systems::RenderingDevice::CreateShaders(
eastl::fixed_vector<vk::PipelineShaderStageCreateInfo, ShaderTypeCount, false> &shadersOut,
Slang::ComPtr<slang::IComponentType> &program, std::span<ShaderInfo const> const &shaders)
{
@ -838,7 +836,7 @@ RenderingDevice::CreateShaders(
if (auto entryPointReflection = progLayout->getEntryPointByIndex(entryPoint))
{
outShader.pName = entryPointReflection->getName();
outShader.stage = _internal::SlangToVulkanShaderStage(entryPointReflection->getStage());
outShader.stage = SlangToVulkanShaderStage(entryPointReflection->getStage());
}
}
@ -872,20 +870,20 @@ RenderingDevice::CreateShaders(
struct PipelineLayoutBuilder
{
RenderingDevice *m_Device;
systems::RenderingDevice *m_Device;
eastl::vector<vk::DescriptorSetLayout> m_DescriptorSetLayouts;
eastl::vector<vk::PushConstantRange> m_PushConstantRanges;
explicit PipelineLayoutBuilder(RenderingDevice *device)
explicit PipelineLayoutBuilder(systems::RenderingDevice *device)
: m_Device{device}
{
}
PipelineCreationError
systems::PipelineCreationError
Build(vk::PipelineLayout &pipelineLayout, eastl::vector<vk::DescriptorSetLayout> &descriptorSetLayouts);
};
PipelineCreationError
systems::PipelineCreationError
PipelineLayoutBuilder::Build(vk::PipelineLayout &pipelineLayout,
eastl::vector<vk::DescriptorSetLayout> &descriptorSetLayouts)
{
@ -903,8 +901,8 @@ PipelineLayoutBuilder::Build(vk::PipelineLayout &pipelineLayout,
return result;
}
PipelineCreationError
RenderingDevice::CreatePipelineLayout(vk::PipelineLayout &pipelineLayout,
systems::PipelineCreationError
systems::RenderingDevice::CreatePipelineLayout(vk::PipelineLayout &pipelineLayout,
Slang::ComPtr<slang::IComponentType> const &program)
{
using Slang::ComPtr;
@ -995,7 +993,7 @@ FindAsyncComputeQueue(PhysicalDevice const &physicalDevice, u32 primaryQueueFami
return std::nullopt;
}
RenderingDevice::RenderingDevice(DeviceCreateInfo const &createInfo)
systems::RenderingDevice::RenderingDevice(DeviceCreateInfo const &createInfo)
: m_Window{createInfo.m_Window}
, m_SyncServer{new _internal::SyncServer{*this}}
{
@ -1112,7 +1110,7 @@ RenderingDevice::RenderingDevice(DeviceCreateInfo const &createInfo)
}
}
RenderingDevice::~RenderingDevice()
systems::RenderingDevice::~RenderingDevice()
{
for (auto &frame : m_Frames)
{
@ -1127,8 +1125,8 @@ RenderingDevice::~RenderingDevice()
#pragma region Frames
// ====================================================================================================
Frame &
RenderingDevice::GetNextFrame()
systems::Frame &
systems::RenderingDevice::GetNextFrame()
{
if (m_CommitManager)
m_CommitManager->Update();
@ -1169,7 +1167,7 @@ RenderingDevice::GetNextFrame()
}
void
RenderingDevice::Present(Frame &frame, GraphicsContext &graphicsContext)
systems::RenderingDevice::Present(Frame &frame, GraphicsContext &graphicsContext)
{
vk::PipelineStageFlags waitDstStage = vk::PipelineStageFlagBits::eColorAttachmentOutput;
vk::SubmitInfo const submitInfo = {
@ -1207,20 +1205,20 @@ RenderingDevice::Present(Frame &frame, GraphicsContext &graphicsContext)
}
}
TransferContext
RenderingDevice::CreateTransferContext()
systems::TransferContext
systems::RenderingDevice::CreateTransferContext()
{
return m_TransferContextPool.CreateTransferContext();
}
ComputeContext
RenderingDevice::CreateComputeContext()
systems::ComputeContext
systems::RenderingDevice::CreateComputeContext()
{
return m_ComputeContextPool.CreateComputeContext();
}
Receipt
RenderingDevice::Submit(Context &context)
systems::Receipt
systems::RenderingDevice::Submit(Context &context)
{
auto const rect = m_SyncServer->Allocate();
auto &entry = m_SyncServer->GetEntry(rect);
@ -1256,13 +1254,13 @@ RenderingDevice::Submit(Context &context)
}
void
RenderingDevice::WaitOn(Receipt recpt)
systems::RenderingDevice::WaitOn(Receipt recpt)
{
m_SyncServer->WaitOn(recpt);
}
void
Frame::Reset(u32 imageIdx, vk::Image swapchainImage, vk::ImageView swapchainImageView, Size2D swapchainSize)
systems::Frame::Reset(u32 imageIdx, vk::Image swapchainImage, vk::ImageView swapchainImageView, Size2D swapchainSize)
{
AbortIfFailedMV(m_Device->m_Device->resetFences(1, &m_FrameAvailableFence), "Fence {} reset failed.", m_FrameIdx);
@ -1276,33 +1274,33 @@ Frame::Reset(u32 imageIdx, vk::Image swapchainImage, vk::ImageView swapchainImag
m_SwapchainSize = swapchainSize;
}
GraphicsContext
Frame::CreateGraphicsContext()
systems::GraphicsContext
systems::Frame::CreateGraphicsContext()
{
return m_PrimaryPool.CreateGraphicsContext();
}
TransferContext
Frame::CreateAsyncTransferContext()
systems::TransferContext
systems::Frame::CreateAsyncTransferContext()
{
return m_AsyncTransferPool.CreateTransferContext();
}
ComputeContext
Frame::CreateAsyncComputeContext()
systems::ComputeContext
systems::Frame::CreateAsyncComputeContext()
{
return m_AsyncComputePool.CreateComputeContext();
}
void
Frame::WaitUntilReady()
systems::Frame::WaitUntilReady()
{
AbortIfFailedMV(m_Device->m_Device->waitForFences(1, &m_FrameAvailableFence, true, MaxValue<u64>),
"Waiting for fence {} failed.", m_FrameIdx);
}
Frame &
Frame::operator=(Frame &&other) noexcept
systems::Frame &
systems::Frame::operator=(Frame &&other) noexcept
{
if (this == &other)
return *this;
@ -1321,7 +1319,7 @@ Frame::operator=(Frame &&other) noexcept
return *this;
}
Frame::Frame(RenderingDevice &device, u32 frameIndex, u32 const primaryQueueFamily,
systems::Frame::Frame(RenderingDevice &device, u32 frameIndex, u32 const primaryQueueFamily,
u32 const asyncTransferQueue, u32 const asyncComputeQueue)
: m_Device{&device}
, m_PrimaryPool{device, primaryQueueFamily, _internal::ContextPool::ManagedBy::eFrame}
@ -1350,7 +1348,7 @@ Frame::Frame(RenderingDevice &device, u32 frameIndex, u32 const primaryQueueFami
DEBUG("Frame {} created successfully.", frameIndex);
}
Frame::Frame(Frame &&other) noexcept
systems::Frame::Frame(Frame &&other) noexcept
: m_Device{Take(other.m_Device)}
, m_PrimaryPool{std::move(other.m_PrimaryPool)}
, m_AsyncTransferPool{std::move(other.m_AsyncTransferPool)}

View File

@ -7,8 +7,7 @@
#include "aster/systems/rendering_device.h"
using namespace aster;
using namespace aster::_internal;
using namespace systems::_internal;
SyncServer::Entry::Entry(RenderingDevice &device)
: m_CurrentPoint{0, 1}
@ -68,7 +67,7 @@ SyncServer::Entry::AttachPool(ContextPool *pool)
m_AttachedPool = pool;
}
Receipt
systems::Receipt
SyncServer::Allocate()
{
auto &entry = AllocateEntry();

View File

@ -5,10 +5,8 @@
#include "aster/util/files.h"
using namespace aster;
eastl::vector<u32>
aster::ReadFile(std::string_view fileName)
ReadFile(std::string_view fileName)
{
FILE *filePtr = fopen(fileName.data(), "rb");
@ -34,7 +32,7 @@ aster::ReadFile(std::string_view fileName)
}
eastl::vector<u8>
aster::ReadFileBytes(std::string_view fileName, bool errorOnFail)
ReadFileBytes(std::string_view fileName, bool errorOnFail)
{
FILE *filePtr = fopen(fileName.data(), "rb");
@ -63,7 +61,7 @@ aster::ReadFileBytes(std::string_view fileName, bool errorOnFail)
}
bool
aster::WriteFileBytes(std::string_view fileName, eastl::span<u8> const data)
WriteFileBytes(std::string_view fileName, eastl::span<u8> const data)
{
FILE *filePtr = fopen(fileName.data(), "wb");

View File

@ -3,9 +3,9 @@
// Copyright (c) 2020-2025 Anish Bhobe
// =============================================
#include "aster/util/logger.h"
#include "util/logger.h"
auto g_Logger = aster::Logger();
auto g_Logger = Logger();
// ReSharper disable once CppInconsistentNaming
/* Credits to Const-me */

View File

@ -5,10 +5,10 @@ cmake_minimum_required(VERSION 3.13)
find_package(imgui CONFIG REQUIRED)
add_library(util_helper STATIC
"helpers.h"
"helpers.cpp"
"frame.cpp"
"frame.h"
"gui.cpp"
"gui.h")

174
samples/00_util/frame.cpp Normal file
View File

@ -0,0 +1,174 @@
// =============================================
// Aster: frame.cpp
// Copyright (c) 2020-2025 Anish Bhobe
// =============================================
#include "frame.h"
#include "aster/core/device.h"
#include "aster/core/swapchain.h"
#include "helpers.h"
Frame::Frame(const Device *device, const u32 queueFamilyIndex, const u32 frameCount)
: m_FrameIdx(frameCount)
, m_ImageIdx(0)
{
m_Device = device;
eastl::fixed_string<char, 50, false> name = "Frame ";
name += static_cast<char>('0' + frameCount);
const vk::CommandPoolCreateInfo commandPoolCreateInfo = {
.flags = vk::CommandPoolCreateFlagBits::eTransient,
.queueFamilyIndex = queueFamilyIndex,
};
AbortIfFailedMV(device->m_Device.createCommandPool(&commandPoolCreateInfo, nullptr, &m_Pool),
"Could not command pool for frame {}", frameCount);
constexpr vk::FenceCreateInfo fenceCreateInfo = {.flags = vk::FenceCreateFlagBits::eSignaled};
AbortIfFailedMV(device->m_Device.createFence(&fenceCreateInfo, nullptr, &m_FrameAvailableFence),
"Could not create a fence for frame {}", frameCount);
constexpr vk::SemaphoreCreateInfo semaphoreCreateInfo = {};
AbortIfFailedMV(device->m_Device.createSemaphore(&semaphoreCreateInfo, nullptr, &m_ImageAcquireSem),
"Could not create IA semaphore for frame {}.", frameCount);
AbortIfFailedMV(device->m_Device.createSemaphore(&semaphoreCreateInfo, nullptr, &m_RenderFinishSem),
"Could not create RF semaphore for frame {}.", frameCount);
const vk::CommandBufferAllocateInfo allocateInfo = {
.commandPool = m_Pool,
.level = vk::CommandBufferLevel::ePrimary,
.commandBufferCount = 1,
};
AbortIfFailed(m_Device->m_Device.allocateCommandBuffers(&allocateInfo, &m_CommandBuffer));
device->SetName(m_Pool, name.c_str());
device->SetName(m_FrameAvailableFence, name.c_str());
device->SetName(m_ImageAcquireSem, name.c_str());
device->SetName(m_RenderFinishSem, name.c_str());
device->SetName(m_CommandBuffer, name.c_str());
DEBUG("Frame {} created successfully.", frameCount);
}
void
Frame::Present(const vk::Queue commandQueue, Swapchain *swapchain, const Surface *surface, Size2D size)
{
vk::PresentInfoKHR presentInfo = {
.waitSemaphoreCount = 1,
.pWaitSemaphores = &m_RenderFinishSem,
.swapchainCount = 1,
.pSwapchains = &swapchain->m_Swapchain,
.pImageIndices = &m_ImageIdx,
.pResults = nullptr,
};
switch (auto result = commandQueue.presentKHR(&presentInfo))
{
case vk::Result::eSuccess:
break;
case vk::Result::eErrorOutOfDateKHR:
case vk::Result::eSuboptimalKHR:
DEBUG("Recreating Swapchain. Cause: {}", result);
swapchain->Create(*surface, size);
break; // Present failed. We do nothing. Frame is skipped.
default:
AbortIfFailedM(result, "Swapchain Present failed.");
}
}
Frame::~Frame()
{
m_Device->m_Device.destroy(m_RenderFinishSem, nullptr);
m_Device->m_Device.destroy(m_ImageAcquireSem, nullptr);
m_Device->m_Device.destroy(m_FrameAvailableFence, nullptr);
m_Device->m_Device.destroy(m_Pool, nullptr);
DEBUG("Destoryed Frame");
}
Frame::Frame(Frame &&other) noexcept
: m_Device(other.m_Device)
, m_Pool(Take(other.m_Pool))
, m_CommandBuffer(Take(other.m_CommandBuffer))
, m_FrameAvailableFence(Take(other.m_FrameAvailableFence))
, m_ImageAcquireSem(Take(other.m_ImageAcquireSem))
, m_RenderFinishSem(Take(other.m_RenderFinishSem))
, m_FrameIdx(other.m_FrameIdx)
, m_ImageIdx(other.m_ImageIdx)
{
}
Frame &
Frame::operator=(Frame &&other) noexcept
{
if (this == &other)
return *this;
m_Device = other.m_Device;
m_Pool = Take(other.m_Pool);
m_CommandBuffer = Take(other.m_CommandBuffer);
m_FrameAvailableFence = Take(other.m_FrameAvailableFence);
m_ImageAcquireSem = Take(other.m_ImageAcquireSem);
m_RenderFinishSem = Take(other.m_RenderFinishSem);
m_FrameIdx = other.m_FrameIdx;
m_ImageIdx = other.m_ImageIdx;
return *this;
}
// Frame Manager
FrameManager::FrameManager(const Device *device, u32 queueFamilyIndex, u32 framesInFlight)
: m_Device(device)
, m_FramesInFlight(framesInFlight)
{
for (u32 i = 0; i < framesInFlight; ++i)
{
m_Frames.emplace_back(device, queueFamilyIndex, i);
}
}
Frame *
FrameManager::GetNextFrame(Swapchain *swapchain, const Surface *surface, Size2D size)
{
Frame *currentFrame = &m_Frames[m_CurrentFrameIdx];
u32 frameIndex = m_CurrentFrameIdx;
m_CurrentFrameIdx = (m_CurrentFrameIdx + 1) % m_FramesInFlight;
AbortIfFailedMV(m_Device->m_Device.waitForFences(1, &currentFrame->m_FrameAvailableFence, true, MaxValue<u64>),
"Waiting for fence {} failed.", frameIndex);
u32 imageIndex = 0;
bool imageAcquired = false;
while (!imageAcquired)
{
auto result = m_Device->m_Device.acquireNextImageKHR(swapchain->m_Swapchain, MaxValue<u64>,
currentFrame->m_ImageAcquireSem, nullptr, &imageIndex);
switch (result)
{
case vk::Result::eSuccess:
case vk::Result::eSuboptimalKHR: // Suboptimal can still render. Better to let this go for semaphores etc.
imageAcquired = true;
break; // Image acquired. Break out of loop.
case vk::Result::eErrorOutOfDateKHR:
DEBUG("Recreating Swapchain. Cause: {}", result);
swapchain->Create(*surface, size);
break; // Image acquire has failed. We move to the next frame.
default:
AbortIfFailedMV(result, "Waiting for swapchain image {} failed.", frameIndex);
}
}
// Reset fences here. In case swapchain was out of date, we leave the fences signalled.
AbortIfFailedMV(m_Device->m_Device.resetFences(1, &currentFrame->m_FrameAvailableFence), "Fence {} reset failed.",
frameIndex);
AbortIfFailedMV(m_Device->m_Device.resetCommandPool(currentFrame->m_Pool, {}), "Command pool {} reset failed.",
frameIndex);
currentFrame->m_ImageIdx = imageIndex;
return currentFrame;
}

55
samples/00_util/frame.h Normal file
View File

@ -0,0 +1,55 @@
// =============================================
// Aster: frame.h
// Copyright (c) 2020-2025 Anish Bhobe
// =============================================
#pragma once
#include "aster/aster.h"
#include "helpers.h"
#include "aster/core/size.h"
#include <EASTL/fixed_vector.h>
struct Device;
struct Window;
struct Swapchain;
struct Surface;
struct Frame
{
// Persistent
const Device *m_Device;
vk::CommandPool m_Pool;
vk::CommandBuffer m_CommandBuffer;
vk::Fence m_FrameAvailableFence;
vk::Semaphore m_ImageAcquireSem;
vk::Semaphore m_RenderFinishSem;
u32 m_FrameIdx;
// Transient
u32 m_ImageIdx;
void Present(vk::Queue commandQueue, Swapchain *swapchain, const Surface *surface, Size2D size);
Frame(const Device *device, u32 queueFamilyIndex, u32 frameCount);
~Frame();
Frame(Frame &&other) noexcept;
Frame &operator=(Frame &&other) noexcept;
DISALLOW_COPY_AND_ASSIGN(Frame);
};
struct FrameManager
{
const Device *m_Device;
eastl::fixed_vector<Frame, 4> m_Frames{};
u32 m_CurrentFrameIdx = 0;
u32 m_FramesInFlight = 0;
FrameManager(const Device *device, u32 queueFamilyIndex, u32 framesInFlight);
Frame *GetNextFrame(Swapchain *swapchain, const Surface *surface, Size2D size);
};

View File

@ -5,7 +5,11 @@
#include "gui.h"
#include "aster/aster.h"
#include "aster/core/device.h"
#include "aster/core/instance.h"
#include "aster/core/window.h"
#include "aster/systems/rendering_device.h"
#include "helpers.h"
#include <imgui_impl_glfw.h>
#include <imgui_impl_vulkan.h>
@ -23,10 +27,8 @@ VulkanAssert(VkResult result)
}
void
Init(aster::RenderingDevice &device, aster::Window &window)
Init(systems::RenderingDevice &device, Window &window)
{
using namespace aster;
g_AttachmentFormat = device.m_Swapchain.m_Format;
eastl::vector<vk::DescriptorPoolSize> poolSizes = {
@ -91,7 +93,72 @@ Init(aster::RenderingDevice &device, aster::Window &window)
}
void
Destroy(aster::RenderingDevice const &device)
Init(Instance const *context, Device const *device, Window const *window, vk::Format attachmentFormat,
u32 const imageCount, u32 const queueFamily, vk::Queue const queue)
{
g_AttachmentFormat = attachmentFormat;
eastl::vector<vk::DescriptorPoolSize> poolSizes = {
{vk::DescriptorType::eSampler, 1000},
{vk::DescriptorType::eCombinedImageSampler, 1000},
{vk::DescriptorType::eSampledImage, 1000},
{vk::DescriptorType::eStorageImage, 1000},
{vk::DescriptorType::eUniformTexelBuffer, 1000},
{vk::DescriptorType::eStorageTexelBuffer, 1000},
{vk::DescriptorType::eUniformBuffer, 1000},
{vk::DescriptorType::eStorageBuffer, 1000},
{vk::DescriptorType::eUniformBufferDynamic, 1000},
{vk::DescriptorType::eStorageBufferDynamic, 1000},
{vk::DescriptorType::eInputAttachment, 1000},
};
vk::DescriptorPoolCreateInfo const descriptorPoolCreateInfo = {
.flags = vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet,
.maxSets = 1000,
.poolSizeCount = static_cast<u32>(poolSizes.size()),
.pPoolSizes = poolSizes.data(),
};
AbortIfFailed(device->m_Device.createDescriptorPool(&descriptorPoolCreateInfo, nullptr, &g_DescriptorPool));
IMGUI_CHECKVERSION();
CreateContext();
ImGuiIO &io = GetIO();
(void)io;
// io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
// io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Viewports bad
StyleColorsDark();
ImGui_ImplGlfw_InitForVulkan(window->m_Window, true);
vk::PipelineRenderingCreateInfo renderingCreateInfo = {
.colorAttachmentCount = 1,
.pColorAttachmentFormats = &g_AttachmentFormat,
};
ImGui_ImplVulkan_InitInfo imguiVulkanInitInfo = {
.Instance = context->m_Instance,
.PhysicalDevice = device->m_PhysicalDevice,
.Device = device->m_Device,
.QueueFamily = queueFamily,
.Queue = queue,
.DescriptorPool = g_DescriptorPool,
.MinImageCount = imageCount,
.ImageCount = imageCount,
.PipelineCache = nullptr,
.UseDynamicRendering = true,
.PipelineRenderingCreateInfo = renderingCreateInfo,
.Allocator = nullptr,
.CheckVkResultFn = VulkanAssert,
};
ImGui_ImplVulkan_Init(&imguiVulkanInitInfo);
ImGui_ImplVulkan_CreateFontsTexture();
}
void
Destroy(systems::RenderingDevice const &device)
{
ImGui_ImplVulkan_Shutdown();
ImGui_ImplGlfw_Shutdown();
@ -100,6 +167,16 @@ Destroy(aster::RenderingDevice const &device)
device.m_Device->destroy(Take(g_DescriptorPool), nullptr);
}
void
Destroy(Device const *device)
{
ImGui_ImplVulkan_Shutdown();
ImGui_ImplGlfw_Shutdown();
DestroyContext();
device->m_Device.destroy(Take(g_DescriptorPool), nullptr);
}
void
StartBuild()
{
@ -200,7 +277,7 @@ Draw(vk::CommandBuffer const commandBuffer, vk::Extent2D const extent, vk::Image
}
void
Draw(aster::Frame &frame, aster::GraphicsContext &context)
Draw(systems::Frame &frame, systems::GraphicsContext &context)
{
context.BeginDebugRegion("UI Pass", {0.9f, 0.9f, 1.0f, 1.0f});

View File

@ -10,12 +10,13 @@
#include <imgui.h>
namespace aster
{
struct Device;
struct Instance;
struct Window;
struct Swapchain;
namespace systems
{
class RenderingDevice;
class GraphicsContext;
struct Frame;
@ -24,13 +25,17 @@ struct Frame;
// ReSharper disable once CppInconsistentNaming
namespace ImGui
{
void Init(aster::RenderingDevice &device, aster::Window &window);
void Destroy(const aster::RenderingDevice &device);
void Init(systems::RenderingDevice &device, Window &window);
void Init(const Instance *context, const Device *device, const Window *window, vk::Format attachmentFormat,
u32 imageCount, u32 queueFamily, vk::Queue queue);
void Destroy(const systems::RenderingDevice &device);
void Destroy(const Device *device);
void Recreate();
void StartBuild();
void EndBuild();
void Draw(aster::Frame &frame, aster::GraphicsContext &context);
void Draw(vk::CommandBuffer commandBuffer, vk::Extent2D extent, vk::ImageView view);
void Draw(systems::Frame &frame, systems::GraphicsContext &context);
void PushDisable();
void PopDisable();

View File

@ -0,0 +1,64 @@
// =============================================
// Aster: helpers.cpp
// Copyright (c) 2020-2025 Anish Bhobe
// =============================================
#include "helpers.h"
#include "aster/core/device.h"
#include "aster/core/physical_device.h"
#include <EASTL/array.h>
constexpr QueueSupportFlags REQUIRED_QUEUE_SUPPORT = QueueSupportFlags{} | QueueSupportFlagBits::eGraphics |
QueueSupportFlagBits::eCompute | QueueSupportFlagBits::ePresent |
QueueSupportFlagBits::eTransfer;
bool
IsSuitableDevice(PhysicalDevice const *physicalDevice)
{
bool const hasAllRequiredQueues =
std::ranges::any_of(physicalDevice->m_QueueFamilies, [](auto const &queueFamilyProp) {
return (queueFamilyProp.m_Support & REQUIRED_QUEUE_SUPPORT) == REQUIRED_QUEUE_SUPPORT;
});
bool const isNotCpu = physicalDevice->m_DeviceProperties.deviceType != vk::PhysicalDeviceType::eCpu;
bool const hasPresentMode = !physicalDevice->m_PresentModes.empty();
bool const hasSurfaceFormat = !physicalDevice->m_SurfaceFormats.empty();
return hasSurfaceFormat && hasPresentMode && isNotCpu && hasAllRequiredQueues;
}
PhysicalDevice
FindSuitableDevice(PhysicalDevices const &physicalDevices)
{
for (auto &physicalDevice : physicalDevices)
{
if (IsSuitableDevice(&physicalDevice))
{
return physicalDevice;
}
}
ERROR("No suitable GPU available on the system.")
THEN_ABORT(vk::Result::eErrorUnknown);
}
QueueAllocation
FindAppropriateQueueAllocation(PhysicalDevice const *physicalDevice)
{
for (auto &queueFamilyInfo : physicalDevice->m_QueueFamilies)
{
if ((queueFamilyInfo.m_Support & REQUIRED_QUEUE_SUPPORT) == REQUIRED_QUEUE_SUPPORT)
{
return {
.m_Family = queueFamilyInfo.m_Index,
.m_Count = queueFamilyInfo.m_Count,
};
}
}
ERROR("No suitable queue family on the GPU.")
THEN_ABORT(vk::Result::eErrorUnknown);
}

46
samples/00_util/helpers.h Normal file
View File

@ -0,0 +1,46 @@
// =============================================
// Aster: helpers.h
// Copyright (c) 2020-2025 Anish Bhobe
// =============================================
#pragma once
#include "aster/aster.h"
#include "aster/core/queue_allocation.h"
#include "EASTL/span.h"
#include <EASTL/vector.h>
#include <glm/gtc/matrix_transform.hpp>
struct PhysicalDevice;
class PhysicalDevices;
PhysicalDevice FindSuitableDevice(const PhysicalDevices &physicalDevices);
QueueAllocation FindAppropriateQueueAllocation(const PhysicalDevice *physicalDevice);
template <usize TSize>
using StackString = eastl::fixed_string<char, TSize, false>;
#define AbortIfFailed(RESULT) \
do \
{ \
vk::Result _checkResultValue_; \
ERROR_IF(Failed(_checkResultValue_ = static_cast<vk::Result>(RESULT)), "Cause: {}", _checkResultValue_) \
THEN_ABORT(_checkResultValue_); \
} while (false)
#define AbortIfFailedMV(RESULT, MSG, EXTRA) \
do \
{ \
vk::Result _checkResultValue_; \
ERROR_IF(Failed(_checkResultValue_ = static_cast<vk::Result>(RESULT)), MSG " Cause: {}", EXTRA, _checkResultValue_) \
THEN_ABORT(_checkResultValue_); \
} while (false)
#define AbortIfFailedM(RESULT, MSG) \
do \
{ \
auto _checkResultValue_ = static_cast<vk::Result>(RESULT); \
ERROR_IF(Failed(_checkResultValue_), MSG " Cause: {}", _checkResultValue_) THEN_ABORT(_checkResultValue_); \
} while (false)

View File

@ -4,9 +4,19 @@
// =============================================
#include "aster/aster.h"
#include "aster/import_types.h"
#include "aster/core/buffer.h"
#include "aster/core/constants.h"
#include "aster/core/instance.h"
#include "aster/core/physical_device.h"
#include "aster/core/pipeline.h"
#include "aster/core/swapchain.h"
#include "aster/core/window.h"
#include "aster/core/pipeline.h"
#include "aster/systems/rendering_device.h"
#include "aster/util/files.h"
#include "helpers.h"
#include <EASTL/array.h>
@ -17,19 +27,19 @@ struct Vertex
vec3 m_Position;
vec3 m_Color;
static eastl::vector<aster::AttributeInfo>
static eastl::vector<systems::AttributeInfo>
GetAttributes()
{
return {
{
.m_Location = 0,
.m_Offset = offsetof(Vertex, m_Position),
.m_Format = aster::AttributeInfo::Format::eFloat32X3,
.m_Format = systems::AttributeInfo::Format::eFloat32X3,
},
{
.m_Location = 1,
.m_Offset = offsetof(Vertex, m_Color),
.m_Format = aster::AttributeInfo::Format::eFloat32X3,
.m_Format = systems::AttributeInfo::Format::eFloat32X3,
},
};
}
@ -38,12 +48,10 @@ struct Vertex
int
main(int, char **)
{
using namespace aster;
MIN_LOG_LEVEL(Logger::LogType::eInfo);
Window window = {"Triangle (Aster)", {640, 480}};
RenderingDevice device{{
systems::RenderingDevice device{{
.m_Window = window,
.m_Features = {.m_Vulkan12Features = {.bufferDeviceAddress = true},
.m_Vulkan13Features = {.synchronization2 = true, .dynamicRendering = true}},
@ -118,7 +126,7 @@ main(int, char **)
INFO("Starting loop");
while (window.Poll())
{
aster::Frame &currentFrame = device.GetNextFrame();
systems::Frame &currentFrame = device.GetNextFrame();
Size2D swapchainSize = currentFrame.m_SwapchainSize;

View File

@ -25,8 +25,6 @@ constexpr auto VERTEX_SHADER_FILE = "shader/box.vs.hlsl.spv";
constexpr auto FRAGMENT_SHADER_FILE = "shader/box.ps.hlsl.spv";
constexpr auto SHADER_FILE = "box";
using namespace aster;
struct ImageFile
{
void *m_Data = nullptr;
@ -119,7 +117,7 @@ main(int, char **)
.m_Vulkan13Features = {.synchronization2 = true, .dynamicRendering = true},
};
RenderingDevice device{{
systems::RenderingDevice device{{
.m_Window = window,
.m_Features = enabledDeviceFeatures,
.m_AppName = "Box",
@ -334,11 +332,11 @@ main(int, char **)
{
uptr m_VertexBuffer;
uptr m_Camera;
ResId<TextureView> m_Texture;
systems::ResId<TextureView> m_Texture;
};
static_assert(sizeof(PCB) == 24);
auto &commitManager = CommitManager::Instance();
auto &commitManager = systems::CommitManager::Instance();
PCB pcb = {
.m_VertexBuffer = vbo->GetDeviceAddress(),

View File

@ -8,6 +8,7 @@
#include "aster/core/image.h"
#include "asset_loader.h"
#include "helpers.h"
#include "aster/systems/commit_manager.h"
#include "aster/systems/rendering_device.h"
@ -26,8 +27,6 @@
#undef LoadImage
#endif
using namespace aster;
constexpr vk::CommandBufferBeginInfo OneTimeCmdBeginInfo = {.flags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit};
vec4
@ -141,7 +140,7 @@ AssetLoader::LoadHdrImage(cstr path, cstr name) const
auto context = m_Device->CreateTransferContext();
context.Begin();
eastl::fixed_string<char, 128> loadActionName = "Load: ";
StackString<128> loadActionName = "Load: ";
loadActionName += name ? name : path;
context.BeginDebugRegion(loadActionName.c_str());
@ -162,7 +161,7 @@ AssetLoader::LoadHdrImage(cstr path, cstr name) const
}
void
GenerateMipMaps(TransferContext &context, Ref<Texture> const &texture, vk::ImageLayout initialLayout,
GenerateMipMaps(systems::TransferContext &context, Ref<Texture> const &texture, vk::ImageLayout initialLayout,
vk::ImageLayout finalLayout, vk::PipelineStageFlags2 prevStage, vk::PipelineStageFlags2 finalStage)
{
#if !defined(ASTER_NDEBUG)
@ -331,8 +330,8 @@ GenerateMipMaps(TransferContext &context, Ref<Texture> const &texture, vk::Image
#endif
}
ResId<TextureView>
AssetLoader::LoadImageToGpu(TransferContext &context, tinygltf::Image *image, bool isSrgb, cstr name) const
systems::ResId<TextureView>
AssetLoader::LoadImageToGpu(systems::TransferContext &context, tinygltf::Image *image, bool isSrgb, cstr name) const
{
// TODO(Something not loading properly).
@ -359,7 +358,7 @@ AssetLoader::LoadImageToGpu(TransferContext &context, tinygltf::Image *image, bo
.m_IsStorage = false,
});
eastl::fixed_string<char,128> loadActionName = "Load: ";
StackString<128> loadActionName = "Load: ";
loadActionName += assignedName;
context.BeginDebugRegion(loadActionName.c_str());
@ -468,11 +467,11 @@ AssetLoader::LoadModelToGpu(cstr path, cstr name)
context.Begin();
eastl::fixed_string<char,128> loadActionName = "Load: ";
StackString<128> loadActionName = "Load: ";
loadActionName += name ? name : path;
context.BeginDebugRegion(loadActionName.c_str());
eastl::hash_map<i32, ResId<TextureView>> textureHandleMap;
eastl::hash_map<i32, systems::ResId<TextureView>> textureHandleMap;
eastl::vector<Material> materials;
Ref<Buffer> materialsBuffer;
@ -481,10 +480,10 @@ AssetLoader::LoadModelToGpu(cstr path, cstr name)
{
// TODO("Something broken on load here.");
auto getTextureHandle = [this, &context, &textureHandleMap,
&model](i32 index, bool const isSrgb) -> ResId<TextureView> {
&model](i32 index, bool const isSrgb) -> systems::ResId<TextureView> {
if (index < 0)
{
return NullId{};
return systems::NullId{};
}
if (auto const iter = textureHandleMap.find(index); iter != textureHandleMap.end())
{
@ -805,8 +804,8 @@ AssetLoader::LoadModelToGpu(cstr path, cstr name)
nodeBuffer->Write(0, nodes.GetGlobalTransformByteSize(), nodes.GetGlobalTransformPtr());
#pragma region Staging / Transfer / Uploads
ResId<Buffer> positionBufferHandle = ResId<Buffer>::Null();
ResId<Buffer> vertexDataHandle = ResId<Buffer>::Null();
systems::ResId<Buffer> positionBufferHandle = systems::ResId<Buffer>::Null();
systems::ResId<Buffer> vertexDataHandle = systems::ResId<Buffer>::Null();
Ref<IndexBuffer> indexBuffer;
auto positionBuffer = m_Device->CreateStorageBuffer(vertexPositions.size() * sizeof vertexPositions[0]);
@ -816,7 +815,7 @@ AssetLoader::LoadModelToGpu(cstr path, cstr name)
context.UploadBuffer(vertexDataBuffer, vertexData);
// TODO: Index buffer needs to be separated.
indexBuffer = CastBuffer<IndexBuffer>(
indexBuffer = systems::CastBuffer<IndexBuffer>(
m_Device->CreateIndexBuffer(indices.size() * sizeof indices[0], "Index Buffer"));
context.UploadBuffer(indexBuffer, indices);
@ -840,7 +839,7 @@ AssetLoader::LoadModelToGpu(cstr path, cstr name)
auto handlesBuffer = m_Device->CreateStorageBuffer(sizeof handlesData, "Materials");
handlesBuffer->Write(0, sizeof handlesData, &handlesData);
eastl::vector<ResId<TextureView>> textureHandles;
eastl::vector<systems::ResId<TextureView>> textureHandles;
textureHandles.reserve(textureHandleMap.size());
for (auto &[key, val] : textureHandleMap)
@ -853,7 +852,7 @@ AssetLoader::LoadModelToGpu(cstr path, cstr name)
};
}
Model::Model(eastl::vector<ResId<TextureView>> &textureHandles, Nodes &&nodes, Ref<Buffer> nodeBuffer,
Model::Model(eastl::vector<systems::ResId<TextureView>> &textureHandles, Nodes &&nodes, Ref<Buffer> nodeBuffer,
ModelHandles &handles, Ref<Buffer> modelHandlesBuffer, Ref<IndexBuffer> indexBuffer,
eastl::vector<MeshPrimitive> const &meshPrimitives)
: m_TextureHandles(std::move(textureHandles))
@ -887,7 +886,7 @@ Model::Update()
}
}
AssetLoader::AssetLoader(RenderingDevice &device)
AssetLoader::AssetLoader(systems::RenderingDevice &device)
: m_Device{&device}
{
}

View File

@ -13,7 +13,12 @@
#include "nodes.h"
#include "tiny_gltf.h"
namespace aster
namespace systems
{
class TransferContext;
}
namespace systems
{
class RenderingDevice;
class ResourceManager;
@ -21,9 +26,6 @@ class SamplerManager;
class BufferManager;
class ImageManager;
class CommitManager;
class TransferContext;
struct Image;
struct Texture;
} // namespace systems
namespace tinygltf
@ -31,6 +33,9 @@ namespace tinygltf
struct Image;
}
struct Image;
struct Texture;
constexpr auto GLTF_ASCII_FILE_EXTENSION = ".gltf";
constexpr auto GLTF_BINARY_FILE_EXTENSION = ".glb";
@ -47,11 +52,11 @@ struct Material
{
vec4 m_AlbedoFactor; // 16 16
vec4 m_EmissionFactor; // 16 32
aster::ResId<aster::TextureView> m_AlbedoTex; // 08 40
aster::ResId<aster::TextureView> m_NormalTex; // 08 48
aster::ResId<aster::TextureView> m_MetalRoughTex; // 08 56
aster::ResId<aster::TextureView> m_OcclusionTex; // 08 64
aster::ResId<aster::TextureView> m_EmissionTex; // 08 72
systems::ResId<TextureView> m_AlbedoTex; // 08 40
systems::ResId<TextureView> m_NormalTex; // 08 48
systems::ResId<TextureView> m_MetalRoughTex; // 08 56
systems::ResId<TextureView> m_OcclusionTex; // 08 64
systems::ResId<TextureView> m_EmissionTex; // 08 72
f32 m_MetalFactor; // 04 76
f32 m_RoughFactor; // 04 80
};
@ -66,7 +71,7 @@ struct VertexData
struct Model
{
eastl::vector<aster::ResId<aster::TextureView>> m_TextureHandles;
eastl::vector<systems::ResId<TextureView>> m_TextureHandles;
Nodes m_Nodes;
struct ModelHandlesData
@ -79,10 +84,10 @@ struct Model
struct ModelHandles
{
aster::Ref<aster::Buffer> m_VertexPositionHandle;
aster::Ref<aster::Buffer> m_VertexDataHandle;
aster::Ref<aster::Buffer> m_MaterialsHandle;
aster::Ref<aster::Buffer> m_NodeHandle;
Ref<Buffer> m_VertexPositionHandle;
Ref<Buffer> m_VertexDataHandle;
Ref<Buffer> m_MaterialsHandle;
Ref<Buffer> m_NodeHandle;
operator ModelHandlesData() const
{
@ -95,17 +100,17 @@ struct Model
}
} m_Handles;
aster::Ref<aster::Buffer> m_NodeBuffer;
aster::Ref<aster::IndexBuffer> m_IndexBuffer;
aster::Ref<aster::Buffer> m_ModelHandlesBuffer;
Ref<Buffer> m_NodeBuffer;
Ref<IndexBuffer> m_IndexBuffer;
Ref<Buffer> m_ModelHandlesBuffer;
eastl::vector<MeshPrimitive> m_MeshPrimitives;
[[nodiscard]] mat4 const &GetModelTransform() const;
void SetModelTransform(mat4 const &transform);
void Update();
Model(eastl::vector<aster::ResId<aster::TextureView>> &textureHandles, Nodes &&nodes, aster::Ref<aster::Buffer> nodeBuffer,
ModelHandles &handles, aster::Ref<aster::Buffer> modelHandlesBuffer, aster::Ref<aster::IndexBuffer> indexBuffer,
Model(eastl::vector<systems::ResId<TextureView>> &textureHandles, Nodes &&nodes, Ref<Buffer> nodeBuffer,
ModelHandles &handles, Ref<Buffer> modelHandlesBuffer, Ref<IndexBuffer> indexBuffer,
eastl::vector<MeshPrimitive> const &meshPrimitives);
~Model() = default;
@ -118,9 +123,9 @@ struct Model
struct AssetLoader
{
aster::RenderingDevice *m_Device;
systems::RenderingDevice *m_Device;
aster::Ref<aster::TextureView> LoadHdrImage(cstr path, cstr name = nullptr) const;
Ref<TextureView> LoadHdrImage(cstr path, cstr name = nullptr) const;
Model LoadModelToGpu(cstr path, cstr name = nullptr);
constexpr static auto ANormal = "NORMAL";
@ -132,32 +137,32 @@ struct AssetLoader
constexpr static auto AJoints0 = "JOINTS_0";
constexpr static auto AWeights0 = "WEIGHTS_0";
explicit AssetLoader(aster::RenderingDevice &device);
explicit AssetLoader(systems::RenderingDevice &device);
private:
aster::ResId<aster::TextureView>
LoadImageToGpu(aster::TransferContext &context, tinygltf::Image *image, bool isSrgb, cstr name = nullptr) const;
systems::ResId<TextureView>
LoadImageToGpu(systems::TransferContext &context, tinygltf::Image *image, bool isSrgb, cstr name = nullptr) const;
};
void
GenerateMipMaps(aster::TransferContext &context, aster::Ref<aster::Texture> const &textureView, vk::ImageLayout initialLayout,
GenerateMipMaps(systems::TransferContext &context, Ref<Texture> const &textureView, vk::ImageLayout initialLayout,
vk::ImageLayout finalLayout, vk::PipelineStageFlags2 prevStage, vk::PipelineStageFlags2 finalStage);
void
GenerateMipMaps(aster::TransferContext &context, aster::concepts::ImageRefTo<aster::Texture> auto &texture,
GenerateMipMaps(systems::TransferContext &context, concepts::ImageRefTo<Texture> auto &texture,
vk::ImageLayout initialLayout, vk::ImageLayout finalLayout,
vk::PipelineStageFlags2 prevStage = vk::PipelineStageFlagBits2::eAllCommands,
vk::PipelineStageFlags2 finalStage = vk::PipelineStageFlagBits2::eAllCommands)
{
GenerateMipMaps(context, aster::CastImage<aster::Texture>(texture), initialLayout, finalLayout, prevStage, finalStage);
GenerateMipMaps(context, systems::CastImage<Texture>(texture), initialLayout, finalLayout, prevStage, finalStage);
}
void
GenerateMipMaps(aster::TransferContext &context, aster::concepts::ViewRefTo<aster::Texture> auto &texture,
GenerateMipMaps(systems::TransferContext &context, concepts::ViewRefTo<Texture> auto &texture,
vk::ImageLayout initialLayout, vk::ImageLayout finalLayout,
vk::PipelineStageFlags2 prevStage = vk::PipelineStageFlagBits2::eAllCommands,
vk::PipelineStageFlags2 finalStage = vk::PipelineStageFlagBits2::eAllCommands)
{
GenerateMipMaps(context, aster::CastImage<aster::Texture>(texture->m_Image), initialLayout, finalLayout, prevStage,
GenerateMipMaps(context, systems::CastImage<Texture>(texture->m_Image), initialLayout, finalLayout, prevStage,
finalStage);
}

View File

@ -9,6 +9,7 @@
#include "aster/core/image.h"
#include "asset_loader.h"
#include "helpers.h"
#include "aster/systems/commit_manager.h"
#include "aster/systems/rendering_device.h"
@ -22,12 +23,10 @@ constexpr auto DIFFUSE_IRRADIANCE_ENTRY = "diffuseIrradiance";
constexpr auto PREFILTER_ENTRY = "prefilter";
constexpr auto BRDF_LUT_ENTRY = "brdfLut";
using namespace aster;
Environment
CreateCubeFromHdrEnv(AssetLoader &assetLoader, u32 const cubeSide, ResId<TextureView> hdrEnv)
CreateCubeFromHdrEnv(AssetLoader &assetLoader, u32 const cubeSide, systems::ResId<TextureView> hdrEnv)
{
RenderingDevice &device = *assetLoader.m_Device;
systems::RenderingDevice &device = *assetLoader.m_Device;
auto *commitManager = device.m_CommitManager.get();
auto skybox = device.CreateTextureCubeWithView<StorageTextureCubeView>({
@ -63,12 +62,12 @@ CreateCubeFromHdrEnv(AssetLoader &assetLoader, u32 const cubeSide, ResId<Texture
});
auto prefilterHandle = commitManager->CommitTexture(prefilterCube); // This stores the original view for us.
constexpr u32 prefilterMipCountMax = 6;
eastl::fixed_vector<ResId<StorageImageView>, prefilterMipCountMax> prefilterStorageHandles;
eastl::fixed_vector<systems::ResId<StorageImageView>, prefilterMipCountMax> prefilterStorageHandles;
// All non-owning copies.
for (u8 mipLevel = 0; mipLevel < prefilterMipCountMax; ++mipLevel)
{
auto view = device.CreateView<StorageTextureCubeView>({
.m_Image = CastImage<StorageTextureCube>(prefilterCube->m_Image),
.m_Image = systems::CastImage<StorageTextureCube>(prefilterCube->m_Image),
.m_ViewType = vk::ImageViewType::eCube,
.m_AspectMask = vk::ImageAspectFlagBits::eColor,
.m_MipLevelCount = 1,
@ -179,27 +178,27 @@ CreateCubeFromHdrEnv(AssetLoader &assetLoader, u32 const cubeSide, ResId<Texture
struct SkyboxPushConstants
{
ResId<TextureView> m_HdrEnvHandle;
ResId<StorageImageView> m_OutputTexture;
systems::ResId<TextureView> m_HdrEnvHandle;
systems::ResId<StorageImageView> m_OutputTexture;
u32 m_CubeSide;
};
struct DiffuseIrradiancePushConstants
{
ResId<TextureView> m_SkyboxHandle;
ResId<StorageImageView> m_OutputTexture;
systems::ResId<TextureView> m_SkyboxHandle;
systems::ResId<StorageImageView> m_OutputTexture;
u32 m_CubeSide;
};
struct PrefilterPushConstants
{
ResId<TextureView> m_SkyboxHandle;
ResId<StorageImageView> m_OutputTexture;
systems::ResId<TextureView> m_SkyboxHandle;
systems::ResId<StorageImageView> m_OutputTexture;
u32 m_CubeSide;
f32 m_Roughness;
u32 m_EnvSide;
};
struct BrdfLutPushConstants
{
ResId<StorageImageView> m_OutputTexture;
systems::ResId<StorageImageView> m_OutputTexture;
};
#pragma region Pipeline Creation etc
@ -333,7 +332,7 @@ CreateCubeFromHdrEnv(AssetLoader &assetLoader, u32 const cubeSide, ResId<Texture
};
PrefilterPushConstants prefilterPushConstants = {
.m_SkyboxHandle = skyboxHandle,
.m_OutputTexture = NullId{},
.m_OutputTexture = systems::NullId{},
.m_EnvSide = cubeSide,
};
BrdfLutPushConstants brdfLutPushConstants = {

View File

@ -6,23 +6,21 @@
#pragma once
#include "aster/aster.h"
#include "aster/import_types.h"
#include "aster/core/image.h"
#include "aster/core/image_view.h"
#include "aster/systems/resource.h"
namespace aster
{
struct Pipeline;
struct Texture;
struct TextureCube;
} // namespace aster
struct AssetLoader;
struct Environment
{
aster::ResId<aster::TextureView> m_Skybox;
aster::ResId<aster::TextureView> m_Diffuse;
aster::ResId<aster::TextureView> m_Prefilter;
aster::ResId<aster::TextureView> m_BrdfLut;
systems::ResId<TextureView> m_Skybox;
systems::ResId<TextureView> m_Diffuse;
systems::ResId<TextureView> m_Prefilter;
systems::ResId<TextureView> m_BrdfLut;
};
Environment CreateCubeFromHdrEnv(AssetLoader &assetLoader, u32 cubeSide, aster::ResId<aster::TextureView> hdrEnv);
Environment CreateCubeFromHdrEnv(AssetLoader &assetLoader, u32 cubeSide, systems::ResId<TextureView> hdrEnv);

View File

@ -55,7 +55,7 @@ ToColor32(vec3 const &col)
return r << 24 | g << 16 | b << 8 | a;
}
LightManager::LightManager(aster::RenderingDevice &device)
LightManager::LightManager(systems::RenderingDevice &device)
: m_Device{&device}
, m_DirectionalLightCount{}
, m_PointLightCount{}

View File

@ -6,16 +6,20 @@
#pragma once
#include "aster/aster.h"
#include "aster/import_types.h"
// TODO: Separate files so you only import handles.
#include "aster/core/buffer.h"
#include "aster/systems/resource.h"
#include <EASTL/vector.h>
namespace aster
namespace systems
{
class RenderingDevice;
}
namespace systems
{
class ResourceManager;
class CommitManager;
} // namespace systems
@ -85,9 +89,9 @@ struct LightManager
u16 m_UnusedPadding0 = 0; // 02 16
};
aster::RenderingDevice *m_Device;
systems::RenderingDevice *m_Device;
eastl::vector<Light> m_Lights;
aster::Ref<aster::Buffer> m_LightBuffer;
Ref<Buffer> m_LightBuffer;
// We don't need a Directional Light free list. We will just brute force iterate.
u16 m_DirectionalLightCount;
@ -110,7 +114,7 @@ struct LightManager
~LightManager() = default;
explicit LightManager(aster::RenderingDevice &device);
explicit LightManager(systems::RenderingDevice &device);
LightManager(LightManager &&other) noexcept = default;
LightManager &operator=(LightManager &&other) noexcept = default;

View File

@ -133,8 +133,6 @@ struct CameraController
int
main(int, char **)
{
using namespace aster;
MIN_LOG_LEVEL(Logger::LogType::eInfo);
Window window = {"ModelRender (Aster)", {INIT_WIDTH, INIT_HEIGHT}};
@ -170,7 +168,7 @@ main(int, char **)
};
auto pipelineCacheData = ReadFileBytes(PIPELINE_CACHE_FILE, false);
RenderingDevice device{{
systems::RenderingDevice device{{
.m_Window = window,
.m_Features = enabledDeviceFeatures,
.m_AppName = "ModelRender",
@ -209,8 +207,8 @@ main(int, char **)
.m_ShaderFile = BACKGROUND_SHADER_FILE,
.m_EntryPoints = {"vsmain", "fsmain"},
}},
.m_DepthTest = GraphicsPipelineCreateInfo::DepthTest::eReadOnly,
.m_DepthOp = GraphicsPipelineCreateInfo::CompareOp::eLessThanOrEqualTo,
.m_DepthTest = systems::GraphicsPipelineCreateInfo::DepthTest::eReadOnly,
.m_DepthOp = systems::GraphicsPipelineCreateInfo::CompareOp::eLessThanOrEqualTo,
.m_Name = "Background",
}))
{

View File

@ -6,7 +6,6 @@
#pragma once
#include "aster/aster.h"
#include "aster/import_types.h"
#include <EASTL/vector.h>