Added new BufferManager.

1. Added a new Manager template and buffer manager.
2. Fixed all warnings.
This commit is contained in:
Anish Bhobe 2025-02-20 00:05:48 +01:00
parent 7d906e08f8
commit cba6c580cf
19 changed files with 256 additions and 25 deletions

View File

@ -25,7 +25,7 @@
#if !defined(NDEBUG)
#define VULKAN_HPP_ASSERT(expr) DEBUG_IF(!(expr), "Vulkan assert failed")
#endif
#endif
#include <EASTL/fixed_string.h>
#include <EASTL/string.h>
#include <vk_mem_alloc.h>
@ -40,6 +40,12 @@ constexpr u32 ASTER_API_VERSION = VK_API_VERSION_1_3;
CLASS_NAME(const CLASS_NAME &other) = delete; \
CLASS_NAME &operator=(const CLASS_NAME &other) = delete
#define PIN_MEMORY(CLASS_NAME) \
CLASS_NAME(const CLASS_NAME &other) = delete; \
CLASS_NAME(CLASS_NAME &&other) noexcept = delete; \
CLASS_NAME &operator=(const CLASS_NAME &other) = delete; \
CLASS_NAME &operator=(CLASS_NAME &&other) noexcept = delete
#define Take(ELEMENT) eastl::exchange(ELEMENT, {})
#define TODO(MSG) assert(false && ("Unimplemented: " MSG))

View File

@ -0,0 +1,8 @@
# CMakeList.txt ; CMake project for Aster Util Headers
cmake_minimum_required(VERSION 3.13)
target_sources(aster_core
INTERFACE
"manager.h"
"buffer_manager.h")

View File

@ -0,0 +1,21 @@
// =============================================
// Aster: manager.h
// Copyright (c) 2020-2024 Anish Bhobe
// =============================================
#pragma once
#include "aster/aster.h"
#include "aster/core/buffer.h"
#include "manager.h"
namespace systems
{
class BufferManager final : public Manager<Buffer>
{
public:
BufferManager(const Device *device, const u32 maxCount);
Ref CreateStorageBuffer(usize size, cstr name = nullptr);
};
} // namespace systems

View File

@ -0,0 +1,147 @@
// =============================================
// Aster: manager.h
// Copyright (c) 2020-2024 Anish Bhobe
// =============================================
#pragma once
#include "aster/aster.h"
#include <EASTL/intrusive_ptr.h>
struct Device;
template <typename T>
requires std::is_default_constructible_v<T>
class Manager
{
using InternalType = T;
public:
struct Type : InternalType
{
void
AddRef()
{
m_Instance->AddRef(this);
}
void
Release()
{
m_Instance->Release(this);
}
u32
GetIndex()
{
return m_Instance->GetIndex(this);
}
};
static_assert(sizeof(Type) == sizeof(InternalType));
using Ref = eastl::intrusive_ptr<Type>;
static Manager *Instance();
explicit Manager(const Device *device, const u32 maxCount)
: m_MaxCount{maxCount}
, m_FreeHead{0}
, m_Device{device}
{
m_Data = new Type[m_MaxCount];
m_RefCount = new u32[m_MaxCount];
for (u32 i = 0; i < m_MaxCount; ++i)
{
m_RefCount[i] = (i + 1);
}
}
virtual ~Manager()
{
if (!m_Data)
return;
for (u32 i = 0; i < m_MaxCount; ++i)
{
m_Data[i].Destroy(m_Device);
}
delete[] m_Data;
delete[] m_RefCount;
m_Data = nullptr;
m_RefCount = nullptr;
m_MaxCount = 0;
m_FreeHead = 0;
m_Device = nullptr;
}
PIN_MEMORY(Manager);
void
AddRef(Type *p)
{
auto index = GetIndex(p);
++m_RefCount[index];
}
void
Release(Type *p)
{
assert(p->IsValid());
auto index = GetIndex(p);
auto rc = --m_RefCount[index];
// Overflow case.
assert(rc != MaxValue<u32>);
if (rc == 0)
{
p->Destroy(m_Device);
m_RefCount[index] = m_FreeHead;
m_FreeHead = index;
}
}
u32
GetIndex(Type *p)
{
auto index = p - m_Data;
assert(index >= 0 && index < m_MaxCount);
return Cast<u32>(index);
}
private:
Type *m_Data = nullptr;
u32 *m_RefCount = nullptr;
u32 m_MaxCount = 0;
u32 m_FreeHead = 0;
static Manager *m_Instance;
protected:
const Device *m_Device;
void
SetInstance(Manager *instance)
{
assert(!m_Instance);
m_Instance = instance;
}
Ref
Alloc()
{
ERROR_IF(m_FreeHead >= m_MaxCount, "Max buffers allocated.") THEN_ABORT(-1);
const auto index = m_FreeHead;
m_FreeHead = m_RefCount[index];
m_RefCount[index] = 0;
return Ref{&m_Data[index]};
}
};

