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
73 lines
1.5 KiB
C++
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
|