diff --git a/aster/include/aster/core/global.h b/aster/include/aster/core/global.h index f157d3e..3a017e4 100644 --- a/aster/include/aster/core/global.h +++ b/aster/include/aster/core/global.h @@ -222,4 +222,7 @@ struct fmt::formatter> : nested_fo }; template -using Ref = std::shared_ptr; \ No newline at end of file +using Ref = std::shared_ptr; + +template +using WeakRef = std::weak_ptr; \ No newline at end of file diff --git a/aster/include/aster/core/image.h b/aster/include/aster/core/image.h index 65f1427..7f34e9b 100644 --- a/aster/include/aster/core/image.h +++ b/aster/include/aster/core/image.h @@ -41,7 +41,6 @@ struct Image VmaAllocation m_Allocation = nullptr; vk::Extent3D m_Extent; vk::Format m_Format; - std::atomic m_RefCount; u8 m_EmptyPadding_ = 0; u8 m_Flags_ = 0; u8 m_LayerCount = 0; @@ -75,42 +74,12 @@ struct Image return m_Image; } - [[nodiscard]] bool - IsReferenced() const - { - return m_RefCount; - } - [[nodiscard]] u32 GetMipLevels() const { return m_MipLevels; } - void - AddRef() - { - const auto rc = ++m_RefCount; - assert(rc > 0); - } - - void - Release() - { - const auto rc = --m_RefCount; - assert(rc < MaxValue); - if (rc == 0) - { - Destroy(); - } - } - - void Destroy(); - ~Image() - { - Destroy(); - } - static bool Conforms(const Image &) { @@ -118,6 +87,18 @@ struct Image } void DestroyView(vk::ImageView imageView) const; + + // Constructors. + + explicit Image(const Device *device, vk::Image image, VmaAllocation allocation, vk::Extent3D extent, + vk::Format format, u8 flags, u8 layerCount, u8 mipLevels); + + Image(Image &&other) noexcept; + Image &operator=(Image &&other) noexcept; + + ~Image(); + + DISALLOW_COPY_AND_ASSIGN(Image); }; namespace concepts diff --git a/aster/include/aster/core/image_view.h b/aster/include/aster/core/image_view.h index 825b65b..247aeed 100644 --- a/aster/include/aster/core/image_view.h +++ b/aster/include/aster/core/image_view.h @@ -13,11 +13,9 @@ struct View { using ImageType = TImage; - const Device *m_Device; Ref m_Image; vk::ImageView m_View = nullptr; vk::Extent3D m_Extent; - std::atomic m_RefCount; u8 m_BaseLayer = 0; u8 m_LayerCount = 0; u8 m_BaseMipLevel = 0; @@ -29,78 +27,69 @@ struct View return m_Image->m_Image; } - void - AddRef() - { - const auto rc = ++m_RefCount; - assert(rc > 0); - } - - void - Release() - { - const auto rc = --m_RefCount; - assert(rc < MaxValue); - if (rc == 0) - { - Destroy(); - } - } - - [[nodiscard]] bool - IsReferenced() const - { - return m_RefCount; - } - [[nodiscard]] bool IsValid() const { return Cast(m_Image); } - void - Destroy() + View(Ref image, const vk::ImageView view, const vk::Extent3D extent, const u8 baseLayer, const u8 layerCount, + const u8 baseMipLevel, const u8 mipLevelCount) + : m_Image{std::move(image)} + , m_View{view} + , m_Extent{extent} + , m_BaseLayer{baseLayer} + , m_LayerCount{layerCount} + , m_BaseMipLevel{baseMipLevel} + , m_MipLevelCount{mipLevelCount} + { + } + + View(View &&other) noexcept + : m_Image{std::move(other.m_Image)} + , m_View{Take(other.m_View)} + , m_Extent{std::move(other.m_Extent)} + , m_BaseLayer{other.m_BaseLayer} + , m_LayerCount{other.m_LayerCount} + , m_BaseMipLevel{other.m_BaseMipLevel} + , m_MipLevelCount{other.m_MipLevelCount} + { + } + + View & + operator=(View &&other) noexcept + { + if (this == &other) + return *this; + using std::swap; + swap(m_Image, other.m_Image); + swap(m_View, other.m_View); + swap(m_Extent, other.m_Extent); + swap(m_BaseLayer, other.m_BaseLayer); + swap(m_LayerCount, other.m_LayerCount); + swap(m_BaseMipLevel, other.m_BaseMipLevel); + swap(m_MipLevelCount, other.m_MipLevelCount); + return *this; + } + + DISALLOW_COPY_AND_ASSIGN(View); + + ~View() { if (!IsValid()) return; m_Image->DestroyView(Take(m_View)); } - - ~View() - { - Destroy(); - } }; -struct ImageView : View -{ -}; - -struct ImageCubeView : View -{ -}; - -struct TextureView : View -{ -}; - -struct TextureCubeView : View -{ -}; - -struct StorageImageView : View -{ -}; - -struct StorageTextureView : View -{ -}; - -struct StorageTextureCubeView : View -{ -}; +using ImageView = View; +using ImageCubeView = View; +using TextureView = View; +using TextureCubeView = View; +using StorageImageView = View; +using StorageTextureView = View; +using StorageTextureCubeView = View; namespace concepts { diff --git a/aster/include/aster/core/sampler.h b/aster/include/aster/core/sampler.h index 46518b6..bd3b478 100644 --- a/aster/include/aster/core/sampler.h +++ b/aster/include/aster/core/sampler.h @@ -9,44 +9,24 @@ struct Device; -// TODO Refactor the Buffer Hierarchy - -struct Sampler +struct Sampler final { const Device *m_Device = nullptr; vk::Sampler m_Sampler = nullptr; - std::atomic m_RefCount = 0; - - void Init(const Device *device, const vk::SamplerCreateInfo &samplerCreateInfo, cstr name); - void Destroy(); - - void - AddRef() - { - const auto rc = ++m_RefCount; - assert(rc > 0); - } - - void - Release() - { - const auto rc = --m_RefCount; - assert(rc < MaxValue); - if (rc == 0) - { - Destroy(); - } - } - - [[nodiscard]] bool - IsReferenced() const - { - return m_RefCount; - } [[nodiscard]] bool IsValid() const { return m_Sampler; } + + // Constructors + + Sampler(const Device *device, const vk::SamplerCreateInfo &samplerCreateInfo, cstr name); + ~Sampler(); + + Sampler(Sampler &&other) noexcept; + Sampler &operator=(Sampler &&other) noexcept; + + DISALLOW_COPY_AND_ASSIGN(Sampler); }; \ No newline at end of file diff --git a/aster/include/aster/core/type_traits.h b/aster/include/aster/core/type_traits.h index 5870dbb..9ba8b88 100644 --- a/aster/include/aster/core/type_traits.h +++ b/aster/include/aster/core/type_traits.h @@ -20,15 +20,4 @@ concept Derefencable = requires(T a) { template using DereferencesTo = std::remove_cvref_t())>; -template -concept DeviceDestructible = requires(T a, Device *p) { - { a.Destroy(p) } -> std::same_as; -}; - -template -concept SelfDestructible = requires(T a) { - { a.Destroy() } -> std::same_as; - { T::m_Device } -> std::convertible_to; -}; - } // namespace concepts \ No newline at end of file diff --git a/aster/include/aster/systems/resource_manager.h b/aster/include/aster/systems/resource_manager.h index 7e90ec6..08dbecf 100644 --- a/aster/include/aster/systems/resource_manager.h +++ b/aster/include/aster/systems/resource_manager.h @@ -135,12 +135,6 @@ class ResourceManager return m_CombinedImageViews; } - void - Update() - { - // TODO: Remove - } - ~ResourceManager() = default; PIN_MEMORY(ResourceManager); diff --git a/aster/include/aster/systems/sampler_manager.h b/aster/include/aster/systems/sampler_manager.h index 6371533..ebc1358 100644 --- a/aster/include/aster/systems/sampler_manager.h +++ b/aster/include/aster/systems/sampler_manager.h @@ -98,7 +98,8 @@ struct SamplerCreateInfo class SamplerManager final { using Handle = Ref; - eastl::hash_map m_HashToSamplerIdx; + using WeakHandle = WeakRef; + eastl::hash_map m_HashToSamplerIdx; const Device *m_Device; diff --git a/aster/include/aster/systems/view_manager.h b/aster/include/aster/systems/view_manager.h index 444b713..be1ac2c 100644 --- a/aster/include/aster/systems/view_manager.h +++ b/aster/include/aster/systems/view_manager.h @@ -21,7 +21,7 @@ CastView(const concepts::ImageViewRef auto &from) return std::reinterpret_pointer_cast(from); } -template +template struct ViewCreateInfo { using ImageType = TImage; @@ -68,7 +68,7 @@ struct ViewCreateInfo } explicit - operator ViewCreateInfo<>() const + operator ViewCreateInfo() const { return { .m_Image = CastImage(m_Image), @@ -95,10 +95,10 @@ class ViewManager final Ref CreateView(const ViewCreateInfo &createInfo) { - return CastView(CreateView(ViewCreateInfo<>(createInfo))); + return CastView(CreateView(ViewCreateInfo(createInfo))); } - [[nodiscard]] Ref CreateView(const ViewCreateInfo<> &createInfo) const; + [[nodiscard]] Ref CreateView(const ViewCreateInfo &createInfo) const; }; } // namespace systems \ No newline at end of file diff --git a/aster/src/aster/core/image.cpp b/aster/src/aster/core/image.cpp index 0043730..bf77161 100644 --- a/aster/src/aster/core/image.cpp +++ b/aster/src/aster/core/image.cpp @@ -7,8 +7,25 @@ #include "core/device.h" -void -Image::Destroy() +Image & +Image::operator=(Image &&other) noexcept +{ + if (this == &other) + return *this; + using std::swap; + swap(m_Device, other.m_Device); + swap(m_Image, other.m_Image); + swap(m_Allocation, other.m_Allocation); + swap(m_Extent, other.m_Extent); + swap(m_Format, other.m_Format); + swap(m_EmptyPadding_, other.m_EmptyPadding_); + swap(m_Flags_, other.m_Flags_); + swap(m_LayerCount, other.m_LayerCount); + swap(m_MipLevels, other.m_MipLevels); + return *this; +} + +Image::~Image() { if (!IsValid()) return; @@ -431,4 +448,29 @@ Image::DestroyView(const vk::ImageView imageView) const // m_LayerCount = 6; // // device->SetName(m_Image, name); -// } \ No newline at end of file +// } +Image::Image(Image &&other) noexcept + : m_Device{Take(other.m_Device)} + , m_Image{Take(other.m_Image)} + , m_Allocation{Take(other.m_Allocation)} + , m_Extent{other.m_Extent} + , m_Format{other.m_Format} + , m_EmptyPadding_{other.m_EmptyPadding_} + , m_Flags_{other.m_Flags_} + , m_LayerCount{other.m_LayerCount} + , m_MipLevels{other.m_MipLevels} +{ +} + +Image::Image(const Device *device, const vk::Image image, const VmaAllocation allocation, const vk::Extent3D extent, + const vk::Format format, const u8 flags, const u8 layerCount, const u8 mipLevels) + : m_Device{device} + , m_Image{image} + , m_Allocation{allocation} + , m_Extent{extent} + , m_Format{format} + , m_Flags_{flags} + , m_LayerCount{layerCount} + , m_MipLevels{mipLevels} +{ +} \ No newline at end of file diff --git a/aster/src/aster/core/sampler.cpp b/aster/src/aster/core/sampler.cpp index 2148fb7..2dcc4c7 100644 --- a/aster/src/aster/core/sampler.cpp +++ b/aster/src/aster/core/sampler.cpp @@ -7,8 +7,7 @@ #include "core/device.h" -void -Sampler::Destroy() +Sampler::~Sampler() { if (!IsValid()) return; @@ -16,10 +15,25 @@ Sampler::Destroy() m_Device->m_Device.destroy(Take(m_Sampler), nullptr); } -void -Sampler::Init(const Device *device, const vk::SamplerCreateInfo &samplerCreateInfo, cstr name) +Sampler::Sampler(const Device *device, const vk::SamplerCreateInfo &samplerCreateInfo, cstr name) { m_Device = device; const auto result = device->m_Device.createSampler(&samplerCreateInfo, nullptr, &m_Sampler); ERROR_IF(Failed(result), "Could not create a sampler {}", name ? name : "") THEN_ABORT(-1); +} + +Sampler & +Sampler::operator=(Sampler &&other) noexcept +{ + if (this == &other) + return *this; + using std::swap; + swap(m_Device, other.m_Device); + swap(m_Sampler, other.m_Sampler); + return *this; +} + +Sampler::Sampler(Sampler &&other) noexcept: m_Device{other.m_Device} + , m_Sampler{Take(other.m_Sampler)} +{ } \ No newline at end of file diff --git a/aster/src/aster/systems/image_manager.cpp b/aster/src/aster/systems/image_manager.cpp index fed1872..722944d 100644 --- a/aster/src/aster/systems/image_manager.cpp +++ b/aster/src/aster/systems/image_manager.cpp @@ -38,30 +38,27 @@ ImageManager::CreateTexture2D(const Texture2DCreateInfo &createInfo) .usage = VMA_MEMORY_USAGE_AUTO, }; - VkImage image; + VkImage rawImage; VmaAllocation allocation; vk::ImageCreateInfo imageCreateInfo = ToImageCreateInfo(createInfo); auto result = Cast(vmaCreateImage(m_Device->m_Allocator, Recast(&imageCreateInfo), - &allocationCreateInfo, &image, &allocation, nullptr)); + &allocationCreateInfo, &rawImage, &allocation, nullptr)); ERROR_IF(Failed(result), "Could not allocate image {}. Cause: {}", createInfo.m_Name, result) THEN_ABORT(result); - auto object = std::make_shared(); - object->m_Device = m_Device; - object->m_Image = image; - object->m_Allocation = allocation; - object->m_Extent = imageCreateInfo.extent; - object->m_Format = imageCreateInfo.format; - object->m_LayerCount = Cast(imageCreateInfo.arrayLayers); - object->m_MipLevels = Cast(imageCreateInfo.mipLevels); - object->m_Flags_ = {}; + vk::Image image = rawImage; + + u8 layerCount = Cast(imageCreateInfo.arrayLayers); + u8 mipLevels = Cast(imageCreateInfo.mipLevels); + u8 flags = 0; if (createInfo.m_IsSampled) - object->m_Flags_ |= Image::SAMPLED_BIT; + flags |= Image::SAMPLED_BIT; if (createInfo.m_IsStorage) - object->m_Flags_ |= Image::STORAGE_BIT; + flags |= Image::STORAGE_BIT; - m_Device->SetName(object->m_Image, createInfo.m_Name); + m_Device->SetName(image, createInfo.m_Name); - return object; + return std::make_shared(m_Device, image, allocation, imageCreateInfo.extent, imageCreateInfo.format, flags, + layerCount, mipLevels); } Ref @@ -72,30 +69,27 @@ ImageManager::CreateTextureCube(const TextureCubeCreateInfo &createInfo) .usage = VMA_MEMORY_USAGE_AUTO, }; - VkImage image; + VkImage rawImage; VmaAllocation allocation; vk::ImageCreateInfo imageCreateInfo = ToImageCreateInfo(createInfo); auto result = Cast(vmaCreateImage(m_Device->m_Allocator, Recast(&imageCreateInfo), - &allocationCreateInfo, &image, &allocation, nullptr)); + &allocationCreateInfo, &rawImage, &allocation, nullptr)); ERROR_IF(Failed(result), "Could not allocate image {}. Cause: {}", createInfo.m_Name, result) THEN_ABORT(result); - auto object = std::make_shared(); - object->m_Device = m_Device; - object->m_Image = image; - object->m_Allocation = allocation; - object->m_Extent = imageCreateInfo.extent; - object->m_Format = imageCreateInfo.format; - object->m_LayerCount = Cast(imageCreateInfo.arrayLayers); - object->m_MipLevels = Cast(imageCreateInfo.mipLevels); - object->m_Flags_ = Image::CUBE_BIT; + vk::Image image = rawImage; + + u8 layerCount = Cast(imageCreateInfo.arrayLayers); + u8 mipLevels = Cast(imageCreateInfo.mipLevels); + u8 flags = Image::CUBE_BIT; if (createInfo.m_IsSampled) - object->m_Flags_ |= Image::SAMPLED_BIT; + flags |= Image::SAMPLED_BIT; if (createInfo.m_IsStorage) - object->m_Flags_ |= Image::STORAGE_BIT; + flags |= Image::STORAGE_BIT; - m_Device->SetName(object->m_Image, createInfo.m_Name); + m_Device->SetName(image, createInfo.m_Name); - return CastImage(object); + return CastImage(std::make_shared(m_Device, image, allocation, imageCreateInfo.extent, + imageCreateInfo.format, flags, layerCount, mipLevels)); } Ref @@ -106,25 +100,22 @@ ImageManager::CreateAttachment(const AttachmentCreateInfo &createInfo) .usage = VMA_MEMORY_USAGE_AUTO, }; - VkImage image; + VkImage rawImage; VmaAllocation allocation; vk::ImageCreateInfo imageCreateInfo = ToImageCreateInfo(createInfo); auto result = Cast(vmaCreateImage(m_Device->m_Allocator, Recast(&imageCreateInfo), - &allocationCreateInfo, &image, &allocation, nullptr)); + &allocationCreateInfo, &rawImage, &allocation, nullptr)); ERROR_IF(Failed(result), "Could not allocate image {}. Cause: {}", createInfo.m_Name, result) THEN_ABORT(result); - auto object = std::make_shared(); - object->m_Device = m_Device; - object->m_Image = image; - object->m_Allocation = allocation; - object->m_Extent = imageCreateInfo.extent; - object->m_Format = imageCreateInfo.format; - object->m_LayerCount = Cast(imageCreateInfo.arrayLayers); - object->m_MipLevels = Cast(imageCreateInfo.mipLevels); + vk::Image image = rawImage; - m_Device->SetName(object->m_Image, createInfo.m_Name); + u8 layerCount = Cast(imageCreateInfo.arrayLayers); + u8 mipLevels = Cast(imageCreateInfo.mipLevels); - return object; + m_Device->SetName(image, createInfo.m_Name); + + return std::make_shared(m_Device, image, allocation, imageCreateInfo.extent, imageCreateInfo.format, 0, + layerCount, mipLevels); } Ref @@ -135,25 +126,22 @@ ImageManager::CreateDepthStencilImage(const DepthStencilImageCreateInfo &createI .usage = VMA_MEMORY_USAGE_AUTO, }; - VkImage image; + VkImage rawImage; VmaAllocation allocation; vk::ImageCreateInfo imageCreateInfo = ToImageCreateInfo(createInfo); auto result = Cast(vmaCreateImage(m_Device->m_Allocator, Recast(&imageCreateInfo), - &allocationCreateInfo, &image, &allocation, nullptr)); + &allocationCreateInfo, &rawImage, &allocation, nullptr)); ERROR_IF(Failed(result), "Could not allocate image {}. Cause: {}", createInfo.m_Name, result) THEN_ABORT(result); - auto object = std::make_shared(); - object->m_Device = m_Device; - object->m_Image = image; - object->m_Allocation = allocation; - object->m_Extent = imageCreateInfo.extent; - object->m_Format = imageCreateInfo.format; - object->m_LayerCount = Cast(imageCreateInfo.arrayLayers); - object->m_MipLevels = Cast(imageCreateInfo.mipLevels); + vk::Image image = rawImage; - m_Device->SetName(object->m_Image, createInfo.m_Name); + u8 layerCount = Cast(imageCreateInfo.arrayLayers); + u8 mipLevels = Cast(imageCreateInfo.mipLevels); - return object; + m_Device->SetName(image, createInfo.m_Name); + + return std::make_shared(m_Device, image, allocation, imageCreateInfo.extent, imageCreateInfo.format, 0, + layerCount, mipLevels); } vk::ImageCreateInfo diff --git a/aster/src/aster/systems/sampler_manager.cpp b/aster/src/aster/systems/sampler_manager.cpp index 2fab62b..dbc775d 100644 --- a/aster/src/aster/systems/sampler_manager.cpp +++ b/aster/src/aster/systems/sampler_manager.cpp @@ -24,14 +24,12 @@ SamplerManager::CreateSampler(const SamplerCreateInfo &createInfo) { auto vkCreateInfo = Cast(createInfo); - if (const auto iter = m_HashToSamplerIdx.find(vkCreateInfo); iter != m_HashToSamplerIdx.end()) + if (const auto iter = m_HashToSamplerIdx.find(vkCreateInfo); iter != m_HashToSamplerIdx.end() && !iter->second.expired()) { - return iter->second; + return iter->second.lock(); } - auto object = std::make_shared(); - - object->Init(m_Device, vkCreateInfo, createInfo.m_Name ? createInfo.m_Name : nullptr); + auto object = std::make_shared(m_Device, vkCreateInfo, createInfo.m_Name ? createInfo.m_Name : nullptr); m_HashToSamplerIdx.emplace(vkCreateInfo, object); return object; diff --git a/aster/src/aster/systems/view_manager.cpp b/aster/src/aster/systems/view_manager.cpp index ffd3094..f812182 100644 --- a/aster/src/aster/systems/view_manager.cpp +++ b/aster/src/aster/systems/view_manager.cpp @@ -15,7 +15,7 @@ ViewManager::ViewManager(const Device *device) } Ref -ViewManager::CreateView(const ViewCreateInfo<> &createInfo) const +ViewManager::CreateView(const ViewCreateInfo &createInfo) const { const auto layerCount = createInfo.GetLayerCount(); const auto mipCount = createInfo.GetMipLevelCount(); @@ -32,15 +32,6 @@ ViewManager::CreateView(const ViewCreateInfo<> &createInfo) const m_Device->SetName(view, createInfo.m_Name); - auto object = std::make_shared(); - object->m_Device = m_Device; - object->m_Image = createInfo.m_Image; - object->m_View = view; - object->m_Extent = createInfo.m_Image->m_Extent; - object->m_BaseLayer = createInfo.m_BaseLayer; - object->m_LayerCount = layerCount; - object->m_BaseMipLevel = createInfo.m_BaseMipLevel; - object->m_MipLevelCount = mipCount; - - return object; + return std::make_shared(createInfo.m_Image, view, createInfo.m_Image->m_Extent, createInfo.m_BaseLayer, + layerCount, createInfo.m_BaseMipLevel, mipCount); } \ No newline at end of file diff --git a/samples/02_box/box.cpp b/samples/02_box/box.cpp index b682647..e9dc6f5 100644 --- a/samples/02_box/box.cpp +++ b/samples/02_box/box.cpp @@ -424,7 +424,6 @@ main(int, char **) { Time::Update(); commitManager.Update(); - resourceManager.Update(); camera.m_Model *= rotate(mat4{1.0f}, Cast(45.0_deg * Time::m_Delta), vec3(0.0f, 1.0f, 0.0f)); ubo->Write(0, sizeof camera, &camera); diff --git a/samples/03_model_render/model_render.cpp b/samples/03_model_render/model_render.cpp index 9c5cc10..e33f91c 100644 --- a/samples/03_model_render/model_render.cpp +++ b/samples/03_model_render/model_render.cpp @@ -434,7 +434,6 @@ main(int, char **) { Time::Update(); commitManager.Update(); - resourceManager.Update(); gui::StartBuild();