mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-15 03:08:36 +12:00
vulkan: Fix blit engine transfer to ARGB8 render target memory
This commit is contained in:
parent
e9d6096356
commit
cc7848b3ef
3 changed files with 51 additions and 2 deletions
|
@ -33,6 +33,8 @@ namespace rsx
|
||||||
u32 dst_gcm_format = 0;
|
u32 dst_gcm_format = 0;
|
||||||
f32 src_scaling_hint = 1.f;
|
f32 src_scaling_hint = 1.f;
|
||||||
f32 dst_scaling_hint = 1.f;
|
f32 dst_scaling_hint = 1.f;
|
||||||
|
texture_upload_context src_context = texture_upload_context::blit_engine_src;
|
||||||
|
texture_upload_context dst_context = texture_upload_context::blit_engine_dst;
|
||||||
|
|
||||||
void analyse()
|
void analyse()
|
||||||
{
|
{
|
||||||
|
@ -2125,6 +2127,7 @@ namespace rsx
|
||||||
if (cached_dest)
|
if (cached_dest)
|
||||||
{
|
{
|
||||||
dest_texture = cached_dest->get_raw_texture();
|
dest_texture = cached_dest->get_raw_texture();
|
||||||
|
typeless_info.dst_context = cached_dest->get_context();
|
||||||
|
|
||||||
max_dst_width = cached_dest->get_width();
|
max_dst_width = cached_dest->get_width();
|
||||||
max_dst_height = cached_dest->get_height();
|
max_dst_height = cached_dest->get_height();
|
||||||
|
@ -2144,6 +2147,7 @@ namespace rsx
|
||||||
dst_area.y2 += dst_subres.y;
|
dst_area.y2 += dst_subres.y;
|
||||||
|
|
||||||
dest_texture = dst_subres.surface->get_surface();
|
dest_texture = dst_subres.surface->get_surface();
|
||||||
|
typeless_info.dst_context = texture_upload_context::framebuffer_storage;
|
||||||
|
|
||||||
max_dst_width = (u16)(dst_subres.surface->get_surface_width() * typeless_info.dst_scaling_hint);
|
max_dst_width = (u16)(dst_subres.surface->get_surface_width() * typeless_info.dst_scaling_hint);
|
||||||
max_dst_height = dst_subres.surface->get_surface_height();
|
max_dst_height = dst_subres.surface->get_surface_height();
|
||||||
|
@ -2179,6 +2183,7 @@ namespace rsx
|
||||||
src_area.y2 <= surface->get_height())
|
src_area.y2 <= surface->get_height())
|
||||||
{
|
{
|
||||||
vram_texture = surface->get_raw_texture();
|
vram_texture = surface->get_raw_texture();
|
||||||
|
typeless_info.src_context = surface->get_context();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2206,6 +2211,7 @@ namespace rsx
|
||||||
subresource_layout, rsx::texture_dimension_extended::texture_dimension_2d, dst.swizzled)->get_raw_texture();
|
subresource_layout, rsx::texture_dimension_extended::texture_dimension_2d, dst.swizzled)->get_raw_texture();
|
||||||
|
|
||||||
m_texture_memory_in_use += src.pitch * src.slice_h;
|
m_texture_memory_in_use += src.pitch * src.slice_h;
|
||||||
|
typeless_info.src_context = texture_upload_context::blit_engine_src;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2232,6 +2238,7 @@ namespace rsx
|
||||||
src_area.y2 += src_subres.y;
|
src_area.y2 += src_subres.y;
|
||||||
|
|
||||||
vram_texture = src_subres.surface->get_surface();
|
vram_texture = src_subres.surface->get_surface();
|
||||||
|
typeless_info.src_context = texture_upload_context::framebuffer_storage;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool src_is_depth = src_subres.is_depth_surface;
|
const bool src_is_depth = src_subres.is_depth_surface;
|
||||||
|
@ -2342,6 +2349,7 @@ namespace rsx
|
||||||
channel_order);
|
channel_order);
|
||||||
|
|
||||||
dest_texture = cached_dest->get_raw_texture();
|
dest_texture = cached_dest->get_raw_texture();
|
||||||
|
typeless_info.dst_context = texture_upload_context::blit_engine_dst;
|
||||||
m_texture_memory_in_use += dst.pitch * dst_dimensions.height;
|
m_texture_memory_in_use += dst.pitch * dst_dimensions.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -195,7 +195,7 @@ namespace vk
|
||||||
if (!g_scratch_buffer)
|
if (!g_scratch_buffer)
|
||||||
{
|
{
|
||||||
// 32M disposable scratch memory
|
// 32M disposable scratch memory
|
||||||
g_scratch_buffer = std::make_unique<vk::buffer>(*g_current_renderer, 32 * 0x100000,
|
g_scratch_buffer = std::make_unique<vk::buffer>(*g_current_renderer, 64 * 0x100000,
|
||||||
g_current_renderer->get_memory_mapping().device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
g_current_renderer->get_memory_mapping().device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||||
VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 0);
|
VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1129,6 +1129,47 @@ namespace vk
|
||||||
vk::copy_image_typeless(*commands, dst, real_dst, { 0, 0, (s32)dst->width(), (s32)dst->height() }, { 0, 0, (s32)internal_width, (s32)dst->height() }, 1,
|
vk::copy_image_typeless(*commands, dst, real_dst, { 0, 0, (s32)dst->width(), (s32)dst->height() }, { 0, 0, (s32)internal_width, (s32)dst->height() }, 1,
|
||||||
vk::get_aspect_flags(dst->info.format), vk::get_aspect_flags(format));
|
vk::get_aspect_flags(dst->info.format), vk::get_aspect_flags(format));
|
||||||
}
|
}
|
||||||
|
else if (xfer_info.dst_context == rsx::texture_upload_context::framebuffer_storage)
|
||||||
|
{
|
||||||
|
if (xfer_info.src_context != rsx::texture_upload_context::blit_engine_dst &&
|
||||||
|
xfer_info.src_context != rsx::texture_upload_context::framebuffer_storage)
|
||||||
|
{
|
||||||
|
// Data moving to rendertarget, where byte ordering has to be preserved
|
||||||
|
// NOTE: This is a workaround, true accuracy would require all RTT<->cache transfers to invoke this step but thats too slow
|
||||||
|
// Sampling is ok; image view swizzle will work around it
|
||||||
|
if (dst->info.format == VK_FORMAT_B8G8R8A8_UNORM)
|
||||||
|
{
|
||||||
|
// For this specific format, channel ordering is faked via custom remap, undo this before transfer
|
||||||
|
VkBufferImageCopy copy{};
|
||||||
|
copy.imageExtent = src->info.extent;
|
||||||
|
copy.imageOffset = { 0, 0, 0 };
|
||||||
|
copy.imageSubresource = { VK_IMAGE_ASPECT_COLOR_BIT, 0, 0, 1 };
|
||||||
|
|
||||||
|
const auto scratch_buf = vk::get_scratch_buffer();
|
||||||
|
const auto data_length = src->info.extent.width * src->info.extent.height * 4;
|
||||||
|
|
||||||
|
const auto current_layout = src->current_layout;
|
||||||
|
vk::change_image_layout(*commands, real_src, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
||||||
|
vkCmdCopyImageToBuffer(*commands, src->value, src->current_layout, scratch_buf->value, 1, ©);
|
||||||
|
vk::change_image_layout(*commands, real_src, current_layout, { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 });
|
||||||
|
|
||||||
|
vk::insert_buffer_memory_barrier(*commands, scratch_buf->value, 0, data_length,
|
||||||
|
VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||||
|
VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT);
|
||||||
|
|
||||||
|
vk::get_compute_task<vk::cs_shuffle_32>()->run(*commands, scratch_buf, data_length);
|
||||||
|
|
||||||
|
vk::insert_buffer_memory_barrier(*commands, scratch_buf->value, 0, data_length,
|
||||||
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
|
||||||
|
VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT);
|
||||||
|
|
||||||
|
real_src = vk::get_typeless_helper(src->info.format);
|
||||||
|
vk::change_image_layout(*commands, real_src, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, {VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1});
|
||||||
|
|
||||||
|
vkCmdCopyBufferToImage(*commands, scratch_buf->value, real_src->value, real_src->current_layout, 1, ©);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Checks
|
// Checks
|
||||||
if (src_area.x2 <= src_area.x1 || src_area.y2 <= src_area.y1 || dst_area.x2 <= dst_area.x1 || dst_area.y2 <= dst_area.y1)
|
if (src_area.x2 <= src_area.x1 || src_area.y2 <= src_area.y1 || dst_area.x2 <= dst_area.x1 || dst_area.y2 <= dst_area.y1)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue