Files
test/source/blender/gpu/vulkan/vk_storage_buffer.hh
Jeroen Bakker cfeacef394 Vulkan: Streaming Buffers
OpenGL has the concept of streaming buffers these buffers are marked to be
rewritten and used a small number of times. Vulkan (being low-level API)
doesn't have this concept. When performing font rendering Blender uses
streaming buffers and can slow down Vulkan as GPU barriers are added
between uploading and using the buffer.

Using a different approach could reduce the GPU barriers. The overall
idea is:

Altering render graph nodes

During font rendering the streaming buffer is rewritten from start with
the data to render the next part. This could only cover a part of the fully
allocated buffer. And would introduce a barrier before and after rewritting
the next part.

The allocated buffer on the GPU can fit more data but that data needs to be
passed along the first update to reduce the barriers. Allowing access to an
existing node in the render graph would allow to change the initial upload to
upload more data, without additional barriers.

VKStreamingBuffer

A new buffer type is introduced that will keep track of the streaming buffer
on the current render graph. A streaming buffer can be shared between multiple
threads and requires state manager to be done per context.

Pull Request: https://projects.blender.org/blender/blender/pulls/146956
2025-09-29 16:15:04 +02:00

73 lines
1.5 KiB
C++

/* SPDX-FileCopyrightText: 2022 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup gpu
*/
#pragma once
#include "GPU_texture.hh"
#include "GPU_vertex_buffer.hh"
#include "gpu_storage_buffer_private.hh"
#include "vk_buffer.hh"
#include "vk_staging_buffer.hh"
namespace blender::gpu {
class VertBuf;
class VKStorageBuffer : public StorageBuf {
GPUUsageType usage_;
VKBuffer buffer_;
/** Staging buffer that is used when doing an async read-back. */
VKStagingBuffer *async_read_buffer_ = nullptr;
VkDeviceSize offset_ = 0;
public:
VKStorageBuffer(size_t size, GPUUsageType usage, const char *name);
~VKStorageBuffer();
void update(const void *data) override;
void bind(int slot) override;
void unbind() 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;
void async_flush_to_host() override;
void sync_as_indirect_buffer() override{/* No-Op. */};
VkBuffer vk_handle() const
{
return buffer_.vk_handle();
}
inline VkDeviceAddress device_address_get() const
{
return buffer_.device_address_get();
}
int64_t size_in_bytes() const
{
return buffer_.size_in_bytes();
}
VkDeviceSize offset_get() const
{
return offset_;
}
void ensure_allocated();
private:
void allocate();
};
BLI_INLINE VKStorageBuffer *unwrap(StorageBuf *storage_buffer)
{
return static_cast<VKStorageBuffer *>(storage_buffer);
}
} // namespace blender::gpu