Skip to content

Commit 3b3c62e

Browse files
2 parents 70843b2 + 36ce392 commit 3b3c62e

File tree

3 files changed

+84
-16
lines changed

3 files changed

+84
-16
lines changed

include/D3D12MemAlloc.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,14 @@ enum POOL_FLAGS
836836
*/
837837
POOL_FLAG_ALGORITHM_LINEAR = 0x1,
838838

839+
/** \brief Optimization, allocate MSAA textures as committed resources always.
840+
841+
Specify this flag to create MSAA textures with implicit heaps, as if they were created
842+
with flag ALLOCATION_FLAG_COMMITTED. Usage of this flags enables pool to create its heaps
843+
on smaller alignment not suitable for MSAA textures.
844+
*/
845+
POOL_FLAG_MSAA_TEXTURES_ALWAYS_COMMITTED = 0x2,
846+
839847
// Bit mask to extract only `ALGORITHM` bits from entire set of flags.
840848
POOL_FLAG_ALGORITHM_MASK = POOL_FLAG_ALGORITHM_LINEAR
841849
};
@@ -1007,6 +1015,14 @@ enum ALLOCATOR_FLAGS
10071015
Only avaiable if `ID3D12Device8` is present. Otherwise, the flag is ignored.
10081016
*/
10091017
ALLOCATOR_FLAG_DEFAULT_POOLS_NOT_ZEROED = 0x4,
1018+
1019+
/** \brief Optimization, allocate MSAA textures as committed resources always.
1020+
1021+
Specify this flag to create MSAA textures with implicit heaps, as if they were created
1022+
with flag ALLOCATION_FLAG_COMMITTED. Usage of this flags enables all default pools
1023+
to create its heaps on smaller alignment not suitable for MSAA textures.
1024+
*/
1025+
ALLOCATOR_FLAG_MSAA_TEXTURES_ALWAYS_COMMITTED = 0x8,
10101026
};
10111027

10121028
/// \brief Parameters of created Allocator object. To be used with CreateAllocator().

src/D3D12MemAlloc.cpp

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ static D3D12_HEAP_TYPE IndexToHeapType(UINT heapTypeIndex)
446446
return (D3D12_HEAP_TYPE)(heapTypeIndex + 1);
447447
}
448448

