vk: Optimize image transfers

- Adds the same optimization/simplification steps to complex image
transfer routines. Whenever possible, multi-step transfers are collapsed
into a single operation.
This commit is contained in:
kd-11 2020-01-16 17:48:55 +03:00 committed by kd-11
parent 82af17beb1
commit 9b34f00241
2 changed files with 42 additions and 0 deletions

View file

@ -876,6 +876,34 @@ namespace vk
vk::image* real_src = src;
vk::image* real_dst = dst;
// Optimization pass; check for pass-through data transfer
if (!xfer_info.flip_horizontal && !xfer_info.flip_vertical && src_area.height() == dst_area.height())
{
auto src_w = src_area.width();
auto dst_w = dst_area.width();
if (xfer_info.src_is_typeless) src_w *= xfer_info.src_scaling_hint;
if (xfer_info.dst_is_typeless) dst_w *= xfer_info.dst_scaling_hint;
if (src_w == dst_w)
{
// Final dimensions are a match
if (xfer_info.src_is_typeless || xfer_info.dst_is_typeless)
{
const areai src_rect = src_area * size2f{ xfer_info.src_scaling_hint, 1.f };
const areai dst_rect = dst_area * size2f{ xfer_info.dst_scaling_hint, 1.f };
vk::copy_image_typeless(cmd, src, dst, src_rect, dst_rect, 1, src->aspect(), dst->aspect());
}
else
{
copy_image(cmd, src->value, dst->value, src->current_layout, dst->current_layout,
src_area, dst_area, 1, src->aspect(), dst->aspect());
}
return;
}
}
if (xfer_info.src_is_typeless)
{
const auto format = xfer_info.src_native_format_override ?

View file

@ -607,6 +607,20 @@ namespace vk
const u16 convert_w = u16(src_w * src_bpp) / dst_bpp;
const u16 convert_x = u16(src_x * src_bpp) / dst_bpp;
if (convert_w == section.dst_w && src_h == section.dst_h &&
transform == rsx::surface_transform::identity &&
section.level == 0 && section.dst_z == 0)
{
// Optimization to avoid double transfer
// TODO: Handle level and layer offsets
const areai src_rect = coordi{{ src_x, src_y }, { src_w, src_h }};
const areai dst_rect = coordi{{ section.dst_x, section.dst_y }, { section.dst_w, section.dst_h }};
vk::copy_image_typeless(cmd, section.src, dst, src_rect, dst_rect, 1, section.src->aspect(), dst_aspect);
section.src->pop_layout(cmd);
continue;
}
src_image = vk::get_typeless_helper(dst->info.format, convert_x + convert_w, src_y + src_h);
src_image->change_layout(cmd, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);