From ec10c5d94be7c84b407c7895ae8cbb7c6ecedf3e Mon Sep 17 00:00:00 2001 From: Vladislav Mikhalin Date: Mon, 25 Nov 2024 09:50:24 +0300 Subject: [PATCH] rebase, initialize hash, fix bounds check --- src/video_core/texture_cache/texture_cache.cpp | 18 +++++++++++------- src/video_core/texture_cache/texture_cache.h | 2 +- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/video_core/texture_cache/texture_cache.cpp b/src/video_core/texture_cache/texture_cache.cpp index 248372ec4..e5bb7a617 100644 --- a/src/video_core/texture_cache/texture_cache.cpp +++ b/src/video_core/texture_cache/texture_cache.cpp @@ -43,16 +43,20 @@ TextureCache::TextureCache(const Vulkan::Instance& instance_, Vulkan::Scheduler& TextureCache::~TextureCache() = default; -void TextureCache::InvalidateMemory(VAddr addr, VAddr addr_aligned, size_t size) { +void TextureCache::InvalidateMemory(VAddr addr, VAddr page_addr, size_t size) { std::scoped_lock lock{mutex}; - ForEachImageInRegion(addr_aligned, size, [&](ImageId image_id, Image& image) { - const auto image_end = image.info.guest_address + image.info.guest_size_bytes; - const auto page_end = addr_aligned + size; - if (addr < image.info.guest_address) { + ForEachImageInRegion(page_addr, size, [&](ImageId image_id, Image& image) { + if (addr < image.cpu_addr) { // This page access may or may not modify the image. // We should not mark it as dirty now, if it really was modified, // it will receive more invalidations on subsequent pages. - if (image_end < page_end) { + const auto page_end = page_addr + size; + if (image.cpu_addr_end <= page_end) { + if (image.hash == 0) { + // Initialize hash + const u8* addr = std::bit_cast(image.info.guest_address); + image.hash = XXH3_64bits(addr, image.info.guest_size_bytes); + } // Image ends on this page so it can not receive any more invalidations. // We will check it's hash later to see if it really was modified. image.flags |= ImageFlagBits::MaybeCpuDirty; @@ -64,7 +68,7 @@ void TextureCache::InvalidateMemory(VAddr addr, VAddr addr_aligned, size_t size) return; } - if (addr < image_end) { + if (addr < image.cpu_addr_end) { // Ensure image is reuploaded when accessed again. image.flags |= ImageFlagBits::CpuDirty; } diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 0dc14a2c6..c1530b7de 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h @@ -95,7 +95,7 @@ public: ~TextureCache(); /// Invalidates any image in the logical page range. - void InvalidateMemory(VAddr addr, VAddr addr_aligned, size_t size); + void InvalidateMemory(VAddr addr, VAddr page_addr, size_t size); /// Marks an image as dirty if it exists at the provided address. void InvalidateMemoryFromGPU(VAddr address, size_t max_size);