From 5f5be06680671fe50eb56780b30796bc8774a749 Mon Sep 17 00:00:00 2001 From: Gliniak Date: Sun, 1 Sep 2024 22:21:28 +0200 Subject: [PATCH] [Memory] Preallocate whole physical range for GPU. Seems like GPU has direct access to whole RAM and can request anything. Removed check for page access as all pages are now available for gpu --- src/xenia/gpu/d3d12/d3d12_shared_memory.cc | 18 ----------- src/xenia/kernel/xboxkrnl/xboxkrnl_memory.cc | 2 ++ src/xenia/memory.cc | 33 +++++++++++++------- 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/xenia/gpu/d3d12/d3d12_shared_memory.cc b/src/xenia/gpu/d3d12/d3d12_shared_memory.cc index 6cb081241..c15d63ca9 100644 --- a/src/xenia/gpu/d3d12/d3d12_shared_memory.cc +++ b/src/xenia/gpu/d3d12/d3d12_shared_memory.cc @@ -421,24 +421,6 @@ bool D3D12SharedMemory::UploadRanges( trace_writer_.WriteMemoryRead(upload_range_start << page_size_log2(), upload_range_length << page_size_log2()); - if (upload_range_length > 0) { - // Hacky handling for certain games (494707D4, 55530874) that crashes due - // to accessing unallocated pages - const uint32_t upload_range_last_page = - upload_range_start + upload_range_length - 1; - - memory::PageAccess page_access = - memory().GetPhysicalHeap()->QueryRangeAccess( - upload_range_last_page << page_size_log2(), - (upload_range_last_page - << page_size_log2())); // Check only last page - - if (page_access == xe::memory::PageAccess::kNoAccess) { - XELOGE("Invalid upload range for GPU: {:08X}", upload_range_start); - return false; - } - } - while (upload_range_length != 0) { ID3D12Resource* upload_buffer; size_t upload_buffer_offset, upload_buffer_size; diff --git a/src/xenia/kernel/xboxkrnl/xboxkrnl_memory.cc b/src/xenia/kernel/xboxkrnl/xboxkrnl_memory.cc index 117acccd3..c685ee79a 100644 --- a/src/xenia/kernel/xboxkrnl/xboxkrnl_memory.cc +++ b/src/xenia/kernel/xboxkrnl/xboxkrnl_memory.cc @@ -451,6 +451,8 @@ uint32_t xeMmAllocatePhysicalMemoryEx(uint32_t flags, uint32_t region_size, adjusted_alignment, allocation_type, protect, top_down, &base_address)) { // Failed - assume no memory available. + XELOGW("MmAllocatePhysicalMemoryEx: Allocation failed: {:08X} Size: {:08X}", + base_address, adjusted_size); return 0; } XELOGD("MmAllocatePhysicalMemoryEx = {:08X} Size: {:08X}", base_address, diff --git a/src/xenia/memory.cc b/src/xenia/memory.cc index 05f5cc095..ac6c201cc 100644 --- a/src/xenia/memory.cc +++ b/src/xenia/memory.cc @@ -84,6 +84,17 @@ void CrashDump() { --in_crash_dump; } +xe::memory::PageAccess ToPageAccess(uint32_t protect) { + if ((protect & kMemoryProtectRead) && !(protect & kMemoryProtectWrite)) { + return xe::memory::PageAccess::kReadOnly; + } else if ((protect & kMemoryProtectRead) && + (protect & kMemoryProtectWrite)) { + return xe::memory::PageAccess::kReadWrite; + } else { + return xe::memory::PageAccess::kNoAccess; + } +} + Memory::Memory() { system_page_size_ = uint32_t(xe::memory::page_size()); system_allocation_granularity_ = @@ -196,6 +207,17 @@ bool Memory::Initialize() { kMemoryAllocationReserve | kMemoryAllocationCommit, kMemoryProtectRead | kMemoryProtectWrite); + // TODO(Gliniak): Seems like GPU has access to whole physical memory range + // without any restriction. This however needs some form of validation. + // That's why we're commiting whole physical memory range and deal with + // allocations issues on custom page protection level. + for (size_t i = 1; i <= 16; i++) { + xe::memory::AllocFixed(heaps_.physical.TranslateRelative(i << 24), + heaps_.physical.page_size() * 0x10000, + xe::memory::AllocationType::kCommit, + xe::memory::PageAccess::kReadWrite); + } + // Add handlers for MMIO. mmio_handler_ = cpu::MMIOHandler::Install( virtual_membase_, physical_membase_, physical_membase_ + 0x1FFFFFFF, @@ -670,17 +692,6 @@ bool Memory::Restore(ByteStream* stream) { return true; } -xe::memory::PageAccess ToPageAccess(uint32_t protect) { - if ((protect & kMemoryProtectRead) && !(protect & kMemoryProtectWrite)) { - return xe::memory::PageAccess::kReadOnly; - } else if ((protect & kMemoryProtectRead) && - (protect & kMemoryProtectWrite)) { - return xe::memory::PageAccess::kReadWrite; - } else { - return xe::memory::PageAccess::kNoAccess; - } -} - uint32_t FromPageAccess(xe::memory::PageAccess protect) { switch (protect) { case memory::PageAccess::kNoAccess: