vk: Clean up WCB readbacks when resource is multisampled

- Resolve image first before performing any transfer operations
This commit is contained in:
kd-11 2019-06-07 21:31:38 +03:00 committed by kd-11
parent 9d314ca4ca
commit 5f34c0c59a

View file

@ -189,23 +189,23 @@ namespace vk
dma_buffer = std::make_unique<vk::buffer>(*m_device, align(get_section_size(), 256), memory_type, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT, 0); dma_buffer = std::make_unique<vk::buffer>(*m_device, align(get_section_size(), 256), memory_type, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_BUFFER_USAGE_TRANSFER_DST_BIT, 0);
} }
vk::image *locked_resource = vram_texture;
if (context == rsx::texture_upload_context::framebuffer_storage) if (context == rsx::texture_upload_context::framebuffer_storage)
{ {
auto as_rtt = static_cast<vk::render_target*>(vram_texture); auto surface = vk::as_rtt(vram_texture);
if (as_rtt->dirty()) as_rtt->read_barrier(cmd); surface->read_barrier(cmd);
locked_resource = surface->get_surface(rsx::surface_access::read);
} }
vk::image *target = vram_texture; verify(HERE), locked_resource->samples() == 1;
real_pitch = vk::get_format_texel_width(vram_texture->info.format) * vram_texture->width();
vk::image* target = locked_resource;
locked_resource->push_layout(cmd, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
real_pitch = vk::get_format_texel_width(locked_resource->info.format) * locked_resource->width();
VkImageAspectFlags aspect_flag = vk::get_aspect_flags(vram_texture->info.format);
VkImageSubresourceRange subresource_range = { aspect_flag, 0, 1, 0, 1 };
u32 transfer_width = width; u32 transfer_width = width;
u32 transfer_height = height; u32 transfer_height = height;
VkImageLayout old_layout = vram_texture->current_layout;
change_image_layout(cmd, vram_texture, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, subresource_range);
if ((rsx::get_resolution_scale_percent() != 100 && context == rsx::texture_upload_context::framebuffer_storage) || if ((rsx::get_resolution_scale_percent() != 100 && context == rsx::texture_upload_context::framebuffer_storage) ||
(real_pitch != rsx_pitch)) (real_pitch != rsx_pitch))
{ {
@ -216,42 +216,39 @@ namespace vk
transfer_height *= surface->samples_y; transfer_height *= surface->samples_y;
} }
if (transfer_width != vram_texture->width() || transfer_height != vram_texture->height()) if (transfer_width != locked_resource->width() || transfer_height != locked_resource->height())
{ {
// TODO: Synchronize access to typeles textures // TODO: Synchronize access to typeles textures
target = vk::get_typeless_helper(vram_texture->info.format, transfer_width, transfer_height); target = vk::get_typeless_helper(vram_texture->info.format, transfer_width, transfer_height);
change_image_layout(cmd, target, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, subresource_range); target->change_layout(cmd, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
// Allow bilinear filtering on color textures where compatibility is likely // Allow bilinear filtering on color textures where compatibility is likely
const auto filter = (aspect_flag == VK_IMAGE_ASPECT_COLOR_BIT) ? VK_FILTER_LINEAR : VK_FILTER_NEAREST; const auto filter = (target->aspect() == VK_IMAGE_ASPECT_COLOR_BIT) ? VK_FILTER_LINEAR : VK_FILTER_NEAREST;
vk::copy_scaled_image(cmd, vram_texture->value, target->value, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, target->current_layout, vk::copy_scaled_image(cmd, locked_resource->value, target->value, locked_resource->current_layout, target->current_layout,
{ 0, 0, (s32)vram_texture->width(), (s32)vram_texture->height() }, { 0, 0, (s32)transfer_width, (s32)transfer_height }, { 0, 0, (s32)locked_resource->width(), (s32)locked_resource->height() }, { 0, 0, (s32)transfer_width, (s32)transfer_height },
1, aspect_flag, true, filter, vram_texture->info.format, target->info.format); 1, target->aspect(), true, filter, vram_texture->format(), target->format());
target->change_layout(cmd, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
} }
} }
if (target->current_layout != VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL) verify(HERE), target->current_layout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
{
// Using a scaled intermediary
verify(HERE), target != vram_texture;
change_image_layout(cmd, target, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, subresource_range);
}
// Handle any format conversions using compute tasks // Handle any format conversions using compute tasks
vk::cs_shuffle_base *shuffle_kernel = nullptr; vk::cs_shuffle_base *shuffle_kernel = nullptr;
if (vram_texture->info.format == VK_FORMAT_D24_UNORM_S8_UINT) if (vram_texture->format() == VK_FORMAT_D24_UNORM_S8_UINT)
{ {
shuffle_kernel = vk::get_compute_task<vk::cs_shuffle_se_d24x8>(); shuffle_kernel = vk::get_compute_task<vk::cs_shuffle_se_d24x8>();
} }
else if (vram_texture->info.format == VK_FORMAT_D32_SFLOAT_S8_UINT) else if (vram_texture->format() == VK_FORMAT_D32_SFLOAT_S8_UINT)
{ {
shuffle_kernel = vk::get_compute_task<vk::cs_shuffle_se_f32_d24x8>(); shuffle_kernel = vk::get_compute_task<vk::cs_shuffle_se_f32_d24x8>();
} }
else if (pack_unpack_swap_bytes) else if (pack_unpack_swap_bytes)
{ {
const auto texel_layout = vk::get_format_element_size(vram_texture->info.format); const auto texel_layout = vk::get_format_element_size(vram_texture->format());
const auto elem_size = texel_layout.first; const auto elem_size = texel_layout.first;
if (elem_size == 2) if (elem_size == 2)
@ -269,12 +266,12 @@ namespace vk
// TODO: Read back stencil values (is this really necessary?) // TODO: Read back stencil values (is this really necessary?)
VkBufferImageCopy region = {}; VkBufferImageCopy region = {};
region.imageSubresource = {aspect_flag & ~(VK_IMAGE_ASPECT_STENCIL_BIT), 0, 0, 1}; region.imageSubresource = {vram_texture->aspect() & ~(VK_IMAGE_ASPECT_STENCIL_BIT), 0, 0, 1};
region.imageExtent = {transfer_width, transfer_height, 1}; region.imageExtent = {transfer_width, transfer_height, 1};
vkCmdCopyImageToBuffer(cmd, target->value, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, mem_target->value, 1, &region); vkCmdCopyImageToBuffer(cmd, target->value, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, mem_target->value, 1, &region);
change_image_layout(cmd, vram_texture, old_layout, subresource_range); locked_resource->pop_layout(cmd);
real_pitch = vk::get_format_texel_width(vram_texture->info.format) * transfer_width; real_pitch = vk::get_format_texel_width(vram_texture->format()) * transfer_width;
if (shuffle_kernel) if (shuffle_kernel)
{ {