diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index 8b52a10e81..283d140066 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -659,26 +659,48 @@ namespace rsx if (found != m_cache.end()) { auto &range_data = found->second; + std::pair best_fit = {}; for (auto &tex : range_data.data) { - if (tex.matches(rsx_address, rsx_size) && !tex.is_dirty()) + if (tex.matches(rsx_address, rsx_size)) { - if (!confirm_dimensions || tex.matches(rsx_address, width, height, depth, mipmaps)) + if (!tex.is_dirty()) { - if (!tex.is_locked() && tex.get_context() == texture_upload_context::framebuffer_storage) - range_data.notify(rsx_address, rsx_size); + if (!confirm_dimensions || tex.matches(rsx_address, width, height, depth, mipmaps)) + { + if (!tex.is_locked() && tex.get_context() == texture_upload_context::framebuffer_storage) + range_data.notify(rsx_address, rsx_size); - return tex; + return tex; + } + else + { + LOG_ERROR(RSX, "Cached object for address 0x%X was found, but it does not match stored parameters.", rsx_address); + LOG_ERROR(RSX, "%d x %d vs %d x %d", width, height, tex.get_width(), tex.get_height()); + } } - else + else if (!best_fit.first) { - LOG_ERROR(RSX, "Cached object for address 0x%X was found, but it does not match stored parameters.", rsx_address); - LOG_ERROR(RSX, "%d x %d vs %d x %d", width, height, tex.get_width(), tex.get_height()); + //By grabbing a ref to a matching entry, duplicates are avoided + best_fit = { &tex, &range_data }; } } } + if (best_fit.first) + { + if (best_fit.first->exists()) + { + m_unreleased_texture_objects--; + free_texture_section(*best_fit.first); + m_texture_memory_in_use -= best_fit.first->get_section_size(); + } + + best_fit.second->notify(rsx_address, rsx_size); + return *best_fit.first; + } + for (auto &tex : range_data.data) { if (tex.is_dirty()) @@ -1344,10 +1366,22 @@ namespace rsx auto cached_texture = find_texture_from_dimensions(texaddr, tex_width, tex_height, depth); if (cached_texture) { - if (cached_texture->get_image_type() == rsx::texture_dimension_extended::texture_dimension_1d) - scale_y = 0.f; + //TODO: Handle invalidated framebuffer textures better. This is awful + if (cached_texture->get_context() == rsx::texture_upload_context::framebuffer_storage) + { + if (!cached_texture->is_locked()) + { + cached_texture->set_dirty(true); + m_unreleased_texture_objects++; + } + } + else + { + if (cached_texture->get_image_type() == rsx::texture_dimension_extended::texture_dimension_1d) + scale_y = 0.f; - return{ cached_texture->get_raw_view(), cached_texture->get_context(), cached_texture->is_depth_texture(), scale_x, scale_y, cached_texture->get_image_type() }; + return{ cached_texture->get_raw_view(), cached_texture->get_context(), cached_texture->is_depth_texture(), scale_x, scale_y, cached_texture->get_image_type() }; + } } if ((!blit_engine_incompatibility_warning_raised && g_cfg.video.use_gpu_texture_scaling) || is_hw_blit_engine_compatible(format)) diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index cc6da419e8..567b93ece5 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -2916,7 +2916,7 @@ void VKGSRender::flip(int buffer) if (image_to_flip) { vk::copy_scaled_image(*m_current_command_buffer, image_to_flip->value, target_image, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, - 0, 0, image_to_flip->width(), image_to_flip->height(), aspect_ratio.x, aspect_ratio.y, aspect_ratio.width, aspect_ratio.height, 1, VK_IMAGE_ASPECT_COLOR_BIT); + 0, 0, image_to_flip->width(), image_to_flip->height(), aspect_ratio.x, aspect_ratio.y, aspect_ratio.width, aspect_ratio.height, 1, VK_IMAGE_ASPECT_COLOR_BIT, false); } else { diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index 640cd93ba2..62d0507c65 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -80,7 +80,7 @@ namespace vk void change_image_layout(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout, VkImageSubresourceRange range); void change_image_layout(VkCommandBuffer cmd, vk::image *image, VkImageLayout new_layout, VkImageSubresourceRange range); void copy_image(VkCommandBuffer cmd, VkImage &src, VkImage &dst, VkImageLayout srcLayout, VkImageLayout dstLayout, u32 width, u32 height, u32 mipmaps, VkImageAspectFlagBits aspect); - void copy_scaled_image(VkCommandBuffer cmd, VkImage &src, VkImage &dst, VkImageLayout srcLayout, VkImageLayout dstLayout, u32 src_x_offset, u32 src_y_offset, u32 src_width, u32 src_height, u32 dst_x_offset, u32 dst_y_offset, u32 dst_width, u32 dst_height, u32 mipmaps, VkImageAspectFlagBits aspect); + void copy_scaled_image(VkCommandBuffer cmd, VkImage &src, VkImage &dst, VkImageLayout srcLayout, VkImageLayout dstLayout, u32 src_x_offset, u32 src_y_offset, u32 src_width, u32 src_height, u32 dst_x_offset, u32 dst_y_offset, u32 dst_width, u32 dst_height, u32 mipmaps, VkImageAspectFlagBits aspect, bool compatible_formats); VkFormat get_compatible_sampler_format(u32 format); u8 get_format_texel_width(const VkFormat format); diff --git a/rpcs3/Emu/RSX/VK/VKTexture.cpp b/rpcs3/Emu/RSX/VK/VKTexture.cpp index 3253fd7b05..bc5e793ee4 100644 --- a/rpcs3/Emu/RSX/VK/VKTexture.cpp +++ b/rpcs3/Emu/RSX/VK/VKTexture.cpp @@ -86,7 +86,7 @@ namespace vk VkImageLayout srcLayout, VkImageLayout dstLayout, u32 src_x_offset, u32 src_y_offset, u32 src_width, u32 src_height, u32 dst_x_offset, u32 dst_y_offset, u32 dst_width, u32 dst_height, - u32 mipmaps, VkImageAspectFlagBits aspect) + u32 mipmaps, VkImageAspectFlagBits aspect, bool compatible_formats) { VkImageSubresourceLayers a_src = {}, a_dst = {}; a_src.aspectMask = aspect; @@ -103,7 +103,7 @@ namespace vk if (dstLayout != VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) change_image_layout(cmd, dst, dstLayout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk::get_image_subresource_range(0, 0, 1, 1, aspect)); - if (src_width != dst_width || src_height != dst_height || mipmaps > 1) + if (src_width != dst_width || src_height != dst_height || mipmaps > 1 || !compatible_formats) { if ((aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0) { diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index 84f812434b..6e1d41ebb6 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -899,7 +899,7 @@ namespace vk } copy_scaled_image(*commands, src->value, dst->value, src->current_layout, dst->current_layout, src_area.x1, src_area.y1, src_area.x2 - src_area.x1, src_area.y2 - src_area.y1, - dst_area.x1, dst_area.y1, dst_area.x2 - dst_area.x1, dst_area.y2 - dst_area.y1, 1, aspect); + dst_area.x1, dst_area.y1, dst_area.x2 - dst_area.x1, dst_area.y2 - dst_area.y1, 1, aspect, src->info.format == dst->info.format); change_image_layout(*commands, dst, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, {(VkImageAspectFlags)aspect, 0, dst->info.mipLevels, 0, dst->info.arrayLayers}); }