diff --git a/core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp b/core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp index 2fa7b67e5..a9c0e59bf 100644 --- a/core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp +++ b/core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp @@ -288,6 +288,7 @@ public: // GuestMemory::GpuMutex only, as Refresh is; never from a build's stage A. DccKeys UploadedKeys() const { return uploadedKeys; } DccKeys FilledKeys() const { return filledKeys; } + bool GuestSnapshotValid() const { return originalValid; } DccKeyProof& KeyProof() const { return keyProof; } DccKeys ProvedKeys() const; bool ServesKeysAt(std::uint64_t dccAddress) const; diff --git a/core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp b/core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp index 71720b8b5..5a3f5eac4 100644 --- a/core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp +++ b/core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp @@ -1686,7 +1686,9 @@ void StorageTexture::upload(const std::vector* layers) { // The clear is recorded into the open batch like a direct upload (the image kept by it): a // batch of its own submitted the recorder's work first and waited for all of it, 25-40 ms // under the GPU mutex at the movie stage. APS5_NO_RECORDED_CLEAR=1 waits as before. - captureGuestBytes(nullptr); + static_cast(HostImportFor(context, descriptor.baseAddress, static_cast(guestBytes))); + if (GuestMemory::Watched(descriptor.baseAddress, static_cast(guestBytes))) originalValid = false; + else captureGuestBytes(nullptr); forgetBorrowed(0, trackedLayers); stampLayers(false); static const bool recordClear = std::getenv("APS5_NO_RECORDED_CLEAR") == nullptr; diff --git a/core/libs/prx/libSceAgcDriver/tests/execution/DccKeysFirstWrite.cpp b/core/libs/prx/libSceAgcDriver/tests/execution/DccKeysFirstWrite.cpp index 47547e67b..20e68d438 100644 --- a/core/libs/prx/libSceAgcDriver/tests/execution/DccKeysFirstWrite.cpp +++ b/core/libs/prx/libSceAgcDriver/tests/execution/DccKeysFirstWrite.cpp @@ -209,6 +209,8 @@ void Run(AgcDriver::VulkanDevice& device, std::uint8_t* block) { Require(image != nullptr && image->Descriptor().dccAddress == AddressOf(keys), "the written surface has no pending image under its keys"); Require(AgcDriver::Graphics::StorageImageServesKeys(*image, AddressOf(copied)), "the written image does not serve the copied keys"); Require(image->UploadedKeys() == DccKeys::Uncompressed && image->FilledKeys() == DccKeys::Uncompressed, "the written image still holds the clear it was uploaded under"); + const bool stillWatched = AgcDriver::GuestMemory::Watched(surface, SurfaceBytes); + Require(image->GuestSnapshotValid() != stillWatched, stillWatched ? "a fast-cleared upload of write-watched memory read its guest bytes" : "a fast-cleared upload of untracked memory kept no guest bytes to compare"); const auto pendingVersion = image->Version(); for (int repeat = 0; repeat < 3; ++repeat) { Require(image->Refresh(), "an unchanged pending image was uploaded again");