From 95475d5f78837b2f8e13e7d6fcc9eb3c5eed4168 Mon Sep 17 00:00:00 2001 From: Triang3l Date: Sun, 23 Feb 2020 15:55:41 +0300 Subject: [PATCH] [D3D12] SharedMemory::ClearCache invalidating pages, destroying watches --- .../gpu/d3d12/d3d12_command_processor.cc | 3 +- src/xenia/gpu/d3d12/shared_memory.cc | 47 ++++++++++++++++++- src/xenia/gpu/d3d12/shared_memory.h | 1 + 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/xenia/gpu/d3d12/d3d12_command_processor.cc b/src/xenia/gpu/d3d12/d3d12_command_processor.cc index 7af8173e6..41af5d0e6 100644 --- a/src/xenia/gpu/d3d12/d3d12_command_processor.cc +++ b/src/xenia/gpu/d3d12/d3d12_command_processor.cc @@ -2115,8 +2115,7 @@ bool D3D12CommandProcessor::EndSubmission(bool is_swap) { } root_signatures_.clear(); - // TODO(Triang3l): Shared memory cache clear. - // shared_memory_->ClearCache(); + shared_memory_->ClearCache(); } } diff --git a/src/xenia/gpu/d3d12/shared_memory.cc b/src/xenia/gpu/d3d12/shared_memory.cc index a88537672..e87567d01 100644 --- a/src/xenia/gpu/d3d12/shared_memory.cc +++ b/src/xenia/gpu/d3d12/shared_memory.cc @@ -140,7 +140,22 @@ bool SharedMemory::Initialize() { void SharedMemory::Shutdown() { ResetTraceGPUWrittenBuffer(); - // TODO(Triang3l): Do something in case any watches are still registered. + FireWatches(0, (kBufferSize - 1) >> page_size_log2_, false); + assert_true(global_watches_.empty()); + // No watches now, so no references to the pools accessible by guest threads - + // safe not to enter the global critical region. + watch_node_first_free_ = nullptr; + watch_node_current_pool_allocated_ = 0; + for (WatchNode* pool : watch_node_pools_) { + delete[] pool; + } + watch_node_pools_.clear(); + watch_range_first_free_ = nullptr; + watch_range_current_pool_allocated_ = 0; + for (WatchRange* pool : watch_range_pools_) { + delete[] pool; + } + watch_range_pools_.clear(); if (memory_invalidation_callback_handle_ != nullptr) { memory_->UnregisterPhysicalMemoryInvalidationCallback( @@ -164,6 +179,36 @@ void SharedMemory::Shutdown() { } } +void SharedMemory::ClearCache() { + upload_buffer_pool_->ClearCache(); + + // Keeping GPU-written data, so "invalidated by GPU". + FireWatches(0, (kBufferSize - 1) >> page_size_log2_, true); + // No watches now, so no references to the pools accessible by guest threads - + // safe not to enter the global critical region. + watch_node_first_free_ = nullptr; + watch_node_current_pool_allocated_ = 0; + for (WatchNode* pool : watch_node_pools_) { + delete[] pool; + } + watch_node_pools_.clear(); + watch_range_first_free_ = nullptr; + watch_range_current_pool_allocated_ = 0; + for (WatchRange* pool : watch_range_pools_) { + delete[] pool; + } + watch_range_pools_.clear(); + + { + auto global_lock = global_critical_region_.Acquire(); + for (SystemPageFlagsBlock& block : system_page_flags_) { + block.valid = block.valid_and_gpu_written; + } + } + + // TODO(Triang3l): Unmap and destroy heaps. +} + void SharedMemory::CompletedSubmissionUpdated() { upload_buffer_pool_->Reclaim(command_processor_->GetCompletedSubmission()); } diff --git a/src/xenia/gpu/d3d12/shared_memory.h b/src/xenia/gpu/d3d12/shared_memory.h index af99fa15b..d0eec5093 100644 --- a/src/xenia/gpu/d3d12/shared_memory.h +++ b/src/xenia/gpu/d3d12/shared_memory.h @@ -37,6 +37,7 @@ class SharedMemory { bool Initialize(); void Shutdown(); + void ClearCache(); ID3D12Resource* GetBuffer() const { return buffer_; } D3D12_GPU_VIRTUAL_ADDRESS GetGPUAddress() const {