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:
@@ -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});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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});
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user