@@ -47,24 +47,23 @@ void TextureCache::InvalidateMemory(VAddr address, size_t size) {
47
47
std::scoped_lock lock{mutex};
48
48
ForEachImageInRegion (address, size, [&](ImageId image_id, Image& image) {
49
49
// Ensure image is reuploaded when accessed again.
50
- image.flags |= ImageFlagBits::CpuModified ;
50
+ image.flags |= ImageFlagBits::CpuDirty ;
51
51
// Untrack image, so the range is unprotected and the guest can write freely.
52
52
UntrackImage (image_id);
53
53
});
54
54
}
55
55
56
- void TextureCache::MarkWritten (VAddr address, size_t max_size) {
57
- static constexpr FindFlags find_flags =
58
- FindFlags::NoCreate | FindFlags::RelaxDim | FindFlags::RelaxFmt | FindFlags::RelaxSize;
59
- ImageInfo info{};
60
- info.guest_address = address;
61
- info.guest_size_bytes = max_size;
62
- const ImageId image_id = FindImage (info, find_flags);
63
- if (!image_id) {
64
- return ;
65
- }
66
- // Ensure image is copied when accessed again.
67
- slot_images[image_id].flags |= ImageFlagBits::CpuModified;
56
+ void TextureCache::InvalidateMemoryFromGPU (VAddr address, size_t max_size) {
57
+ std::scoped_lock lock{mutex};
58
+ ForEachImageInRegion (address, max_size, [&](ImageId image_id, Image& image) {
59
+ // Only consider images that match base address.
60
+ // TODO: Maybe also consider subresources
61
+ if (image.info .guest_address != address) {
62
+ return ;
63
+ }
64
+ // Ensure image is reuploaded when accessed again.
65
+ image.flags |= ImageFlagBits::GpuDirty;
66
+ });
68
67
}
69
68
70
69
void TextureCache::UnmapMemory (VAddr cpu_addr, size_t size) {
@@ -189,7 +188,7 @@ ImageId TextureCache::ExpandImage(const ImageInfo& info, ImageId image_id) {
189
188
FreeImage (image_id);
190
189
191
190
TrackImage (new_image_id);
192
- new_image.flags &= ~ImageFlagBits::CpuModified ;
191
+ new_image.flags &= ~ImageFlagBits::Dirty ;
193
192
return new_image_id;
194
193
}
195
194
@@ -325,7 +324,7 @@ ImageView& TextureCache::FindDepthTarget(const ImageInfo& image_info,
325
324
const ImageId image_id = FindImage (image_info);
326
325
Image& image = slot_images[image_id];
327
326
image.flags |= ImageFlagBits::GpuModified;
328
- image.flags &= ~ImageFlagBits::CpuModified ;
327
+ image.flags &= ~ImageFlagBits::Dirty ;
329
328
image.aspect_mask = vk::ImageAspectFlagBits::eDepth;
330
329
331
330
const bool has_stencil = image_info.usage .stencil ;
@@ -362,11 +361,9 @@ ImageView& TextureCache::FindDepthTarget(const ImageInfo& image_info,
362
361
}
363
362
364
363
void TextureCache::RefreshImage (Image& image, Vulkan::Scheduler* custom_scheduler /* = nullptr*/ ) {
365
- if (False (image.flags & ImageFlagBits::CpuModified )) {
364
+ if (False (image.flags & ImageFlagBits::Dirty )) {
366
365
return ;
367
366
}
368
- // Mark image as validated.
369
- image.flags &= ~ImageFlagBits::CpuModified;
370
367
371
368
const auto & num_layers = image.info .resources .layers ;
372
369
const auto & num_mips = image.info .resources .levels ;
@@ -380,9 +377,10 @@ void TextureCache::RefreshImage(Image& image, Vulkan::Scheduler* custom_schedule
380
377
image.info .props .is_volume ? std::max (image.info .size .depth >> m, 1u ) : 1u ;
381
378
const auto & [mip_size, mip_pitch, mip_height, mip_ofs] = image.info .mips_layout [m];
382
379
383
- // Protect GPU modified resources from accidental reuploads.
384
- if (True (image.flags & ImageFlagBits::GpuModified) &&
385
- !buffer_cache.IsRegionGpuModified (image.info .guest_address + mip_ofs, mip_size)) {
380
+ // Protect GPU modified resources from accidental CPU reuploads.
381
+ const bool is_gpu_modified = True (image.flags & ImageFlagBits::GpuModified);
382
+ const bool is_gpu_dirty = True (image.flags & ImageFlagBits::GpuDirty);
383
+ if (is_gpu_modified && !is_gpu_dirty) {
386
384
const u8 * addr = std::bit_cast<u8 *>(image.info .guest_address );
387
385
const u64 hash = XXH3_64bits (addr + mip_ofs, mip_size);
388
386
if (image.mip_hashes [m] == hash) {
@@ -438,6 +436,7 @@ void TextureCache::RefreshImage(Image& image, Vulkan::Scheduler* custom_schedule
438
436
}
439
437
440
438
cmdbuf.copyBufferToImage (buffer, image.image , vk::ImageLayout::eTransferDstOptimal, image_copy);
439
+ image.flags &= ~ImageFlagBits::Dirty;
441
440
}
442
441
443
442
vk::Sampler TextureCache::GetSampler (const AmdGpu::Sampler& sampler) {
0 commit comments