[D3D12] SHM: Watches prototype, some uploading

This commit is contained in:
Triang3l
2018-07-26 22:52:26 +03:00
parent 812a35caff
commit 4f7edff19d
7 changed files with 192 additions and 6 deletions

View File

@@ -214,6 +214,58 @@ void MMIOHandler::CancelAccessWatch(uintptr_t watch_handle) {
delete entry;
}
void MMIOHandler::SetGlobalPhysicalAccessWatch(
GlobalAccessWatchCallback callback, void* callback_context) {
auto lock = global_critical_region_.Acquire();
global_physical_watch_callback_ = callback;
global_physical_watch_callback_context_ = callback_context;
}
void MMIOHandler::ProtectPhysicalMemory(uint32_t physical_address,
uint32_t length, WatchType type) {
uint32_t base_address = physical_address & 0x1FFFFFFF;
// Can only protect sizes matching system page size.
// This means we need to round up, which will cause spurious access
// violations and invalidations.
// TODO(benvanik): only invalidate if actually within the region?
length =
xe::round_up(length + (base_address % uint32_t(xe::memory::page_size())),
uint32_t(xe::memory::page_size()));
base_address = base_address - (base_address % xe::memory::page_size());
auto page_access = memory::PageAccess::kNoAccess;
switch (type) {
case kWatchInvalid:
page_access = memory::PageAccess::kReadWrite;
break;
case kWatchWrite:
page_access = memory::PageAccess::kReadOnly;
break;
case kWatchReadWrite:
page_access = memory::PageAccess::kNoAccess;
break;
default:
assert_unhandled_case(type);
break;
}
// Protect the range under all address spaces
memory::Protect(physical_membase_ + base_address, length, page_access,
nullptr);
memory::Protect(virtual_membase_ + 0xA0000000 + base_address, length,
page_access, nullptr);
memory::Protect(virtual_membase_ + 0xC0000000 + base_address, length,
page_access, nullptr);
memory::Protect(virtual_membase_ + 0xE0000000 + base_address, length,
page_access, nullptr);
}
void MMIOHandler::UnprotectPhysicalMemory(uint32_t physical_address,
uint32_t length) {
ProtectPhysicalMemory(physical_address, length, kWatchInvalid);
}
void MMIOHandler::InvalidateRange(uint32_t physical_address, size_t length) {
auto lock = global_critical_region_.Acquire();
@@ -262,6 +314,13 @@ bool MMIOHandler::IsRangeWatched(uint32_t physical_address, size_t length) {
bool MMIOHandler::CheckAccessWatch(uint32_t physical_address) {
auto lock = global_critical_region_.Acquire();
if (global_physical_watch_callback_ != nullptr) {
if (global_physical_watch_callback_(global_physical_watch_callback_context_,
physical_address)) {
return true;
}
}
bool hit = false;
for (auto it = access_watches_.begin(); it != access_watches_.end();) {
auto entry = *it;