Blender V5.0
vk_storage_buffer.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2022 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8#include "vk_shader.hh"
10#include "vk_staging_buffer.hh"
11#include "vk_state_manager.hh"
12#include "vk_vertex_buffer.hh"
13
14#include "vk_storage_buffer.hh"
15
16#include "CLG_log.h"
17
18static CLG_LogRef LOG = {"gpu.vulkan"};
19
20namespace blender::gpu {
21
23 : StorageBuf(size, name), usage_(usage)
24{
25 UNUSED_VARS(usage_);
26}
28{
29 if (async_read_buffer_) {
30 MEM_delete(async_read_buffer_);
31 async_read_buffer_ = nullptr;
32 }
33}
34
36{
37 VKContext &context = *VKContext::get();
39 if (!buffer_.is_allocated()) {
41 "Unable to upload data to storage buffer as the storage buffer could not be "
42 "allocated on GPU.");
43 return;
44 }
45
46 if (usage_ == GPU_USAGE_STREAM) {
47 const VKDevice &device = VKBackend::get().device;
48 VKStreamingBuffer &streaming_buffer = *context.get_or_create_streaming_buffer(
49 buffer_, device.physical_device_properties_get().limits.minStorageBufferOffsetAlignment);
50 offset_ = streaming_buffer.update(context, data, usage_size_in_bytes_);
51 return;
52 }
53
54 VKStagingBuffer staging_buffer(
56 VKBuffer &buffer = staging_buffer.host_buffer_get();
57 if (buffer.is_allocated()) {
59 staging_buffer.copy_to_device(context);
60 }
61 else {
63 &LOG,
64 "Unable to upload data to storage buffer via a staging buffer as the staging buffer "
65 "could not be allocated. Storage buffer will be filled with on zeros to reduce "
66 "drawing artifacts due to read from uninitialized memory.");
67 buffer_.clear(context, 0u);
68 }
69}
70
72{
73 if (!buffer_.is_allocated()) {
74 allocate();
75 }
76}
77
78void VKStorageBuffer::allocate()
79{
80 const VkBufferUsageFlags buffer_usage_flags = VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT |
81 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
82 VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
83 VK_BUFFER_USAGE_TRANSFER_DST_BIT;
84 buffer_.create(size_in_bytes_,
85 buffer_usage_flags,
86 VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
87 VmaAllocationCreateFlags(0),
88 0.8f);
89 if (buffer_.is_allocated()) {
91 }
92}
93
95{
96 VKContext &context = *VKContext::get();
97 context.state_manager_get().storage_buffer_bind(
99}
100
102{
103 VKContext *context = VKContext::get();
104 if (context) {
105 context->state_manager_get().storage_buffer_unbind(this);
106 }
107}
108
109void VKStorageBuffer::clear(uint32_t clear_value)
110{
112 VKContext &context = *VKContext::get();
113 buffer_.clear(context, clear_value);
114}
115
116void VKStorageBuffer::copy_sub(VertBuf *src, uint dst_offset, uint src_offset, uint copy_size)
117{
119
120 VKVertexBuffer &src_vertex_buffer = *unwrap(src);
121 src_vertex_buffer.upload();
122
124 copy_buffer.src_buffer = src_vertex_buffer.vk_handle();
125 copy_buffer.dst_buffer = vk_handle();
126 copy_buffer.region.srcOffset = src_offset;
127 copy_buffer.region.dstOffset = dst_offset;
128 copy_buffer.region.size = copy_size;
129
130 VKContext &context = *VKContext::get();
131 context.render_graph().add_node(copy_buffer);
132}
133
135{
136 if (async_read_buffer_ != nullptr) {
137 return;
138 }
140 VKContext &context = *VKContext::get();
141
142 async_read_buffer_ = MEM_new<VKStagingBuffer>(
144 async_read_buffer_->copy_from_device(context);
145 async_read_buffer_->host_buffer_get().async_flush_to_host(context);
146}
147
149{
150 if (async_read_buffer_ == nullptr) {
152 }
153
154 VKContext &context = *VKContext::get();
155 async_read_buffer_->host_buffer_get().read_async(context, data);
156 MEM_delete(async_read_buffer_);
157 async_read_buffer_ = nullptr;
158}
159
160} // namespace blender::gpu
unsigned int uint
#define UNUSED_VARS(...)
#define CLOG_ERROR(clg_ref,...)
Definition CLG_log.h:188
#define CLOG_WARN(clg_ref,...)
Definition CLG_log.h:189
@ GPU_USAGE_STREAM
BMesh const char void * data
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
StorageBuf(size_t size, const char *name)
static VKBackend & get()
Definition vk_backend.hh:91
void update_immediately(const void *data) const
Definition vk_buffer.cc:123
bool is_allocated() const
Definition vk_buffer.hh:145
VkBuffer vk_handle() const
Definition vk_buffer.hh:101
bool create(size_t size, VkBufferUsageFlags buffer_usage, VmaMemoryUsage vma_memory_usage, VmaAllocationCreateFlags vma_allocation_flags, float priority, bool export_memory=false)
Definition vk_buffer.cc:27
static VKContext * get()
const VkPhysicalDeviceProperties & physical_device_properties_get() const
Definition vk_device.hh:269
void copy_to_device(VKContext &context)
void update(const void *data) override
void clear(uint32_t clear_value) override
void copy_sub(VertBuf *src, uint dst_offset, uint src_offset, uint copy_size) override
void read(void *data) override
VKStorageBuffer(size_t size, GPUUsageType usage, const char *name)
void bind(int slot) override
VkDeviceSize update(VKContext &context, const void *data, size_t data_size)
#define LOG(level)
Definition log.h:97
void object_label(GLenum type, GLuint object, const char *name)
Definition gl_debug.cc:329
static Context * unwrap(GPUContext *ctx)
static CLG_LogRef LOG
const char * name