Image, View and Sampler are all updated.

This commit is contained in:
Anish Bhobe 2025-04-06 21:55:00 +02:00
parent d8770c1e06
commit 1748a48272
15 changed files with 193 additions and 225 deletions

View File

@ -222,4 +222,7 @@ struct fmt::formatter<eastl::fixed_string<TType, TCount, TOverflow>> : nested_fo
};
template <typename T>
using Ref = std::shared_ptr<T>;
using Ref = std::shared_ptr<T>;
template <typename T>
using WeakRef = std::weak_ptr<T>;

View File

@ -41,7 +41,6 @@ struct Image
VmaAllocation m_Allocation = nullptr;
vk::Extent3D m_Extent;
vk::Format m_Format;
std::atomic<u32> 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<u32>);
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

View File

@ -13,11 +13,9 @@ struct View
{
using ImageType = TImage;
const Device *m_Device;
Ref<Image> m_Image;
vk::ImageView m_View = nullptr;
vk::Extent3D m_Extent;
std::atomic<u32> 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<u32>);
if (rc == 0)
{
Destroy();
}
}
[[nodiscard]] bool
IsReferenced() const
{
return m_RefCount;
}
[[nodiscard]] bool
IsValid() const
{
return Cast<bool>(m_Image);
}
void
Destroy()
View(Ref<Image> 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<Image>
{
};
struct ImageCubeView : View<ImageCube>
{
};
struct TextureView : View<Texture>
{
};
struct TextureCubeView : View<TextureCube>
{
};
struct StorageImageView : View<StorageImage>
{
};
struct StorageTextureView : View<StorageTexture>
{
};
struct StorageTextureCubeView : View<StorageTextureCube>
{
};
using ImageView = View<Image>;
using ImageCubeView = View<ImageCube>;
using TextureView = View<Texture>;
using TextureCubeView = View<TextureCube>;
using StorageImageView = View<StorageImage>;
using StorageTextureView = View<StorageTexture>;
using StorageTextureCubeView = View<StorageTextureCube>;
namespace concepts
{

View File

@ -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<u32> 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<u32>);
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);
};

View File

@ -20,15 +20,4 @@ concept Derefencable = requires(T a) {
template <Derefencable T>
using DereferencesTo = std::remove_cvref_t<decltype(*std::declval<T>())>;
template <typename T>
concept DeviceDestructible = requires(T a, Device *p) {
{ a.Destroy(p) } -> std::same_as<void>;
};
template <typename T>
concept SelfDestructible = requires(T a) {
{ a.Destroy() } -> std::same_as<void>;
{ T::m_Device } -> std::convertible_to<const Device *>;
};
} // namespace concepts

View File

@ -135,12 +135,6 @@ class ResourceManager
return m_CombinedImageViews;
}
void
Update()
{
// TODO: Remove
}
~ResourceManager() = default;
PIN_MEMORY(ResourceManager);

View File

@ -98,7 +98,8 @@ struct SamplerCreateInfo
class SamplerManager final
{
using Handle = Ref<Sampler>;
eastl::hash_map<vk::SamplerCreateInfo, Handle> m_HashToSamplerIdx;
using WeakHandle = WeakRef<Sampler>;
eastl::hash_map<vk::SamplerCreateInfo, WeakHandle> m_HashToSamplerIdx;
const Device *m_Device;

View File

@ -21,7 +21,7 @@ CastView(const concepts::ImageViewRef auto &from)
return std::reinterpret_pointer_cast<TTo>(from);
}
template <concepts::Image TImage = Image>
template <concepts::Image TImage>
struct ViewCreateInfo
{
using ImageType = TImage;
@ -68,7 +68,7 @@ struct ViewCreateInfo
}
explicit
operator ViewCreateInfo<>() const
operator ViewCreateInfo<Image>() const
{
return {
.m_Image = CastImage<Image>(m_Image),
@ -95,10 +95,10 @@ class ViewManager final
Ref<TImageView>
CreateView(const ViewCreateInfo<typename TImageView::ImageType> &createInfo)
{
return CastView<TImageView>(CreateView(ViewCreateInfo<>(createInfo)));
return CastView<TImageView>(CreateView(ViewCreateInfo<Image>(createInfo)));
}
[[nodiscard]] Ref<ImageView> CreateView(const ViewCreateInfo<> &createInfo) const;
[[nodiscard]] Ref<ImageView> CreateView(const ViewCreateInfo<Image> &createInfo) const;
};
} // namespace systems

View File

@ -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);
// }
// }
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}
{
}

View File

@ -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 : "<unnamed>") 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)}
{
}

View File

