diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc index 120da350d..b5949eca1 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_io.cc @@ -172,8 +172,8 @@ dword_result_t NtReadFile(dword_t file_handle, dword_t event_handle, // some games NtReadFile() directly into texture memory // TODO(rick): better checking of physical address if (buffer.guest_address() >= 0xA0000000) { - cpu::MMIOHandler::global_handler()->InvalidateRange( - buffer.guest_address(), buffer_length); + kernel_memory()->TriggerWatches(buffer.guest_address(), buffer_length, + true); } // Synchronous. diff --git a/src/xenia/memory.cc b/src/xenia/memory.cc index 5053e4b23..d02bea540 100644 --- a/src/xenia/memory.cc +++ b/src/xenia/memory.cc @@ -460,6 +460,21 @@ void Memory::CancelAccessWatch(uintptr_t watch_handle) { mmio_handler_->CancelAccessWatch(watch_handle); } +bool Memory::TriggerWatches(uint32_t virtual_address, uint32_t length, + bool is_write) { + BaseHeap* heap = LookupHeap(virtual_address); + if (heap == &heaps_.vA0000000 || heap == &heaps_.vC0000000 || + heap == &heaps_.vE0000000) { + // TODO(Triang3l): Remove InvalidateRange when legacy (old Vulkan renderer) + // watches are removed. + cpu::MMIOHandler::global_handler()->InvalidateRange(virtual_address, + length); + return static_cast(heap)->TriggerWatches(virtual_address, + length, is_write); + } + return false; +} + void* Memory::RegisterPhysicalWriteWatch(PhysicalWriteWatchCallback callback, void* callback_context) { PhysicalWriteWatchEntry* entry = new PhysicalWriteWatchEntry; diff --git a/src/xenia/memory.h b/src/xenia/memory.h index 8f6431ba3..cf5cd4284 100644 --- a/src/xenia/memory.h +++ b/src/xenia/memory.h @@ -388,6 +388,11 @@ class Memory { // protection placed by the watches. void WatchPhysicalMemoryWrite(uint32_t physical_address, uint32_t length); + // Forces triggering of watch callbacks for a virtual address range if pages + // are watched there and unwatching them. Returns whether any page was + // watched. + bool TriggerWatches(uint32_t virtual_address, uint32_t length, bool is_write); + // Allocates virtual memory from the 'system' heap. // System memory is kept separate from game memory but is still accessible // using normal guest virtual addresses. Kernel structures and other internal