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
57 lines
1015 B
C++
57 lines
1015 B
C++
/* SPDX-FileCopyrightText: 2022 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup gpu
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "BLI_utility_mixins.hh"
|
|
|
|
#include "gpu_uniform_buffer_private.hh"
|
|
|
|
#include "vk_buffer.hh"
|
|
|
|
namespace blender::gpu {
|
|
|
|
class VKUniformBuffer : public UniformBuf, NonCopyable {
|
|
VKBuffer buffer_;
|
|
|
|
public:
|
|
VKUniformBuffer(size_t size, const char *name) : UniformBuf(size, name) {}
|
|
|
|
void update(const void *data) override;
|
|
void clear_to_zero() override;
|
|
void bind(int slot) override;
|
|
void bind_as_ssbo(int slot) override;
|
|
|
|
/**
|
|
* Unbind uniform buffer from active context.
|
|
*/
|
|
void unbind() override;
|
|
|
|
VkBuffer vk_handle() const
|
|
{
|
|
return buffer_.vk_handle();
|
|
}
|
|
|
|
size_t size_in_bytes() const
|
|
{
|
|
return size_in_bytes_;
|
|
}
|
|
|
|
void ensure_updated();
|
|
|
|
private:
|
|
void allocate();
|
|
};
|
|
|
|
BLI_INLINE UniformBuf *wrap(VKUniformBuffer *uniform_buffer)
|
|
{
|
|
return static_cast<UniformBuf *>(uniform_buffer);
|
|
}
|
|
|
|
} // namespace blender::gpu
|