vulkan_memory_allocator: Add "download" memory usage hint
Allow users of the allocator to hint memory usage for downloads. This removes the non-descriptive boolean passed for "host visible" or not host visible memory commits, and uses an enum to hint device local, upload and download usages.
This commit is contained in:
parent
fade63b58e
commit
72541af3bc
9 changed files with 86 additions and 45 deletions
|
@ -156,11 +156,13 @@ MemoryAllocator::MemoryAllocator(const Device& device_)
|
|||
|
||||
MemoryAllocator::~MemoryAllocator() = default;
|
||||
|
||||
MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, bool host_visible) {
|
||||
MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, MemoryUsage usage) {
|
||||
const u64 chunk_size = GetAllocationChunkSize(requirements.size);
|
||||
|
||||
// When a host visible commit is asked, search for host visible and coherent, otherwise search
|
||||
// for a fast device local type.
|
||||
// TODO: Deduce memory types from usage in a better way
|
||||
const bool host_visible = IsHostVisible(usage);
|
||||
const VkMemoryPropertyFlags wanted_properties =
|
||||
host_visible ? VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
|
||||
: VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
|
@ -176,14 +178,14 @@ MemoryCommit MemoryAllocator::Commit(const VkMemoryRequirements& requirements, b
|
|||
return TryAllocCommit(requirements, wanted_properties).value();
|
||||
}
|
||||
|
||||
MemoryCommit MemoryAllocator::Commit(const vk::Buffer& buffer, bool host_visible) {
|
||||
auto commit = Commit(device.GetLogical().GetBufferMemoryRequirements(*buffer), host_visible);
|
||||
MemoryCommit MemoryAllocator::Commit(const vk::Buffer& buffer, MemoryUsage usage) {
|
||||
auto commit = Commit(device.GetLogical().GetBufferMemoryRequirements(*buffer), usage);
|
||||
buffer.BindMemory(commit.Memory(), commit.Offset());
|
||||
return commit;
|
||||
}
|
||||
|
||||
MemoryCommit MemoryAllocator::Commit(const vk::Image& image, bool host_visible) {
|
||||
auto commit = Commit(device.GetLogical().GetImageMemoryRequirements(*image), host_visible);
|
||||
MemoryCommit MemoryAllocator::Commit(const vk::Image& image, MemoryUsage usage) {
|
||||
auto commit = Commit(device.GetLogical().GetImageMemoryRequirements(*image), usage);
|
||||
image.BindMemory(commit.Memory(), commit.Offset());
|
||||
return commit;
|
||||
}
|
||||
|
@ -224,4 +226,16 @@ std::optional<MemoryCommit> MemoryAllocator::TryAllocCommit(
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool IsHostVisible(MemoryUsage usage) noexcept {
|
||||
switch (usage) {
|
||||
case MemoryUsage::DeviceLocal:
|
||||
return false;
|
||||
case MemoryUsage::Upload:
|
||||
case MemoryUsage::Download:
|
||||
return true;
|
||||
}
|
||||
UNREACHABLE_MSG("Invalid memory usage={}", usage);
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace Vulkan
|
||||
|
|
|
@ -17,7 +17,16 @@ class Device;
|
|||
class MemoryMap;
|
||||
class MemoryAllocation;
|
||||
|
||||
class MemoryCommit final {
|
||||
/// Hints and requirements for the backing memory type of a commit
|
||||
enum class MemoryUsage {
|
||||
DeviceLocal, ///< Hints device local usages, fastest memory type to read and write from the GPU
|
||||
Upload, ///< Requires a host visible memory type optimized for CPU to GPU uploads
|
||||
Download, ///< Requires a host visible memory type optimized for GPU to CPU readbacks
|
||||
};
|
||||
|
||||
/// Ownership handle of a memory commitment.
|
||||
/// Points to a subregion of a memory allocation.
|
||||
class MemoryCommit {
|
||||
public:
|
||||
explicit MemoryCommit() noexcept = default;
|
||||
explicit MemoryCommit(const Device& device_, MemoryAllocation* allocation_,
|
||||
|
@ -54,7 +63,9 @@ private:
|
|||
std::span<u8> span; ///< Host visible memory span. Empty if not queried before.
|
||||
};
|
||||
|
||||
class MemoryAllocator final {
|
||||
/// Memory allocator container.
|
||||
/// Allocates and releases memory allocations on demand.
|
||||
class MemoryAllocator {
|
||||
public:
|
||||
explicit MemoryAllocator(const Device& device_);
|
||||
~MemoryAllocator();
|
||||
|
@ -71,13 +82,13 @@ public:
|
|||
*
|
||||
* @returns A memory commit.
|
||||
*/
|
||||
MemoryCommit Commit(const VkMemoryRequirements& requirements, bool host_visible);
|
||||
MemoryCommit Commit(const VkMemoryRequirements& requirements, MemoryUsage usage);
|
||||
|
||||
/// Commits memory required by the buffer and binds it.
|
||||
MemoryCommit Commit(const vk::Buffer& buffer, bool host_visible);
|
||||
MemoryCommit Commit(const vk::Buffer& buffer, MemoryUsage usage);
|
||||
|
||||
/// Commits memory required by the image and binds it.
|
||||
MemoryCommit Commit(const vk::Image& image, bool host_visible);
|
||||
MemoryCommit Commit(const vk::Image& image, MemoryUsage usage);
|
||||
|
||||
private:
|
||||
/// Allocates a chunk of memory.
|
||||
|
@ -92,4 +103,7 @@ private:
|
|||
std::vector<std::unique_ptr<MemoryAllocation>> allocations; ///< Current allocations.
|
||||
};
|
||||
|
||||
/// Returns true when a memory usage is guaranteed to be host visible.
|
||||
bool IsHostVisible(MemoryUsage usage) noexcept;
|
||||
|
||||
} // namespace Vulkan
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue