Blender V4.3
vk_vertex_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
9#include "MEM_guardedalloc.h"
10
11#include "vk_data_conversion.hh"
12#include "vk_memory.hh"
13#include "vk_shader.hh"
15#include "vk_staging_buffer.hh"
16#include "vk_state_manager.hh"
17#include "vk_vertex_buffer.hh"
18
19namespace blender::gpu {
20
25
27{
28 VKContext &context = *VKContext::get();
29 VKStateManager &state_manager = context.state_manager_get();
31}
32
34{
35 VKContext &context = *VKContext::get();
36 VKStateManager &state_manager = context.state_manager_get();
37 state_manager.texel_buffer_bind(*this, binding);
38}
39
44
46{
47 if (vk_buffer_view_ != VK_NULL_HANDLE) {
48 return;
49 }
50
51 VkBufferViewCreateInfo buffer_view_info = {};
53
54 buffer_view_info.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
55 buffer_view_info.buffer = buffer_.vk_handle();
56 buffer_view_info.format = to_vk_format(texture_format);
57 buffer_view_info.range = buffer_.size_in_bytes();
58
60 const VKDevice &device = VKBackend::get().device;
61 vkCreateBufferView(
62 device.vk_handle(), &buffer_view_info, vk_allocation_callbacks, &vk_buffer_view_);
63 debug::object_label(vk_buffer_view_, "VertexBufferView");
64}
65
70
71void VKVertexBuffer::update_sub(uint /*start*/, uint /*len*/, const void * /*data*/)
72{
74}
75
76void VKVertexBuffer::read(void *data) const
77{
78 VKContext &context = *VKContext::get();
79 if (buffer_.is_mapped()) {
80 buffer_.read(context, data);
81 return;
82 }
83
85 staging_buffer.copy_from_device(context);
86 staging_buffer.host_buffer_get().read(context, data);
87}
88
90{
92 return;
93 }
94
95 /* Discard previous data if any. */
96 /* TODO: Use mapped memory. */
98 data_ = (uchar *)MEM_mallocN(sizeof(uchar) * this->size_alloc_get(), __func__);
99}
100
102{
104 return;
105 }
106
107 data_ = (uchar *)MEM_reallocN(data_, sizeof(uchar) * this->size_alloc_get());
108}
109
111{
112 if (vk_buffer_view_ != VK_NULL_HANDLE) {
113 const VKDevice &device = VKBackend::get().device;
115 vkDestroyBufferView(device.vk_handle(), vk_buffer_view_, vk_allocation_callbacks);
116 vk_buffer_view_ = VK_NULL_HANDLE;
117 }
118
120}
121
122void VKVertexBuffer::upload_data_direct(const VKBuffer &host_buffer)
123{
125 if (vertex_format_converter.needs_conversion()) {
126 if (G.debug & G_DEBUG_GPU) {
127 std::cout << "PERFORMANCE: Vertex buffer requires conversion.\n";
128 }
129 vertex_format_converter.convert(host_buffer.mapped_memory_get(), data_, vertex_len);
130 host_buffer.flush();
131 }
132 else {
133 host_buffer.update_immediately(data_);
134 }
135}
136
137void VKVertexBuffer::upload_data_via_staging_buffer(VKContext &context)
138{
139 VKStagingBuffer staging_buffer(buffer_, VKStagingBuffer::Direction::HostToDevice);
140 upload_data_direct(staging_buffer.host_buffer_get());
141 staging_buffer.copy_to_device(context);
142}
143
145{
146 if (!buffer_.is_allocated()) {
147 allocate();
148 }
150 return;
151 }
152
155 if (buffer_.is_mapped()) {
156 upload_data_direct(buffer_);
157 }
158 else {
159 VKContext &context = *VKContext::get();
160 upload_data_via_staging_buffer(context);
161 }
162 if (usage_ == GPU_USAGE_STATIC) {
164 }
165
166 flag &= ~GPU_VERTBUF_DATA_DIRTY;
168 }
169}
170
175
177{
178 if (!vertex_format_converter.is_initialized()) {
179 const VKWorkarounds &workarounds = VKBackend::get().device.workarounds_get();
180 vertex_format_converter.init(&format, workarounds);
181 }
182}
183
185{
186 return vertex_format_converter.device_format_get();
187}
188
189void VKVertexBuffer::allocate()
190{
191 VkBufferUsageFlags vk_buffer_usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
192 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
193 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
194 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT |
195 VK_BUFFER_USAGE_TRANSFER_DST_BIT;
196
197 buffer_.create(size_alloc_get(), GPU_USAGE_STATIC, vk_buffer_usage, false);
198 debug::object_label(buffer_.vk_handle(), "VertexBuffer");
199}
200
201} // namespace blender::gpu
@ G_DEBUG_GPU
unsigned char uchar
unsigned int uint
#define ELEM(...)
eGPUTextureFormat
@ GPU_VERTBUF_DATA_DIRTY
@ GPU_VERTBUF_DATA_UPLOADED
@ GPU_USAGE_STATIC
@ GPU_USAGE_STREAM
@ GPU_USAGE_DYNAMIC
@ GPU_USAGE_DEVICE_ONLY
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
#define MEM_reallocN(vmemh, len)
static VKBackend & get()
Definition vk_backend.hh:92
void update_immediately(const void *data) const
Definition vk_buffer.cc:109
bool is_allocated() const
Definition vk_buffer.cc:22
bool create(size_t size, GPUUsageType usage, VkBufferUsageFlags buffer_usage, bool is_host_visible=true)
Definition vk_buffer.cc:53
bool is_mapped() const
Definition vk_buffer.cc:157
void read(VKContext &context, void *data) const
Definition vk_buffer.cc:142
VkBuffer vk_handle() const
Definition vk_buffer.hh:69
void * mapped_memory_get() const
Definition vk_buffer.cc:151
int64_t size_in_bytes() const
Definition vk_buffer.hh:64
static VKContext * get()
Definition vk_context.hh:97
VkDevice vk_handle() const
Definition vk_device.hh:224
const VKWorkarounds & workarounds_get() const
Definition vk_device.hh:286
const VKBuffer & host_buffer_get() const
void copy_from_device(VKContext &context)
void texel_buffer_bind(VKVertexBuffer &vertex_buffer, int slot)
void storage_buffer_bind(BindSpaceStorageBuffers::Type resource_type, void *resource, int binding)
void duplicate_data(VertBuf *dst) override
const GPUVertFormat & device_format_get() const
void update_sub(uint start, uint len, const void *data) override
void wrap_handle(uint64_t handle) override
void bind_as_ssbo(uint binding) override
void bind_as_texture(uint binding) override
void read(void *data) const override
format
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
#define G(x, y, z)
void object_label(GLenum type, GLuint object, const char *name)
Definition gl_debug.cc:344
VkFormat to_vk_format(const eGPUTextureFormat format)
Definition vk_common.cc:131
static eGPUTextureFormat to_texture_format(const GPUVertFormat *format)
unsigned __int64 uint64_t
Definition stdint.h:90
void init(const GPUVertFormat *vertex_format, const VKWorkarounds &workarounds)
void convert(void *device_data, const void *src_data, const uint vertex_len) const
const GPUVertFormat & device_format_get() const
#define NOT_YET_IMPLEMENTED
Definition vk_common.hh:132
#define VK_ALLOCATION_CALLBACKS
Definition vk_memory.hh:58