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 {