diff --git a/src/gpgmm/d3d12/BufferAllocatorD3D12.cpp b/src/gpgmm/d3d12/BufferAllocatorD3D12.cpp index cc0856bb0..408108b4e 100644 --- a/src/gpgmm/d3d12/BufferAllocatorD3D12.cpp +++ b/src/gpgmm/d3d12/BufferAllocatorD3D12.cpp @@ -43,6 +43,8 @@ namespace gpgmm { namespace d3d12 { bool prefetchMemory) { TRACE_EVENT0(TraceEventCategory::Default, "BufferAllocator.TryAllocateMemory"); + std::lock_guard lock(mMutex); + if (GetMemorySize() != size || GetMemoryAlignment() != alignment || neverAllocate) { return {}; } @@ -69,12 +71,20 @@ namespace gpgmm { namespace d3d12 { return {}; } + mInfo.UsedMemoryUsage += resourceHeap->GetSize(); + mInfo.UsedMemoryCount++; + return std::make_unique(this, resourceHeap); } void BufferAllocator::DeallocateMemory(std::unique_ptr allocation) { TRACE_EVENT0(TraceEventCategory::Default, "BufferAllocator.DeallocateMemory"); - mResourceAllocator->DeallocateMemory(std::move(allocation)); + std::lock_guard lock(mMutex); + + mInfo.UsedMemoryUsage -= allocation->GetSize(); + mInfo.UsedMemoryCount--; + + SafeRelease(allocation); } uint64_t BufferAllocator::GetMemorySize() const { diff --git a/src/tests/end2end/D3D12ResourceAllocatorTests.cpp b/src/tests/end2end/D3D12ResourceAllocatorTests.cpp index e606cad17..82c8c2faf 100644 --- a/src/tests/end2end/D3D12ResourceAllocatorTests.cpp +++ b/src/tests/end2end/D3D12ResourceAllocatorTests.cpp @@ -908,4 +908,39 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferManyThreaded) { for (std::thread& thread : threads) { thread.join(); } + + EXPECT_EQ(resourceAllocator->GetInfo().UsedMemoryUsage, 0u); +} + +// Creates a bunch of buffers concurrently. +TEST_F(D3D12ResourceAllocatorTests, CreateBufferWithinManyThreaded) { + ComPtr resourceAllocator; + ASSERT_SUCCEEDED( + ResourceAllocator::CreateAllocator(CreateBasicAllocatorDesc(), &resourceAllocator)); + ASSERT_NE(resourceAllocator, nullptr); + + ALLOCATION_DESC allocationDesc = {}; + allocationDesc.Flags = ALLOCATION_FLAG_ALLOW_SUBALLOCATE_WITHIN_RESOURCE; + allocationDesc.HeapType = D3D12_HEAP_TYPE_UPLOAD; + + constexpr uint32_t kSubAllocationSize = 4u; + + constexpr uint32_t kThreadCount = 64u; + std::vector threads(kThreadCount); + for (size_t threadIdx = 0; threadIdx < threads.size(); threadIdx++) { + threads[threadIdx] = std::thread([&]() { + ComPtr allocation; + ASSERT_SUCCEEDED(resourceAllocator->CreateResource( + allocationDesc, CreateBasicBufferDesc(kSubAllocationSize), + D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, &allocation)); + ASSERT_NE(allocation, nullptr); + EXPECT_EQ(allocation->GetMethod(), gpgmm::AllocationMethod::kSubAllocatedWithin); + }); + } + + for (std::thread& thread : threads) { + thread.join(); + } + + EXPECT_EQ(resourceAllocator->GetInfo().UsedMemoryUsage, 0u); }