From 1864f3d9f212fe81ca1c6b6e4ab6969ebdb0553c Mon Sep 17 00:00:00 2001 From: Gliniak Date: Sat, 10 Aug 2024 20:58:53 +0200 Subject: [PATCH] [D3D12] Redesigned page access for gpu buffer allocation --- src/xenia/gpu/d3d12/d3d12_shared_memory.cc | 31 +++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/xenia/gpu/d3d12/d3d12_shared_memory.cc b/src/xenia/gpu/d3d12/d3d12_shared_memory.cc index 200207e99..9c895abe1 100644 --- a/src/xenia/gpu/d3d12/d3d12_shared_memory.cc +++ b/src/xenia/gpu/d3d12/d3d12_shared_memory.cc @@ -421,6 +421,22 @@ bool D3D12SharedMemory::UploadRanges( trace_writer_.WriteMemoryRead(upload_range_start << page_size_log2(), upload_range_length << page_size_log2()); while (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; + } + ID3D12Resource* upload_buffer; size_t upload_buffer_offset, upload_buffer_size; uint8_t* upload_buffer_mapping = upload_buffer_pool_->RequestPartial( @@ -435,21 +451,6 @@ bool D3D12SharedMemory::UploadRanges( MakeRangeValid(upload_range_start << page_size_log2(), uint32_t(upload_buffer_size), false, false); - // Handling for certain games that crashes due to accessing unallocated - // pages. It's usually happens with base_page that is completely different - // that any previously used ones. It always is completely not allocated. - // Additionally these requests are usually quite small 1-2 pages. - memory::PageAccess page_access = - memory().GetPhysicalHeap()->QueryRangeAccess( - upload_range_start << page_size_log2(), - (upload_range_start << page_size_log2()) + - (uint32_t)1); // Check only first page - - if (page_access == xe::memory::PageAccess::kNoAccess) { - XELOGE("Invalid upload range for GPU: {:08X}", upload_range_start); - return false; - } - if (upload_buffer_size < (1ULL << 32) && upload_buffer_size > 8192) { memory::vastcpy( upload_buffer_mapping,