16 vk_buffer_memory_barrier_ = {};
17 vk_buffer_memory_barrier_.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
18 vk_buffer_memory_barrier_.pNext =
nullptr;
19 vk_buffer_memory_barrier_.srcAccessMask = VK_ACCESS_NONE;
20 vk_buffer_memory_barrier_.dstAccessMask = VK_ACCESS_NONE;
21 vk_buffer_memory_barrier_.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
22 vk_buffer_memory_barrier_.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
23 vk_buffer_memory_barrier_.buffer = VK_NULL_HANDLE;
24 vk_buffer_memory_barrier_.offset = 0;
25 vk_buffer_memory_barrier_.size = VK_WHOLE_SIZE;
27 vk_image_memory_barrier_ = {};
28 vk_image_memory_barrier_.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
29 vk_image_memory_barrier_.pNext =
nullptr;
30 vk_image_memory_barrier_.srcAccessMask = VK_ACCESS_NONE;
31 vk_image_memory_barrier_.dstAccessMask = VK_ACCESS_NONE;
32 vk_image_memory_barrier_.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
33 vk_image_memory_barrier_.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
34 vk_image_memory_barrier_.image = VK_NULL_HANDLE;
35 vk_image_memory_barrier_.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
36 vk_image_memory_barrier_.newLayout = VK_IMAGE_LAYOUT_UNDEFINED;
37 vk_image_memory_barrier_.subresourceRange.aspectMask = VK_IMAGE_ASPECT_NONE;
38 vk_image_memory_barrier_.subresourceRange.baseArrayLayer = 0;
39 vk_image_memory_barrier_.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
40 vk_image_memory_barrier_.subresourceRange.baseMipLevel = 0;
41 vk_image_memory_barrier_.subresourceRange.levelCount = VK_REMAINING_MIP_LEVELS;
55 state_.active_pipelines = {};
58 state_.debug_level = 0;
59 state_.active_debug_group_id = -1;
60 std::optional<NodeHandle> rendering_scope;
72 node_group = nodes_range.slice(0, node_group.
size() + 1);
75 build_node_group(render_graph, command_buffer, nodes.slice(node_group), rendering_scope);
79 finish_debug_groups(command_buffer);
80 state_.debug_level = 0;
85void VKCommandBuilder::build_node_group(
VKRenderGraph &render_graph,
88 std::optional<NodeHandle> &r_rendering_scope)
90 bool is_rendering =
false;
94 std::cout <<
"node_group: " << node_group.
first() <<
"-" << node_group.
last()
95 <<
", node_handle: " << node_handle <<
", node_type: " << node.type <<
"\n";
100 build_pipeline_barriers(render_graph, command_buffer, node_handle, node.pipeline_stage_get());
102 layer_tracking_begin(render_graph, node_handle);
107 VKRenderGraphNode &node = render_graph.nodes_[node_handle];
111 r_rendering_scope = node_handle;
116 const VKRenderGraphNode &last_node = render_graph.nodes_[node_group[node_group.
size() - 1]];
118 if (will_be_suspended) {
119 node.begin_rendering.vk_rendering_info.flags = VK_RENDERING_SUSPENDING_BIT;
125 r_rendering_scope.reset();
126 is_rendering =
false;
132 VKRenderGraphNode &rendering_node = render_graph.nodes_[*r_rendering_scope];
133 rendering_node.begin_rendering.vk_rendering_info.flags = VK_RENDERING_RESUMING_BIT;
134 rendering_node.build_commands(command_buffer, state_.active_pipelines);
139 std::cout <<
"node_group: " << node_group.
first() <<
"-" << node_group.
last()
140 <<
", node_handle: " << node_handle <<
", node_type: " << node.type <<
"\n";
143 activate_debug_group(render_graph, command_buffer, node_handle);
145 node.build_commands(command_buffer, state_.active_pipelines);
150 layer_tracking_end(command_buffer,
false);
155 is_rendering =
false;
157 if (state_.subresource_tracking_enabled()) {
158 layer_tracking_end(command_buffer,
true);
163void VKCommandBuilder::activate_debug_group(VKRenderGraph &render_graph,
164 VKCommandBufferInterface &command_buffer,
167 VKRenderGraph::DebugGroupID debug_group = render_graph.debug_.node_group_map[node_handle];
168 if (debug_group == state_.active_debug_group_id) {
176 if (debug_group == -1) {
177 num_ends = state_.debug_level;
180 Vector<VKRenderGraph::DebugGroupNameID> &to_group =
181 render_graph.debug_.used_groups[debug_group];
182 if (state_.active_debug_group_id != -1) {
183 Vector<VKRenderGraph::DebugGroupNameID> &from_group =
184 render_graph.debug_.used_groups[state_.active_debug_group_id];
186 num_ends =
max_ii(from_group.size() - to_group.size(), 0);
187 int num_checks =
min_ii(from_group.size(), to_group.size());
188 for (
int index : IndexRange(num_checks)) {
189 if (from_group[index] != to_group[index]) {
190 num_ends += num_checks - index;
196 num_begins = to_group.size() - (state_.debug_level - num_ends);
200 for (
int index = 0; index < num_ends; index++) {
201 command_buffer.end_debug_utils_label();
203 state_.debug_level -= num_ends;
206 if (num_begins > 0) {
207 Vector<VKRenderGraph::DebugGroupNameID> &to_group =
208 render_graph.debug_.used_groups[debug_group];
209 VkDebugUtilsLabelEXT debug_utils_label = {};
210 debug_utils_label.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
211 for (
int index : IndexRange(state_.
debug_level, num_begins)) {
212 std::string group_name = render_graph.debug_.group_names[to_group[index]];
213 debug_utils_label.pLabelName = group_name.c_str();
214 command_buffer.begin_debug_utils_label(&debug_utils_label);
218 state_.debug_level += num_begins;
219 state_.active_debug_group_id = debug_group;
222void VKCommandBuilder::finish_debug_groups(VKCommandBufferInterface &command_buffer)
224 for (
int i = 0; i < state_.debug_level; i++) {
225 command_buffer.end_debug_utils_label();
227 state_.debug_level = 0;
230void VKCommandBuilder::build_pipeline_barriers(VKRenderGraph &render_graph,
231 VKCommandBufferInterface &command_buffer,
233 VkPipelineStageFlags pipeline_stage)
236 add_image_barriers(render_graph, node_handle, pipeline_stage);
237 add_buffer_barriers(render_graph, node_handle, pipeline_stage);
238 send_pipeline_barriers(command_buffer);
247void VKCommandBuilder::reset_barriers()
249 vk_buffer_memory_barriers_.
clear();
250 vk_image_memory_barriers_.
clear();
251 state_.src_stage_mask = VK_PIPELINE_STAGE_NONE;
252 state_.dst_stage_mask = VK_PIPELINE_STAGE_NONE;
255void VKCommandBuilder::send_pipeline_barriers(VKCommandBufferInterface &command_buffer)
257 if (vk_image_memory_barriers_.
is_empty() && vk_buffer_memory_barriers_.
is_empty()) {
265 if (state_.src_stage_mask == VK_PIPELINE_STAGE_NONE) {
266 state_.src_stage_mask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
269 command_buffer.pipeline_barrier(state_.src_stage_mask,
270 state_.dst_stage_mask,
271 VK_DEPENDENCY_BY_REGION_BIT,
274 vk_buffer_memory_barriers_.
size(),
275 vk_buffer_memory_barriers_.
data(),
276 vk_image_memory_barriers_.
size(),
277 vk_image_memory_barriers_.
data());
281void VKCommandBuilder::add_buffer_barriers(VKRenderGraph &render_graph,
283 VkPipelineStageFlags node_stages)
285 add_buffer_read_barriers(render_graph, node_handle, node_stages);
286 add_buffer_write_barriers(render_graph, node_handle, node_stages);
289void VKCommandBuilder::add_buffer_read_barriers(VKRenderGraph &render_graph,
291 VkPipelineStageFlags node_stages)
293 for (
const VKRenderGraphLink &link : render_graph.links_[node_handle].inputs) {
294 const ResourceWithStamp &versioned_resource = link.resource;
295 VKResourceStateTracker::Resource &resource = render_graph.resources_.resources_.lookup(
296 versioned_resource.handle);
301 VKResourceBarrierState &resource_state = resource.barrier_state;
302 const bool is_first_read = resource_state.is_new_stamp();
303 if (!is_first_read &&
304 (resource_state.vk_access & link.vk_access_flags) == link.vk_access_flags &&
305 (resource_state.vk_pipeline_stages & node_stages) == node_stages)
311 const VkAccessFlags wait_access = resource_state.vk_access;
313 state_.src_stage_mask |= resource_state.vk_pipeline_stages;
314 state_.dst_stage_mask |= node_stages;
317 resource_state.vk_access = link.vk_access_flags;
318 resource_state.vk_pipeline_stages = node_stages;
321 resource_state.vk_access |= link.vk_access_flags;
322 resource_state.vk_pipeline_stages |= node_stages;
325 add_buffer_barrier(resource.buffer.vk_buffer, wait_access, link.vk_access_flags);
329void VKCommandBuilder::add_buffer_write_barriers(VKRenderGraph &render_graph,
331 VkPipelineStageFlags node_stages)
333 for (
const VKRenderGraphLink link : render_graph.links_[node_handle].outputs) {
334 const ResourceWithStamp &versioned_resource = link.resource;
335 VKResourceStateTracker::Resource &resource = render_graph.resources_.resources_.lookup(
336 versioned_resource.handle);
341 VKResourceBarrierState &resource_state = resource.barrier_state;
342 const VkAccessFlags wait_access = resource_state.vk_access;
344 state_.src_stage_mask |= resource_state.vk_pipeline_stages;
345 state_.dst_stage_mask |= node_stages;
347 resource_state.vk_access = link.vk_access_flags;
348 resource_state.vk_pipeline_stages = node_stages;
350 if (wait_access != VK_ACCESS_NONE) {
351 add_buffer_barrier(resource.buffer.vk_buffer, wait_access, link.vk_access_flags);
356void VKCommandBuilder::add_buffer_barrier(VkBuffer vk_buffer,
357 VkAccessFlags src_access_mask,
358 VkAccessFlags dst_access_mask)
360 for (VkBufferMemoryBarrier &vk_buffer_memory_barrier : vk_buffer_memory_barriers_) {
361 if (vk_buffer_memory_barrier.buffer == vk_buffer) {
364 if ((vk_buffer_memory_barrier.dstAccessMask & src_access_mask) == src_access_mask) {
365 vk_buffer_memory_barrier.dstAccessMask |= dst_access_mask;
369 if ((vk_buffer_memory_barrier.dstAccessMask & dst_access_mask) == dst_access_mask &&
370 (vk_buffer_memory_barrier.srcAccessMask & src_access_mask) == src_access_mask)
377 vk_buffer_memory_barrier_.srcAccessMask = src_access_mask;
378 vk_buffer_memory_barrier_.dstAccessMask = dst_access_mask;
379 vk_buffer_memory_barrier_.buffer = vk_buffer;
380 vk_buffer_memory_barriers_.
append(vk_buffer_memory_barrier_);
381 vk_buffer_memory_barrier_.srcAccessMask = VK_ACCESS_NONE;
382 vk_buffer_memory_barrier_.dstAccessMask = VK_ACCESS_NONE;
383 vk_buffer_memory_barrier_.buffer = VK_NULL_HANDLE;
386void VKCommandBuilder::add_image_barriers(VKRenderGraph &render_graph,
388 VkPipelineStageFlags node_stages)
390 add_image_read_barriers(render_graph, node_handle, node_stages);
391 add_image_write_barriers(render_graph, node_handle, node_stages);
394void VKCommandBuilder::add_image_read_barriers(VKRenderGraph &render_graph,
396 VkPipelineStageFlags node_stages)
398 for (
const VKRenderGraphLink &link : render_graph.links_[node_handle].inputs) {
399 const ResourceWithStamp &versioned_resource = link.resource;
400 VKResourceStateTracker::Resource &resource = render_graph.resources_.resources_.lookup(
401 versioned_resource.handle);
406 VKResourceBarrierState &resource_state = resource.barrier_state;
407 const bool is_first_read = resource_state.is_new_stamp();
408 if ((!is_first_read) &&
409 (resource_state.vk_access & link.vk_access_flags) == link.vk_access_flags &&
410 (resource_state.vk_pipeline_stages & node_stages) == node_stages &&
411 resource_state.image_layout == link.vk_image_layout)
417 if (state_.layered_attachments.contains(resource.image.vk_image) &&
418 resource_state.image_layout != link.vk_image_layout)
420 layer_tracking_update(resource.image.vk_image,
423 resource_state.image_layout,
424 link.vk_image_layout);
428 VkAccessFlags wait_access = resource_state.vk_access;
430 state_.src_stage_mask |= resource_state.vk_pipeline_stages;
431 state_.dst_stage_mask |= node_stages;
434 resource_state.vk_access = link.vk_access_flags;
435 resource_state.vk_pipeline_stages = node_stages;
438 resource_state.vk_access |= link.vk_access_flags;
439 resource_state.vk_pipeline_stages |= node_stages;
442 add_image_barrier(resource.image.vk_image,
444 link.vk_access_flags,
445 resource_state.image_layout,
446 link.vk_image_layout,
447 link.vk_image_aspect);
448 resource_state.image_layout = link.vk_image_layout;
452void VKCommandBuilder::add_image_write_barriers(VKRenderGraph &render_graph,
454 VkPipelineStageFlags node_stages)
456 for (
const VKRenderGraphLink link : render_graph.links_[node_handle].outputs) {
457 const ResourceWithStamp &versioned_resource = link.resource;
458 VKResourceStateTracker::Resource &resource = render_graph.resources_.resources_.lookup(
459 versioned_resource.handle);
464 VKResourceBarrierState &resource_state = resource.barrier_state;
465 const VkAccessFlags wait_access = resource_state.vk_access;
467 if (state_.layered_attachments.contains(resource.image.vk_image) &&
468 resource_state.image_layout != link.vk_image_layout)
470 layer_tracking_update(resource.image.vk_image,
473 resource_state.image_layout,
474 link.vk_image_layout);
479 state_.src_stage_mask |= resource_state.vk_pipeline_stages;
480 state_.dst_stage_mask |= node_stages;
482 resource_state.vk_access = link.vk_access_flags;
483 resource_state.vk_pipeline_stages = node_stages;
485 if (wait_access != VK_ACCESS_NONE || link.vk_image_layout != resource_state.image_layout) {
486 add_image_barrier(resource.image.vk_image,
488 link.vk_access_flags,
489 resource_state.image_layout,
490 link.vk_image_layout,
491 link.vk_image_aspect);
492 resource_state.image_layout = link.vk_image_layout;
497void VKCommandBuilder::add_image_barrier(VkImage vk_image,
498 VkAccessFlags src_access_mask,
499 VkAccessFlags dst_access_mask,
500 VkImageLayout old_layout,
501 VkImageLayout new_layout,
502 VkImageAspectFlags aspect_mask,
506 BLI_assert(aspect_mask != VK_IMAGE_ASPECT_NONE);
507 for (VkImageMemoryBarrier &vk_image_memory_barrier : vk_image_memory_barriers_) {
508 if (vk_image_memory_barrier.image == vk_image) {
512 if ((vk_image_memory_barrier.dstAccessMask & src_access_mask) == src_access_mask) {
513 vk_image_memory_barrier.dstAccessMask |= dst_access_mask;
517 if ((vk_image_memory_barrier.dstAccessMask & dst_access_mask) == dst_access_mask &&
518 (vk_image_memory_barrier.srcAccessMask & src_access_mask) == src_access_mask &&
519 old_layout == new_layout)
526 vk_image_memory_barrier_.srcAccessMask = src_access_mask;
527 vk_image_memory_barrier_.dstAccessMask = dst_access_mask;
528 vk_image_memory_barrier_.image = vk_image;
529 vk_image_memory_barrier_.oldLayout = old_layout;
530 vk_image_memory_barrier_.newLayout = new_layout;
531 vk_image_memory_barrier_.subresourceRange.aspectMask = aspect_mask;
532 vk_image_memory_barrier_.subresourceRange.baseArrayLayer = layer_base;
533 vk_image_memory_barrier_.subresourceRange.layerCount = layer_count;
534 vk_image_memory_barriers_.
append(vk_image_memory_barrier_);
536 vk_image_memory_barrier_.srcAccessMask = VK_ACCESS_NONE;
537 vk_image_memory_barrier_.dstAccessMask = VK_ACCESS_NONE;
538 vk_image_memory_barrier_.image = VK_NULL_HANDLE;
539 vk_image_memory_barrier_.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
540 vk_image_memory_barrier_.newLayout = VK_IMAGE_LAYOUT_UNDEFINED;
541 vk_image_memory_barrier_.subresourceRange.aspectMask = VK_IMAGE_ASPECT_NONE;
542 vk_image_memory_barrier_.subresourceRange.baseArrayLayer = 0;
543 vk_image_memory_barrier_.subresourceRange.layerCount = VK_REMAINING_ARRAY_LAYERS;
552void VKCommandBuilder::layer_tracking_begin(
const VKRenderGraph &render_graph,
556 state_.layered_attachments.clear();
557 state_.layered_bindings.clear();
559 const VKRenderGraphNodeLinks &links = render_graph.links_[node_handle];
560 for (
const VKRenderGraphLink &link : links.outputs) {
561 VKResourceStateTracker::Resource &resource = render_graph.resources_.resources_.lookup(
562 link.resource.handle);
563 if (resource.has_multiple_layers()) {
564 state_.layered_attachments.add(resource.image.vk_image);
569void VKCommandBuilder::layer_tracking_update(VkImage vk_image,
572 VkImageLayout old_layout,
573 VkImageLayout new_layout)
576 if (binding.vk_image == vk_image && binding.layer == layer) {
578 "We don't support that one layer transitions multiple times during a "
586 state_.layered_bindings.append({vk_image, new_layout, layer, layer_count});
589 state_.src_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
590 state_.dst_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
591 add_image_barrier(vk_image,
592 VK_ACCESS_TRANSFER_WRITE_BIT,
593 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT |
594 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
595 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_TRANSFER_READ_BIT |
596 VK_ACCESS_TRANSFER_WRITE_BIT,
599 VK_IMAGE_ASPECT_COLOR_BIT,
604void VKCommandBuilder::layer_tracking_end(VKCommandBufferInterface &command_buffer,
bool suspend)
606 if (!state_.layered_bindings.is_empty()) {
609 state_.src_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
610 state_.dst_stage_mask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
614 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT |
615 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
616 VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
617 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT |
618 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
619 VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT,
620 binding.vk_image_layout,
621 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
622 VK_IMAGE_ASPECT_COLOR_BIT,
624 binding.layer_count);
626 send_pipeline_barriers(command_buffer);
628 state_.layered_bindings.clear();
630 state_.layered_attachments.clear();
#define BLI_assert_msg(a, msg)
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
constexpr int64_t first() const
constexpr int64_t size() const
constexpr bool is_empty() const
constexpr IndexRange slice(int64_t start, int64_t size) const
constexpr IndexRange index_range() const
constexpr IndexRange drop_front(int64_t n) const
constexpr const T & first() const
constexpr int64_t size() const
constexpr const T & last(const int64_t n=0) const
void append(const T &value)
virtual void end_recording()=0
virtual void end_rendering()=0
virtual void begin_recording()=0
Vector< LayeredImageBinding > layered_bindings
void build_nodes(VKRenderGraph &render_graph, VKCommandBufferInterface &command_buffer, Span< NodeHandle > node_handles)
void debug_print(NodeHandle node_handle) const
void reset_image_layouts()
BLI_INLINE bool node_type_is_rendering(VKNodeType node_type)
BLI_INLINE bool node_type_is_within_rendering(VKNodeType node_type)