Resource binding was over-complicated as I didn't understood the state manager and vulkan to make the correct decisions at that time. This refactor will remove a lot of the complexity and improves the performance. **Performance** The performance improvement is noticeable in complex grease pencil scenes. Grease pencil benchmark file picknick: - `NVIDIA Quadro RTX 6000` 17 fps -> 24 fps - `Intel(R) Arc(tm) A750 Graphics (DG2)` 6 -> 21 fps **Bottle-neck** The performance improvements originates from moving the update entry point from state manager to shader interface. The previous implementation (state manager) had to loop over all the bound resources and find in the shader interface where it was located in the descriptor set. Ignoring resources that were not used by the shader. But also making it hard to determine if descriptor sets actually changed. Previous implementation assumed descriptor sets always changed. When descriptor set changed a new descriptor set needed to be allocated. Most drivers this is a fast operation, but on Intel/Mesa this was measurable slow. Using an allocation pool doesn't fit the Vulkan API as you are only able to reuse when the layout matches exactly. Of course doable, but requires another structure to keep track of the actual layouts. **Solution** By using the shader interface as entry point we can: 1. Keep track if there are any changes in the state manager. If not and the layout is the same, the previous shader can be reused. 2. In stead of looping over each bound resource, we loop over bind points. **Future extensions** Bundle all descriptor set uploads just before use. This would be more in line with how 'modern' Vulkan should be implemented. This PR already separates the uploading from the updating and technically allows to upload more than one descriptor set. Instead of looking 1 set back we should measure if we can handle multiple or keep track of the different layouts resources to improve the performance even further. Optional use `VK_KHR_descriptor_buffer` when available. Pull Request: https://projects.blender.org/blender/blender/pulls/128068
75 lines
1.7 KiB
C++
75 lines
1.7 KiB
C++
/* SPDX-FileCopyrightText: 2022 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup gpu
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "GPU_vertex_buffer.hh"
|
|
|
|
#include "vk_buffer.hh"
|
|
#include "vk_data_conversion.hh"
|
|
|
|
namespace blender::gpu {
|
|
|
|
class VKVertexBuffer : public VertBuf {
|
|
VKBuffer buffer_;
|
|
/** When a vertex buffer is used as a UNIFORM_TEXEL_BUFFER the buffer requires a buffer view. */
|
|
VkBufferView vk_buffer_view_ = VK_NULL_HANDLE;
|
|
|
|
VertexFormatConverter vertex_format_converter;
|
|
|
|
public:
|
|
~VKVertexBuffer();
|
|
|
|
void bind_as_ssbo(uint binding) override;
|
|
void bind_as_texture(uint binding) override;
|
|
void wrap_handle(uint64_t handle) override;
|
|
|
|
void update_sub(uint start, uint len, const void *data) override;
|
|
void read(void *data) const override;
|
|
|
|
VkBuffer vk_handle() const
|
|
{
|
|
BLI_assert(buffer_.is_allocated());
|
|
return buffer_.vk_handle();
|
|
}
|
|
|
|
VkBufferView vk_buffer_view_get() const
|
|
{
|
|
BLI_assert(vk_buffer_view_ != VK_NULL_HANDLE);
|
|
return vk_buffer_view_;
|
|
}
|
|
|
|
void device_format_ensure();
|
|
const GPUVertFormat &device_format_get() const;
|
|
void ensure_updated();
|
|
void ensure_buffer_view();
|
|
|
|
protected:
|
|
void acquire_data() override;
|
|
void resize_data() override;
|
|
void release_data() override;
|
|
void upload_data() override;
|
|
void duplicate_data(VertBuf *dst) override;
|
|
|
|
private:
|
|
void allocate();
|
|
|
|
void upload_data_direct(const VKBuffer &host_buffer);
|
|
void upload_data_via_staging_buffer(VKContext &context);
|
|
|
|
/* VKTexture requires access to `buffer_` to convert a vertex buffer to a texture. */
|
|
friend class VKTexture;
|
|
};
|
|
|
|
BLI_INLINE VKVertexBuffer *unwrap(VertBuf *vertex_buffer)
|
|
{
|
|
return static_cast<VKVertexBuffer *>(vertex_buffer);
|
|
}
|
|
|
|
} // namespace blender::gpu
|