Files
test/source/blender/gpu/vulkan/vk_buffer.hh
Jeroen Bakker 7de4e6d2ee Vulkan: Add support for ReBAR
This adds initial support for ReBAR capable platforms.

It ensures that when allocating buffers that should not be host visible, still
tries to allocate in host visible memory. When there is space in this memory
heap the buffer will be automatically mapped to host memory.

When mapped staging buffers can be skipped when the buffer was newly
created. In order to make better usage of ReBAR the `VKBuffer::create`
function will need to be revisit. It currently hides to much options to allocate
in the correct memory heap. This change isn't part of this PR.

Using shader_balls.blend rendering the first 50 frames in main takes 1516ms.
When using ReBAR it takes 1416ms.
```
Operating system: Linux-6.8.0-49-generic-x86_64-with-glibc2.39 64 Bits, X11 UI
Graphics card: AMD Radeon Pro W7700 (RADV NAVI32) Advanced Micro Devices radv Mesa 24.3.1 - kisak-mesa PPA Vulkan Backend
```

Pull Request: https://projects.blender.org/blender/blender/pulls/131856
2024-12-16 10:09:33 +01:00

114 lines
2.7 KiB
C++

/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup gpu
*/
#pragma once
#include "gpu_context_private.hh"
#include "BLI_utility_mixins.hh"
#include "vk_common.hh"
namespace blender::gpu {
class VKContext;
class VKDevice;
/**
* Class for handing vulkan buffers (allocation/updating/binding).
*/
class VKBuffer : public NonCopyable {
size_t size_in_bytes_ = 0;
VkBuffer vk_buffer_ = VK_NULL_HANDLE;
VmaAllocation allocation_ = VK_NULL_HANDLE;
VkMemoryPropertyFlags vk_memory_property_flags_;
/* Pointer to the virtually mapped memory. */
void *mapped_memory_ = nullptr;
public:
VKBuffer() = default;
virtual ~VKBuffer();
/** Has this buffer been allocated? */
bool is_allocated() const;
/**
* Allocate the buffer.
*
* When `is_host_visible` is set to true it will allocate from a host visible memory heap. When
* `is_host_visible` is false it will try to allocate from a host visible memory heap. When not
* available it will allocate from a not host visible memory heap. This is also known as
* Resizable BAR or ReBAR.
*/
bool create(size_t size,
GPUUsageType usage,
VkBufferUsageFlags buffer_usage,
bool is_host_visible);
void clear(VKContext &context, uint32_t clear_value);
void update_immediately(const void *data) const;
/**
* Update the buffer as part of the render graph evaluation. The ownership of data will be
* transferred to the render graph and should have been allocated using guarded alloc.
*/
void update_render_graph(VKContext &context, void *data) const;
void flush() const;
void read(VKContext &context, void *data) const;
/**
* Free the buffer.
*
* Discards the buffer so it can be destroyed safely later. Buffers can still be used when
* rendering so we can only destroy them after the rendering is completed.
*/
bool free();
/**
* Destroy the buffer immediately.
*/
void free_immediately(VKDevice &device);
int64_t size_in_bytes() const
{
return size_in_bytes_;
}
VkBuffer vk_handle() const
{
return vk_buffer_;
}
/**
* Get the reference to the mapped memory.
*
* Can only be called when the buffer is (still) mapped.
*/
void *mapped_memory_get() const;
/**
* Is this buffer mapped (visible on host)
*/
bool is_mapped() const;
private:
/** Check if this buffer is mapped. */
bool map();
void unmap();
};
/**
* Helper struct to enable buffers to be bound with an offset.
*
* Used for de-interleaved vertex input buffers and immediate mode buffers.
*/
struct VKBufferWithOffset {
const VkBuffer buffer;
VkDeviceSize offset;
};
} // namespace blender::gpu