From 910fc54ee227845f0c002640be2b2822427ec9e8 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Fri, 9 Mar 2018 20:55:19 +0300 Subject: [PATCH] vk: Implement reading from cell if swap image isn't found --- rpcs3/Emu/RSX/VK/VKGSRender.cpp | 5 ++++ rpcs3/Emu/RSX/VK/VKTextureCache.h | 47 +++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index b87aac0ea6..5269d05f67 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -3057,6 +3057,11 @@ void VKGSRender::flip(int buffer) //The render might have been done offscreen or in software and a blit used to display image_to_flip = surface->get_raw_texture(); } + else + { + //Read from cell + image_to_flip = m_texture_cache.upload_image_simple(*m_current_command_buffer, absolute_address, buffer_width, buffer_height); + } } VkImage target_image = m_swapchain->get_image(m_current_frame->present_image); diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index e0474de50a..f1c9135b82 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -1120,6 +1120,53 @@ namespace vk return upload_texture(cmd, tex, m_rtts, cmd, m_memory_types, const_cast(m_submit_queue)); } + vk::image *upload_image_simple(vk::command_buffer& cmd, u32 address, u32 width, u32 height) + { + //Uploads a linear memory range as a BGRA8 texture + auto image = std::make_unique(*m_device, m_memory_types.host_visible_coherent, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, + VK_IMAGE_TYPE_2D, + VK_FORMAT_B8G8R8A8_UNORM, + width, height, 1, 1, 1, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_TILING_LINEAR, VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0); + + VkImageSubresource subresource{}; + subresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + + VkSubresourceLayout layout{}; + vkGetImageSubresourceLayout(*m_device, image->value, &subresource, &layout); + + void* mem = nullptr; + vkMapMemory(*m_device, image->memory->memory, 0, layout.rowPitch * height, 0, &mem); + + u32 row_pitch = width * 4; + char *src = (char *)vm::base(address); + char *dst = (char *)mem; + + //TODO: SSE optimization + for (u32 row = 0; row < height; ++row) + { + be_t* casted_src = (be_t*)src; + u32* casted_dst = (u32*)dst; + + for (int col = 0; col < width; ++col) + casted_dst[col] = casted_src[col]; + + src += row_pitch; + dst += layout.rowPitch; + } + + vkUnmapMemory(*m_device, image->memory->memory); + + auto result = image.get(); + const u32 resource_memory = width * height * 4; //Rough approximate + m_discardable_storage.push_back(image); + m_discardable_storage.back().block_size = resource_memory; + m_discarded_memory_size += resource_memory; + + return result; + } + vk_blit_op_result blit(rsx::blit_src_info& src, rsx::blit_dst_info& dst, bool interpolate, rsx::vk_render_targets& m_rtts, vk::command_buffer& cmd) { struct blit_helper