Vulkan: Share rendergraphs on context inside same thread
This PR will share render graphs between all contexts that run in the same thread. This allows the draw manager commands to be added to the same render graph as the UI. - Fixes debug groups hiearchy. Draw manager would restart a hierarchy as it wasn't aware of the debug groups already added by the UI - Removes cpu sync when switching between contexts. In a future change this is needed to improve discarding resources. Pull Request: https://projects.blender.org/blender/blender/pulls/124715
This commit is contained in:
@@ -17,11 +17,6 @@ VKRenderGraph::VKRenderGraph(std::unique_ptr<VKCommandBufferInterface> command_b
|
||||
submission_id.reset();
|
||||
}
|
||||
|
||||
void VKRenderGraph::free_data()
|
||||
{
|
||||
command_buffer_.reset();
|
||||
}
|
||||
|
||||
void VKRenderGraph::remove_nodes(Span<NodeHandle> node_handles)
|
||||
{
|
||||
UNUSED_VARS_NDEBUG(node_handles);
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "BKE_global.hh"
|
||||
|
||||
@@ -119,6 +120,12 @@ class VKRenderGraph : public NonCopyable {
|
||||
|
||||
public:
|
||||
VKSubmissionID submission_id;
|
||||
/**
|
||||
* Thread this render graph belongs to.
|
||||
*
|
||||
* Contexts of the same thread will share the same render graph. See `VKDevice::render_graph()`.
|
||||
*/
|
||||
pthread_t thread_id;
|
||||
|
||||
/**
|
||||
* Construct a new render graph instance.
|
||||
@@ -129,17 +136,6 @@ class VKRenderGraph : public NonCopyable {
|
||||
VKRenderGraph(std::unique_ptr<VKCommandBufferInterface> command_buffer,
|
||||
VKResourceStateTracker &resources);
|
||||
|
||||
/**
|
||||
* Free all resources held by the render graph. After calling this function the render graph may
|
||||
* not work as expected, leading to crashes.
|
||||
*
|
||||
* Freeing data of context resources cannot be done inside the destructor due to an issue when
|
||||
* Blender (read window manager) exits. During this phase the backend is deallocated, device is
|
||||
* destroyed, but window manager requires a context so it creates new one. We work around this
|
||||
* issue by ensuring the VKDevice is always in control of releasing resources.
|
||||
*/
|
||||
void free_data();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Add a node to the render graph.
|
||||
|
||||
@@ -174,7 +174,7 @@ Context *VKBackend::context_alloc(void *ghost_window, void *ghost_context)
|
||||
device.init(ghost_context);
|
||||
}
|
||||
|
||||
VKContext *context = new VKContext(ghost_window, ghost_context, device.resources);
|
||||
VKContext *context = new VKContext(ghost_window, ghost_context, device.render_graph());
|
||||
device.context_register(*context);
|
||||
GHOST_SetVulkanSwapBuffersCallbacks((GHOST_ContextHandle)ghost_context,
|
||||
VKContext::swap_buffers_pre_callback,
|
||||
|
||||
@@ -23,8 +23,8 @@ namespace blender::gpu {
|
||||
|
||||
VKContext::VKContext(void *ghost_window,
|
||||
void *ghost_context,
|
||||
render_graph::VKResourceStateTracker &resources)
|
||||
: render_graph(std::make_unique<render_graph::VKCommandBufferWrapper>(), resources)
|
||||
render_graph::VKRenderGraph &render_graph)
|
||||
: render_graph(render_graph)
|
||||
{
|
||||
ghost_window_ = ghost_window;
|
||||
ghost_context_ = ghost_context;
|
||||
@@ -46,7 +46,6 @@ VKContext::~VKContext()
|
||||
GPU_texture_free(surface_texture_);
|
||||
surface_texture_ = nullptr;
|
||||
}
|
||||
render_graph.free_data();
|
||||
VKBackend::get().device.context_unregister(*this);
|
||||
|
||||
delete imm;
|
||||
@@ -115,9 +114,6 @@ void VKContext::activate()
|
||||
|
||||
void VKContext::deactivate()
|
||||
{
|
||||
/* Draw manager draws in a different context than the rest of the UI. Although run from the
|
||||
* same thread. Commands inside the render-graph need to be submitted into the device queue. */
|
||||
flush_render_graph();
|
||||
immDeactivate();
|
||||
is_active_ = false;
|
||||
}
|
||||
|
||||
@@ -40,11 +40,9 @@ class VKContext : public Context, NonCopyable {
|
||||
bool is_init_ = false;
|
||||
|
||||
public:
|
||||
render_graph::VKRenderGraph render_graph;
|
||||
render_graph::VKRenderGraph &render_graph;
|
||||
|
||||
VKContext(void *ghost_window,
|
||||
void *ghost_context,
|
||||
render_graph::VKResourceStateTracker &resources);
|
||||
VKContext(void *ghost_window, void *ghost_context, render_graph::VKRenderGraph &render_graph);
|
||||
virtual ~VKContext();
|
||||
|
||||
void activate() override;
|
||||
|
||||
@@ -40,6 +40,14 @@ void VKDevice::deinit()
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
std::scoped_lock mutex(resources.mutex);
|
||||
for (render_graph::VKRenderGraph *render_graph : render_graphs_) {
|
||||
delete render_graph;
|
||||
}
|
||||
render_graphs_.clear();
|
||||
}
|
||||
|
||||
dummy_buffer_.free();
|
||||
samplers_.free();
|
||||
destroy_discarded_resources();
|
||||
@@ -342,6 +350,24 @@ std::string VKDevice::driver_version() const
|
||||
/** \name Resource management
|
||||
* \{ */
|
||||
|
||||
render_graph::VKRenderGraph &VKDevice::render_graph()
|
||||
{
|
||||
std::scoped_lock mutex(resources.mutex);
|
||||
pthread_t current_thread_id = pthread_self();
|
||||
|
||||
for (render_graph::VKRenderGraph *render_graph : render_graphs_) {
|
||||
if (pthread_equal(render_graph->thread_id, current_thread_id)) {
|
||||
return *render_graph;
|
||||
}
|
||||
}
|
||||
|
||||
render_graph::VKRenderGraph *render_graph = new render_graph::VKRenderGraph(
|
||||
std::make_unique<render_graph::VKCommandBufferWrapper>(), resources);
|
||||
render_graph->thread_id = current_thread_id;
|
||||
render_graphs_.append(render_graph);
|
||||
return *render_graph;
|
||||
}
|
||||
|
||||
void VKDevice::context_register(VKContext &context)
|
||||
{
|
||||
contexts_.append(std::reference_wrapper(context));
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "BLI_utility_mixins.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "render_graph/vk_render_graph.hh"
|
||||
#include "render_graph/vk_resource_state_tracker.hh"
|
||||
#include "vk_buffer.hh"
|
||||
#include "vk_common.hh"
|
||||
@@ -103,6 +104,7 @@ class VKDevice : public NonCopyable {
|
||||
Vector<VkImageView> discarded_image_views_;
|
||||
|
||||
std::string glsl_patch_;
|
||||
Vector<render_graph::VKRenderGraph *> render_graphs_;
|
||||
|
||||
public:
|
||||
render_graph::VKResourceStateTracker resources;
|
||||
@@ -235,6 +237,10 @@ class VKDevice : public NonCopyable {
|
||||
/** \name Resource management
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Get the render graph associated with the current thread. Create a new one when not existing.
|
||||
*/
|
||||
render_graph::VKRenderGraph &render_graph();
|
||||
void context_register(VKContext &context);
|
||||
void context_unregister(VKContext &context);
|
||||
Span<std::reference_wrapper<VKContext>> contexts_get() const;
|
||||
|
||||
Reference in New Issue
Block a user