yes
This commit is contained in:
49
Runtime/Includes/Renderer/Memory/Block.h
git.filemode.normal_file
49
Runtime/Includes/Renderer/Memory/Block.h
git.filemode.normal_file
@@ -0,0 +1,49 @@
|
||||
#ifndef __SCOP_VULKAN_MEMORY_BLOCK__
|
||||
#define __SCOP_VULKAN_MEMORY_BLOCK__
|
||||
|
||||
#include <kvf.h>
|
||||
#include <algorithm>
|
||||
|
||||
namespace Scop
|
||||
{
|
||||
class MemoryBlock
|
||||
{
|
||||
friend class MemoryChunk;
|
||||
|
||||
public:
|
||||
MemoryBlock() = default;
|
||||
|
||||
[[nodiscard]] inline bool operator==(const MemoryBlock& rhs) const noexcept
|
||||
{
|
||||
return memory == rhs.memory &&
|
||||
offset == rhs.offset &&
|
||||
size == rhs.size &&
|
||||
free == rhs.free &&
|
||||
map == rhs.map;
|
||||
}
|
||||
|
||||
inline void Swap(MemoryBlock& rhs) noexcept
|
||||
{
|
||||
std::swap(memory, rhs.memory);
|
||||
std::swap(offset, rhs.offset);
|
||||
std::swap(size, rhs.size);
|
||||
std::swap(map, rhs.map);
|
||||
std::swap(free, rhs.free);
|
||||
}
|
||||
|
||||
~MemoryBlock() = default;
|
||||
|
||||
public:
|
||||
VkDeviceMemory memory = VK_NULL_HANDLE;
|
||||
VkDeviceSize offset = 0;
|
||||
VkDeviceSize size = 0;
|
||||
void* map = nullptr; // useless if it's a GPU allocation
|
||||
|
||||
private:
|
||||
bool free = false;
|
||||
};
|
||||
|
||||
constexpr MemoryBlock NULL_MEMORY_BLOCK{};
|
||||
}
|
||||
|
||||
#endif
|
||||
39
Runtime/Includes/Renderer/Memory/Chunk.h
git.filemode.normal_file
39
Runtime/Includes/Renderer/Memory/Chunk.h
git.filemode.normal_file
@@ -0,0 +1,39 @@
|
||||
#ifndef __SCOP_VULKAN_MEMORY_CHUNK__
|
||||
#define __SCOP_VULKAN_MEMORY_CHUNK__
|
||||
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
#include <Renderer/Memory/Block.h>
|
||||
|
||||
namespace Scop
|
||||
{
|
||||
class MemoryChunk
|
||||
{
|
||||
public:
|
||||
MemoryChunk(VkDevice device, VkPhysicalDevice physical, VkDeviceSize size, std::int32_t memory_type_index, bool is_dedicated, std::uint32_t& vram_usage, std::uint32_t& vram_host_visible_usage);
|
||||
|
||||
[[nodiscard]] std::optional<MemoryBlock> Allocate(VkDeviceSize size, VkDeviceSize alignment);
|
||||
void Deallocate(const MemoryBlock& block);
|
||||
[[nodiscard]] inline bool Has(const MemoryBlock& block) const noexcept { return block.memory == m_memory; }
|
||||
[[nodiscard]] inline std::int32_t GetMemoryTypeIndex() const noexcept { return m_memory_type_index; }
|
||||
[[nodiscard]] inline bool IsDedicated() const noexcept { return m_is_dedicated; }
|
||||
[[nodiscard]] inline void* GetMap() const noexcept { return p_map; }
|
||||
[[nodiscard]] inline VkDeviceSize GetSize() const noexcept { return m_size; }
|
||||
|
||||
~MemoryChunk();
|
||||
|
||||
protected:
|
||||
std::vector<MemoryBlock> m_blocks;
|
||||
VkDevice m_device = VK_NULL_HANDLE;
|
||||
VkPhysicalDevice m_physical = VK_NULL_HANDLE;
|
||||
VkDeviceMemory m_memory = VK_NULL_HANDLE;
|
||||
void* p_map = nullptr;
|
||||
VkDeviceSize m_size = 0;
|
||||
std::int32_t m_memory_type_index;
|
||||
bool m_is_dedicated;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
52
Runtime/Includes/Renderer/Memory/DeviceAllocator.h
git.filemode.normal_file
52
Runtime/Includes/Renderer/Memory/DeviceAllocator.h
git.filemode.normal_file
@@ -0,0 +1,52 @@
|
||||
#ifndef __SCOP_VULKAN_MEMORY_DEVICE_ALLOCATOR__
|
||||
#define __SCOP_VULKAN_MEMORY_DEVICE_ALLOCATOR__
|
||||
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
|
||||
#include <Renderer/Memory/Block.h>
|
||||
#include <Renderer/Memory/Chunk.h>
|
||||
|
||||
namespace Scop
|
||||
{
|
||||
constexpr std::size_t SMALL_HEAP_MAX_SIZE = (1024ULL * 1024 * 1024); // 1GB
|
||||
constexpr std::size_t DEFAULT_LARGE_HEAP_BLOCK_SIZE = (256ULL * 1024 * 1024); // 256MiB
|
||||
constexpr std::uint32_t NEW_BLOCK_SIZE_SHIFT_MAX = 3;
|
||||
|
||||
class DeviceAllocator
|
||||
{
|
||||
public:
|
||||
DeviceAllocator() = default;
|
||||
|
||||
void AttachToDevice(VkDevice device, VkPhysicalDevice physical) noexcept;
|
||||
inline void DetachFromDevice() noexcept { m_chunks.clear(); m_device = VK_NULL_HANDLE; m_physical = VK_NULL_HANDLE; }
|
||||
[[nodiscard]] inline std::size_t GetAllocationsCount() const noexcept { return m_allocations_count; }
|
||||
|
||||
[[nodiscard]] MemoryBlock Allocate(VkDeviceSize size, VkDeviceSize alignment, std::int32_t memory_type_index, bool dedicated_chunk = false);
|
||||
void Deallocate(const MemoryBlock& block);
|
||||
|
||||
[[nodiscard]] inline std::uint32_t GetVramUsage() const noexcept { return m_vram_usage; }
|
||||
[[nodiscard]] inline std::uint32_t GetVramHostVisibleUsage() const noexcept { return m_vram_host_visible_usage; }
|
||||
|
||||
~DeviceAllocator() = default;
|
||||
|
||||
private:
|
||||
VkDeviceSize CalcPreferredChunkSize(std::uint32_t mem_type_index);
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<MemoryChunk>> m_chunks;
|
||||
VkPhysicalDeviceMemoryProperties m_mem_props;
|
||||
VkDevice m_device = VK_NULL_HANDLE;
|
||||
VkPhysicalDevice m_physical = VK_NULL_HANDLE;
|
||||
std::size_t m_allocations_count = 0;
|
||||
std::mutex m_alloc_mutex;
|
||||
std::mutex m_dealloc_mutex;
|
||||
std::uint32_t m_vram_usage = 0;
|
||||
std::uint32_t m_vram_host_visible_usage = 0;
|
||||
bool m_last_chunk_creation_failed = false;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user