rsx/tecture_cache: Addendum - fix data cast with scaling conversion (AA emulation)

- Blit operations do format conversion automatically which is NOT what we want!
- Scale onto temp buffer with similar format before performing data cast.
This commit is contained in:
kd-11 2019-02-27 21:28:49 +03:00 committed by kd-11
parent 10dc3dadee
commit 0395fb9955
3 changed files with 62 additions and 12 deletions

View File

@ -426,7 +426,7 @@ namespace gl
if (require_manual_shuffle)
{
//byte swapping does not work on byte types, use uint_8_8_8_8 for rgba8 instead to avoid penalty
rsx::shuffle_texel_data_wzyx<u8>(dst, rsx_pitch, width, valid_length / rsx_pitch);
rsx::shuffle_texel_data_wzyx<u8>(dst, rsx_pitch, width, align(valid_length, rsx_pitch) / rsx_pitch);
}
else if (pack_unpack_swap_bytes && ::gl::get_driver_caps().vendor_AMD)
{
@ -750,12 +750,28 @@ namespace gl
{
verify(HERE), dst_image->get_target() == gl::texture::target::texture2D;
std::unique_ptr<gl::texture> tmp;
auto _dst = dst_image;
auto _blitter = gl::g_hw_blitter;
const areai src_rect = { slice.src_x, slice.src_y, slice.src_x + slice.src_w, slice.src_y + slice.src_h };
const areai dst_rect = { slice.dst_x, slice.dst_y, slice.dst_x + slice.dst_w, slice.dst_y + slice.dst_h };
_blitter->scale_image(cmd, slice.src, dst_image,
if (UNLIKELY(slice.src->get_internal_format() != dst_image->get_internal_format()))
{
tmp = std::make_unique<texture>(GL_TEXTURE_2D, dst_rect.x2, dst_rect.y2, 1, 1, (GLenum)slice.src->get_internal_format());
_dst = tmp.get();
}
_blitter->scale_image(cmd, slice.src, _dst,
src_rect, dst_rect, false, false, {});
if (tmp)
{
// Data cast comes after scaling
glCopyImageSubData(tmp->id(), GL_TEXTURE_2D, 0, slice.dst_x, slice.dst_y, 0,
dst_image->id(), (GLenum)dst_image->get_target(), 0, slice.dst_x, slice.dst_y, slice.dst_z, slice.dst_w, slice.dst_h, 1);
}
}
}
}
@ -860,8 +876,7 @@ namespace gl
const texture_channel_remap_t& remap_vector) override
{
auto _template = get_template_from_collection_impl(sections_to_copy);
const GLenum ifmt = _template ? (GLenum)_template->get_internal_format() : GL_NONE;
auto result = create_temporary_subresource_impl(_template, ifmt, GL_TEXTURE_2D, gcm_format, 0, 0, width, height, remap_vector, false);
auto result = create_temporary_subresource_impl(_template, GL_NONE, GL_TEXTURE_2D, gcm_format, 0, 0, width, height, remap_vector, false);
copy_transfer_regions_impl(cmd, result->image(), sections_to_copy);
return result;

View File

@ -236,7 +236,7 @@ namespace vk
for (u32 mip_level = 0; mip_level < mipmaps; ++mip_level)
{
vkCmdCopyImage(cmd, src, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &rgn);
vkCmdCopyImage(cmd, src, preferred_src_format, dst, preferred_dst_format, 1, &rgn);
rgn.srcSubresource.mipLevel++;
rgn.dstSubresource.mipLevel++;

View File

@ -535,13 +535,27 @@ namespace vk
else
{
verify(HERE), section.dst_z == 0;
u32 dst_x = section.dst_x, dst_y = section.dst_y;
vk::image* _dst;
if (LIKELY(section.src->info.format == dst->info.format))
{
_dst = dst;
}
else
{
_dst = vk::get_typeless_helper(section.src->info.format, dst->width(), dst->height() * 2);
vk::change_image_layout(cmd, _dst, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, src_range);
}
if (section.xform == surface_transform::identity)
{
vk::copy_scaled_image(cmd, section.src->value, dst->value, section.src->current_layout, dst->current_layout,
vk::copy_scaled_image(cmd, section.src->value, _dst->value, section.src->current_layout, _dst->current_layout,
section.src_x, section.src_y, section.src_w, section.src_h,
section.dst_x, section.dst_y, section.dst_w, section.dst_h,
1, src_aspect, section.src->info.format == dst->info.format,
VK_FILTER_NEAREST);
1, src_aspect, section.src->info.format == _dst->info.format,
VK_FILTER_NEAREST, section.src->info.format, _dst->info.format);
}
else if (section.xform == surface_transform::argb_to_bgra)
{
@ -572,11 +586,17 @@ namespace vk
vkCmdCopyBufferToImage(cmd, scratch_buf->value, tmp->value, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &copy);
vk::copy_scaled_image(cmd, tmp->value, dst->value, tmp->current_layout, dst->current_layout,
if (UNLIKELY(tmp == _dst))
{
dst_x = 0;
dst_y = section.src_h;
}
vk::copy_scaled_image(cmd, tmp->value, _dst->value, tmp->current_layout, _dst->current_layout,
0, 0, section.src_w, section.src_h,
section.dst_x, section.dst_y, section.dst_w, section.dst_h,
1, src_aspect, section.src->info.format == dst->info.format,
VK_FILTER_NEAREST);
dst_x, dst_y, section.dst_w, section.dst_h,
1, src_aspect, section.src->info.format == _dst->info.format,
VK_FILTER_NEAREST, tmp->info.format, _dst->info.format);
vk::change_image_layout(cmd, section.src, old_src_layout, src_range);
}
@ -584,6 +604,21 @@ namespace vk
{
fmt::throw_exception("Unreachable" HERE);
}
if (UNLIKELY(_dst != dst))
{
// Casting comes after the scaling!
VkImageCopy copy_rgn;
copy_rgn.srcOffset = { s32(dst_x), s32(dst_y), 0 };
copy_rgn.dstOffset = { section.dst_x, section.dst_y, 0 };
copy_rgn.dstSubresource = { dst_aspect & ~(VK_IMAGE_ASPECT_STENCIL_BIT), 0, 0, 1 };
copy_rgn.srcSubresource = { src_aspect & ~(VK_IMAGE_ASPECT_STENCIL_BIT), 0, 0, 1 };
copy_rgn.extent = { section.dst_w, section.dst_h, 1 };
vk::change_image_layout(cmd, _dst, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, src_range);
vkCmdCopyImage(cmd, _dst->value, _dst->current_layout, dst->value, dst->current_layout, 1, &copy_rgn);
}
}
}
}