// ============================================= // Aster: buffer.h // Copyright (c) 2020-2024 Anish Bhobe // ============================================= #pragma once #include "global.h" struct Device; struct Buffer { vk::Buffer m_Buffer = nullptr; VmaAllocation m_Allocation = nullptr; // If the buffer is host visible, it should be (and stay) mapped. u8 *m_Mapped = nullptr; [[nodiscard]] usize GetSize() const; [[nodiscard]] bool IsHostVisible() const; [[nodiscard]] bool IsValid() const; [[nodiscard]] bool IsMapped() const; [[nodiscard]] bool IsOwned() const; void Destroy(const Device *device); void Write(const Device *device, usize offset, usize size, const void *data); void Allocate(const Device *device, usize size, vk::BufferUsageFlags bufferUsage, VmaAllocationCreateFlags allocationFlags, VmaMemoryUsage memoryUsage, cstr name); // Buffer.size is used for bookkeeping // If the buffer is Invalid, the remaining data in Buffer is used intrusively by `GpuResourceManager`. usize m_Size_ = 0; constexpr static usize VALID_BUFFER_BIT = Cast(1llu << 63); constexpr static usize OWNED_BIT = 1llu << 62; constexpr static usize SIZE_MASK = ~(VALID_BUFFER_BIT | OWNED_BIT); }; // Ensure that m_Size doesn't get used intrusively since it manages the state. static_assert(offsetof(Buffer, m_Size_) > sizeof(usize)); struct UniformBuffer : Buffer { void Init(const Device *device, usize size, cstr name = nullptr); }; struct StorageBuffer : Buffer { void Init(const Device *device, usize size, bool hostVisible, cstr name = nullptr); }; struct VertexBuffer : Buffer { void Init(const Device *device, usize size, cstr name = nullptr); void Write(const Device *device, void *data, usize size, usize offset) const = delete; }; struct IndexBuffer : Buffer { void Init(const Device *device, usize size, cstr name = nullptr); void Write(const Device *device, void *data, usize size, usize offset) const = delete; }; struct StagingBuffer : Buffer { void Init(const Device *device, usize size, cstr name = nullptr); }; inline usize Buffer::GetSize() const { return m_Size_ & SIZE_MASK; } inline bool Buffer::IsHostVisible() const { return IsMapped(); } inline bool Buffer::IsValid() const { return m_Size_ & VALID_BUFFER_BIT; } inline bool Buffer::IsMapped() const { return m_Mapped; } inline bool Buffer::IsOwned() const { return m_Size_ & OWNED_BIT; }