Skip to content

Commit 5a3c1b1

Browse files
Fixed 2 bugs found on UMA devices
1. In GetBudgetForHeapType. 2. In BlockVector::AllocatePage. Occurring on integrated graphics or WARP device. Found in test TestDefragmentationSimple.
1 parent 0c573d8 commit 5a3c1b1

File tree

1 file changed

+62
-46
lines changed

1 file changed

+62
-46
lines changed

src/D3D12MemAlloc.cpp

Lines changed: 62 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5578,6 +5578,7 @@ class BlockVector
55785578
UINT64 size,
55795579
UINT64 alignment,
55805580
const ALLOCATION_DESC& allocDesc,
5581+
bool committedAllowed,
55815582
size_t allocationCount,
55825583
Allocation** pAllocations);
55835584

@@ -5588,6 +5589,7 @@ class BlockVector
55885589
UINT64 alignment,
55895590
const ALLOCATION_DESC& allocDesc,
55905591
const CREATE_RESOURCE_PARAMS& createParams,
5592+
bool committedAllowed,
55915593
Allocation** ppAllocation,
55925594
REFIID riidResource,
55935595
void** ppvResource);
@@ -5638,6 +5640,7 @@ class BlockVector
56385640
UINT64 size,
56395641
UINT64 alignment,
56405642
const ALLOCATION_DESC& allocDesc,
5643+
bool committedAllowed,
56415644
Allocation** pAllocation);
56425645

