Reworked buffer types.
This commit is contained in:
parent
1748a48272
commit
703624eb86
|
|
@ -10,13 +10,28 @@
|
||||||
struct Device;
|
struct Device;
|
||||||
|
|
||||||
/// A Vulkan buffer wrapper.
|
/// A Vulkan buffer wrapper.
|
||||||
struct Buffer final
|
struct Buffer
|
||||||
{
|
{
|
||||||
|
enum class FlagBits : u8
|
||||||
|
{
|
||||||
|
eNone = 0x0,
|
||||||
|
eStaging = 0x1,
|
||||||
|
eUniform = 0x2,
|
||||||
|
eStorage = 0x4,
|
||||||
|
eIndex = 0x8,
|
||||||
|
eVertex = 0x10,
|
||||||
|
eIndirect = 0x20,
|
||||||
|
};
|
||||||
|
|
||||||
|
using Flags = vk::Flags<FlagBits>;
|
||||||
|
constexpr static Flags FLAGS = {};
|
||||||
|
|
||||||
const Device *m_Device = nullptr;
|
const Device *m_Device = nullptr;
|
||||||
vk::Buffer m_Buffer = nullptr;
|
vk::Buffer m_Buffer = nullptr;
|
||||||
VmaAllocation m_Allocation = nullptr;
|
VmaAllocation m_Allocation = nullptr;
|
||||||
u8 *m_Mapped = nullptr; ///< If the buffer is host visible, it should be (and stay) mapped.
|
u8 *m_Mapped = nullptr; ///< If the buffer is host visible, it should be (and stay) mapped.
|
||||||
usize m_Size = 0;
|
usize m_Size = 0;
|
||||||
|
Flags m_Flags = {};
|
||||||
|
|
||||||
/// @returns True if it is a valid vulkan buffer.
|
/// @returns True if it is a valid vulkan buffer.
|
||||||
[[nodiscard]] bool
|
[[nodiscard]] bool
|
||||||
|
|
@ -53,3 +68,50 @@ struct Buffer final
|
||||||
|
|
||||||
DISALLOW_COPY_AND_ASSIGN(Buffer);
|
DISALLOW_COPY_AND_ASSIGN(Buffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct UniformBuffer : Buffer
|
||||||
|
{
|
||||||
|
constexpr static Flags FLAGS = FlagBits::eUniform;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StorageBuffer : Buffer
|
||||||
|
{
|
||||||
|
constexpr static Flags FLAGS = FlagBits::eStorage;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IndirectBuffer : Buffer
|
||||||
|
{
|
||||||
|
constexpr static Flags FLAGS = FlagBits::eIndirect;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VertexBuffer : Buffer
|
||||||
|
{
|
||||||
|
constexpr static Flags FLAGS = FlagBits::eVertex;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IndexBuffer : Buffer
|
||||||
|
{
|
||||||
|
constexpr static Flags FLAGS = FlagBits::eIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StagingBuffer : Buffer
|
||||||
|
{
|
||||||
|
constexpr static Flags FLAGS = FlagBits::eStaging;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace concepts
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
concept AnyBuffer = std::derived_from<T, Buffer>;
|
||||||
|
|
||||||
|
template <typename T, typename TInto>
|
||||||
|
concept BufferInto = std::derived_from<T, Buffer> and std::derived_from<TInto, Buffer> and
|
||||||
|
(Cast<bool>(T::FLAGS & TInto::FLAGS) or std::same_as<Buffer, TInto>);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept AnyBufferRef = Deref<T> and AnyBuffer<DerefType<T>>;
|
||||||
|
|
||||||
|
template <typename T, typename TTo>
|
||||||
|
concept BufferRefTo = Deref<T> and BufferInto<DerefType<T>, TTo>;
|
||||||
|
|
||||||
|
} // namespace concepts
|
||||||
|
|
@ -36,38 +36,26 @@ ToOffset3D(const vk::Extent3D &extent)
|
||||||
|
|
||||||
struct Image
|
struct Image
|
||||||
{
|
{
|
||||||
|
enum class FlagBits : u8
|
||||||
|
{
|
||||||
|
eSampled = 0x1,
|
||||||
|
eStorage = 0x2,
|
||||||
|
eCube = 0x4,
|
||||||
|
};
|
||||||
|
|
||||||
|
using Flags = vk::Flags<FlagBits>;
|
||||||
|
constexpr static Flags FLAGS = {};
|
||||||
|
|
||||||
const Device *m_Device = nullptr;
|
const Device *m_Device = nullptr;
|
||||||
vk::Image m_Image = nullptr;
|
vk::Image m_Image = nullptr;
|
||||||
VmaAllocation m_Allocation = nullptr;
|
VmaAllocation m_Allocation = nullptr;
|
||||||
vk::Extent3D m_Extent;
|
vk::Extent3D m_Extent;
|
||||||
vk::Format m_Format;
|
vk::Format m_Format;
|
||||||
u8 m_EmptyPadding_ = 0;
|
u8 m_EmptyPadding_ = 0;
|
||||||
u8 m_Flags_ = 0;
|
Flags m_Flags_ = {};
|
||||||
u8 m_LayerCount = 0;
|
u8 m_LayerCount = 0;
|
||||||
u8 m_MipLevels = 0;
|
u8 m_MipLevels = 0;
|
||||||
|
|
||||||
constexpr static u8 SAMPLED_BIT = 1 << 7;
|
|
||||||
constexpr static u8 STORAGE_BIT = 1 << 6;
|
|
||||||
constexpr static u8 CUBE_BIT = 1 << 5;
|
|
||||||
|
|
||||||
[[nodiscard]] bool
|
|
||||||
IsSampled() const
|
|
||||||
{
|
|
||||||
return m_Flags_ & SAMPLED_BIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] bool
|
|
||||||
IsStorage() const
|
|
||||||
{
|
|
||||||
return m_Flags_ & STORAGE_BIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] bool
|
|
||||||
IsCube() const
|
|
||||||
{
|
|
||||||
return m_Flags_ & CUBE_BIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] bool
|
[[nodiscard]] bool
|
||||||
IsValid() const
|
IsValid() const
|
||||||
{
|
{
|
||||||
|
|
@ -80,18 +68,12 @@ struct Image
|
||||||
return m_MipLevels;
|
return m_MipLevels;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
Conforms(const Image &)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DestroyView(vk::ImageView imageView) const;
|
void DestroyView(vk::ImageView imageView) const;
|
||||||
|
|
||||||
// Constructors.
|
// Constructors.
|
||||||
|
|
||||||
explicit Image(const Device *device, vk::Image image, VmaAllocation allocation, vk::Extent3D extent,
|
explicit Image(const Device *device, vk::Image image, VmaAllocation allocation, vk::Extent3D extent,
|
||||||
vk::Format format, u8 flags, u8 layerCount, u8 mipLevels);
|
vk::Format format, Flags flags, u8 layerCount, u8 mipLevels);
|
||||||
|
|
||||||
Image(Image &&other) noexcept;
|
Image(Image &&other) noexcept;
|
||||||
Image &operator=(Image &&other) noexcept;
|
Image &operator=(Image &&other) noexcept;
|
||||||
|
|
@ -101,106 +83,50 @@ struct Image
|
||||||
DISALLOW_COPY_AND_ASSIGN(Image);
|
DISALLOW_COPY_AND_ASSIGN(Image);
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace concepts
|
|
||||||
{
|
|
||||||
template <typename T>
|
|
||||||
concept Image = std::derived_from<T, Image>;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
concept ImageRef = Derefencable<T> and Image<DereferencesTo<T>>;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
concept SampledImage = requires() {
|
|
||||||
{ T::SAMPLED } -> std::convertible_to<bool>;
|
|
||||||
} and T::SAMPLED and Image<T>;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
concept SampledImageRef = Derefencable<T> and SampledImage<DereferencesTo<T>>;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
concept ImageCube = requires() {
|
|
||||||
{ T::CUBE } -> std::convertible_to<bool>;
|
|
||||||
} and T::CUBE and Image<T>;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
concept ImageCubeRef = Derefencable<T> and ImageCube<DereferencesTo<T>>;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
concept StorageImage = requires() {
|
|
||||||
{ T::STORAGE } -> std::convertible_to<bool>;
|
|
||||||
} and T::STORAGE and Image<T>;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
concept StorageImageRef = Derefencable<T> and StorageImage<DereferencesTo<T>>;
|
|
||||||
|
|
||||||
} // namespace concepts
|
|
||||||
|
|
||||||
struct Texture : Image
|
struct Texture : Image
|
||||||
{
|
{
|
||||||
constexpr static bool SAMPLED = true;
|
constexpr static Flags FLAGS = FlagBits::eSampled;
|
||||||
|
|
||||||
static bool
|
|
||||||
Conforms(const Image &other)
|
|
||||||
{
|
|
||||||
return other.IsSampled();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ImageCube : Image
|
struct ImageCube : Image
|
||||||
{
|
{
|
||||||
constexpr static bool CUBE = true;
|
constexpr static Flags FLAGS = FlagBits::eCube;
|
||||||
|
|
||||||
static bool
|
|
||||||
Conforms(const Image &other)
|
|
||||||
{
|
|
||||||
return other.IsCube();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TextureCube : Image
|
struct TextureCube : Image
|
||||||
{
|
{
|
||||||
constexpr static bool SAMPLED = true;
|
constexpr static Flags FLAGS = Texture::FLAGS | ImageCube::FLAGS;
|
||||||
constexpr static bool CUBE = true;
|
|
||||||
|
|
||||||
static bool
|
|
||||||
Conforms(const Image &other)
|
|
||||||
{
|
|
||||||
return other.IsSampled() && other.IsCube();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StorageImage : Image
|
struct StorageImage : Image
|
||||||
{
|
{
|
||||||
constexpr static bool STORAGE = true;
|
constexpr static Flags FLAGS = FlagBits::eStorage;
|
||||||
|
|
||||||
static bool
|
|
||||||
Conforms(const Image &other)
|
|
||||||
{
|
|
||||||
return other.IsStorage();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StorageTexture : StorageImage
|
struct StorageTexture : StorageImage
|
||||||
{
|
{
|
||||||
constexpr static bool SAMPLED = true;
|
constexpr static Flags FLAGS = StorageImage::FLAGS | Texture::FLAGS;
|
||||||
constexpr static bool STORAGE = true;
|
|
||||||
|
|
||||||
static bool
|
|
||||||
Conforms(const Image &other)
|
|
||||||
{
|
|
||||||
return other.IsStorage() && other.IsSampled();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StorageTextureCube : StorageImage
|
struct StorageTextureCube : StorageImage
|
||||||
{
|
{
|
||||||
constexpr static bool SAMPLED = true;
|
constexpr static Flags FLAGS = StorageImage::FLAGS | Texture::FLAGS | ImageCube::FLAGS;
|
||||||
constexpr static bool CUBE = true;
|
|
||||||
constexpr static bool STORAGE = true;
|
|
||||||
|
|
||||||
static bool
|
|
||||||
Conforms(const Image &other)
|
|
||||||
{
|
|
||||||
return other.IsStorage() && other.IsSampled() && other.IsCube();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace concepts
|
||||||
|
{
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept AnyImage = std::derived_from<T, Image>;
|
||||||
|
|
||||||
|
template <typename T, typename TInto>
|
||||||
|
concept ImageInto = std::derived_from<T, Image> and std::derived_from<TInto, Image> and
|
||||||
|
(Cast<bool>(T::FLAGS & TInto::FLAGS) or std::same_as<Image, TInto>);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
concept AnyImageRef = Deref<T> and AnyImage<DerefType<T>>;
|
||||||
|
|
||||||
|
template <typename T, typename TTo>
|
||||||
|
concept ImageRefTo = Deref<T> and ImageInto<DerefType<T>, TTo>;
|
||||||
|
|
||||||
|
} // namespace concepts
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
|
||||||
template <concepts::Image TImage>
|
template <concepts::AnyImage TImage>
|
||||||
struct View
|
struct View
|
||||||
{
|
{
|
||||||
using ImageType = TImage;
|
using ImageType = TImage;
|
||||||
|
|
@ -93,31 +93,16 @@ using StorageTextureCubeView = View<StorageTextureCube>;
|
||||||
|
|
||||||
namespace concepts
|
namespace concepts
|
||||||
{
|
{
|
||||||
template <typename TView>
|
template <typename T>
|
||||||
concept View = std::derived_from<TView, View<typename TView::ImageType>>;
|
concept View = std::derived_from<T, View<typename T::ImageType>>;
|
||||||
|
|
||||||
|
template <typename T, typename TTo>
|
||||||
|
concept ViewTo = View<T> and ImageInto<typename T::ImageType, TTo>;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept ViewRef = Derefencable<T> and View<DereferencesTo<T>>;
|
concept ViewRef = Deref<T> and View<DerefType<T>>;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T, typename TTo>
|
||||||
concept ImageView = View<T> and Image<typename T::ImageType>;
|
concept ViewRefTo = ViewRef<T> and ImageInto<typename DerefType<T>::ImageType, TTo>;
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
concept ImageViewRef = Derefencable<T> and ImageView<DereferencesTo<T>>;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
concept ImageCubeView = View<T> and ImageCube<typename T::ImageType>;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
concept SampledImageView = View<T> and SampledImage<typename T::ImageType>;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
concept SampledImageViewRef = Derefencable<T> and SampledImageView<DereferencesTo<T>>;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
concept StorageImageView = View<T> and StorageImage<typename T::ImageType>;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
concept StorageImageViewRef = Derefencable<T> and StorageImageView<DereferencesTo<T>>;
|
|
||||||
|
|
||||||
} // namespace concepts
|
} // namespace concepts
|
||||||
|
|
@ -13,11 +13,16 @@ struct Image;
|
||||||
namespace concepts
|
namespace concepts
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T>
|
||||||
concept Derefencable = requires(T a) {
|
concept Deref = requires(T a) {
|
||||||
{ *a };
|
{ *a };
|
||||||
};
|
};
|
||||||
|
|
||||||
template <Derefencable T>
|
template <typename TRef, typename TVal>
|
||||||
using DereferencesTo = std::remove_cvref_t<decltype(*std::declval<T>())>;
|
concept DerefTo = requires(TRef a) {
|
||||||
|
{ *a } -> std::convertible_to<TVal>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <Deref T>
|
||||||
|
using DerefType = std::remove_cvref_t<decltype(*std::declval<T>())>;
|
||||||
|
|
||||||
} // namespace concepts
|
} // namespace concepts
|
||||||
|
|
@ -10,17 +10,25 @@
|
||||||
|
|
||||||
namespace systems
|
namespace systems
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template <std::derived_from<Buffer> TTo, std::derived_from<Buffer> TFrom>
|
||||||
|
static Ref<TTo>
|
||||||
|
CastBuffer(const Ref<TFrom> &from)
|
||||||
|
{
|
||||||
|
if constexpr (not concepts::BufferInto<TFrom, TTo>)
|
||||||
|
assert(TTo::FLAGS & from->m_Flags);
|
||||||
|
return std::reinterpret_pointer_cast<TTo>(from);
|
||||||
|
}
|
||||||
|
|
||||||
class BufferManager final
|
class BufferManager final
|
||||||
{
|
{
|
||||||
using Handle = Ref<Buffer>;
|
|
||||||
|
|
||||||
const Device *m_Device = nullptr;
|
const Device *m_Device = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BufferManager(const Device *device);
|
explicit BufferManager(const Device *device);
|
||||||
|
|
||||||
[[nodiscard]] Handle CreateStorageBuffer(usize size, cstr name = nullptr);
|
[[nodiscard]] Ref<StorageBuffer> CreateStorageBuffer(usize size, cstr name = nullptr) const;
|
||||||
[[nodiscard]] Handle CreateUniformBuffer(usize size, cstr name = nullptr);
|
[[nodiscard]] Ref<UniformBuffer> CreateUniformBuffer(usize size, cstr name = nullptr) const;
|
||||||
[[nodiscard]] Handle CreateStagingBuffer(usize size, cstr name = nullptr);
|
[[nodiscard]] Ref<StagingBuffer> CreateStagingBuffer(usize size, cstr name = nullptr) const;
|
||||||
};
|
};
|
||||||
} // namespace systems
|
} // namespace systems
|
||||||
|
|
@ -224,7 +224,7 @@ class CommitManager
|
||||||
|
|
||||||
// Commit Storage Images
|
// Commit Storage Images
|
||||||
ResId<StorageImageView>
|
ResId<StorageImageView>
|
||||||
CommitStorageImage(const concepts::StorageImageViewRef auto &image)
|
CommitStorageImage(const concepts::ViewRefTo<StorageImage> auto &image)
|
||||||
{
|
{
|
||||||
return CommitStorageImage(CastView<StorageImageView>(image));
|
return CommitStorageImage(CastView<StorageImageView>(image));
|
||||||
}
|
}
|
||||||
|
|
@ -233,19 +233,17 @@ class CommitManager
|
||||||
|
|
||||||
// Sampled Images
|
// Sampled Images
|
||||||
ResId<TextureView>
|
ResId<TextureView>
|
||||||
CommitTexture(const concepts::SampledImageViewRef auto &image, const Ref<Sampler> &sampler)
|
CommitTexture(const concepts::ViewRefTo<Texture> auto &image, const Ref<Sampler> &sampler)
|
||||||
{
|
{
|
||||||
return CommitTexture(CastView<TextureView>(image), sampler);
|
return CommitTexture(CastView<TextureView>(image), sampler);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResId<TextureView>
|
ResId<TextureView>
|
||||||
CommitTexture(const concepts::SampledImageViewRef auto &image)
|
CommitTexture(const concepts::ViewRefTo<Texture> auto &image)
|
||||||
{
|
{
|
||||||
return CommitTexture(CastView<TextureView>(image));
|
return CommitTexture(CastView<TextureView>(image));
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assert(concepts::SampledImageViewRef<Ref<TextureView>>);
|
|
||||||
|
|
||||||
ResId<TextureView> CommitTexture(const Ref<TextureView> &handle);
|
ResId<TextureView> CommitTexture(const Ref<TextureView> &handle);
|
||||||
ResId<TextureView> CommitTexture(const Ref<TextureView> &image, const Ref<Sampler> &sampler);
|
ResId<TextureView> CommitTexture(const Ref<TextureView> &image, const Ref<Sampler> &sampler);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,12 @@
|
||||||
namespace systems
|
namespace systems
|
||||||
{
|
{
|
||||||
|
|
||||||
template <std::derived_from<Image> TTo>
|
template <std::derived_from<Image> TTo, std::derived_from<Image> TFrom>
|
||||||
static Ref<TTo>
|
static Ref<TTo>
|
||||||
CastImage(const concepts::ImageRef auto &from)
|
CastImage(const Ref<TFrom> &from)
|
||||||
{
|
{
|
||||||
assert(TTo::Conforms(*from.get()));
|
if constexpr (not concepts::ImageInto<TFrom, TTo>)
|
||||||
|
assert(TTo::FLAGS & from->m_Flags_);
|
||||||
return std::reinterpret_pointer_cast<TTo>(from);
|
return std::reinterpret_pointer_cast<TTo>(from);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -55,10 +56,11 @@ struct DepthStencilImageCreateInfo
|
||||||
class ImageManager final
|
class ImageManager final
|
||||||
{
|
{
|
||||||
const Device *m_Device;
|
const Device *m_Device;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ImageManager(const Device *device);
|
explicit ImageManager(const Device *device);
|
||||||
|
|
||||||
template <concepts::Image T>
|
template <concepts::ImageInto<Texture> T>
|
||||||
[[nodiscard]] Ref<T>
|
[[nodiscard]] Ref<T>
|
||||||
CreateTexture2D(const Texture2DCreateInfo &createInfo)
|
CreateTexture2D(const Texture2DCreateInfo &createInfo)
|
||||||
{
|
{
|
||||||
|
|
@ -66,7 +68,7 @@ class ImageManager final
|
||||||
return CastImage<T>(handle);
|
return CastImage<T>(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <concepts::Image T>
|
template <concepts::ImageInto<TextureCube> T>
|
||||||
[[nodiscard]] Ref<T>
|
[[nodiscard]] Ref<T>
|
||||||
CreateTextureCube(const TextureCubeCreateInfo &createInfo)
|
CreateTextureCube(const TextureCubeCreateInfo &createInfo)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ class ResourceManager
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template <concepts::ImageView T>
|
template <concepts::ViewTo<Image> T>
|
||||||
[[nodiscard]] Ref<T>
|
[[nodiscard]] Ref<T>
|
||||||
CreateTexture2D(const Texture2DCreateInfo &createInfo)
|
CreateTexture2D(const Texture2DCreateInfo &createInfo)
|
||||||
{
|
{
|
||||||
|
|
@ -36,7 +36,7 @@ class ResourceManager
|
||||||
return CastView<T>(handle);
|
return CastView<T>(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <concepts::ImageCubeView T>
|
template <concepts::ViewTo<ImageCube> T>
|
||||||
[[nodiscard]] Ref<T>
|
[[nodiscard]] Ref<T>
|
||||||
CreateTextureCube(const TextureCubeCreateInfo &createInfo)
|
CreateTextureCube(const TextureCubeCreateInfo &createInfo)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -13,15 +13,16 @@
|
||||||
namespace systems
|
namespace systems
|
||||||
{
|
{
|
||||||
|
|
||||||
template <concepts::ImageView TTo>
|
template <concepts::View TTo, std::derived_from<Image> TFrom>
|
||||||
static Ref<TTo>
|
static Ref<TTo>
|
||||||
CastView(const concepts::ImageViewRef auto &from)
|
CastView(const Ref<View<TFrom>> &from)
|
||||||
{
|
{
|
||||||
assert(TTo::ImageType::Conforms(*from->m_Image.get()));
|
if constexpr (not concepts::ImageInto<TFrom, typename TTo::ImageType>)
|
||||||
|
assert(TTo::ImageType::FLAGS & from->m_Image->m_Flags_);
|
||||||
return std::reinterpret_pointer_cast<TTo>(from);
|
return std::reinterpret_pointer_cast<TTo>(from);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <concepts::Image TImage>
|
template <concepts::AnyImage TImage>
|
||||||
struct ViewCreateInfo
|
struct ViewCreateInfo
|
||||||
{
|
{
|
||||||
using ImageType = TImage;
|
using ImageType = TImage;
|
||||||
|
|
@ -91,7 +92,7 @@ class ViewManager final
|
||||||
public:
|
public:
|
||||||
explicit ViewManager(const Device *device);
|
explicit ViewManager(const Device *device);
|
||||||
|
|
||||||
template <concepts::ImageView TImageView>
|
template <concepts::View TImageView>
|
||||||
Ref<TImageView>
|
Ref<TImageView>
|
||||||
CreateView(const ViewCreateInfo<typename TImageView::ImageType> &createInfo)
|
CreateView(const ViewCreateInfo<typename TImageView::ImageType> &createInfo)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,19 @@ Buffer::Buffer(const Device *device, const usize size, const vk::BufferUsageFlag
|
||||||
m_Size = size;
|
m_Size = size;
|
||||||
m_Allocation = allocation;
|
m_Allocation = allocation;
|
||||||
m_Mapped = Cast<u8 *>(allocationInfo.pMappedData);
|
m_Mapped = Cast<u8 *>(allocationInfo.pMappedData);
|
||||||
|
m_Flags = {};
|
||||||
|
if (bufferUsage & vk::BufferUsageFlagBits::eTransferSrc)
|
||||||
|
m_Flags |= FlagBits::eStaging;
|
||||||
|
if (bufferUsage & vk::BufferUsageFlagBits::eIndexBuffer)
|
||||||
|
m_Flags |= FlagBits::eIndex;
|
||||||
|
if (bufferUsage & vk::BufferUsageFlagBits::eIndirectBuffer)
|
||||||
|
m_Flags |= FlagBits::eIndirect;
|
||||||
|
if (bufferUsage & vk::BufferUsageFlagBits::eVertexBuffer)
|
||||||
|
m_Flags |= FlagBits::eVertex;
|
||||||
|
if (bufferUsage & vk::BufferUsageFlagBits::eUniformBuffer)
|
||||||
|
m_Flags |= FlagBits::eUniform;
|
||||||
|
if (bufferUsage & vk::BufferUsageFlagBits::eStorageBuffer)
|
||||||
|
m_Flags |= FlagBits::eStorage;
|
||||||
|
|
||||||
device->SetName(m_Buffer, name);
|
device->SetName(m_Buffer, name);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ Image::~Image()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
vmaDestroyImage(m_Device->m_Allocator, Take(m_Image), m_Allocation);
|
vmaDestroyImage(m_Device->m_Allocator, Take(m_Image), m_Allocation);
|
||||||
m_Flags_ = 0;
|
m_Flags_ = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -463,7 +463,7 @@ Image::Image(Image &&other) noexcept
|
||||||
}
|
}
|
||||||
|
|
||||||
Image::Image(const Device *device, const vk::Image image, const VmaAllocation allocation, const vk::Extent3D extent,
|
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)
|
const vk::Format format, const Flags flags, const u8 layerCount, const u8 mipLevels)
|
||||||
: m_Device{device}
|
: m_Device{device}
|
||||||
, m_Image{image}
|
, m_Image{image}
|
||||||
, m_Allocation{allocation}
|
, m_Allocation{allocation}
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@
|
||||||
|
|
||||||
using namespace systems;
|
using namespace systems;
|
||||||
|
|
||||||
Ref<Buffer>
|
Ref<StorageBuffer>
|
||||||
BufferManager::CreateStorageBuffer(const usize size, const cstr name)
|
BufferManager::CreateStorageBuffer(const usize size, const cstr name) const
|
||||||
{
|
{
|
||||||
// TODO: Storage and Index buffer are set.
|
// TODO: Storage and Index buffer are set.
|
||||||
// This is hacky and should be improved.
|
// This is hacky and should be improved.
|
||||||
|
|
@ -19,30 +19,131 @@ BufferManager::CreateStorageBuffer(const usize size, const cstr name)
|
||||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT |
|
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT |
|
||||||
VMA_ALLOCATION_CREATE_MAPPED_BIT;
|
VMA_ALLOCATION_CREATE_MAPPED_BIT;
|
||||||
constexpr VmaMemoryUsage memoryUsage = VMA_MEMORY_USAGE_AUTO;
|
constexpr VmaMemoryUsage memoryUsage = VMA_MEMORY_USAGE_AUTO;
|
||||||
return std::make_shared<Buffer>(m_Device, size, usage, createFlags, memoryUsage, name);
|
return std::make_shared<StorageBuffer>(Buffer{m_Device, size, usage, createFlags, memoryUsage, name});
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Buffer>
|
Ref<UniformBuffer>
|
||||||
BufferManager::CreateUniformBuffer(const usize size, const cstr name)
|
BufferManager::CreateUniformBuffer(const usize size, const cstr name) const
|
||||||
{
|
{
|
||||||
constexpr vk::BufferUsageFlags usage = vk::BufferUsageFlagBits::eUniformBuffer;
|
constexpr vk::BufferUsageFlags usage = vk::BufferUsageFlagBits::eUniformBuffer;
|
||||||
constexpr VmaAllocationCreateFlags createFlags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
|
constexpr VmaAllocationCreateFlags createFlags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
|
||||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT |
|
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT |
|
||||||
VMA_ALLOCATION_CREATE_MAPPED_BIT;
|
VMA_ALLOCATION_CREATE_MAPPED_BIT;
|
||||||
constexpr VmaMemoryUsage memoryUsage = VMA_MEMORY_USAGE_AUTO;
|
constexpr VmaMemoryUsage memoryUsage = VMA_MEMORY_USAGE_AUTO;
|
||||||
return std::make_shared<Buffer>(m_Device, size, usage, createFlags, memoryUsage, name);
|
return std::make_shared<UniformBuffer>(Buffer{m_Device, size, usage, createFlags, memoryUsage, name});
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Buffer>
|
Ref<StagingBuffer>
|
||||||
BufferManager::CreateStagingBuffer(const usize size, const cstr name)
|
BufferManager::CreateStagingBuffer(const usize size, const cstr name) const
|
||||||
{
|
{
|
||||||
constexpr vk::BufferUsageFlags usage = vk::BufferUsageFlagBits::eTransferSrc;
|
constexpr vk::BufferUsageFlags usage = vk::BufferUsageFlagBits::eTransferSrc;
|
||||||
constexpr VmaAllocationCreateFlags createFlags =
|
constexpr VmaAllocationCreateFlags createFlags =
|
||||||
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT;
|
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT;
|
||||||
constexpr VmaMemoryUsage memoryUsage = VMA_MEMORY_USAGE_AUTO;
|
constexpr VmaMemoryUsage memoryUsage = VMA_MEMORY_USAGE_AUTO;
|
||||||
return std::make_shared<Buffer>(m_Device, size, usage, createFlags, memoryUsage, name);
|
return std::make_shared<StagingBuffer>(Buffer{m_Device, size, usage, createFlags, memoryUsage, name});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// void
|
||||||
|
// UniformBuffer::Init(const Device *device, const usize size, const cstr name)
|
||||||
|
//{
|
||||||
|
// Allocate(device, size, vk::BufferUsageFlagBits::eUniformBuffer,
|
||||||
|
// VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
|
||||||
|
// VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
|
||||||
|
// VMA_MEMORY_USAGE_AUTO, name);
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
// void
|
||||||
|
// StorageBuffer::Init(const Device *device, usize size, bool hostVisible, cstr name)
|
||||||
|
//{
|
||||||
|
// Init(device, size, hostVisible, false, name);
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
// void
|
||||||
|
// StorageBuffer::Init(const Device *device, usize size, bool hostVisible, bool deviceAddress, cstr name)
|
||||||
|
//{
|
||||||
|
// vk::BufferUsageFlags usage = vk::BufferUsageFlagBits::eStorageBuffer;
|
||||||
|
// if (deviceAddress)
|
||||||
|
// {
|
||||||
|
// usage |= vk::BufferUsageFlagBits::eShaderDeviceAddress;
|
||||||
|
// }
|
||||||
|
// if (hostVisible)
|
||||||
|
// {
|
||||||
|
// Allocate(device, size, usage,
|
||||||
|
// VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
|
||||||
|
// VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
|
||||||
|
// VMA_MEMORY_USAGE_AUTO, name);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// usage |= vk::BufferUsageFlagBits::eTransferDst;
|
||||||
|
// Allocate(device, size, usage, 0, VMA_MEMORY_USAGE_AUTO, name);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
// void
|
||||||
|
// StorageIndexBuffer::Init(const Device *device, usize size, bool hostVisible, bool deviceAddress, cstr name)
|
||||||
|
//{
|
||||||
|
// vk::BufferUsageFlags usage = vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eIndexBuffer;
|
||||||
|
// if (deviceAddress)
|
||||||
|
// {
|
||||||
|
// usage |= vk::BufferUsageFlagBits::eShaderDeviceAddress;
|
||||||
|
// }
|
||||||
|
// if (hostVisible)
|
||||||
|
// {
|
||||||
|
// Allocate(device, size, usage,
|
||||||
|
// VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
|
||||||
|
// VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
|
||||||
|
// VMA_MEMORY_USAGE_AUTO, name);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// usage |= vk::BufferUsageFlagBits::eTransferDst;
|
||||||
|
// Allocate(device, size, usage, 0, VMA_MEMORY_USAGE_AUTO, name);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
// void
|
||||||
|
// IndirectBuffer::Init(const Device *device, usize size, bool hostVisible, cstr name)
|
||||||
|
//{
|
||||||
|
// vk::BufferUsageFlags usage = vk::BufferUsageFlagBits::eStorageBuffer | vk::BufferUsageFlagBits::eIndirectBuffer |
|
||||||
|
// vk::BufferUsageFlagBits::eShaderDeviceAddress;
|
||||||
|
// if (hostVisible)
|
||||||
|
// {
|
||||||
|
// Allocate(device, size, usage,
|
||||||
|
// VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT |
|
||||||
|
// VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
|
||||||
|
// VMA_MEMORY_USAGE_AUTO, name);
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// usage |= vk::BufferUsageFlagBits::eTransferDst;
|
||||||
|
// Allocate(device, size, usage, 0, VMA_MEMORY_USAGE_AUTO, name);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
// void
|
||||||
|
// VertexBuffer::Init(const Device *device, usize size, cstr name)
|
||||||
|
//{
|
||||||
|
// Allocate(device, size, vk::BufferUsageFlagBits::eVertexBuffer | vk::BufferUsageFlagBits::eTransferDst, 0,
|
||||||
|
// VMA_MEMORY_USAGE_AUTO, name);
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
// void
|
||||||
|
// IndexBuffer::Init(const Device *device, usize size, cstr name)
|
||||||
|
//{
|
||||||
|
// Allocate(device, size, vk::BufferUsageFlagBits::eIndexBuffer | vk::BufferUsageFlagBits::eTransferDst, 0,
|
||||||
|
// VMA_MEMORY_USAGE_AUTO, name);
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
// void
|
||||||
|
// StagingBuffer::Init(const Device *device, usize size, cstr name)
|
||||||
|
//{
|
||||||
|
// Allocate(device, size, vk::BufferUsageFlagBits::eTransferSrc,
|
||||||
|
// VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
|
||||||
|
// VMA_MEMORY_USAGE_AUTO, name);
|
||||||
|
//}
|
||||||
|
|
||||||
BufferManager::BufferManager(const Device *device)
|
BufferManager::BufferManager(const Device *device)
|
||||||
: m_Device{device}
|
: m_Device{device}
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -49,11 +49,11 @@ ImageManager::CreateTexture2D(const Texture2DCreateInfo &createInfo)
|
||||||
|
|
||||||
u8 layerCount = Cast<u8>(imageCreateInfo.arrayLayers);
|
u8 layerCount = Cast<u8>(imageCreateInfo.arrayLayers);
|
||||||
u8 mipLevels = Cast<u8>(imageCreateInfo.mipLevels);
|
u8 mipLevels = Cast<u8>(imageCreateInfo.mipLevels);
|
||||||
u8 flags = 0;
|
Image::Flags flags = {};
|
||||||
if (createInfo.m_IsSampled)
|
if (createInfo.m_IsSampled)
|
||||||
flags |= Image::SAMPLED_BIT;
|
flags |= Image::FlagBits::eSampled;
|
||||||
if (createInfo.m_IsStorage)
|
if (createInfo.m_IsStorage)
|
||||||
flags |= Image::STORAGE_BIT;
|
flags |= Image::FlagBits::eStorage;
|
||||||
|
|
||||||
m_Device->SetName(image, createInfo.m_Name);
|
m_Device->SetName(image, createInfo.m_Name);
|
||||||
|
|
||||||
|
|
@ -80,11 +80,11 @@ ImageManager::CreateTextureCube(const TextureCubeCreateInfo &createInfo)
|
||||||
|
|
||||||
u8 layerCount = Cast<u8>(imageCreateInfo.arrayLayers);
|
u8 layerCount = Cast<u8>(imageCreateInfo.arrayLayers);
|
||||||
u8 mipLevels = Cast<u8>(imageCreateInfo.mipLevels);
|
u8 mipLevels = Cast<u8>(imageCreateInfo.mipLevels);
|
||||||
u8 flags = Image::CUBE_BIT;
|
Image::Flags flags = Image::FlagBits::eCube;
|
||||||
if (createInfo.m_IsSampled)
|
if (createInfo.m_IsSampled)
|
||||||
flags |= Image::SAMPLED_BIT;
|
flags |= Image::FlagBits::eSampled;
|
||||||
if (createInfo.m_IsStorage)
|
if (createInfo.m_IsStorage)
|
||||||
flags |= Image::STORAGE_BIT;
|
flags |= Image::FlagBits::eStorage;
|
||||||
|
|
||||||
m_Device->SetName(image, createInfo.m_Name);
|
m_Device->SetName(image, createInfo.m_Name);
|
||||||
|
|
||||||
|
|
@ -114,8 +114,8 @@ ImageManager::CreateAttachment(const AttachmentCreateInfo &createInfo)
|
||||||
|
|
||||||
m_Device->SetName(image, createInfo.m_Name);
|
m_Device->SetName(image, createInfo.m_Name);
|
||||||
|
|
||||||
return std::make_shared<Image>(m_Device, image, allocation, imageCreateInfo.extent, imageCreateInfo.format, 0,
|
return std::make_shared<Image>(m_Device, image, allocation, imageCreateInfo.extent, imageCreateInfo.format,
|
||||||
layerCount, mipLevels);
|
Image::Flags{}, layerCount, mipLevels);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Image>
|
Ref<Image>
|
||||||
|
|
@ -140,8 +140,8 @@ ImageManager::CreateDepthStencilImage(const DepthStencilImageCreateInfo &createI
|
||||||
|
|
||||||
m_Device->SetName(image, createInfo.m_Name);
|
m_Device->SetName(image, createInfo.m_Name);
|
||||||
|
|
||||||
return std::make_shared<Image>(m_Device, image, allocation, imageCreateInfo.extent, imageCreateInfo.format, 0,
|
return std::make_shared<Image>(m_Device, image, allocation, imageCreateInfo.extent, imageCreateInfo.format,
|
||||||
layerCount, mipLevels);
|
Image::Flags{}, layerCount, mipLevels);
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::ImageCreateInfo
|
vk::ImageCreateInfo
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ GenerateMipMaps(vk::CommandBuffer commandBuffer, const Ref<Texture> &textureView
|
||||||
vk::ImageLayout finalLayout, vk::PipelineStageFlags2 prevStage, vk::PipelineStageFlags2 finalStage);
|
vk::ImageLayout finalLayout, vk::PipelineStageFlags2 prevStage, vk::PipelineStageFlags2 finalStage);
|
||||||
|
|
||||||
void
|
void
|
||||||
GenerateMipMaps(vk::CommandBuffer commandBuffer, concepts::SampledImageRef auto &texture, vk::ImageLayout initialLayout,
|
GenerateMipMaps(vk::CommandBuffer commandBuffer, concepts::ImageRefTo<Texture> auto &texture, vk::ImageLayout initialLayout,
|
||||||
vk::ImageLayout finalLayout,
|
vk::ImageLayout finalLayout,
|
||||||
vk::PipelineStageFlags2 prevStage = vk::PipelineStageFlagBits2::eAllCommands,
|
vk::PipelineStageFlags2 prevStage = vk::PipelineStageFlagBits2::eAllCommands,
|
||||||
vk::PipelineStageFlags2 finalStage = vk::PipelineStageFlagBits2::eAllCommands)
|
vk::PipelineStageFlags2 finalStage = vk::PipelineStageFlagBits2::eAllCommands)
|
||||||
|
|
@ -149,7 +149,7 @@ GenerateMipMaps(vk::CommandBuffer commandBuffer, concepts::SampledImageRef auto
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GenerateMipMaps(vk::CommandBuffer commandBuffer, concepts::SampledImageViewRef auto &texture,
|
GenerateMipMaps(vk::CommandBuffer commandBuffer, concepts::ViewRefTo<Texture> auto &texture,
|
||||||
vk::ImageLayout initialLayout, vk::ImageLayout finalLayout,
|
vk::ImageLayout initialLayout, vk::ImageLayout finalLayout,
|
||||||
vk::PipelineStageFlags2 prevStage = vk::PipelineStageFlagBits2::eAllCommands,
|
vk::PipelineStageFlags2 prevStage = vk::PipelineStageFlagBits2::eAllCommands,
|
||||||
vk::PipelineStageFlags2 finalStage = vk::PipelineStageFlagBits2::eAllCommands)
|
vk::PipelineStageFlags2 finalStage = vk::PipelineStageFlagBits2::eAllCommands)
|
||||||
|
|
@ -157,5 +157,3 @@ GenerateMipMaps(vk::CommandBuffer commandBuffer, concepts::SampledImageViewRef a
|
||||||
GenerateMipMaps(commandBuffer, systems::CastImage<Texture>(texture->m_Image), initialLayout, finalLayout, prevStage,
|
GenerateMipMaps(commandBuffer, systems::CastImage<Texture>(texture->m_Image), initialLayout, finalLayout, prevStage,
|
||||||
finalStage);
|
finalStage);
|
||||||
}
|
}
|
||||||
|
|
||||||
static_assert(concepts::SampledImageRef<Ref<Texture>>);
|
|
||||||
Loading…
Reference in New Issue