diff --git a/rpcs3/Emu/RSX/Common/surface_store.h b/rpcs3/Emu/RSX/Common/surface_store.h index 3659cb3dc5..aa1165ceeb 100644 --- a/rpcs3/Emu/RSX/Common/surface_store.h +++ b/rpcs3/Emu/RSX/Common/surface_store.h @@ -849,7 +849,7 @@ namespace rsx for (auto &tex_info : data) { auto this_address = std::get<0>(tex_info); - if (this_address > limit) + if (this_address >= limit) continue; auto surface = std::get<1>(tex_info).get(); diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index 351b599ac6..50cf0e4e78 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -910,6 +910,7 @@ namespace rsx } section_storage_type tmp; + update_cache_tag(); m_cache[block_address].add(tmp, rsx_address, rsx_size); return m_cache[block_address].data.back(); } @@ -961,10 +962,35 @@ namespace rsx region.set_context(texture_upload_context::framebuffer_storage); region.set_sampler_status(rsx::texture_sampler_status::status_uninitialized); region.set_image_type(rsx::texture_dimension_extended::texture_dimension_2d); - update_cache_tag(); - region.set_memory_read_flags(memory_read_flags::flush_always); + m_flush_always_cache[memory_address] = memory_size; + + //Test for invalidated sections from surface cache occupying same address range + auto &overlapped = find_texture_from_range(memory_address, memory_size); + if (overlapped.size() > 1) + { + for (auto surface : overlapped) + { + if (surface == ®ion) + continue; + + //Memory is shared with another surface + //Discard it - the backend should ensure memory contents are preserved if needed + surface->set_dirty(true); + + if (surface->get_context() != rsx::texture_upload_context::framebuffer_storage) + m_unreleased_texture_objects++; + + if (surface->is_locked()) + { + surface->unprotect(); + m_cache[get_block_address(surface->get_section_base())].remove_one(); + } + } + } + + update_cache_tag(); } void set_memory_read_flags(u32 memory_address, u32 memory_size, memory_read_flags flags) @@ -2303,18 +2329,20 @@ namespace rsx if (m_cache_update_tag.load(std::memory_order_consume) != m_flush_always_update_timestamp) { writer_lock lock(m_cache_mutex); + bool update_tag = false; for (const auto &It : m_flush_always_cache) { auto& section = find_cached_texture(It.first, It.second); if (section.get_protection() != utils::protection::no) { - auto &range = m_cache[get_block_address(It.first)]; + //NOTE: find_cached_texture will increment block ctr section.reprotect(utils::protection::no); - range.notify(); + update_tag = true; } } + if (update_tag) update_cache_tag(); m_flush_always_update_timestamp = m_cache_update_tag.load(std::memory_order_consume); } } diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index 045731e772..a787261118 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -736,7 +736,7 @@ namespace vk VK_IMAGE_VIEW_TYPE_2D, gcm_format, 0, 0, width, height, remap_vector, false); VkImage dst = result->info.image; - VkImageAspectFlags dst_aspect = VK_IMAGE_ASPECT_COLOR_BIT; + VkImageAspectFlags dst_aspect = vk::get_aspect_flags(result->info.format); VkImageSubresourceRange dst_range = { dst_aspect, 0, 1, 0, 1 }; vk::change_image_layout(cmd, dst, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst_range);