56435646
HRESULT AllocateFromBlock(
@@ -6516,7 +6519,7 @@ HRESULT AllocatorPimpl::CreateResource(
65166519
if (blockVector != NULL)
65176520
{
65186521
hr = blockVector->CreateResource(resAllocInfo.SizeInBytes, resAllocInfo.Alignment,
6519-
*pAllocDesc, finalCreateParams,
6522+
*pAllocDesc, finalCreateParams, committedAllocationParams.IsValid(),
65206523
ppAllocation, riidResource, ppvResource);
65216524
if (SUCCEEDED(hr))
65226525
return hr;
@@ -6559,7 +6562,7 @@ HRESULT AllocatorPimpl::AllocateMemory(
65596562
if (blockVector != NULL)
65606563
{
65616564
hr = blockVector->Allocate(pAllocInfo->SizeInBytes, pAllocInfo->Alignment,
6562-
*pAllocDesc, 1, (Allocation**)ppAllocation);
6565+
*pAllocDesc, committedAllocationParams.IsValid(), 1, (Allocation**)ppAllocation);
65636566
if (SUCCEEDED(hr))
65646567
return hr;
65656568
}
@@ -6873,17 +6876,15 @@ void AllocatorPimpl::GetBudget(Budget* outLocalBudget, Budget* outNonLocalBudget
68736876

68746877
void AllocatorPimpl::GetBudgetForHeapType(Budget& outBudget, D3D12_HEAP_TYPE heapType)
68756878
{
6876-
switch (heapType)
6879+
const bool isLocal = StandardHeapTypeToMemorySegmentGroup(heapType) ==
6880+
DXGI_MEMORY_SEGMENT_GROUP_LOCAL_COPY;
6881+
if (isLocal)
68776882
{
6878-
case D3D12_HEAP_TYPE_DEFAULT:
6879-
case D3D12_HEAP_TYPE_GPU_UPLOAD_COPY:
68806883
GetBudget(&outBudget, NULL);
6881-
break;
6882-
case D3D12_HEAP_TYPE_UPLOAD:
6883-
case D3D12_HEAP_TYPE_READBACK:
6884+
}
6885+
else
6886+
{
68846887
GetBudget(NULL, &outBudget);
6885-
break;
6886-
default: D3D12MA_ASSERT(0);
68876888
}
68886889
}
68896890

@@ -8124,6 +8125,7 @@ HRESULT BlockVector::Allocate(
81248125
UINT64 size,
81258126
UINT64 alignment,
81268127
const ALLOCATION_DESC& allocDesc,
8128+
bool committedAllowed,
81278129
size_t allocationCount,
81288130
Allocation** pAllocations)
81298131
{
@@ -8138,6 +8140,7 @@ HRESULT BlockVector::Allocate(
81388140
size,
81398141
alignment,
81408142
allocDesc,
8143+
committedAllowed,
81418144
pAllocations + allocIndex);
81428145
if (FAILED(hr))
81438146
{
@@ -8226,40 +8229,43 @@ HRESULT BlockVector::CreateResource(
82268229
UINT64 alignment,
82278230
const ALLOCATION_DESC& allocDesc,
82288231
const CREATE_RESOURCE_PARAMS& createParams,
8232+
bool committedAllowed,
82298233
Allocation** ppAllocation,
82308234
REFIID riidResource,
82318235
void** ppvResource)
82328236
{
8233-
HRESULT hr = Allocate(size, alignment, allocDesc, 1, ppAllocation);
8237+
HRESULT hr = Allocate(size, alignment, allocDesc, committedAllowed, 1, ppAllocation);
8238+
if (FAILED(hr))
8239+
{
8240+
return hr;
8241+
}
8242+
8243+
ID3D12Resource* res = NULL;
8244+
hr = m_hAllocator->CreatePlacedResourceWrap(
8245+
(*ppAllocation)->m_Placed.block->GetHeap(),
8246+
(*ppAllocation)->GetOffset(),
8247+
createParams,
8248+
D3D12MA_IID_PPV_ARGS(&res));
82348249
if (SUCCEEDED(hr))
82358250
{
8236-
ID3D12Resource* res = NULL;
8237-
hr = m_hAllocator->CreatePlacedResourceWrap(
8238-
(*ppAllocation)->m_Placed.block->GetHeap(),
8239-
(*ppAllocation)->GetOffset(),
8240-
createParams,
8241-
D3D12MA_IID_PPV_ARGS(&res));
8251+
if (ppvResource != NULL)
8252+
{
8253+
hr = res->QueryInterface(riidResource, ppvResource);
8254+
}
82428255
if (SUCCEEDED(hr))
82438256
{
8244-
if (ppvResource != NULL)
8245-
{
8246-
hr = res->QueryInterface(riidResource, ppvResource);
8247-
}
8248-
if (SUCCEEDED(hr))
8249-
{
8250-
(*ppAllocation)->SetResourcePointer(res, createParams.GetBaseResourceDesc());
8251-
}
8252-
else
8253-
{
8254-
res->Release();
8255-
SAFE_RELEASE(*ppAllocation);
8256-
}
8257+
(*ppAllocation)->SetResourcePointer(res, createParams.GetBaseResourceDesc());
82578258
}
82588259
else
82598260
{
8261+
res->Release();
82608262
SAFE_RELEASE(*ppAllocation);
82618263
}
82628264
}
8265+
else
8266+
{
8267+
SAFE_RELEASE(*ppAllocation);
8268+
}
82638269
return hr;
82648270
}
82658271

@@ -8377,6 +8383,7 @@ HRESULT BlockVector::AllocatePage(
83778383
UINT64 size,
83788384
UINT64 alignment,
83798385
const ALLOCATION_DESC& allocDesc,
8386+
bool committedAllowed,
83808387
Allocation** pAllocation)
83818388
{
83828389
// Early reject: requested allocation size is larger that maximum block size for this block vector.
@@ -8393,13 +8400,19 @@ HRESULT BlockVector::AllocatePage(
83938400
freeMemory = (budget.UsageBytes < budget.BudgetBytes) ? (budget.BudgetBytes - budget.UsageBytes) : 0;
83948401
}
83958402

8396-
const bool canCreateNewBlock =
8403+
const bool canExceedFreeMemory = !committedAllowed;
8404+
8405+
bool canCreateNewBlock =
83978406
((allocDesc.Flags & ALLOCATION_FLAG_NEVER_ALLOCATE) == 0) &&
8398-
(m_Blocks.size() < m_MaxBlockCount) &&
8399-
// Even if we don't have to stay within budget with this allocation, when the
8400-
// budget would be exceeded, we don't want to allocate new blocks, but always
8401-
// create resources as committed.
8402-
freeMemory >= size;
8407+
(m_Blocks.size() < m_MaxBlockCount);
8408+
8409+
// Even if we don't have to stay within budget with this allocation, when the
8410+
// budget would be exceeded, we don't want to allocate new blocks, but always
8411+
// create resources as committed.
8412+
if (freeMemory < size && !canExceedFreeMemory)
8413+
{
8414+
canCreateNewBlock = false;
8415+
}
84038416

84048417
// 1. Search existing allocations
84058418
{
@@ -8449,25 +8462,28 @@ HRESULT BlockVector::AllocatePage(
84498462
}
84508463
}
84518464

8452-
size_t newBlockIndex = 0;
8453-
HRESULT hr = newBlockSize <= freeMemory ?
8454-
CreateBlock(newBlockSize, &newBlockIndex) : E_OUTOFMEMORY;
8465+
size_t newBlockIndex = SIZE_MAX;
8466+
HRESULT hr = E_OUTOFMEMORY;
8467+
if (newBlockSize <= freeMemory || canExceedFreeMemory)
8468+
{
8469+
hr = CreateBlock(newBlockSize, &newBlockIndex);
8470+
}
84558471
// Allocation of this size failed? Try 1/2, 1/4, 1/8 of m_PreferredBlockSize.
84568472
if (!m_ExplicitBlockSize)
84578473
{
84588474
while (FAILED(hr) && newBlockSizeShift < NEW_BLOCK_SIZE_SHIFT_MAX)
84598475
{
84608476
const UINT64 smallerNewBlockSize = newBlockSize / 2;
8461-
if (smallerNewBlockSize >= size)
8477+
if (smallerNewBlockSize < size)
84628478
{
8463-
newBlockSize = smallerNewBlockSize;
8464-
++newBlockSizeShift;
8465-
hr = newBlockSize <= freeMemory ?
8466-
CreateBlock(newBlockSize, &newBlockIndex) : E_OUTOFMEMORY;
8479+
break;
84678480
}
8468-
else
8481+
8482+
newBlockSize = smallerNewBlockSize;
8483+
++newBlockSizeShift;
8484+
if (newBlockSize <= freeMemory || canExceedFreeMemory)
84698485
{
8470-
break;
8486+
hr = CreateBlock(newBlockSize, &newBlockIndex);
84718487
}
84728488
}
84738489
}

0 commit comments

Comments
 (0)