mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-08-04 16:32:39 +00:00
track potentially dirty images and hash them
This commit is contained in:
parent
7ac7398ab4
commit
7936dd7386
@ -22,9 +22,10 @@ VK_DEFINE_HANDLE(VmaAllocator)
|
||||
namespace VideoCore {
|
||||
|
||||
enum ImageFlagBits : u32 {
|
||||
MaybeCpuDirty = 1 << 0, ///< The page this image is in was touched before the image address
|
||||
CpuDirty = 1 << 1, ///< Contents have been modified from the CPU
|
||||
GpuDirty = 1 << 2, ///< Contents have been modified from the GPU (valid data in buffer cache)
|
||||
Dirty = CpuDirty | GpuDirty,
|
||||
Dirty = CpuDirty | GpuDirty | MaybeCpuDirty,
|
||||
GpuModified = 1 << 3, ///< Contents have been modified from the GPU
|
||||
Tracked = 1 << 4, ///< Writes and reads are being hooked from the CPU
|
||||
Registered = 1 << 6, ///< True when the image is registered
|
||||
@ -130,6 +131,7 @@ struct Image {
|
||||
std::vector<State> subresource_states{};
|
||||
boost::container::small_vector<u64, 14> mip_hashes{};
|
||||
u64 tick_accessed_last{0};
|
||||
u64 hash{0};
|
||||
|
||||
struct {
|
||||
union {
|
||||
|
@ -47,7 +47,17 @@ void TextureCache::InvalidateMemory(VAddr addr, VAddr addr_aligned, 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;
|
||||
if (addr < image_end) {
|
||||
const auto page_end = addr_aligned + size;
|
||||
if (addr < image.info.guest_address) {
|
||||
// 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) {
|
||||
// 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;
|
||||
}
|
||||
} else if (addr < image_end) {
|
||||
// Ensure image is reuploaded when accessed again.
|
||||
image.flags |= ImageFlagBits::CpuDirty;
|
||||
}
|
||||
@ -418,6 +428,19 @@ void TextureCache::RefreshImage(Image& image, Vulkan::Scheduler* custom_schedule
|
||||
return;
|
||||
}
|
||||
|
||||
if (True(image.flags & ImageFlagBits::MaybeCpuDirty) &&
|
||||
False(image.flags & ImageFlagBits::CpuDirty)) {
|
||||
// The image size should be less than page size to be considered MaybeCpuDirty
|
||||
// So this calculation should be very uncommon and reasonably fast
|
||||
ASSERT(image.info.guest_size_bytes <= 4_KB);
|
||||
const u8* addr = std::bit_cast<u8*>(image.info.guest_address);
|
||||
const u64 hash = XXH3_64bits(addr, image.info.guest_size_bytes);
|
||||
if (image.hash == hash) {
|
||||
return;
|
||||
}
|
||||
image.hash = hash;
|
||||
}
|
||||
|
||||
const auto& num_layers = image.info.resources.layers;
|
||||
const auto& num_mips = image.info.resources.levels;
|
||||
ASSERT(num_mips == image.info.mips_layout.size());
|
||||
|
Loading…
Reference in New Issue
Block a user