diff --git a/aster/include/aster/core/global.h b/aster/include/aster/core/global.h index 07400b8..fc9b114 100644 --- a/aster/include/aster/core/global.h +++ b/aster/include/aster/core/global.h @@ -25,7 +25,7 @@ #if !defined(NDEBUG) #define VULKAN_HPP_ASSERT(expr) DEBUG_IF(!(expr), "Vulkan assert failed") -#endif +#endif #include #include #include @@ -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)) diff --git a/aster/include/aster/systems/CMakeLists.txt b/aster/include/aster/systems/CMakeLists.txt new file mode 100644 index 0000000..75395d1 --- /dev/null +++ b/aster/include/aster/systems/CMakeLists.txt @@ -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") diff --git a/aster/include/aster/systems/buffer_manager.h b/aster/include/aster/systems/buffer_manager.h new file mode 100644 index 0000000..ccf4abd --- /dev/null +++ b/aster/include/aster/systems/buffer_manager.h @@ -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 +{ + public: + BufferManager(const Device *device, const u32 maxCount); + + Ref CreateStorageBuffer(usize size, cstr name = nullptr); +}; +} // namespace systems diff --git a/aster/include/aster/systems/manager.h b/aster/include/aster/systems/manager.h new file mode 100644 index 0000000..becd42f --- /dev/null +++ b/aster/include/aster/systems/manager.h @@ -0,0 +1,147 @@ +// ============================================= +// Aster: manager.h +// Copyright (c) 2020-2024 Anish Bhobe +// ============================================= + +#pragma once + +#include "aster/aster.h" + +#include + +struct Device; + +template + requires std::is_default_constructible_v +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; + + 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); + 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(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]}; + } +}; diff --git a/aster/include/aster/util/logger.h b/aster/include/aster/util/logger.h index ed025d9..e53a1a8 100644 --- a/aster/include/aster/util/logger.h +++ b/aster/include/aster/util/logger.h @@ -5,7 +5,7 @@ #pragma once -#include "core/constants.h" +#include "aster/core/constants.h" #include #include diff --git a/aster/src/aster/CMakeLists.txt b/aster/src/aster/CMakeLists.txt index 8b7401e..ace9224 100644 --- a/aster/src/aster/CMakeLists.txt +++ b/aster/src/aster/CMakeLists.txt @@ -3,4 +3,5 @@ cmake_minimum_required(VERSION 3.13) add_subdirectory("core") +add_subdirectory("systems") add_subdirectory("util") \ No newline at end of file diff --git a/aster/src/aster/core/buffer.cpp b/aster/src/aster/core/buffer.cpp index 6a01f5e..a8fc1d2 100644 --- a/aster/src/aster/core/buffer.cpp +++ b/aster/src/aster/core/buffer.cpp @@ -44,7 +44,8 @@ Buffer::Allocate(const Device *device, usize size, vk::BufferUsageFlags bufferUs vk::MemoryPropertyFlags memoryPropertyFlags; vmaGetAllocationMemoryProperties(device->m_Allocator, allocation, Recast(&memoryPropertyFlags)); - bool hostAccessible = Cast(memoryPropertyFlags & vk::MemoryPropertyFlagBits::eHostVisible); + // TODO: Actually track Host Access + // bool hostAccessible = Cast(memoryPropertyFlags & vk::MemoryPropertyFlagBits::eHostVisible); m_Buffer = buffer; m_Size_ = size | VALID_BUFFER_BIT | OWNED_BIT; diff --git a/aster/src/aster/core/global.cpp b/aster/src/aster/core/global.cpp index da429e2..9dd4eb5 100644 --- a/aster/src/aster/core/global.cpp +++ b/aster/src/aster/core/global.cpp @@ -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(totalMb / 1024); return *this; } @@ -56,8 +56,7 @@ struct fmt::formatter // 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(mem.m_Megabytes / 1024.0)); + return v10::format_to(ctx.out(), "{}.{} GB", mem.m_Gigabytes, Cast(mem.m_Megabytes / 1024.0)); } if (mem.m_Megabytes > 0) { diff --git a/aster/src/aster/core/surface.cpp b/aster/src/aster/core/surface.cpp index f615f71..f960fdf 100644 --- a/aster/src/aster/core/surface.cpp +++ b/aster/src/aster/core/surface.cpp @@ -10,6 +10,7 @@ Surface::Surface(Context *context, const Window *window, cstr name) : m_Context(context) + , m_Name(name) { VkSurfaceKHR surface; auto result = Cast( diff --git a/aster/src/aster/systems/CMakeLists.txt b/aster/src/aster/systems/CMakeLists.txt new file mode 100644 index 0000000..548374e --- /dev/null +++ b/aster/src/aster/systems/CMakeLists.txt @@ -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") diff --git a/aster/src/aster/systems/buffer_manager.cpp b/aster/src/aster/systems/buffer_manager.cpp new file mode 100644 index 0000000..67225f2 --- /dev/null +++ b/aster/src/aster/systems/buffer_manager.cpp @@ -0,0 +1,32 @@ +// ============================================= +// Aster: buffer_manager.cpp +// Copyright (c) 2020-2025 Anish Bhobe +// ============================================= + +#include "systems/buffer_manager.h" + +Manager *Manager::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); +} \ No newline at end of file diff --git a/aster/src/aster/systems/manager.cpp b/aster/src/aster/systems/manager.cpp new file mode 100644 index 0000000..fefa1e0 --- /dev/null +++ b/aster/src/aster/systems/manager.cpp @@ -0,0 +1,6 @@ +// ============================================= +// Aster: manager.cpp +// Copyright (c) 2020-2025 Anish Bhobe +// ============================================= + +#include "systems/manager.h" diff --git a/samples/03_model_render/ibl_helpers.cpp b/samples/03_model_render/ibl_helpers.cpp index 164b6ed..f726302 100644 --- a/samples/03_model_render/ibl_helpers.cpp +++ b/samples/03_model_render/ibl_helpers.cpp @@ -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(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 pipelines; - AbortIfFailed(pDevice->m_Device.createComputePipelines(pDevice->m_PipelineCache, computePipelineCreateInfo.size(), + AbortIfFailed(pDevice->m_Device.createComputePipelines(pDevice->m_PipelineCache, Cast(computePipelineCreateInfo.size()), computePipelineCreateInfo.data(), nullptr, pipelines.data())); diff --git a/samples/03_model_render/light_manager.h b/samples/03_model_render/light_manager.h index 5e2bb28..e57feeb 100644 --- a/samples/03_model_render/light_manager.h +++ b/samples/03_model_render/light_manager.h @@ -66,7 +66,7 @@ struct LightManager // Using lower bit. Capacity can be directly a multiple of 2 // Thus, range is up to MaxValue constexpr static u16 UPDATE_REQUIRED_BIT = 1; - constexpr static u16 CAPACITY_MASK = ~(UPDATE_REQUIRED_BIT); + constexpr static u16 CAPACITY_MASK = Cast(~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); diff --git a/samples/04_scenes/ibl_helpers.cpp b/samples/04_scenes/ibl_helpers.cpp index ed534fe..e6a5270 100644 --- a/samples/04_scenes/ibl_helpers.cpp +++ b/samples/04_scenes/ibl_helpers.cpp @@ -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(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 pipelines; - AbortIfFailed(pDevice->m_Device.createComputePipelines(pDevice->m_PipelineCache, computePipelineCreateInfo.size(), + AbortIfFailed(pDevice->m_Device.createComputePipelines(pDevice->m_PipelineCache, Cast(computePipelineCreateInfo.size()), computePipelineCreateInfo.data(), nullptr, pipelines.data())); diff --git a/samples/04_scenes/light_manager.h b/samples/04_scenes/light_manager.h index 802b869..a123334 100644 --- a/samples/04_scenes/light_manager.h +++ b/samples/04_scenes/light_manager.h @@ -73,7 +73,7 @@ struct LightManager // Using lower bit. Capacity can be directly a multiple of 2 // Thus, range is up to MaxValue constexpr static u16 UPDATE_REQUIRED_BIT = 1; - constexpr static u16 CAPACITY_MASK = ~(UPDATE_REQUIRED_BIT); + constexpr static u16 CAPACITY_MASK = Cast(~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); diff --git a/samples/04_scenes/main.cpp b/samples/04_scenes/main.cpp index b673304..1cbea3a 100644 --- a/samples/04_scenes/main.cpp +++ b/samples/04_scenes/main.cpp @@ -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 models; models.emplace_back(assetLoader.LoadModelToGpu(MODEL_FILE, "Main Model")); - //registry.get(model.m_RootEntity).m_Position = vec3(2 * i, 0, 2 * j); + // registry.get(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(30_deg * (++index) * Time::m_Delta), vec3{0.0f, 1.0f, 0.0f}); - //} + // dynTrans.m_Rotation = + // glm::rotate(dynTrans.m_Rotation, Cast(30_deg * (++index) * Time::m_Delta), vec3{0.0f, 1.0f, + // 0.0f}); + // } Frame *currentFrame = frameManager.GetNextFrame(&swapchain, &surface, window.GetSize()); diff --git a/samples/04_scenes/render_resource_manager.cpp b/samples/04_scenes/render_resource_manager.cpp index 32bf78a..bfa4544 100644 --- a/samples/04_scenes/render_resource_manager.cpp +++ b/samples/04_scenes/render_resource_manager.cpp @@ -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. } diff --git a/vcpkg b/vcpkg index b276513..0ca64b4 160000 --- a/vcpkg +++ b/vcpkg @@ -1 +1 @@ -Subproject commit b27651341123a59f7187b42ef2bc476284afb310 +Subproject commit 0ca64b4e1c70fa6d9f53b369b8f3f0843797c20c