@ -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<vk::Result>(vmaCreateImage(m_Device->m_Allocator, Recast<VkImageCreateInfo *>(&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<Image>();
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<u8>(imageCreateInfo.arrayLayers);
object->m_MipLevels = Cast<u8>(imageCreateInfo.mipLevels);
object->m_Flags_ = {};
vk::Image image = rawImage;
u8 layerCount = Cast<u8>(imageCreateInfo.arrayLayers);
u8 mipLevels = Cast<u8>(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<Image>(m_Device, image, allocation, imageCreateInfo.extent, imageCreateInfo.format, flags,
layerCount, mipLevels);
}
Ref<ImageCube>
@ -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<vk::Result>(vmaCreateImage(m_Device->m_Allocator, Recast<VkImageCreateInfo *>(&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<Image>();
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<u8>(imageCreateInfo.arrayLayers);
object->m_MipLevels = Cast<u8>(imageCreateInfo.mipLevels);
object->m_Flags_ = Image::CUBE_BIT;
vk::Image image = rawImage;
u8 layerCount = Cast<u8>(imageCreateInfo.arrayLayers);
u8 mipLevels = Cast<u8>(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<ImageCube>(object);
return CastImage<ImageCube>(std::make_shared<Image>(m_Device, image, allocation, imageCreateInfo.extent,
imageCreateInfo.format, flags, layerCount, mipLevels));
}
Ref<Image>
@ -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<vk::Result>(vmaCreateImage(m_Device->m_Allocator, Recast<VkImageCreateInfo *>(&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<Image>();
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<u8>(imageCreateInfo.arrayLayers);
object->m_MipLevels = Cast<u8>(imageCreateInfo.mipLevels);
vk::Image image = rawImage;
m_Device->SetName(object->m_Image, createInfo.m_Name);
u8 layerCount = Cast<u8>(imageCreateInfo.arrayLayers);
u8 mipLevels = Cast<u8>(imageCreateInfo.mipLevels);
return object;
m_Device->SetName(image, createInfo.m_Name);
return std::make_shared<Image>(m_Device, image, allocation, imageCreateInfo.extent, imageCreateInfo.format, 0,
layerCount, mipLevels);
}
Ref<Image>
@ -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<vk::Result>(vmaCreateImage(m_Device->m_Allocator, Recast<VkImageCreateInfo *>(&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<Image>();
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<u8>(imageCreateInfo.arrayLayers);
object->m_MipLevels = Cast<u8>(imageCreateInfo.mipLevels);
vk::Image image = rawImage;
m_Device->SetName(object->m_Image, createInfo.m_Name);
u8 layerCount = Cast<u8>(imageCreateInfo.arrayLayers);
u8 mipLevels = Cast<u8>(imageCreateInfo.mipLevels);
return object;
m_Device->SetName(image, createInfo.m_Name);
return std::make_shared<Image>(m_Device, image, allocation, imageCreateInfo.extent, imageCreateInfo.format, 0,
layerCount, mipLevels);
}
vk::ImageCreateInfo

View File

@ -24,14 +24,12 @@ SamplerManager::CreateSampler(const SamplerCreateInfo &createInfo)
{
auto vkCreateInfo = Cast<vk::SamplerCreateInfo>(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<Sampler>();
object->Init(m_Device, vkCreateInfo, createInfo.m_Name ? createInfo.m_Name : nullptr);
auto object = std::make_shared<Sampler>(m_Device, vkCreateInfo, createInfo.m_Name ? createInfo.m_Name : nullptr);
m_HashToSamplerIdx.emplace(vkCreateInfo, object);
return object;

View File

@ -15,7 +15,7 @@ ViewManager::ViewManager(const Device *device)
}
Ref<ImageView>
ViewManager::CreateView(const ViewCreateInfo<> &createInfo) const
ViewManager::CreateView(const ViewCreateInfo<Image> &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<ImageView>();
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<ImageView>(createInfo.m_Image, view, createInfo.m_Image->m_Extent, createInfo.m_BaseLayer,
layerCount, createInfo.m_BaseMipLevel, mipCount);
}

View File

@ -424,7 +424,6 @@ main(int, char **)
{
Time::Update();
commitManager.Update();
resourceManager.Update();
camera.m_Model *= rotate(mat4{1.0f}, Cast<f32>(45.0_deg * Time::m_Delta), vec3(0.0f, 1.0f, 0.0f));
ubo->Write(0, sizeof camera, &camera);

View File

@ -434,7 +434,6 @@ main(int, char **)
{
Time::Update();
commitManager.Update();
resourceManager.Update();
gui::StartBuild();