Vulkan: Fix incorrect reordering when copying attachment
Solved by not supporting complex reordering at this moment. It is currently better to focus on quality and add back performance later. During tests I didn't detect any user noticeable performance degradation. Could also be because we support rendering suspending/resuming. Fixes artifacts in EEVEE volumes and raytracing. Pull Request: https://projects.blender.org/blender/blender/pulls/126974
This commit is contained in:
@@ -437,18 +437,8 @@ TEST(vk_render_graph, begin_clear_attachments_copy_buffer_clear_attachments_end)
|
||||
}
|
||||
|
||||
render_graph.submit_for_present(image);
|
||||
EXPECT_EQ(8, log.size());
|
||||
EXPECT_EQ(
|
||||
"pipeline_barrier(src_stage_mask=VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "
|
||||
"dst_stage_mask=VK_PIPELINE_STAGE_TRANSFER_BIT" +
|
||||
endl() +
|
||||
" - buffer_barrier(src_access_mask=, dst_access_mask=VK_ACCESS_TRANSFER_READ_BIT, "
|
||||
"buffer=0x3, offset=0, size=18446744073709551615)" +
|
||||
endl() + ")",
|
||||
log[0]);
|
||||
EXPECT_EQ("copy_buffer(src_buffer=0x3, dst_buffer=0x4" + endl() +
|
||||
" - region(src_offset=0, dst_offset=0, size=0)" + endl() + ")",
|
||||
log[1]);
|
||||
EXPECT_EQ(10, log.size());
|
||||
|
||||
EXPECT_EQ(
|
||||
"pipeline_barrier(src_stage_mask=VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "
|
||||
"dst_stage_mask=VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT" +
|
||||
@@ -461,33 +451,60 @@ TEST(vk_render_graph, begin_clear_attachments_copy_buffer_clear_attachments_end)
|
||||
" aspect_mask=VK_IMAGE_ASPECT_COLOR_BIT, base_mip_level=0, level_count=4294967295, "
|
||||
"base_array_layer=0, layer_count=4294967295 )" +
|
||||
endl() + ")",
|
||||
log[0]);
|
||||
EXPECT_EQ(
|
||||
"begin_rendering(p_rendering_info=flags=VK_RENDERING_SUSPENDING_BIT, "
|
||||
"VK_RENDERING_SUSPENDING_BIT_KHR, render_area=" +
|
||||
endl() + " offset=" + endl() + " x=0, y=0 , extent=" + endl() +
|
||||
" width=0, height=0 , layer_count=1, view_mask=0, color_attachment_count=1, "
|
||||
"p_color_attachments=" +
|
||||
endl() +
|
||||
" image_view=0x2, image_layout=VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, "
|
||||
"resolve_mode=VK_RESOLVE_MODE_NONE, resolve_image_view=0, "
|
||||
"resolve_image_layout=VK_IMAGE_LAYOUT_UNDEFINED, "
|
||||
"load_op=VK_ATTACHMENT_LOAD_OP_DONT_CARE, store_op=VK_ATTACHMENT_STORE_OP_STORE" +
|
||||
endl() + ")",
|
||||
log[1]);
|
||||
EXPECT_EQ(
|
||||
"clear_attachments( - attachment(aspect_mask=VK_IMAGE_ASPECT_COLOR_BIT, "
|
||||
"color_attachment=0)" +
|
||||
endl() + " - rect(rect=" + endl() + " offset=" + endl() +
|
||||
" x=0, y=0 , extent=" + endl() +
|
||||
" width=1920, height=1080 , base_array_layer=0, layer_count=1)" + endl() + ")",
|
||||
log[2]);
|
||||
EXPECT_EQ("begin_rendering(p_rendering_info=flags=, render_area=" + endl() +
|
||||
" offset=" + endl() + " x=0, y=0 , extent=" + endl() +
|
||||
" width=0, height=0 , layer_count=1, view_mask=0, color_attachment_count=1, "
|
||||
"p_color_attachments=" +
|
||||
endl() +
|
||||
" image_view=0x2, image_layout=VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, "
|
||||
"resolve_mode=VK_RESOLVE_MODE_NONE, resolve_image_view=0, "
|
||||
"resolve_image_layout=VK_IMAGE_LAYOUT_UNDEFINED, "
|
||||
"load_op=VK_ATTACHMENT_LOAD_OP_DONT_CARE, store_op=VK_ATTACHMENT_STORE_OP_STORE" +
|
||||
endl() + ")",
|
||||
log[3]);
|
||||
EXPECT_EQ("end_rendering()", log[3]);
|
||||
EXPECT_EQ(
|
||||
"clear_attachments( - attachment(aspect_mask=VK_IMAGE_ASPECT_COLOR_BIT, "
|
||||
"color_attachment=0)" +
|
||||
endl() + " - rect(rect=" + endl() + " offset=" + endl() +
|
||||
" x=0, y=0 , extent=" + endl() +
|
||||
" width=1920, height=1080 , base_array_layer=0, layer_count=1)" + endl() + ")",
|
||||
"pipeline_barrier(src_stage_mask=VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "
|
||||
"dst_stage_mask=VK_PIPELINE_STAGE_TRANSFER_BIT" +
|
||||
endl() +
|
||||
" - buffer_barrier(src_access_mask=, dst_access_mask=VK_ACCESS_TRANSFER_READ_BIT, "
|
||||
"buffer=0x3, offset=0, size=18446744073709551615)" +
|
||||
endl() + ")",
|
||||
log[4]);
|
||||
EXPECT_EQ("copy_buffer(src_buffer=0x3, dst_buffer=0x4" + endl() +
|
||||
" - region(src_offset=0, dst_offset=0, size=0)" + endl() + ")",
|
||||
log[5]);
|
||||
EXPECT_EQ(
|
||||
"begin_rendering(p_rendering_info=flags=VK_RENDERING_RESUMING_BIT, "
|
||||
"VK_RENDERING_RESUMING_BIT_KHR, render_area=" +
|
||||
endl() + " offset=" + endl() + " x=0, y=0 , extent=" + endl() +
|
||||
" width=0, height=0 , layer_count=1, view_mask=0, color_attachment_count=1, "
|
||||
"p_color_attachments=" +
|
||||
endl() +
|
||||
" image_view=0x2, image_layout=VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, "
|
||||
"resolve_mode=VK_RESOLVE_MODE_NONE, resolve_image_view=0, "
|
||||
"resolve_image_layout=VK_IMAGE_LAYOUT_UNDEFINED, "
|
||||
"load_op=VK_ATTACHMENT_LOAD_OP_DONT_CARE, store_op=VK_ATTACHMENT_STORE_OP_STORE" +
|
||||
endl() + ")",
|
||||
log[6]);
|
||||
EXPECT_EQ(
|
||||
"clear_attachments( - attachment(aspect_mask=VK_IMAGE_ASPECT_COLOR_BIT, "
|
||||
"color_attachment=0)" +
|
||||
endl() + " - rect(rect=" + endl() + " offset=" + endl() +
|
||||
" x=0, y=0 , extent=" + endl() +
|
||||
" width=1920, height=1080 , base_array_layer=0, layer_count=1)" + endl() + ")",
|
||||
log[5]);
|
||||
EXPECT_EQ("end_rendering()", log[6]);
|
||||
log[7]);
|
||||
EXPECT_EQ("end_rendering()", log[8]);
|
||||
EXPECT_EQ(
|
||||
"pipeline_barrier(src_stage_mask=VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, "
|
||||
"dst_stage_mask=VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT" +
|
||||
@@ -500,7 +517,185 @@ TEST(vk_render_graph, begin_clear_attachments_copy_buffer_clear_attachments_end)
|
||||
" aspect_mask=VK_IMAGE_ASPECT_COLOR_BIT, base_mip_level=0, level_count=4294967295, "
|
||||
"base_array_layer=0, layer_count=4294967295 )" +
|
||||
endl() + ")",
|
||||
log[9]);
|
||||
}
|
||||
|
||||
/**
|
||||
* When copying the frame buffer content between two draw calls we should not move the command.
|
||||
*
|
||||
* This happens in EEVEE where the feedback radiance is copied before the world background is added
|
||||
* to the combined texture.
|
||||
*/
|
||||
TEST(vk_render_graph, begin_draw_copy_framebuffer_draw_end)
|
||||
{
|
||||
VkHandle<VkImage> image_attachment(1u);
|
||||
VkHandle<VkImage> image_feedback(2u);
|
||||
VkHandle<VkImageView> image_view_attachment(3u);
|
||||
VkHandle<VkPipelineLayout> pipeline_layout_combine(4u);
|
||||
VkHandle<VkPipeline> pipeline_combine(5u);
|
||||
VkHandle<VkPipelineLayout> pipeline_layout_background(6u);
|
||||
VkHandle<VkPipeline> pipeline_background(7u);
|
||||
|
||||
Vector<std::string> log;
|
||||
VKResourceStateTracker resources;
|
||||
VKRenderGraph render_graph(std::make_unique<CommandBufferLog>(log), resources);
|
||||
resources.add_image(
|
||||
image_attachment, 1, VK_IMAGE_LAYOUT_UNDEFINED, render_graph::ResourceOwner::APPLICATION);
|
||||
resources.add_image(
|
||||
image_feedback, 1, VK_IMAGE_LAYOUT_UNDEFINED, render_graph::ResourceOwner::APPLICATION);
|
||||
|
||||
{
|
||||
VKResourceAccessInfo access_info = {};
|
||||
access_info.images.append(
|
||||
{image_attachment, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_IMAGE_ASPECT_COLOR_BIT, 0});
|
||||
VKBeginRenderingNode::CreateInfo begin_rendering(access_info);
|
||||
begin_rendering.node_data.color_attachments[0].sType =
|
||||
VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR;
|
||||
begin_rendering.node_data.color_attachments[0].imageLayout =
|
||||
VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
||||
begin_rendering.node_data.color_attachments[0].imageView = image_view_attachment;
|
||||
begin_rendering.node_data.color_attachments[0].loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
begin_rendering.node_data.color_attachments[0].storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
begin_rendering.node_data.vk_rendering_info.sType = VK_STRUCTURE_TYPE_RENDERING_INFO;
|
||||
begin_rendering.node_data.vk_rendering_info.colorAttachmentCount = 1;
|
||||
begin_rendering.node_data.vk_rendering_info.layerCount = 1;
|
||||
begin_rendering.node_data.vk_rendering_info.pColorAttachments =
|
||||
begin_rendering.node_data.color_attachments;
|
||||
|
||||
render_graph.add_node(begin_rendering);
|
||||
}
|
||||
|
||||
{
|
||||
VKResourceAccessInfo access_info = {};
|
||||
VKDrawNode::CreateInfo draw(access_info);
|
||||
draw.node_data.first_instance = 0;
|
||||
draw.node_data.first_vertex = 0;
|
||||
draw.node_data.instance_count = 1;
|
||||
draw.node_data.vertex_count = 4;
|
||||
draw.node_data.pipeline_data.push_constants_data = nullptr;
|
||||
draw.node_data.pipeline_data.push_constants_size = 0;
|
||||
draw.node_data.pipeline_data.vk_descriptor_set = VK_NULL_HANDLE;
|
||||
draw.node_data.pipeline_data.vk_pipeline = pipeline_combine;
|
||||
draw.node_data.pipeline_data.vk_pipeline_layout = pipeline_layout_combine;
|
||||
render_graph.add_node(draw);
|
||||
}
|
||||
|
||||
{
|
||||
VKCopyImageNode::CreateInfo copy_image = {};
|
||||
copy_image.vk_image_aspect = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
copy_image.node_data.src_image = image_attachment;
|
||||
copy_image.node_data.dst_image = image_feedback;
|
||||
copy_image.node_data.region.extent.width = 1920;
|
||||
copy_image.node_data.region.extent.height = 1080;
|
||||
copy_image.node_data.region.extent.depth = 1;
|
||||
copy_image.node_data.region.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
copy_image.node_data.region.srcSubresource.baseArrayLayer = 0;
|
||||
copy_image.node_data.region.srcSubresource.layerCount = 1;
|
||||
copy_image.node_data.region.srcSubresource.mipLevel = 0;
|
||||
render_graph.add_node(copy_image);
|
||||
}
|
||||
|
||||
{
|
||||
VKResourceAccessInfo access_info = {};
|
||||
VKDrawNode::CreateInfo draw(access_info);
|
||||
draw.node_data.first_instance = 0;
|
||||
draw.node_data.first_vertex = 0;
|
||||
draw.node_data.instance_count = 1;
|
||||
draw.node_data.vertex_count = 4;
|
||||
draw.node_data.pipeline_data.push_constants_data = nullptr;
|
||||
draw.node_data.pipeline_data.push_constants_size = 0;
|
||||
draw.node_data.pipeline_data.vk_descriptor_set = VK_NULL_HANDLE;
|
||||
draw.node_data.pipeline_data.vk_pipeline = pipeline_background;
|
||||
draw.node_data.pipeline_data.vk_pipeline_layout = pipeline_layout_background;
|
||||
render_graph.add_node(draw);
|
||||
}
|
||||
|
||||
{
|
||||
VKEndRenderingNode::CreateInfo end_rendering = {};
|
||||
render_graph.add_node(end_rendering);
|
||||
}
|
||||
|
||||
render_graph.submit();
|
||||
ASSERT_EQ(11, log.size());
|
||||
|
||||
EXPECT_EQ(
|
||||
"pipeline_barrier(src_stage_mask=VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "
|
||||
"dst_stage_mask=VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT" +
|
||||
endl() +
|
||||
" - image_barrier(src_access_mask=, "
|
||||
"dst_access_mask=VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, "
|
||||
"old_layout=VK_IMAGE_LAYOUT_UNDEFINED, "
|
||||
"new_layout=VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, image=0x1, subresource_range=" +
|
||||
endl() +
|
||||
" aspect_mask=VK_IMAGE_ASPECT_COLOR_BIT, base_mip_level=0, level_count=4294967295, "
|
||||
"base_array_layer=0, layer_count=4294967295 )" +
|
||||
endl() + ")",
|
||||
log[0]);
|
||||
EXPECT_EQ(
|
||||
"begin_rendering(p_rendering_info=flags=VK_RENDERING_SUSPENDING_BIT, "
|
||||
"VK_RENDERING_SUSPENDING_BIT_KHR, render_area=" +
|
||||
endl() + " offset=" + endl() + " x=0, y=0 , extent=" + endl() +
|
||||
" width=0, height=0 , layer_count=1, view_mask=0, color_attachment_count=1, "
|
||||
"p_color_attachments=" +
|
||||
endl() +
|
||||
" image_view=0x3, image_layout=VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, "
|
||||
"resolve_mode=VK_RESOLVE_MODE_NONE, resolve_image_view=0, "
|
||||
"resolve_image_layout=VK_IMAGE_LAYOUT_UNDEFINED, "
|
||||
"load_op=VK_ATTACHMENT_LOAD_OP_DONT_CARE, store_op=VK_ATTACHMENT_STORE_OP_STORE" +
|
||||
endl() + ")",
|
||||
log[1]);
|
||||
EXPECT_EQ("bind_pipeline(pipeline_bind_point=VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline=0x5)",
|
||||
log[2]);
|
||||
EXPECT_EQ("draw(vertex_count=4, instance_count=1, first_vertex=0, first_instance=0)", log[3]);
|
||||
EXPECT_EQ("end_rendering()", log[4]);
|
||||
EXPECT_EQ(
|
||||
"pipeline_barrier(src_stage_mask=VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, "
|
||||
"dst_stage_mask=VK_PIPELINE_STAGE_TRANSFER_BIT" +
|
||||
endl() +
|
||||
" - image_barrier(src_access_mask=VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, "
|
||||
"dst_access_mask=VK_ACCESS_TRANSFER_READ_BIT, "
|
||||
"old_layout=VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, "
|
||||
"new_layout=VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, image=0x1, subresource_range=" +
|
||||
endl() +
|
||||
" aspect_mask=VK_IMAGE_ASPECT_COLOR_BIT, base_mip_level=0, level_count=4294967295, "
|
||||
"base_array_layer=0, layer_count=4294967295 )" +
|
||||
endl() +
|
||||
" - image_barrier(src_access_mask=, dst_access_mask=VK_ACCESS_TRANSFER_WRITE_BIT, "
|
||||
"old_layout=VK_IMAGE_LAYOUT_UNDEFINED, new_layout=VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, "
|
||||
"image=0x2, subresource_range=" +
|
||||
endl() +
|
||||
" aspect_mask=VK_IMAGE_ASPECT_COLOR_BIT, base_mip_level=0, level_count=4294967295, "
|
||||
"base_array_layer=0, layer_count=4294967295 )" +
|
||||
endl() + ")",
|
||||
log[5]);
|
||||
EXPECT_EQ(
|
||||
"copy_image(src_image=0x1, src_image_layout=VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, "
|
||||
"dst_image=0x2, dst_image_layout=VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL" +
|
||||
endl() + " - region(src_subresource=" + endl() +
|
||||
" aspect_mask=VK_IMAGE_ASPECT_COLOR_BIT, mip_level=0, base_array_layer=0, "
|
||||
"layer_count=1 , src_offset=" +
|
||||
endl() + " x=0, y=0, z=0 , dst_subresource=" + endl() +
|
||||
" aspect_mask=, mip_level=0, base_array_layer=0, layer_count=0 , dst_offset=" +
|
||||
endl() + " x=0, y=0, z=0 , extent=" + endl() +
|
||||
" width=1920, height=1080, depth=1 )" + endl() + ")",
|
||||
log[6]);
|
||||
EXPECT_EQ(
|
||||
"begin_rendering(p_rendering_info=flags=VK_RENDERING_RESUMING_BIT, "
|
||||
"VK_RENDERING_RESUMING_BIT_KHR, render_area=" +
|
||||
endl() + " offset=" + endl() + " x=0, y=0 , extent=" + endl() +
|
||||
" width=0, height=0 , layer_count=1, view_mask=0, color_attachment_count=1, "
|
||||
"p_color_attachments=" +
|
||||
endl() +
|
||||
" image_view=0x3, image_layout=VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, "
|
||||
"resolve_mode=VK_RESOLVE_MODE_NONE, resolve_image_view=0, "
|
||||
"resolve_image_layout=VK_IMAGE_LAYOUT_UNDEFINED, "
|
||||
"load_op=VK_ATTACHMENT_LOAD_OP_DONT_CARE, store_op=VK_ATTACHMENT_STORE_OP_STORE" +
|
||||
endl() + ")",
|
||||
log[7]);
|
||||
EXPECT_EQ("bind_pipeline(pipeline_bind_point=VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline=0x7)",
|
||||
log[8]);
|
||||
EXPECT_EQ("draw(vertex_count=4, instance_count=1, first_vertex=0, first_instance=0)", log[9]);
|
||||
EXPECT_EQ("end_rendering()", log[10]);
|
||||
}
|
||||
|
||||
} // namespace blender::gpu::render_graph
|
||||
|
||||
@@ -89,10 +89,6 @@ std::optional<std::pair<int64_t, int64_t>> VKScheduler::find_rendering_scope(
|
||||
void VKScheduler::move_transfer_and_dispatch_outside_rendering_scope(
|
||||
const VKRenderGraph &render_graph)
|
||||
{
|
||||
Vector<NodeHandle> pre_rendering_handles;
|
||||
Vector<NodeHandle> rendering_handles;
|
||||
Set<ResourceHandle> accessed_resources;
|
||||
|
||||
foreach_rendering_scope(render_graph, [&](int64_t start_index, int64_t end_index) {
|
||||
/* Move end_rendering right after the last graphics node. */
|
||||
for (int index = end_index - 1; index >= start_index; index--) {
|
||||
@@ -115,60 +111,6 @@ void VKScheduler::move_transfer_and_dispatch_outside_rendering_scope(
|
||||
std::swap(result_[start_index], result_[index]);
|
||||
start_index += 1;
|
||||
}
|
||||
|
||||
/* Move all other none graphics commands to before the begin_rendering unless the resource they
|
||||
* are modifying is already being used by a draw command. Uses temporary allocated vectors to
|
||||
* reduce the amount and size of copying data. */
|
||||
pre_rendering_handles.clear();
|
||||
rendering_handles.clear();
|
||||
accessed_resources.clear();
|
||||
|
||||
for (int index = start_index + 1; index < end_index; index++) {
|
||||
NodeHandle node_handle = result_[index];
|
||||
const VKRenderGraphNode &node = render_graph.nodes_[node_handle];
|
||||
if (pre_rendering_handles.is_empty()) {
|
||||
if (!node_type_is_rendering(node.type)) {
|
||||
rendering_handles.extend(&result_[start_index], index - start_index);
|
||||
pre_rendering_handles.append(node_handle);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const VKRenderGraphNodeLinks &node_links = render_graph.links_[node_handle];
|
||||
if (node_type_is_rendering(node.type)) {
|
||||
rendering_handles.append(node_handle);
|
||||
for (const VKRenderGraphLink &input : node_links.inputs) {
|
||||
accessed_resources.add(input.resource.handle);
|
||||
}
|
||||
}
|
||||
else {
|
||||
bool prepend = true;
|
||||
for (const VKRenderGraphLink &output : node_links.outputs) {
|
||||
if (accessed_resources.contains(output.resource.handle)) {
|
||||
accessed_resources.remove(output.resource.handle);
|
||||
prepend = false;
|
||||
}
|
||||
}
|
||||
if (prepend) {
|
||||
pre_rendering_handles.append(node_handle);
|
||||
}
|
||||
else {
|
||||
// This adds a none rendering node into a rendering scope.
|
||||
// later on the rendering will be suspended when the commands
|
||||
// for these nodes are build.
|
||||
rendering_handles.append(node_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!pre_rendering_handles.is_empty()) {
|
||||
MutableSpan<NodeHandle> store_none_rendering = result_.as_mutable_span().slice(
|
||||
start_index, pre_rendering_handles.size());
|
||||
MutableSpan<NodeHandle> store_rendering = result_.as_mutable_span().slice(
|
||||
start_index + pre_rendering_handles.size(), rendering_handles.size());
|
||||
store_none_rendering.copy_from(pre_rendering_handles);
|
||||
store_rendering.copy_from(rendering_handles);
|
||||
start_index += pre_rendering_handles.size();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user