aboutsummaryrefslogtreecommitdiff
path: root/src/core/device_memory_manager.inc
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/device_memory_manager.inc')
-rw-r--r--src/core/device_memory_manager.inc49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/core/device_memory_manager.inc b/src/core/device_memory_manager.inc
index 83faa1b3f3..5931fd0882 100644
--- a/src/core/device_memory_manager.inc
+++ b/src/core/device_memory_manager.inc
@@ -171,6 +171,7 @@ struct DeviceMemoryManagerAllocator {
template <typename Traits>
DeviceMemoryManager<Traits>::DeviceMemoryManager(const DeviceMemory& device_memory_)
: physical_base{uintptr_t(device_memory_.buffer.BackingBasePointer())}
+ , device_memory_ptr{&device_memory_}
, device_inter{nullptr}
, compressed_device_addr(1ULL << ((Settings::values.memory_layout_mode.GetValue() == Settings::MemoryLayout::Memory_4Gb ? physical_min_bits : physical_max_bits) - Memory::YUZU_PAGEBITS))
, tracked_entries(device_as_size >> Memory::YUZU_PAGEBITS)
@@ -183,6 +184,49 @@ template <typename Traits>
DeviceMemoryManager<Traits>::~DeviceMemoryManager() = default;
template <typename Traits>
+void DeviceMemoryManager<Traits>::HintCold(DAddr address, size_t size) {
+ struct Run {
+ u64 physical_offset;
+ VAddr virtual_address; ///< 0: no CPU mapping known
+ u64 size;
+ };
+ std::vector<Run> runs;
+ const size_t page_end = Common::DivCeil(address + size, Memory::YUZU_PAGESIZE);
+ for (size_t page = address >> Memory::YUZU_PAGEBITS; page < page_end; ++page) {
+ const u32 compressed = tracked_entries[page].compressed_physical_ptr;
+ if (compressed == 0) {
+ continue;
+ }
+ const u64 physical = u64{compressed - 1} << Memory::YUZU_PAGEBITS;
+ const VAddr vaddr = ExtractCPUBacking(page).second;
+ if (!runs.empty()) {
+ Run& last = runs.back();
+ const bool contiguous_view =
+ last.virtual_address == 0 ? vaddr == 0 : last.virtual_address + last.size == vaddr;
+ if (last.physical_offset + last.size == physical && contiguous_view) {
+ last.size += Memory::YUZU_PAGESIZE;
+ continue;
+ }
+ }
+ runs.push_back({physical, vaddr, Memory::YUZU_PAGESIZE});
+ }
+ if (runs.empty()) {
+ return;
+ }
+ if (!cold_hint_worker) {
+ cold_hint_worker = std::make_unique<Common::ThreadWorker>(1, "DeviceMemory:ColdHint");
+ }
+ cold_hint_worker->QueueWork([this, runs = std::move(runs)] {
+ for (const Run& run : runs) {
+ device_memory_ptr->buffer.HintCold(
+ run.physical_offset, run.size,
+ run.virtual_address != 0 ? std::optional<size_t>{run.virtual_address}
+ : std::nullopt);
+ }
+ });
+}
+
+template <typename Traits>
void DeviceMemoryManager<Traits>::BindInterface(DeviceInterface* device_inter_) {
device_inter = device_inter_;
}
@@ -582,6 +626,11 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCountNoLock(DAddr addr, size_
const size_t page_end = Common::DivCeil(addr + size, Memory::YUZU_PAGESIZE);
size_t page = addr >> Memory::YUZU_PAGEBITS;
auto [asid, base_vaddress] = ExtractCPUBacking(page);
+ // Sem processo registrado nao ha o que marcar, e asid.id 0 indexaria um vetor vazio. Acontece
+ // no alvo de testes, que chama UpdatePagesCachedBatch num DeviceMemoryManager recem-criado.
+ if (asid.id >= registered_processes.size()) {
+ return;
+ }
auto* memory_device_inter = registered_processes[asid.id];
const auto release_pending = [&] {
if (uncache_bytes > 0) {