diff --git a/src/gpgmm/d3d12/DebugResourceAllocatorD3D12.cpp b/src/gpgmm/d3d12/DebugResourceAllocatorD3D12.cpp index e7f2e23e1..4b98737e4 100644 --- a/src/gpgmm/d3d12/DebugResourceAllocatorD3D12.cpp +++ b/src/gpgmm/d3d12/DebugResourceAllocatorD3D12.cpp @@ -47,6 +47,8 @@ namespace gpgmm { namespace d3d12 { } void DebugResourceAllocator::ReportLiveAllocations() const { + std::lock_guard lock(mMutex); + for (auto allocationEntry : mLiveAllocations) { const ResourceAllocation* allocation = allocationEntry->GetValue().GetAllocation(); gpgmm::WarningLog() << "Live ResourceAllocation: " @@ -58,6 +60,8 @@ namespace gpgmm { namespace d3d12 { } void DebugResourceAllocator::AddLiveAllocation(ResourceAllocation* allocation) { + std::lock_guard lock(mMutex); + mLiveAllocations.GetOrCreate( ResourceAllocationEntry(allocation, allocation->GetAllocator()), true); @@ -66,6 +70,8 @@ namespace gpgmm { namespace d3d12 { } void DebugResourceAllocator::DeallocateMemory(std::unique_ptr allocation) { + std::lock_guard lock(mMutex); + // KeepAlive must be false so |mLiveAllocations| cache will shrink by 1 entry once |entry| // falls out of scope below since AddLiveAllocation() adds one (and only one) ref. auto entry = mLiveAllocations.GetOrCreate( diff --git a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp index ec20fb765..1d81ab130 100644 --- a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp +++ b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp @@ -414,8 +414,7 @@ namespace gpgmm { namespace d3d12 { mResourceHeapTier(descriptor.ResourceHeapTier), mIsAlwaysCommitted(descriptor.Flags & ALLOCATOR_FLAG_ALWAYS_COMMITED), mIsAlwaysInBudget(descriptor.Flags & ALLOCATOR_FLAG_ALWAYS_IN_BUDGET), - mMaxResourceHeapSize(descriptor.MaxResourceHeapSize), - mAllocationTimer(gpgmm::CreatePlatformTime()) { + mMaxResourceHeapSize(descriptor.MaxResourceHeapSize) { GPGMM_TRACE_EVENT_OBJECT_NEW(this); #if defined(GPGMM_ENABLE_ALLOCATOR_CHECKS) @@ -606,19 +605,20 @@ namespace gpgmm { namespace d3d12 { TRACE_EVENT0(TraceEventCategory::Default, "ResourceAllocator.CreateResource"); - std::lock_guard lock(mMutex); + // Timer isn't thread safe so it cannot be shared between invocations of CreateResource. + std::unique_ptr timer(CreatePlatformTime()); - mAllocationTimer->StartElapsedTime(); + timer->StartElapsedTime(); ReturnIfFailed(CreateResourceInternal(allocationDescriptor, resourceDescriptor, initialResourceState, clearValue, resourceAllocationOut)); - const double allocationLatency = mAllocationTimer->EndElapsedTime() * 1e6; + const double allocationLatency = timer->EndElapsedTime() * 1e6; GPGMM_UNUSED(allocationLatency); TRACE_COUNTER1(TraceEventCategory::Default, "GPU allocation latency (us)", allocationLatency); - const RESOURCE_ALLOCATOR_INFO& info = GetInfo(); + const RESOURCE_ALLOCATOR_INFO info = GetInfo(); GPGMM_UNUSED(info); TRACE_COUNTER1(TraceEventCategory::Default, "GPU memory fragmentation (MB)", @@ -649,6 +649,8 @@ namespace gpgmm { namespace d3d12 { D3D12_RESOURCE_STATES initialResourceState, const D3D12_CLEAR_VALUE* clearValue, ResourceAllocation** resourceAllocationOut) { + std::lock_guard lock(mMutex); + // If d3d tells us the resource size is invalid, treat the error as OOM. // Otherwise, creating a very large resource could overflow the allocator. D3D12_RESOURCE_DESC newResourceDesc = resourceDescriptor; @@ -950,6 +952,8 @@ namespace gpgmm { namespace d3d12 { } RESOURCE_ALLOCATOR_INFO ResourceAllocator::GetInfo() const { + std::lock_guard lock(mMutex); + // ResourceAllocator itself could call CreateCommittedResource directly. RESOURCE_ALLOCATOR_INFO result = mInfo; diff --git a/src/gpgmm/d3d12/ResourceAllocatorD3D12.h b/src/gpgmm/d3d12/ResourceAllocatorD3D12.h index e635b18cc..d0b1b90f8 100644 --- a/src/gpgmm/d3d12/ResourceAllocatorD3D12.h +++ b/src/gpgmm/d3d12/ResourceAllocatorD3D12.h @@ -355,7 +355,6 @@ namespace gpgmm { namespace d3d12 { mBufferAllocatorOfType; std::unique_ptr mDebugAllocator; - std::unique_ptr mAllocationTimer; }; }} // namespace gpgmm::d3d12