View File

@ -5,7 +5,7 @@
#pragma once
#include "core/constants.h"
#include "aster/core/constants.h"
#include <debugbreak.h>
#include <fmt/core.h>

View File

@ -3,4 +3,5 @@
cmake_minimum_required(VERSION 3.13)
add_subdirectory("core")
add_subdirectory("systems")
add_subdirectory("util")

View File

@ -44,7 +44,8 @@ Buffer::Allocate(const Device *device, usize size, vk::BufferUsageFlags bufferUs
vk::MemoryPropertyFlags memoryPropertyFlags;
vmaGetAllocationMemoryProperties(device->m_Allocator, allocation,
Recast<VkMemoryPropertyFlags *>(&memoryPropertyFlags));
bool hostAccessible = Cast<bool>(memoryPropertyFlags & vk::MemoryPropertyFlagBits::eHostVisible);
// TODO: Actually track Host Access
// bool hostAccessible = Cast<bool>(memoryPropertyFlags & vk::MemoryPropertyFlagBits::eHostVisible);
m_Buffer = buffer;
m_Size_ = size | VALID_BUFFER_BIT | OWNED_BIT;

View File

@ -30,7 +30,7 @@ struct MemorySize
m_Kilobytes = totalKb % 1024;
const usize totalMb = m_Megabytes + totalKb / 1024;
m_Megabytes = totalMb % 1024;
m_Gigabytes += totalMb / 1024;
m_Gigabytes += Cast<u16>(totalMb / 1024);
return *this;
}
@ -56,8 +56,7 @@ struct fmt::formatter<MemorySize>
// return format_to(ctx.out(), "({}, {})", foo.a, foo.b); // --== KEY LINE ==--
if (mem.m_Gigabytes > 0)
{
return v10::format_to(ctx.out(), "{}.{} GB", mem.m_Gigabytes,
Cast<u16>(mem.m_Megabytes / 1024.0));
return v10::format_to(ctx.out(), "{}.{} GB", mem.m_Gigabytes, Cast<u16>(mem.m_Megabytes / 1024.0));
}
if (mem.m_Megabytes > 0)
{

View File

@ -10,6 +10,7 @@
Surface::Surface(Context *context, const Window *window, cstr name)
: m_Context(context)
, m_Name(name)
{
VkSurfaceKHR surface;
auto result = Cast<vk::Result>(

View File

@ -0,0 +1,8 @@
# CMakeList.txt ; CMake project for Aster Util Headers
cmake_minimum_required(VERSION 3.13)
target_sources(aster_core
PRIVATE
"manager.cpp"
"buffer_manager.cpp")

View File

@ -0,0 +1,32 @@
// =============================================
// Aster: buffer_manager.cpp
// Copyright (c) 2020-2025 Anish Bhobe
// =============================================
#include "systems/buffer_manager.h"
Manager<Buffer> *Manager<Buffer>::m_Instance;
systems::BufferManager::Ref
systems::BufferManager::CreateStorageBuffer(const usize size, const cstr name)
{
Ref object = Alloc();
// TODO: Storage and Index buffer are set.
// This is hacky and should be improved.
constexpr vk::BufferUsageFlags usage = vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eIndexBuffer |
vk::BufferUsageFlagBits::eShaderDeviceAddress;
constexpr VmaAllocationCreateFlags createFlags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT |
VMA_ALLOCATION_CREATE_MAPPED_BIT;
constexpr VmaMemoryUsage memoryUsage = VMA_MEMORY_USAGE_AUTO;
object->Allocate(m_Device, size, usage, createFlags, memoryUsage, name);
return object;
}
systems::BufferManager::BufferManager(const Device *device, const u32 maxCount)
: Manager{device, maxCount}
{
SetInstance(this);
}

View File

@ -0,0 +1,6 @@
// =============================================
// Aster: manager.cpp
// Copyright (c) 2020-2025 Anish Bhobe
// =============================================
#include "systems/manager.h"

View File

@ -197,8 +197,8 @@ CreateCubeFromHdrEnv(AssetLoader *assetLoader, vk::Queue computeQueue, const u32
vk::PushConstantRange pcr = {
.stageFlags = vk::ShaderStageFlagBits::eCompute,
.offset = 0,
.size = eastl::max(eastl::max(sizeof(SkyboxPushConstants), sizeof(BrdfLutPushConstants)),
eastl::max(sizeof(DiffuseIrradiancePushConstants), sizeof(PrefilterPushConstants))),
.size = Cast<u32>(eastl::max(eastl::max(sizeof(SkyboxPushConstants), sizeof(BrdfLutPushConstants)),
eastl::max(sizeof(DiffuseIrradiancePushConstants), sizeof(PrefilterPushConstants)))),
};
vk::PipelineLayout pipelineLayout;
@ -254,7 +254,7 @@ CreateCubeFromHdrEnv(AssetLoader *assetLoader, vk::Queue computeQueue, const u32
};
eastl::array<vk::Pipeline, computePipelineCreateInfo.size()> pipelines;
AbortIfFailed(pDevice->m_Device.createComputePipelines(pDevice->m_PipelineCache, computePipelineCreateInfo.size(),
AbortIfFailed(pDevice->m_Device.createComputePipelines(pDevice->m_PipelineCache, Cast<u32>(computePipelineCreateInfo.size()),
computePipelineCreateInfo.data(), nullptr,
pipelines.data()));

View File

@ -66,7 +66,7 @@ struct LightManager
// Using lower bit. Capacity can be directly a multiple of 2
// Thus, range is up to MaxValue<u16>
constexpr static u16 UPDATE_REQUIRED_BIT = 1;
constexpr static u16 CAPACITY_MASK = ~(UPDATE_REQUIRED_BIT);
constexpr static u16 CAPACITY_MASK = Cast<u16>(~UPDATE_REQUIRED_BIT);
LightHandle AddDirectional(const vec3 &direction, const vec3 &color, f32 intensity);
LightHandle AddPoint(const vec3 &position, const vec3 &color, f32 radius, f32 intensity);

View File

@ -197,8 +197,8 @@ CreateEnvironment(AssetLoader *assetLoader, vk::Queue computeQueue, const u32 cu
vk::PushConstantRange pcr = {
.stageFlags = vk::ShaderStageFlagBits::eCompute,
.offset = 0,
.size = eastl::max(eastl::max(sizeof(SkyboxPushConstants), sizeof(BrdfLutPushConstants)),
eastl::max(sizeof(DiffuseIrradiancePushConstants), sizeof(PrefilterPushConstants))),
.size = Cast<u32>(eastl::max(eastl::max(sizeof(SkyboxPushConstants), sizeof(BrdfLutPushConstants)),
eastl::max(sizeof(DiffuseIrradiancePushConstants), sizeof(PrefilterPushConstants)))),
};
vk::PipelineLayout pipelineLayout;
@ -254,7 +254,7 @@ CreateEnvironment(AssetLoader *assetLoader, vk::Queue computeQueue, const u32 cu
};
eastl::array<vk::Pipeline, computePipelineCreateInfo.size()> pipelines;
AbortIfFailed(pDevice->m_Device.createComputePipelines(pDevice->m_PipelineCache, computePipelineCreateInfo.size(),
AbortIfFailed(pDevice->m_Device.createComputePipelines(pDevice->m_PipelineCache, Cast<u32>(computePipelineCreateInfo.size()),
computePipelineCreateInfo.data(), nullptr,
pipelines.data()));

View File

@ -73,7 +73,7 @@ struct LightManager
// Using lower bit. Capacity can be directly a multiple of 2
// Thus, range is up to MaxValue<u16>
constexpr static u16 UPDATE_REQUIRED_BIT = 1;
constexpr static u16 CAPACITY_MASK = ~(UPDATE_REQUIRED_BIT);
constexpr static u16 CAPACITY_MASK = Cast<u16>(~UPDATE_REQUIRED_BIT);
LightHandle AddDirectional(const vec3 &direction, const vec3 &color, f32 intensity);
LightHandle AddPoint(const vec3 &position, const vec3 &color, f32 radius, f32 intensity);

View File

@ -5,11 +5,11 @@
#include "aster/core/context.h"
#include "aster/core/device.h"
#include "aster/core/image.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/image.h"
#include "aster/core/pipeline.h"
#include "helpers.h"
#include "render_resource_manager.h"
@ -93,7 +93,7 @@ main(int, char *[])
Device device = {&context, &deviceToUse, &enabledDeviceFeatures,
{queueAllocation}, pipelineCacheData, "Primary Device"};
vk::Queue graphicsQueue = device.GetQueue(queueAllocation.m_Family, 0);
Swapchain swapchain = {&surface, &device, window.GetSize(),"Primary Chain"};
Swapchain swapchain = {&surface, &device, window.GetSize(), "Primary Chain"};
RenderResourceManager resourceManager = {&device, 1024};
EcsRegistry registry;
@ -114,7 +114,7 @@ main(int, char *[])
eastl::vector<Model> models;
models.emplace_back(assetLoader.LoadModelToGpu(MODEL_FILE, "Main Model"));
//registry.get<CDynamicTransform>(model.m_RootEntity).m_Position = vec3(2 * i, 0, 2 * j);
// registry.get<CDynamicTransform>(model.m_RootEntity).m_Position = vec3(2 * i, 0, 2 * j);
UniformBuffer ubo;
constexpr usize uboLightManagerOffset = sizeof cameraController.m_Camera;
@ -350,12 +350,13 @@ main(int, char *[])
{
Time::Update();
//u32 index = 0;
//for (auto [entity, dynTrans] : rootModel.each())
// u32 index = 0;
// for (auto [entity, dynTrans] : rootModel.each())
//{
// dynTrans.m_Rotation =
// glm::rotate(dynTrans.m_Rotation, Cast<f32>(30_deg * (++index) * Time::m_Delta), vec3{0.0f, 1.0f, 0.0f});
//}
// dynTrans.m_Rotation =
// glm::rotate(dynTrans.m_Rotation, Cast<f32>(30_deg * (++index) * Time::m_Delta), vec3{0.0f, 1.0f,
// 0.0f});
// }
Frame *currentFrame = frameManager.GetNextFrame(&swapchain, &surface, window.GetSize());

View File

@ -315,7 +315,7 @@ VirtualizedBufferPool::InitIndex(const Device *device, usize bufferMaxSize)
}
void
VirtualizedBufferPool::UpdateToGpu(const Device *device)
VirtualizedBufferPool::UpdateToGpu(const Device *)
{
// Unrequired until adding the non-ReBAR support.
}

2
vcpkg

@ -1 +1 @@
Subproject commit b27651341123a59f7187b42ef2bc476284afb310
Subproject commit 0ca64b4e1c70fa6d9f53b369b8f3f0843797c20c