Blender V4.3
vk_render_graph.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "vk_render_graph.hh"
10
12
13VKRenderGraph::VKRenderGraph(std::unique_ptr<VKCommandBufferInterface> command_buffer,
14 VKResourceStateTracker &resources)
15 : command_buffer_(std::move(command_buffer)), resources_(resources)
16{
17 submission_id.reset();
18}
19
20void VKRenderGraph::remove_nodes(Span<NodeHandle> node_handles)
21{
22 UNUSED_VARS_NDEBUG(node_handles);
23 BLI_assert_msg(node_handles.size() == nodes_.size(),
24 "Currently only supporting removing all nodes. The VKScheduler doesn't walk the "
25 "nodes, and will use incorrect ordering when not all nodes are removed. This "
26 "needs to be fixed when implementing a better scheduler.");
27 links_.clear();
28 for (VKRenderGraphNode &node : nodes_) {
29 node.free_data();
30 }
31 nodes_.clear();
32
33 debug_.node_group_map.clear();
34 debug_.used_groups.clear();
35}
36
39/* -------------------------------------------------------------------- */
43void VKRenderGraph::submit_for_present(VkImage vk_swapchain_image)
44{
45 /* Needs to be executed at forehand as `add_node` also locks the mutex. */
46 VKSynchronizationNode::CreateInfo synchronization = {};
47 synchronization.vk_image = vk_swapchain_image;
48 synchronization.vk_image_layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
49 synchronization.vk_image_aspect = VK_IMAGE_ASPECT_COLOR_BIT;
50 add_node<VKSynchronizationNode>(synchronization);
51
52 std::scoped_lock lock(resources_.mutex);
53 Span<NodeHandle> node_handles = scheduler_.select_nodes_for_image(*this, vk_swapchain_image);
54 command_builder_.build_nodes(*this, *command_buffer_, node_handles);
55 /* TODO: To improve performance it could be better to return a semaphore. This semaphore can be
56 * passed in the swapchain to ensure GPU synchronization. This also require a second semaphore to
57 * pause drawing until the swapchain has completed its drawing phase.
58 *
59 * Currently using CPU synchronization for safety. */
60 command_buffer_->submit_with_cpu_synchronization();
61 submission_id.next();
62 remove_nodes(node_handles);
63 command_buffer_->wait_for_cpu_synchronization();
64}
65
67{
68 std::scoped_lock lock(resources_.mutex);
69 Span<NodeHandle> node_handles = scheduler_.select_nodes_for_buffer(*this, vk_buffer);
70 command_builder_.build_nodes(*this, *command_buffer_, node_handles);
71 command_buffer_->submit_with_cpu_synchronization();
72 submission_id.next();
73 remove_nodes(node_handles);
74 command_buffer_->wait_for_cpu_synchronization();
75}
76
78{
79 /* Using `VK_NULL_HANDLE` will select the default VkFence of the command buffer. */
80 submit_synchronization_event(VK_NULL_HANDLE);
81 wait_synchronization_event(VK_NULL_HANDLE);
82}
83
85{
86 std::scoped_lock lock(resources_.mutex);
87 Span<NodeHandle> node_handles = scheduler_.select_nodes(*this);
88 command_builder_.build_nodes(*this, *command_buffer_, node_handles);
89 command_buffer_->submit_with_cpu_synchronization(vk_fence);
90 submission_id.next();
91 remove_nodes(node_handles);
92}
93
95{
96 command_buffer_->wait_for_cpu_synchronization(vk_fence);
97}
98
101/* -------------------------------------------------------------------- */
106{
107 DebugGroupNameID name_id = debug_.group_names.index_of_or_add(std::string(name));
108 debug_.group_stack.append(name_id);
109 debug_.group_used = false;
110}
111
113{
114 debug_.group_stack.pop_last();
115 debug_.group_used = false;
116}
117
119{
120 std::ostream &os = std::cout;
121 os << "NODE:\n";
122 const VKRenderGraphNode &node = nodes_[node_handle];
123 os << " type:" << node.type << "\n";
124
125 const VKRenderGraphNodeLinks &links = links_[node_handle];
126 os << " inputs:\n";
127 for (const VKRenderGraphLink &link : links.inputs) {
128 os << " ";
129 link.debug_print(os, resources_);
130 os << "\n";
131 }
132 os << " outputs:\n";
133 for (const VKRenderGraphLink &link : links.outputs) {
134 os << " ";
135 link.debug_print(os, resources_);
136 os << "\n";
137 }
138}
139
142} // namespace blender::gpu::render_graph
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
#define UNUSED_VARS_NDEBUG(...)
volatile int lock
constexpr int64_t size() const
Definition BLI_span.hh:253
void build_nodes(VKRenderGraph &render_graph, VKCommandBufferInterface &command_buffer, Span< NodeHandle > node_handles)
void submit_buffer_for_read(VkBuffer vk_buffer)
VKRenderGraph(std::unique_ptr< VKCommandBufferInterface > command_buffer, VKResourceStateTracker &resources)
void wait_synchronization_event(VkFence vk_fence)
void submit_for_present(VkImage vk_swapchain_image)
void debug_print(NodeHandle node_handle) const
void submit_synchronization_event(VkFence vk_fence)
Span< NodeHandle > select_nodes(const VKRenderGraph &render_graph)
Span< NodeHandle > select_nodes_for_image(const VKRenderGraph &render_graph, VkImage vk_image)
Span< NodeHandle > select_nodes_for_buffer(const VKRenderGraph &render_graph, VkBuffer vk_buffer)