diff --git a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Synchronization/LabelHistory.cpp b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Synchronization/LabelHistory.cpp index 3bac0c6355..db078dae9d 100644 --- a/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Synchronization/LabelHistory.cpp +++ b/core/libs/prx/libSceAgcDriver/Execution/src/Driver/Synchronization/LabelHistory.cpp @@ -39,21 +39,28 @@ void Driver::noteLabelPass(std::span packet, std::uint32_t } void Driver::noteLabelIssue(std::span packet, std::uint32_t queue) { - switch ((packet[0] >> 8u) & 0xffu) { - case 0x37: case 0x40: case 0x49: case 0x50: case 0x83: break; - default: return; - } - const auto stores = Pm4::DecodeStores(packet); - if (stores.empty()) return; - std::lock_guard lock(labelStoresMutex); - if (labelPasses.empty()) return; - for (const auto& store : stores) { - if (store.conditional || !KeepsLabelStore(store.address, static_cast(store.bytes))) continue; - for (std::uint64_t offset = 0; offset < store.bytes; offset += 4) { - const auto key = queueDword(queue, store.address + offset); + const auto take = [&](std::uint64_t address, std::uint64_t bytes) { + for (std::uint64_t offset = 0; offset < bytes; offset += 4) { + const auto key = queueDword(queue, address + offset); if (const auto pass = labelPasses.find(key); pass != labelPasses.end()) labelTaken[key] = pass->second; } + }; + switch ((packet[0] >> 8u) & 0xffu) { + case 0x37: case 0x49: { + const auto label = Pm4::DecodeLabelWrite(packet); + if (!label.has_value() || !KeepsLabelStore(label->address, label->Bytes().size())) return; + std::lock_guard lock(labelStoresMutex); + take(label->address, label->Bytes().size()); + return; + } + case 0x40: case 0x50: case 0x83: break; + default: return; } + auto stores = Pm4::DecodeStores(packet); + std::erase_if(stores, [](const Pm4::PacketStore& store) { return store.conditional || !KeepsLabelStore(store.address, static_cast(store.bytes)); }); + if (stores.empty()) return; + std::lock_guard lock(labelStoresMutex); + for (const auto& store : stores) take(store.address, store.bytes); } bool Driver::storedSince(std::span packet, std::uint64_t address, std::size_t bytes, std::uint64_t received, std::uint32_t queue, std::uint32_t* writer) {