Vulkan: Incorrect image aspect when transferring depth textures

When copying from/to depth stencil images the aspect of the image was
set incorrectly. It pointed to only one aspect of the full image when
building resource links, which could lead to incorrect decisions in the
driver.

Found when researching #131269

Pull Request: https://projects.blender.org/blender/blender/pulls/131298
This commit is contained in:
Jeroen Bakker
2024-12-03 12:36:39 +01:00
parent f0500a28ee
commit c480b7ffd3
5 changed files with 67 additions and 45 deletions

View File

@@ -20,8 +20,13 @@ struct VKCopyBufferToImageData {
VkBufferImageCopy region;
};
struct VKCopyBufferToImageCreateInfo {
VKCopyBufferToImageData node_data;
VkImageAspectFlags vk_image_aspects;
};
class VKCopyBufferToImageNode : public VKNodeInfo<VKNodeType::COPY_BUFFER_TO_IMAGE,
VKCopyBufferToImageData,
VKCopyBufferToImageCreateInfo,
VKCopyBufferToImageData,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VKResourceType::IMAGE | VKResourceType::BUFFER> {
@@ -35,7 +40,7 @@ class VKCopyBufferToImageNode : public VKNodeInfo<VKNodeType::COPY_BUFFER_TO_IMA
*/
template<typename Node> static void set_node_data(Node &node, const CreateInfo &create_info)
{
node.copy_buffer_to_image = create_info;
node.copy_buffer_to_image = create_info.node_data;
}
/**
@@ -45,14 +50,15 @@ class VKCopyBufferToImageNode : public VKNodeInfo<VKNodeType::COPY_BUFFER_TO_IMA
VKRenderGraphNodeLinks &node_links,
const CreateInfo &create_info) override
{
ResourceWithStamp src_resource = resources.get_buffer(create_info.src_buffer);
ResourceWithStamp dst_resource = resources.get_image_and_increase_stamp(create_info.dst_image);
ResourceWithStamp src_resource = resources.get_buffer(create_info.node_data.src_buffer);
ResourceWithStamp dst_resource = resources.get_image_and_increase_stamp(
create_info.node_data.dst_image);
node_links.inputs.append(
{src_resource, VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED});
node_links.outputs.append({dst_resource,
VK_ACCESS_TRANSFER_WRITE_BIT,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
create_info.region.imageSubresource.aspectMask});
create_info.vk_image_aspects});
}
/**

View File

@@ -24,8 +24,13 @@ struct VKCopyImageToBufferData {
VkBufferImageCopy region;
};
struct VKCopyImageToBufferCreateInfo {
VKCopyImageToBufferData node_data;
VkImageAspectFlags vk_image_aspects;
};
class VKCopyImageToBufferNode : public VKNodeInfo<VKNodeType::COPY_IMAGE_TO_BUFFER,
VKCopyImageToBufferData,
VKCopyImageToBufferCreateInfo,
VKCopyImageToBufferData,
VK_PIPELINE_STAGE_TRANSFER_BIT,
VKResourceType::IMAGE | VKResourceType::BUFFER> {
@@ -39,7 +44,7 @@ class VKCopyImageToBufferNode : public VKNodeInfo<VKNodeType::COPY_IMAGE_TO_BUFF
*/
template<typename Node> static void set_node_data(Node &node, const CreateInfo &create_info)
{
node.copy_image_to_buffer = create_info;
node.copy_image_to_buffer = create_info.node_data;
}
/**
@@ -49,13 +54,13 @@ class VKCopyImageToBufferNode : public VKNodeInfo<VKNodeType::COPY_IMAGE_TO_BUFF
VKRenderGraphNodeLinks &node_links,
const CreateInfo &create_info) override
{
ResourceWithStamp src_resource = resources.get_image(create_info.src_image);
ResourceWithStamp src_resource = resources.get_image(create_info.node_data.src_image);
ResourceWithStamp dst_resource = resources.get_buffer_and_increase_stamp(
create_info.dst_buffer);
create_info.node_data.dst_buffer);
node_links.inputs.append({src_resource,
VK_ACCESS_TRANSFER_READ_BIT,
VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
create_info.region.imageSubresource.aspectMask});
create_info.vk_image_aspects});
node_links.outputs.append(
{dst_resource, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED});
}

View File

@@ -64,9 +64,10 @@ TEST(vk_render_graph, begin_clear_attachments_end_read_back)
{
VKCopyImageToBufferNode::CreateInfo copy_image_to_buffer = {};
copy_image_to_buffer.src_image = image;
copy_image_to_buffer.dst_buffer = buffer;
copy_image_to_buffer.region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy_image_to_buffer.node_data.src_image = image;
copy_image_to_buffer.node_data.dst_buffer = buffer;
copy_image_to_buffer.node_data.region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy_image_to_buffer.vk_image_aspects = VK_IMAGE_ASPECT_COLOR_BIT;
render_graph.add_node(copy_image_to_buffer);
}

View File

@@ -142,9 +142,11 @@ TEST(vk_render_graph, clear_clear_copy_and_read_back)
copy_image.node_data.region.dstSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy_image.vk_image_aspect = VK_IMAGE_ASPECT_COLOR_BIT;
VKCopyImageToBufferNode::CreateInfo copy_dst_image_to_buffer = {};
copy_dst_image_to_buffer.src_image = dst_image;
copy_dst_image_to_buffer.dst_buffer = staging_buffer;
copy_dst_image_to_buffer.region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy_dst_image_to_buffer.node_data.src_image = dst_image;
copy_dst_image_to_buffer.node_data.dst_buffer = staging_buffer;
copy_dst_image_to_buffer.node_data.region.imageSubresource.aspectMask =
VK_IMAGE_ASPECT_COLOR_BIT;
copy_dst_image_to_buffer.vk_image_aspects = VK_IMAGE_ASPECT_COLOR_BIT;
render_graph.add_node(clear_color_image_src);
render_graph.add_node(clear_color_image_dst);
@@ -269,9 +271,11 @@ TEST(vk_render_graph, clear_blit_copy_and_read_back)
clear_color_image_src.vk_image = src_image;
clear_color_image_src.vk_clear_color_value = color_black;
VKCopyImageToBufferNode::CreateInfo copy_dst_image_to_buffer = {};
copy_dst_image_to_buffer.src_image = dst_image;
copy_dst_image_to_buffer.dst_buffer = staging_buffer;
copy_dst_image_to_buffer.region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
copy_dst_image_to_buffer.node_data.src_image = dst_image;
copy_dst_image_to_buffer.node_data.dst_buffer = staging_buffer;
copy_dst_image_to_buffer.node_data.region.imageSubresource.aspectMask =
VK_IMAGE_ASPECT_COLOR_BIT;
copy_dst_image_to_buffer.vk_image_aspects = VK_IMAGE_ASPECT_COLOR_BIT;
render_graph.add_node(clear_color_image_src);
VKBlitImageNode::CreateInfo blit_image = {src_image, dst_image, vk_image_blit, VK_FILTER_LINEAR};

View File

@@ -189,19 +189,22 @@ void VKTexture::read_sub(
staging_buffer.create(device_memory_size, GPU_USAGE_DYNAMIC, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
render_graph::VKCopyImageToBufferNode::CreateInfo copy_image_to_buffer = {};
copy_image_to_buffer.src_image = vk_image_handle();
copy_image_to_buffer.dst_buffer = staging_buffer.vk_handle();
copy_image_to_buffer.region.imageOffset.x = region[0];
copy_image_to_buffer.region.imageOffset.y = region[1];
copy_image_to_buffer.region.imageOffset.z = region[2];
copy_image_to_buffer.region.imageExtent.width = extent.x;
copy_image_to_buffer.region.imageExtent.height = extent.y;
copy_image_to_buffer.region.imageExtent.depth = extent.z;
copy_image_to_buffer.region.imageSubresource.aspectMask = to_vk_image_aspect_single_bit(
to_vk_image_aspect_flag_bits(device_format_), false);
copy_image_to_buffer.region.imageSubresource.mipLevel = mip;
copy_image_to_buffer.region.imageSubresource.baseArrayLayer = layers.start();
copy_image_to_buffer.region.imageSubresource.layerCount = layers.size();
render_graph::VKCopyImageToBufferNode::Data &node_data = copy_image_to_buffer.node_data;
node_data.src_image = vk_image_handle();
node_data.dst_buffer = staging_buffer.vk_handle();
node_data.region.imageOffset.x = region[0];
node_data.region.imageOffset.y = region[1];
node_data.region.imageOffset.z = region[2];
node_data.region.imageExtent.width = extent.x;
node_data.region.imageExtent.height = extent.y;
node_data.region.imageExtent.depth = extent.z;
VkImageAspectFlags vk_image_aspects = to_vk_image_aspect_flag_bits(device_format_);
copy_image_to_buffer.vk_image_aspects = vk_image_aspects;
node_data.region.imageSubresource.aspectMask = to_vk_image_aspect_single_bit(vk_image_aspects,
false);
node_data.region.imageSubresource.mipLevel = mip;
node_data.region.imageSubresource.baseArrayLayer = layers.start();
node_data.region.imageSubresource.layerCount = layers.size();
VKContext &context = *VKContext::get();
context.rendering_end();
@@ -313,19 +316,22 @@ void VKTexture::update_sub(
}
render_graph::VKCopyBufferToImageNode::CreateInfo copy_buffer_to_image = {};
copy_buffer_to_image.src_buffer = staging_buffer.vk_handle();
copy_buffer_to_image.dst_image = vk_image_handle();
copy_buffer_to_image.region.imageExtent.width = extent.x;
copy_buffer_to_image.region.imageExtent.height = extent.y;
copy_buffer_to_image.region.imageExtent.depth = extent.z;
copy_buffer_to_image.region.imageOffset.x = offset.x;
copy_buffer_to_image.region.imageOffset.y = offset.y;
copy_buffer_to_image.region.imageOffset.z = offset.z;
copy_buffer_to_image.region.imageSubresource.aspectMask = to_vk_image_aspect_single_bit(
to_vk_image_aspect_flag_bits(device_format_), false);
copy_buffer_to_image.region.imageSubresource.mipLevel = mip;
copy_buffer_to_image.region.imageSubresource.baseArrayLayer = start_layer;
copy_buffer_to_image.region.imageSubresource.layerCount = layers;
render_graph::VKCopyBufferToImageNode::Data &node_data = copy_buffer_to_image.node_data;
node_data.src_buffer = staging_buffer.vk_handle();
node_data.dst_image = vk_image_handle();
node_data.region.imageExtent.width = extent.x;
node_data.region.imageExtent.height = extent.y;
node_data.region.imageExtent.depth = extent.z;
node_data.region.imageOffset.x = offset.x;
node_data.region.imageOffset.y = offset.y;
node_data.region.imageOffset.z = offset.z;
VkImageAspectFlags vk_image_aspects = to_vk_image_aspect_flag_bits(device_format_);
copy_buffer_to_image.vk_image_aspects = vk_image_aspects;
node_data.region.imageSubresource.aspectMask = to_vk_image_aspect_single_bit(vk_image_aspects,
false);
node_data.region.imageSubresource.mipLevel = mip;
node_data.region.imageSubresource.baseArrayLayer = start_layer;
node_data.region.imageSubresource.layerCount = layers;
context.render_graph.add_node(copy_buffer_to_image);
}