Vulkan: Resource Submission Tracking #105183

Merged
Jeroen Bakker merged 84 commits from Jeroen-Bakker/blender:vulkan-submission-resource-tracking into main 2023-03-24 07:48:04 +01:00
12 changed files with 49 additions and 44 deletions
Showing only changes of commit 667cb0b0d6 - Show all commits

View File

@ -78,6 +78,11 @@ struct Shader {
GPUShader *shader = nullptr;
Vector<CallData> call_datas;
Shader()
{
call_datas.reserve(10);
}
~Shader()
{
if (shader != nullptr) {
@ -117,7 +122,9 @@ struct Shader {
void dispatch()
{
GPU_compute_dispatch(shader, 1, 1, 1);
/* Dispatching 1000000 times to add some stress to the GPU. Without it tests mail succeed when
* using to simple shaders. */
Jeroen-Bakker marked this conversation as resolved Outdated

Typo: to > too

Typo: `to` > `too`
GPU_compute_dispatch(shader, 1000, 1000, 1);
}
};

View File

@ -81,12 +81,12 @@ void VKBackend::compute_dispatch(int groups_x_len, int groups_y_len, int groups_
case VKPushConstants::StorageType::UNIFORM_BUFFER:
push_constants.update_uniform_buffer();
descriptor_set.bind(push_constants.uniform_buffer_get(),
descriptor_set.bind(*push_constants.uniform_buffer_get(),
push_constants.layout_get().descriptor_set_location_get());
break;
}
descriptor_set.update(context);
command_buffer.bind(descriptor_set.active_descriptor_set(),
command_buffer.bind(*descriptor_set.active_descriptor_set(),
shader->vk_pipeline_layout_get(),
VK_PIPELINE_BIND_POINT_COMPUTE);
command_buffer.dispatch(groups_x_len, groups_y_len, groups_z_len);

View File

@ -6,6 +6,7 @@
*/
#include "vk_buffer.hh"
#include "vk_context.hh"
namespace blender::gpu {

View File

@ -10,11 +10,11 @@
#include "gpu_context_private.hh"
#include "vk_common.hh"
#include "vk_context.hh"
#include "vk_mem_alloc.h"
namespace blender::gpu {
class VKContext;
/**
* Class for handing vulkan buffers (allocation/updating/binding).

View File

@ -80,7 +80,8 @@ bool VKDescriptorPools::is_last_pool_active()
return active_pool_index_ == pools_.size() - 1;
}
VKDescriptorSet VKDescriptorPools::allocate(const VkDescriptorSetLayout &descriptor_set_layout)
std::unique_ptr<VKDescriptorSet> VKDescriptorPools::allocate(
const VkDescriptorSetLayout &descriptor_set_layout)
{
VkDescriptorSetAllocateInfo allocate_info = {};
VkDescriptorPool pool = active_pool_get();
@ -102,7 +103,7 @@ VKDescriptorSet VKDescriptorPools::allocate(const VkDescriptorSetLayout &descrip
return allocate(descriptor_set_layout);
}
return VKDescriptorSet(pool, vk_descriptor_set);
return std::make_unique<VKDescriptorSet>(pool, vk_descriptor_set);
}
void VKDescriptorPools::free(VKDescriptorSet &descriptor_set)

View File

@ -47,7 +47,7 @@ class VKDescriptorPools {
void init(const VkDevice vk_device);
VKDescriptorSet allocate(const VkDescriptorSetLayout &descriptor_set_layout);
std::unique_ptr<VKDescriptorSet> allocate(const VkDescriptorSetLayout &descriptor_set_layout);
void free(VKDescriptorSet &descriptor_set);
/**

View File

@ -101,8 +101,8 @@ VKDescriptorSetTracker::Binding &VKDescriptorSetTracker::ensure_location(
void VKDescriptorSetTracker::update(VKContext &context)
{
handle_pre_update(context);
VKDescriptorSet &descriptor_set = active_descriptor_set();
VkDescriptorSet vk_descriptor_set = descriptor_set.vk_handle();
std::unique_ptr<VKDescriptorSet> &descriptor_set = active_descriptor_set();
VkDescriptorSet vk_descriptor_set = descriptor_set->vk_handle();
Vector<VkDescriptorBufferInfo> buffer_infos;
Vector<VkWriteDescriptorSet> descriptor_writes;
@ -157,7 +157,7 @@ void VKDescriptorSetTracker::update(VKContext &context)
bindings_.clear();
}
VKDescriptorSet VKDescriptorSetTracker::create_new_resource(VKContext &context)
std::unique_ptr<VKDescriptorSet> VKDescriptorSetTracker::create_new_resource(VKContext &context)
{
return context.descriptor_pools_get().allocate(layout_);
}

View File

@ -12,8 +12,10 @@
#include "gpu_shader_private.hh"
#include "vk_buffer.hh"
#include "vk_common.hh"
#include "vk_submission_tracker.hh"
#include "vk_uniform_buffer.hh"
namespace blender::gpu {
class VKIndexBuffer;
@ -144,7 +146,7 @@ class VKDescriptorSetTracker : protected ResourceTracker<VKDescriptorSet> {
VKDescriptorSetTracker()
{
}
VKDescriptorSetTracker(VkDescriptorSetLayout layout) : layout_(layout)
{
}
@ -160,13 +162,13 @@ class VKDescriptorSetTracker : protected ResourceTracker<VKDescriptorSet> {
*/
void update(VKContext &context);
VKDescriptorSet &active_descriptor_set()
std::unique_ptr<VKDescriptorSet> &active_descriptor_set()
{
return active_resource();
}
protected:
VKDescriptorSet create_new_resource(VKContext &context) override;
std::unique_ptr<VKDescriptorSet> create_new_resource(VKContext &context) override;
private:
Binding &ensure_location(VKDescriptorSet::Location location);

View File

@ -7,6 +7,7 @@
#include "vk_push_constants.hh"
#include "vk_backend.hh"
#include "vk_context.hh"
#include "vk_memory_layout.hh"
#include "vk_shader_interface.hh"
#include "vk_storage_buffer.hh"
@ -102,24 +103,12 @@ VKPushConstants::VKPushConstants() = default;
VKPushConstants::VKPushConstants(const Layout *layout) : layout_(layout)
{
data_ = MEM_mallocN(layout->size_in_bytes(), __func__);
switch (layout_->storage_type_get()) {
case StorageType::UNIFORM_BUFFER:
uniform_buffer_ = new VKUniformBuffer(layout_->size_in_bytes(), __func__);
break;
case StorageType::PUSH_CONSTANTS:
case StorageType::NONE:
break;
}
}
VKPushConstants::VKPushConstants(VKPushConstants &&other) : layout_(other.layout_)
{
data_ = other.data_;
other.data_ = nullptr;
uniform_buffer_ = other.uniform_buffer_;
other.uniform_buffer_ = nullptr;
}
VKPushConstants::~VKPushConstants()
@ -128,9 +117,6 @@ VKPushConstants::~VKPushConstants()
MEM_freeN(data_);
data_ = nullptr;
}
delete uniform_buffer_;
uniform_buffer_ = nullptr;
}
VKPushConstants &VKPushConstants::operator=(VKPushConstants &&other)
@ -140,25 +126,27 @@ VKPushConstants &VKPushConstants::operator=(VKPushConstants &&other)
data_ = other.data_;
other.data_ = nullptr;
uniform_buffer_ = other.uniform_buffer_;
other.uniform_buffer_ = nullptr;
return *this;
}
void VKPushConstants::update_uniform_buffer()
{
BLI_assert(layout_->storage_type_get() == StorageType::UNIFORM_BUFFER);
BLI_assert(uniform_buffer_ != nullptr);
BLI_assert(data_ != nullptr);
uniform_buffer_->update(data_);
VKContext &context = *VKContext::get();
std::unique_ptr<VKUniformBuffer> &uniform_buffer = handle_pre_update(context);
uniform_buffer->update(data_);
}
VKUniformBuffer &VKPushConstants::uniform_buffer_get()
std::unique_ptr<VKUniformBuffer> &VKPushConstants::uniform_buffer_get()
{
BLI_assert(layout_->storage_type_get() == StorageType::UNIFORM_BUFFER);
BLI_assert(uniform_buffer_ != nullptr);
return *uniform_buffer_;
return active_resource();
}
std::unique_ptr<VKUniformBuffer> VKPushConstants::create_new_resource(VKContext & /*context*/)
{
return std::make_unique<VKUniformBuffer>(layout_->size_in_bytes(), __func__);
}
} // namespace blender::gpu

View File

@ -42,7 +42,7 @@ class VKUniformBuffer;
* It should also keep track of the submissions in order to reuse the allocated
* data.
*/
class VKPushConstants : NonCopyable {
class VKPushConstants : ResourceTracker<VKUniformBuffer> {
public:
/** Different methods to store push constants.*/
enum class StorageType {
@ -150,7 +150,6 @@ class VKPushConstants : NonCopyable {
private:
const Layout *layout_ = nullptr;
void *data_ = nullptr;
VKUniformBuffer *uniform_buffer_ = nullptr;
public:
VKPushConstants();
@ -183,7 +182,12 @@ class VKPushConstants : NonCopyable {
*
* Only valid when storage type = StorageType::UNIFORM_BUFFER.
*/
VKUniformBuffer &uniform_buffer_get();
std::unique_ptr<VKUniformBuffer> &uniform_buffer_get();
/**
* Part of Resource Tracking API is called when new resource is needed.
*/
std::unique_ptr<VKUniformBuffer> create_new_resource(VKContext &context) override;
/**
* Get the reference to the active data.

View File

@ -100,7 +100,7 @@ class SubmissionTracker {
template<typename Resource> class ResourceTracker : NonCopyable {
SubmissionTracker submission_tracker_;
Vector<Resource> tracked_resources_;
Vector<std::unique_ptr<Resource>> tracked_resources_;
protected:
ResourceTracker<Resource>()
@ -124,7 +124,7 @@ template<typename Resource> class ResourceTracker : NonCopyable {
free_tracked_resources();
}
Resource &handle_pre_update(VKContext &context)
std::unique_ptr<Resource> &handle_pre_update(VKContext &context)
{
if (submission_tracker_.submission_tracker_pre_update(context) ==
SubmissionTracker::Result::FREE_AND_CREATE_NEW_RESOURCE) {
@ -134,9 +134,9 @@ template<typename Resource> class ResourceTracker : NonCopyable {
return active_resource();
}
virtual Resource create_new_resource(VKContext &context) = 0;
virtual std::unique_ptr<Resource> create_new_resource(VKContext &context) = 0;
Resource &active_resource()
std::unique_ptr<Resource> &active_resource()
{
BLI_assert(!tracked_resources_.is_empty());
return tracked_resources_.last();

View File

@ -7,13 +7,15 @@
#pragma once
#include "BLI_utility_mixins.hh"
#include "gpu_uniform_buffer_private.hh"
#include "vk_buffer.hh"
namespace blender::gpu {
class VKUniformBuffer : public UniformBuf {
class VKUniformBuffer : public UniformBuf, NonCopyable {
VKBuffer buffer_;
public: