diff --git a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp index a95369534..f8adbfbe0 100644 --- a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp +++ b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp @@ -616,7 +616,8 @@ namespace gpgmm::d3d12 { EventRecordScope::kPerInstance), mUseDetailedTimingEvents(descriptor.RecordOptions.UseDetailedTimingEvents), mIsCustomHeapsDisabled(descriptor.Flags & ALLOCATOR_FLAG_DISABLE_UNIFIED_MEMORY), - mIsAlwaysCreateResident(descriptor.Flags & ALLOCATOR_FLAG_ALWAYS_RESIDENT) { + mIsAlwaysCreateResident(descriptor.Flags & ALLOCATOR_FLAG_ALWAYS_RESIDENT), + mMaxResourceHeapSize(descriptor.MaxResourceHeapSize) { ASSERT(mDevice != nullptr); GPGMM_TRACE_EVENT_OBJECT_NEW(this); @@ -745,12 +746,11 @@ namespace gpgmm::d3d12 { double memoryGrowthFactor, bool isPrefetchAllowed, std::unique_ptr underlyingAllocator) { - const uint64_t maxResourceHeapSize = mCaps->GetMaxResourceHeapSize(); switch (algorithm) { case ALLOCATOR_ALGORITHM_BUDDY_SYSTEM: { // System and memory size must be aligned at creation-time. return std::make_unique( - /*systemSize*/ PrevPowerOfTwo(maxResourceHeapSize), + /*systemSize*/ PrevPowerOfTwo(mMaxResourceHeapSize), /*memorySize*/ NextPowerOfTwo(memorySize), /*memoryAlignment*/ memoryAlignment, /*memoryAllocator*/ std::move(underlyingAllocator)); @@ -759,7 +759,7 @@ namespace gpgmm::d3d12 { // Min slab size is always equal to the memory size because the // slab allocator aligns the slab size at allocate-time. return std::make_unique( - /*maxSlabSize*/ PrevPowerOfTwo(maxResourceHeapSize), + /*maxSlabSize*/ PrevPowerOfTwo(mMaxResourceHeapSize), /*minSlabSize*/ memorySize, /*slabAlignment*/ memoryAlignment, /*slabFragmentationLimit*/ memoryFragmentationLimit, @@ -975,12 +975,12 @@ namespace gpgmm::d3d12 { D3D12_RESOURCE_DESC newResourceDesc = resourceDescriptor; const D3D12_RESOURCE_ALLOCATION_INFO resourceInfo = GetResourceAllocationInfo(mDevice, newResourceDesc); - if (resourceInfo.SizeInBytes > mCaps->GetMaxResourceSize()) { + if (resourceInfo.SizeInBytes > mMaxResourceHeapSize) { ErrorLog(MessageId::kSizeExceeded) << "Unable to create resource allocation because the resource size exceeded " "the capabilities of the device: " << GPGMM_BYTES_TO_GB(resourceInfo.SizeInBytes) << " vs " - << GPGMM_BYTES_TO_GB(mCaps->GetMaxResourceSize()) << " GBs."; + << GPGMM_BYTES_TO_GB(mMaxResourceHeapSize) << " GBs."; return E_OUTOFMEMORY; } @@ -1069,7 +1069,7 @@ namespace gpgmm::d3d12 { request.AlwaysPrefetch = (allocationDescriptor.Flags & ALLOCATION_FLAG_ALWAYS_PREFETCH_MEMORY); request.AlwaysCacheSize = (allocationDescriptor.Flags & ALLOCATION_FLAG_ALWAYS_CACHE_SIZE); - request.AvailableForAllocation = mCaps->GetMaxResourceHeapSize(); + request.AvailableForAllocation = mMaxResourceHeapSize; // Apply extra padding to the resource heap size, if specified. // Padding can only be applied to standalone non-committed resources. diff --git a/src/gpgmm/d3d12/ResourceAllocatorD3D12.h b/src/gpgmm/d3d12/ResourceAllocatorD3D12.h index 9b1c767eb..48de5b29b 100644 --- a/src/gpgmm/d3d12/ResourceAllocatorD3D12.h +++ b/src/gpgmm/d3d12/ResourceAllocatorD3D12.h @@ -159,6 +159,7 @@ namespace gpgmm::d3d12 { const bool mUseDetailedTimingEvents; const bool mIsCustomHeapsDisabled; const bool mIsAlwaysCreateResident; + const uint64_t mMaxResourceHeapSize; static constexpr uint64_t kNumOfResourceHeapTypes = 12u; diff --git a/src/tests/end2end/D3D12ResourceAllocatorTests.cpp b/src/tests/end2end/D3D12ResourceAllocatorTests.cpp index 5ab1c0765..66d659c44 100644 --- a/src/tests/end2end/D3D12ResourceAllocatorTests.cpp +++ b/src/tests/end2end/D3D12ResourceAllocatorTests.cpp @@ -689,6 +689,20 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBuffer) { {}, CreateBasicBufferDesc(kBufferOf4MBAllocationSize), D3D12_RESOURCE_STATE_UNORDERED_ACCESS, nullptr, &allocation)); } + + // Create a buffer that exceeds the max size should always fail. + { + ALLOCATOR_DESC allocatorDesc = CreateBasicAllocatorDesc(); + allocatorDesc.MaxResourceHeapSize = kBufferOf4MBAllocationSize; + + ComPtr resourceAllocatorLimitedTo4MB; + ASSERT_SUCCEEDED(CreateResourceAllocator(allocatorDesc, mDevice.Get(), mAdapter.Get(), + &resourceAllocatorLimitedTo4MB, nullptr)); + + ASSERT_FAILED(resourceAllocatorLimitedTo4MB->CreateResource( + {}, CreateBasicBufferDesc(kBufferOf4MBAllocationSize + 1), + D3D12_RESOURCE_STATE_UNORDERED_ACCESS, nullptr, nullptr)); + } } TEST_F(D3D12ResourceAllocatorTests, CreateBufferLeaked) {