mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-06-25 20:06:17 +00:00
buffer_cache: Better image search for buffer validation (#3057)
This commit is contained in:
parent
f2bbb6847d
commit
a07a6bb9d3
1 changed files with 36 additions and 15 deletions
|
@ -798,24 +798,45 @@ void BufferCache::SynchronizeBuffer(Buffer& buffer, VAddr device_addr, u32 size,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BufferCache::SynchronizeBufferFromImage(Buffer& buffer, VAddr device_addr, u32 size) {
|
bool BufferCache::SynchronizeBufferFromImage(Buffer& buffer, VAddr device_addr, u32 size) {
|
||||||
static constexpr FindFlags find_flags =
|
boost::container::small_vector<ImageId, 6> image_ids;
|
||||||
FindFlags::NoCreate | FindFlags::RelaxDim | FindFlags::RelaxFmt | FindFlags::RelaxSize;
|
texture_cache.ForEachImageInRegion(device_addr, size, [&](ImageId image_id, Image& image) {
|
||||||
TextureCache::BaseDesc desc{};
|
if (image.info.guest_address != device_addr) {
|
||||||
desc.info.guest_address = device_addr;
|
return;
|
||||||
desc.info.guest_size = size;
|
}
|
||||||
const ImageId image_id = texture_cache.FindImage(desc, find_flags);
|
// Only perform sync if image is:
|
||||||
if (!image_id) {
|
// - GPU modified; otherwise there are no changes to synchronize.
|
||||||
|
// - Not CPU dirty; otherwise we could overwrite CPU changes with stale GPU changes.
|
||||||
|
// - Not GPU dirty; otherwise we could overwrite GPU changes with stale image data.
|
||||||
|
if (False(image.flags & ImageFlagBits::GpuModified) ||
|
||||||
|
True(image.flags & ImageFlagBits::Dirty)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
image_ids.push_back(image_id);
|
||||||
|
});
|
||||||
|
if (image_ids.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
ImageId image_id{};
|
||||||
|
if (image_ids.size() == 1) {
|
||||||
|
// Sometimes image size might not exactly match with requested buffer size
|
||||||
|
// If we only found 1 candidate image use it without too many questions.
|
||||||
|
image_id = image_ids[0];
|
||||||
|
} else {
|
||||||
|
for (s32 i = 0; i < image_ids.size(); ++i) {
|
||||||
|
Image& image = texture_cache.GetImage(image_ids[i]);
|
||||||
|
if (image.info.guest_size == size) {
|
||||||
|
image_id = image_ids[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!image_id) {
|
||||||
|
LOG_WARNING(Render_Vulkan,
|
||||||
|
"Failed to find exact image match for copy addr={:#x}, size={:#x}",
|
||||||
|
device_addr, size);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
Image& image = texture_cache.GetImage(image_id);
|
Image& image = texture_cache.GetImage(image_id);
|
||||||
// Only perform sync if image is:
|
|
||||||
// - GPU modified; otherwise there are no changes to synchronize.
|
|
||||||
// - Not CPU dirty; otherwise we could overwrite CPU changes with stale GPU changes.
|
|
||||||
// - Not GPU dirty; otherwise we could overwrite GPU changes with stale image data.
|
|
||||||
if (False(image.flags & ImageFlagBits::GpuModified) ||
|
|
||||||
True(image.flags & ImageFlagBits::Dirty)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
ASSERT_MSG(device_addr == image.info.guest_address,
|
ASSERT_MSG(device_addr == image.info.guest_address,
|
||||||
"Texel buffer aliases image subresources {:x} : {:x}", device_addr,
|
"Texel buffer aliases image subresources {:x} : {:x}", device_addr,
|
||||||
image.info.guest_address);
|
image.info.guest_address);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue