diff --git a/src/xenia/cpu/mmio_handler.cc b/src/xenia/cpu/mmio_handler.cc index f691c287e..ba03e1c9e 100644 --- a/src/xenia/cpu/mmio_handler.cc +++ b/src/xenia/cpu/mmio_handler.cc @@ -222,7 +222,8 @@ void MMIOHandler::SetGlobalPhysicalAccessWatch( } void MMIOHandler::ProtectPhysicalMemory(uint32_t physical_address, - uint32_t length, WatchType type) { + uint32_t length, WatchType type, + bool protect_host_access) { uint32_t base_address = physical_address & 0x1FFFFFFF; // Can only protect sizes matching system page size. @@ -250,9 +251,11 @@ void MMIOHandler::ProtectPhysicalMemory(uint32_t physical_address, break; } - // Protect the range under all address spaces - memory::Protect(physical_membase_ + base_address, length, page_access, - nullptr); + // Protect the range under all address spaces. + if (protect_host_access) { + 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, @@ -262,8 +265,10 @@ void MMIOHandler::ProtectPhysicalMemory(uint32_t physical_address, } void MMIOHandler::UnprotectPhysicalMemory(uint32_t physical_address, - uint32_t length) { - ProtectPhysicalMemory(physical_address, length, kWatchInvalid); + uint32_t length, + bool unprotect_host_access) { + ProtectPhysicalMemory(physical_address, length, kWatchInvalid, + unprotect_host_access); } void MMIOHandler::InvalidateRange(uint32_t physical_address, size_t length) { diff --git a/src/xenia/cpu/mmio_handler.h b/src/xenia/cpu/mmio_handler.h index 8a864a9a6..b3f5d6972 100644 --- a/src/xenia/cpu/mmio_handler.h +++ b/src/xenia/cpu/mmio_handler.h @@ -78,8 +78,9 @@ class MMIOHandler { void SetGlobalPhysicalAccessWatch(GlobalAccessWatchCallback callback, void* callback_context); void ProtectPhysicalMemory(uint32_t physical_address, uint32_t length, - WatchType type); - void UnprotectPhysicalMemory(uint32_t physical_address, uint32_t length); + WatchType type, bool protect_host_access); + void UnprotectPhysicalMemory(uint32_t physical_address, uint32_t length, + bool unprotect_host_access); // Fires and clears any access watches that overlap this range. void InvalidateRange(uint32_t physical_address, size_t length); diff --git a/src/xenia/gpu/d3d12/shared_memory.cc b/src/xenia/gpu/d3d12/shared_memory.cc index e64851226..033045336 100644 --- a/src/xenia/gpu/d3d12/shared_memory.cc +++ b/src/xenia/gpu/d3d12/shared_memory.cc @@ -118,8 +118,6 @@ void SharedMemory::Shutdown() { } void SharedMemory::BeginFrame() { - // XELOGGPU("SharedMemory: BeginFrame start"); - // Check triggered watches, clear them and mark modified pages as out of date. watch_mutex_.lock(); for (uint32_t i = 0; i < watches_triggered_l2_.size(); ++i) { @@ -138,14 +136,10 @@ void SharedMemory::BeginFrame() { upload_buffer_pool_->BeginFrame(); heap_creation_failed_ = false; - - // XELOGGPU("SharedMemory: BeginFrame end"); } bool SharedMemory::EndFrame(ID3D12GraphicsCommandList* command_list_setup, ID3D12GraphicsCommandList* command_list_draw) { - // XELOGGPU("SharedMemory: EndFrame start"); - // Before drawing starts, it's assumed that the buffer is a copy destination. // This transition is for the next frame, not for the current one. TransitionBuffer(D3D12_RESOURCE_STATE_COPY_DEST, command_list_draw); @@ -214,9 +208,9 @@ bool SharedMemory::EndFrame(ID3D12GraphicsCommandList* command_list_setup, } watched_pages_[i] |= protect_bits; } - memory_->ProtectPhysicalMemory(protect_start << page_size_log2_, - protect_length << page_size_log2_, - cpu::MMIOHandler::WatchType::kWatchWrite); + memory_->ProtectPhysicalMemory( + protect_start << page_size_log2_, protect_length << page_size_log2_, + cpu::MMIOHandler::WatchType::kWatchWrite, false); protect_end = protect_last + 1; if (protect_end >= upload_end) { break; @@ -239,8 +233,6 @@ bool SharedMemory::EndFrame(ID3D12GraphicsCommandList* command_list_setup, } } - // XELOGGPU("SharedMemory: EndFrame end"); - return upload_end != 0; } @@ -260,7 +252,7 @@ uint32_t SharedMemory::NextUploadRange(uint32_t search_start, // Found the beginning of a range - find the end. uint32_t start_page = (i << 6) + start_page_local; for (uint32_t j = i; j < upload_pages_.size(); ++j) { - uint64_t end_block = upload_pages_[i]; + uint64_t end_block = upload_pages_[j]; if (j == i) { end_block |= (1ull << start_page_local) - 1; } @@ -302,9 +294,6 @@ bool SharedMemory::UseRange(uint32_t start, uint32_t length) { // current frame anymore if have failed at least once. return false; } - /* XELOGGPU("Shared memory: Creating %.8X-%.8X tile heap", - heap_first << kHeapSizeLog2, - (heap_last << kHeapSizeLog2) + (kHeapSize - 1)); */ auto provider = context_->GetD3D12Provider(); auto device = provider->GetDevice(); auto direct_queue = provider->GetDirectQueue(); @@ -391,7 +380,7 @@ bool SharedMemory::WatchCallback(uint32_t address) { // Unprotect the page. memory_->UnprotectPhysicalMemory(page_index_l1_global << page_size_log2_, - 1 << page_size_log2_); + 1 << page_size_log2_, false); watched_pages_[block_index_l1] &= ~page_bit_l1; return true; } diff --git a/src/xenia/memory.cc b/src/xenia/memory.cc index e4ab8611b..084358218 100644 --- a/src/xenia/memory.cc +++ b/src/xenia/memory.cc @@ -418,13 +418,16 @@ void Memory::SetGlobalPhysicalAccessWatch( } void Memory::ProtectPhysicalMemory(uint32_t physical_address, uint32_t length, - cpu::MMIOHandler::WatchType type) { - mmio_handler_->ProtectPhysicalMemory(physical_address, length, type); + cpu::MMIOHandler::WatchType type, + bool protect_host_access) { + mmio_handler_->ProtectPhysicalMemory(physical_address, length, type, + protect_host_access); } -void Memory::UnprotectPhysicalMemory(uint32_t physical_address, - uint32_t length) { - mmio_handler_->UnprotectPhysicalMemory(physical_address, length); +void Memory::UnprotectPhysicalMemory(uint32_t physical_address, uint32_t length, + bool unprotect_host_access) { + mmio_handler_->UnprotectPhysicalMemory(physical_address, length, + unprotect_host_access); } uint32_t Memory::SystemHeapAlloc(uint32_t size, uint32_t alignment, diff --git a/src/xenia/memory.h b/src/xenia/memory.h index 87834280f..2229c951a 100644 --- a/src/xenia/memory.h +++ b/src/xenia/memory.h @@ -328,12 +328,14 @@ class Memory { // Protects a physical memory range without adding a watch, primarily for use // with the global physical access watch. void ProtectPhysicalMemory(uint32_t physical_address, uint32_t length, - cpu::MMIOHandler::WatchType type); + cpu::MMIOHandler::WatchType type, + bool protect_host_access); // Unprotects a physical memory range previously protected using // ProtectPhysicalMemory, primarily for use with the global physical access // watch. - void UnprotectPhysicalMemory(uint32_t physical_address, uint32_t length); + void UnprotectPhysicalMemory(uint32_t physical_address, uint32_t length, + bool unprotect_host_access); // Allocates virtual memory from the 'system' heap. // System memory is kept separate from game memory but is still accessible