449-
static UINT64 HeapFlagsToAlignment(D3D12_HEAP_FLAGS flags)
449+
static UINT64 HeapFlagsToAlignment(D3D12_HEAP_FLAGS flags, bool denyMsaaTextures)
450450
{
451451
/*
452452
Documentation of D3D12_HEAP_DESC structure says:
@@ -459,6 +459,9 @@ static UINT64 HeapFlagsToAlignment(D3D12_HEAP_FLAGS flags)
459459
https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_heap_desc
460460
*/
461461

462+
if (denyMsaaTextures)
463+
return D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT;
464+
462465
const D3D12_HEAP_FLAGS denyAllTexturesFlags =
463466
D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES | D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES;
464467
const bool canContainAnyTextures =
@@ -3815,7 +3818,7 @@ bool BlockMetadata_Linear::Validate() const
38153818
{
38163819
if (!IsVirtual())
38173820
{
3818-
D3D12MA_VALIDATE((UINT64)alloc->GetAllocHandle() == suballoc.offset);
3821+
D3D12MA_VALIDATE(GetAllocationOffset(alloc->GetAllocHandle()) == suballoc.offset);
38193822
D3D12MA_VALIDATE(alloc->GetSize() == suballoc.size);
38203823
}
38213824
sumUsedSize += suballoc.size;
@@ -3857,7 +3860,7 @@ bool BlockMetadata_Linear::Validate() const
38573860
{
38583861
if (!IsVirtual())
38593862
{
3860-
D3D12MA_VALIDATE((UINT64)alloc->GetAllocHandle() == suballoc.offset);
3863+
D3D12MA_VALIDATE(GetAllocationOffset(alloc->GetAllocHandle()) == suballoc.offset);
38613864
D3D12MA_VALIDATE(alloc->GetSize() == suballoc.size);
38623865
}
38633866
sumUsedSize += suballoc.size;
@@ -3891,7 +3894,7 @@ bool BlockMetadata_Linear::Validate() const
38913894
{
38923895
if (!IsVirtual())
38933896
{
3894-
D3D12MA_VALIDATE((UINT64)alloc->GetAllocHandle() == suballoc.offset);
3897+
D3D12MA_VALIDATE(GetAllocationOffset(alloc->GetAllocHandle()) == suballoc.offset);
38953898
D3D12MA_VALIDATE(alloc->GetSize() == suballoc.size);
38963899
}
38973900
sumUsedSize += suballoc.size;
@@ -5791,7 +5794,7 @@ class MemoryBlock
57915794
const UINT64 m_Size;
57925795
const UINT m_Id;
57935796

5794-
HRESULT Init(ID3D12ProtectedResourceSession* pProtectedSession);
5797+
HRESULT Init(ID3D12ProtectedResourceSession* pProtectedSession, bool denyMsaaTextures);
57955798

57965799
private:
57975800
ID3D12Heap* m_Heap = NULL;
@@ -5823,7 +5826,7 @@ class NormalBlock : public MemoryBlock
58235826
BlockVector* GetBlockVector() const { return m_BlockVector; }
58245827

58255828
// 'algorithm' should be one of the *_ALGORITHM_* flags in enums POOL_FLAGS or VIRTUAL_BLOCK_FLAGS
5826-
HRESULT Init(UINT32 algorithm, ID3D12ProtectedResourceSession* pProtectedSession);
5829+
HRESULT Init(UINT32 algorithm, ID3D12ProtectedResourceSession* pProtectedSession, bool denyMsaaTextures);
58275830

58285831
// Validates all data structures inside this object. If not valid, returns false.
58295832
bool Validate() const;
@@ -5934,13 +5937,15 @@ class BlockVector
59345937
bool explicitBlockSize,
59355938
UINT64 minAllocationAlignment,
59365939
UINT32 algorithm,
5940+
bool denyMsaaTextures,
59375941
ID3D12ProtectedResourceSession* pProtectedSession);
59385942
~BlockVector();
59395943

59405944
const D3D12_HEAP_PROPERTIES& GetHeapProperties() const { return m_HeapProps; }
59415945
D3D12_HEAP_FLAGS GetHeapFlags() const { return m_HeapFlags; }
59425946
UINT64 GetPreferredBlockSize() const { return m_PreferredBlockSize; }
59435947
UINT32 GetAlgorithm() const { return m_Algorithm; }
5948+
bool DeniesMsaaTextures() const { return m_DenyMsaaTextures; }
59445949
// To be used only while the m_Mutex is locked. Used during defragmentation.
59455950
size_t GetBlockCount() const { return m_Blocks.size(); }
59465951
// To be used only while the m_Mutex is locked. Used during defragmentation.
@@ -5998,6 +6003,7 @@ class BlockVector
59986003
const bool m_ExplicitBlockSize;
59996004
const UINT64 m_MinAllocationAlignment;
60006005
const UINT32 m_Algorithm;
6006+
const bool m_DenyMsaaTextures;
60016007
ID3D12ProtectedResourceSession* const m_ProtectedSession;
60026008
/* There can be at most one allocation that is completely empty - a
60036009
hysteresis to avoid pessimistic case of alternating creation and destruction
@@ -6420,6 +6426,7 @@ class AllocatorPimpl
64206426

64216427
const bool m_UseMutex;
64226428
const bool m_AlwaysCommitted;
6429+
const bool m_MsaaAlwaysCommitted;
64236430
ID3D12Device* m_Device; // AddRef
64246431
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
64256432
ID3D12Device4* m_Device4 = NULL; // AddRef, optional
@@ -6511,6 +6518,7 @@ class AllocatorPimpl
65116518
AllocatorPimpl::AllocatorPimpl(const ALLOCATION_CALLBACKS& allocationCallbacks, const ALLOCATOR_DESC& desc)
65126519
: m_UseMutex((desc.Flags & ALLOCATOR_FLAG_SINGLETHREADED) == 0),
65136520
m_AlwaysCommitted((desc.Flags & ALLOCATOR_FLAG_ALWAYS_COMMITTED) != 0),
6521+
m_MsaaAlwaysCommitted((desc.Flags & ALLOCATOR_FLAG_MSAA_TEXTURES_ALWAYS_COMMITTED) != 0),
65146522
m_Device(desc.pDevice),
65156523
m_Adapter(desc.pAdapter),
65166524
m_PreferredBlockSize(desc.PreferredBlockSize != 0 ? desc.PreferredBlockSize : D3D12MA_DEFAULT_BLOCK_SIZE),
@@ -6594,7 +6602,8 @@ HRESULT AllocatorPimpl::Init(const ALLOCATOR_DESC& desc)
65946602
SIZE_MAX, // maxBlockCount
65956603
false, // explicitBlockSize
65966604
D3D12MA_DEBUG_ALIGNMENT, // minAllocationAlignment
6597-
0, // Default algorithm
6605+
0, // Default algorithm,
6606+
m_MsaaAlwaysCommitted,
65986607
NULL); // pProtectedSession
65996608
// No need to call m_pBlockVectors[i]->CreateMinBlocks here, becase minBlockCount is 0.
66006609
}
@@ -7493,7 +7502,7 @@ HRESULT AllocatorPimpl::AllocateCommittedResource(
74937502
{
74947503
D3D12_RESOURCE_ALLOCATION_INFO heapAllocInfo = {};
74957504
heapAllocInfo.SizeInBytes = resourceSize;
7496-
heapAllocInfo.Alignment = HeapFlagsToAlignment(committedAllocParams.m_HeapFlags);
7505+
heapAllocInfo.Alignment = HeapFlagsToAlignment(committedAllocParams.m_HeapFlags, m_MsaaAlwaysCommitted);
74977506
hr = AllocateHeap(committedAllocParams, heapAllocInfo, withinBudget, pPrivateData, ppAllocation);
74987507
if (SUCCEEDED(hr))
74997508
{
@@ -7608,7 +7617,7 @@ HRESULT AllocatorPimpl::AllocateCommittedResource2(
76087617
{
76097618
D3D12_RESOURCE_ALLOCATION_INFO heapAllocInfo = {};
76107619
heapAllocInfo.SizeInBytes = resourceSize;
7611-
heapAllocInfo.Alignment = HeapFlagsToAlignment(committedAllocParams.m_HeapFlags);
7620+
heapAllocInfo.Alignment = HeapFlagsToAlignment(committedAllocParams.m_HeapFlags, m_MsaaAlwaysCommitted);
76127621
hr = AllocateHeap(committedAllocParams, heapAllocInfo, withinBudget, pPrivateData, ppAllocation);
76137622
if (SUCCEEDED(hr))
76147623
{
@@ -7732,10 +7741,12 @@ HRESULT AllocatorPimpl::CalcAllocationParams(const ALLOCATION_DESC& allocDesc, U
77327741
outCommittedAllocationParams = CommittedAllocationParameters();
77337742
outPreferCommitted = false;
77347743

7744+
bool msaaAlwaysCommitted;
77357745
if (allocDesc.CustomPool != NULL)
77367746
{
77377747
PoolPimpl* const pool = allocDesc.CustomPool->m_Pimpl;
77387748

7749+
msaaAlwaysCommitted = pool->GetBlockVector()->DeniesMsaaTextures();
77397750
outBlockVector = pool->GetBlockVector();
77407751

77417752
outCommittedAllocationParams.m_ProtectedSession = pool->GetDesc().pProtectedSession;
@@ -7749,6 +7760,7 @@ HRESULT AllocatorPimpl::CalcAllocationParams(const ALLOCATION_DESC& allocDesc, U
77497760
{
77507761
return E_INVALIDARG;
77517762
}
7763+
msaaAlwaysCommitted = m_MsaaAlwaysCommitted;
77527764

77537765
outCommittedAllocationParams.m_HeapProperties = StandardHeapTypeToHeapProperties(allocDesc.HeapType);
77547766
outCommittedAllocationParams.m_HeapFlags = allocDesc.ExtraHeapFlags;
@@ -7790,9 +7802,12 @@ HRESULT AllocatorPimpl::CalcAllocationParams(const ALLOCATION_DESC& allocDesc, U
77907802
}
77917803
outCommittedAllocationParams.m_CanAlias = allocDesc.Flags & ALLOCATION_FLAG_CAN_ALIAS;
77927804

7793-
if (resDesc != NULL && !outPreferCommitted && PrefersCommittedAllocation(*resDesc))
7805+
if (resDesc != NULL)
77947806
{
7795-
outPreferCommitted = true;
7807+
if (resDesc->SampleDesc.Count > 1 && msaaAlwaysCommitted)
7808+
outBlockVector = NULL;
7809+
if (!outPreferCommitted && PrefersCommittedAllocation(*resDesc))
7810+
outPreferCommitted = true;
77967811
}
77977812

77987813
return (outBlockVector != NULL || outCommittedAllocationParams.m_List != NULL) ? S_OK : E_INVALIDARG;
@@ -8045,14 +8060,14 @@ MemoryBlock::~MemoryBlock()
80458060
}
80468061
}
80478062

8048-
HRESULT MemoryBlock::Init(ID3D12ProtectedResourceSession* pProtectedSession)
8063+
HRESULT MemoryBlock::Init(ID3D12ProtectedResourceSession* pProtectedSession, bool denyMsaaTextures)
80498064
{
80508065
D3D12MA_ASSERT(m_Heap == NULL && m_Size > 0);
80518066

80528067
D3D12_HEAP_DESC heapDesc = {};
80538068
heapDesc.SizeInBytes = m_Size;
80548069
heapDesc.Properties = m_HeapProps;
8055-
heapDesc.Alignment = HeapFlagsToAlignment(m_HeapFlags);
8070+
heapDesc.Alignment = HeapFlagsToAlignment(m_HeapFlags, denyMsaaTextures);
80568071
heapDesc.Flags = m_HeapFlags;
80578072

80588073
HRESULT hr;
@@ -8102,9 +8117,9 @@ NormalBlock::~NormalBlock()
81028117
}
81038118
}
81048119

8105-
HRESULT NormalBlock::Init(UINT32 algorithm, ID3D12ProtectedResourceSession* pProtectedSession)
8120+
HRESULT NormalBlock::Init(UINT32 algorithm, ID3D12ProtectedResourceSession* pProtectedSession, bool denyMsaaTextures)
81068121
{
8107-
HRESULT hr = MemoryBlock::Init(pProtectedSession);
8122+
HRESULT hr = MemoryBlock::Init(pProtectedSession, denyMsaaTextures);
81088123
if (FAILED(hr))
81098124
{
81108125
return hr;
@@ -8226,6 +8241,7 @@ BlockVector::BlockVector(
82268241
bool explicitBlockSize,
82278242
UINT64 minAllocationAlignment,
82288243
UINT32 algorithm,
8244+
bool denyMsaaTextures,
82298245
ID3D12ProtectedResourceSession* pProtectedSession)
82308246
: m_hAllocator(hAllocator),
82318247
m_HeapProps(heapProps),
@@ -8236,6 +8252,7 @@ BlockVector::BlockVector(
82368252
m_ExplicitBlockSize(explicitBlockSize),
82378253
m_MinAllocationAlignment(minAllocationAlignment),
82388254
m_Algorithm(algorithm),
8255+
m_DenyMsaaTextures(denyMsaaTextures),
82398256
m_ProtectedSession(pProtectedSession),
82408257
m_HasEmptyBlock(false),
82418258
m_Blocks(hAllocator->GetAllocs()),
@@ -8765,7 +8782,7 @@ HRESULT BlockVector::CreateBlock(
87658782
m_HeapFlags,
87668783
blockSize,
87678784
m_NextBlockId++);
8768-
HRESULT hr = pBlock->Init(m_Algorithm, m_ProtectedSession);
8785+
HRESULT hr = pBlock->Init(m_Algorithm, m_ProtectedSession, m_DenyMsaaTextures);
87698786
if (FAILED(hr))
87708787
{
87718788
D3D12MA_DELETE(m_hAllocator->GetAllocs(), pBlock);
@@ -9433,6 +9450,7 @@ PoolPimpl::PoolPimpl(AllocatorPimpl* allocator, const POOL_DESC& desc)
94339450
explicitBlockSize,
94349451
D3D12MA_MAX(desc.MinAllocationAlignment, (UINT64)D3D12MA_DEBUG_ALIGNMENT),
94359452
desc.Flags & POOL_FLAG_ALGORITHM_MASK,
9453+
desc.Flags & POOL_FLAG_MSAA_TEXTURES_ALWAYS_COMMITTED,
94369454
desc.pProtectedSession);
94379455
}
94389456

src/Tests.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,6 +1486,39 @@ static void TestAliasingImplicitCommitted(const TestContext& ctx)
14861486
CHECK_BOOL(aliasingRes != NULL);
14871487
}
14881488

1489+
static void TestPoolMsaaTextureAsCommitted(const TestContext& ctx)
1490+
{
1491+
wprintf(L"Test MSAA texture always as committed in pool\n");
1492+
1493+
D3D12MA::POOL_DESC poolDesc = {};
1494+
poolDesc.HeapFlags = D3D12_HEAP_FLAG_ALLOW_ONLY_RT_DS_TEXTURES;
1495+
poolDesc.HeapProperties.Type = D3D12_HEAP_TYPE_DEFAULT;
1496+
poolDesc.Flags = D3D12MA::POOL_FLAG_MSAA_TEXTURES_ALWAYS_COMMITTED;
1497+
1498+
ComPtr<D3D12MA::Pool> pool;
1499+
CHECK_HR(ctx.allocator->CreatePool(&poolDesc, &pool));
1500+
1501+
D3D12MA::ALLOCATION_DESC allocDesc = {};
1502+
allocDesc.CustomPool = pool.Get();
1503+
1504+
D3D12_RESOURCE_DESC resDesc = {};
1505+
resDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
1506+
resDesc.Width = 1024;
1507+
resDesc.Height = 512;
1508+
resDesc.DepthOrArraySize = 1;
1509+
resDesc.MipLevels = 1;
1510+
resDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
1511+
resDesc.SampleDesc.Count = 2;
1512+
resDesc.SampleDesc.Quality = 0;
1513+
resDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
1514+
resDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
1515+
1516+
ComPtr<D3D12MA::Allocation> alloc;
1517+
CHECK_HR(ctx.allocator->CreateResource(&allocDesc, &resDesc, D3D12_RESOURCE_STATE_RENDER_TARGET, nullptr, &alloc, IID_NULL, nullptr));
1518+
// Committed allocation should not have explicit heap
1519+
CHECK_BOOL(alloc->GetHeap() == nullptr);
1520+
}
1521+
14891522
static void TestMapping(const TestContext& ctx)
14901523
{
14911524
wprintf(L"Test mapping\n");
@@ -4042,6 +4075,7 @@ static void TestGroupBasics(const TestContext& ctx)
40424075
TestStandardCustomCommittedPlaced(ctx);
40434076
TestAliasingMemory(ctx);
40444077
TestAliasingImplicitCommitted(ctx);
4078+
TestPoolMsaaTextureAsCommitted(ctx);
40454079
TestMapping(ctx);
40464080
TestStats(ctx);
40474081
TestTransfer(ctx);

0 commit comments

Comments
 (0)